From 3c2a1171fff245eedee4c2cd3e12c554d20c505e Mon Sep 17 00:00:00 2001 From: diego Date: Tue, 9 Jun 2020 15:17:01 -0500 Subject: [PATCH 0001/2410] Adding latch tests for shift&mask AST dynamic part-select enhancements --- tests/various/dynamic_part_select.ys | 82 ++++++++-- .../dynamic_part_select/forloop_select.v | 16 +- .../dynamic_part_select/forloop_select_gate.v | 9 +- tests/various/dynamic_part_select/latch_002.v | 13 ++ .../dynamic_part_select/latch_002_gate.v | 18 +++ .../dynamic_part_select/latch_002_gate_good.v | 141 ++++++++++++++++++ .../various/dynamic_part_select/latch_1990.v | 12 ++ .../dynamic_part_select/latch_1990_gate.v | 6 + .../dynamic_part_select/multiple_blocking.v | 9 +- .../multiple_blocking_gate.v | 9 +- .../various/dynamic_part_select/nonblocking.v | 9 +- .../dynamic_part_select/nonblocking_gate.v | 9 +- tests/various/dynamic_part_select/original.v | 9 +- .../dynamic_part_select/original_gate.v | 9 +- .../various/dynamic_part_select/reset_test.v | 12 +- .../dynamic_part_select/reset_test_gate.v | 12 +- tests/various/dynamic_part_select/reversed.v | 9 +- .../dynamic_part_select/reversed_gate.v | 9 +- 18 files changed, 325 insertions(+), 68 deletions(-) create mode 100644 tests/various/dynamic_part_select/latch_002.v create mode 100644 tests/various/dynamic_part_select/latch_002_gate.v create mode 100644 tests/various/dynamic_part_select/latch_002_gate_good.v create mode 100644 tests/various/dynamic_part_select/latch_1990.v create mode 100644 tests/various/dynamic_part_select/latch_1990_gate.v diff --git a/tests/various/dynamic_part_select.ys b/tests/various/dynamic_part_select.ys index abc1daad642..7db0f62c074 100644 --- a/tests/various/dynamic_part_select.ys +++ b/tests/various/dynamic_part_select.ys @@ -3,18 +3,18 @@ read_verilog ./dynamic_part_select/original.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/original_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + ### Multiple blocking assingments ### design -reset read_verilog ./dynamic_part_select/multiple_blocking.v @@ -29,7 +29,7 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv @@ -39,7 +39,7 @@ read_verilog ./dynamic_part_select/nonblocking.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/nonblocking_gate.v proc rename -top gate @@ -47,7 +47,7 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv @@ -57,7 +57,7 @@ read_verilog ./dynamic_part_select/forloop_select.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/forloop_select_gate.v proc rename -top gate @@ -65,7 +65,7 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv @@ -75,12 +75,12 @@ read_verilog ./dynamic_part_select/reset_test.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/reset_test_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate @@ -93,14 +93,70 @@ read_verilog ./dynamic_part_select/reversed.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/reversed_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv + +### Latches +## Issue 1990 +design -reset +read_verilog ./dynamic_part_select/latch_1990.v +hierarchy -top latch_1990; prep; async2sync +rename -top gold +design -stash gold + +read_verilog ./dynamic_part_select/latch_1990_gate.v +hierarchy -top latch_1990_gate; prep +rename -top gate +design -stash gate + +design -copy-from gold -as gold gold +design -copy-from gate -as gate gate + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv +sat -prove-asserts -show-public -verify -set-init-zero equiv + +### +## Part select with obvious latch, expected to fail due comparison with old shift&mask AST transformation +design -reset +read_verilog ./dynamic_part_select/latch_002.v +hierarchy -top latch_002; prep; async2sync +rename -top gold +design -stash gold + +read_verilog ./dynamic_part_select/latch_002_gate.v +hierarchy -top latch_002_gate; prep; async2sync +rename -top gate +design -stash gate + +design -copy-from gold -as gold gold +design -copy-from gate -as gate gate + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv +sat -prove-asserts -seq 10 -show-public -falsify -set-init-zero equiv + +## Part select + latch, with no shift&mask +design -reset +read_verilog ./dynamic_part_select/latch_002.v +hierarchy -top latch_002; prep; async2sync +rename -top gold +design -stash gold + +read_verilog ./dynamic_part_select/latch_002_gate_good.v +hierarchy -top latch_002_gate; prep; async2sync +rename -top gate +design -stash gate + +design -copy-from gold -as gold gold +design -copy-from gate -as gate gate + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv +sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv diff --git a/tests/various/dynamic_part_select/forloop_select.v b/tests/various/dynamic_part_select/forloop_select.v index 8260f3186d1..926fb3133e7 100644 --- a/tests/various/dynamic_part_select/forloop_select.v +++ b/tests/various/dynamic_part_select/forloop_select.v @@ -1,13 +1,14 @@ +`default_nettype none module forloop_select #(parameter WIDTH=16, SELW=4, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input en, + (input wire clk, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire en, output reg [WIDTH-1:0] dout); - - reg [SELW:0] sel; + + reg [SELW:0] sel; localparam SLICE = WIDTH/(SELW**2); - + always @(posedge clk) begin if (en) begin @@ -16,4 +17,3 @@ module forloop_select #(parameter WIDTH=16, SELW=4, CTRLW=$clog2(WIDTH), DINW=2* end end endmodule - diff --git a/tests/various/dynamic_part_select/forloop_select_gate.v b/tests/various/dynamic_part_select/forloop_select_gate.v index 71ae88537ce..1a5fffdc73c 100644 --- a/tests/various/dynamic_part_select/forloop_select_gate.v +++ b/tests/various/dynamic_part_select/forloop_select_gate.v @@ -1,8 +1,9 @@ +`default_nettype none module forloop_select_gate (clk, ctrl, din, en, dout); - input clk; - input [3:0] ctrl; - input [15:0] din; - input en; + input wire clk; + input wire [3:0] ctrl; + input wire [15:0] din; + input wire en; output reg [15:0] dout; reg [4:0] sel; always @(posedge clk) diff --git a/tests/various/dynamic_part_select/latch_002.v b/tests/various/dynamic_part_select/latch_002.v new file mode 100644 index 00000000000..7617d6a7287 --- /dev/null +++ b/tests/various/dynamic_part_select/latch_002.v @@ -0,0 +1,13 @@ +`default_nettype none +module latch_002 + (dword, sel, st, vect); + output reg [63:0] dword; + input wire [7:0] vect; + input wire [7:0] sel; + input wire st; + + always @(*) begin + if (st) + dword[8*sel +:8] <= vect[7:0]; + end +endmodule // latch_002 diff --git a/tests/various/dynamic_part_select/latch_002_gate.v b/tests/various/dynamic_part_select/latch_002_gate.v new file mode 100644 index 00000000000..4acf129c653 --- /dev/null +++ b/tests/various/dynamic_part_select/latch_002_gate.v @@ -0,0 +1,18 @@ +`default_nettype none +module latch_002_gate(dword, vect, sel, st); + output reg [63:0] dword; + input wire [7:0] vect; + input wire [7:0] sel; + input wire st; + reg [63:0] mask; + reg [63:0] data; + always @* + case (|(st)) + 1'b 1: + begin + mask = (8'b 11111111)<<((((8)*(sel)))+(0)); + data = ((8'b 11111111)&(vect[7:0]))<<((((8)*(sel)))+(0)); + dword <= ((dword)&(~(mask)))|(data); + end + endcase +endmodule diff --git a/tests/various/dynamic_part_select/latch_002_gate_good.v b/tests/various/dynamic_part_select/latch_002_gate_good.v new file mode 100644 index 00000000000..809c74fc918 --- /dev/null +++ b/tests/various/dynamic_part_select/latch_002_gate_good.v @@ -0,0 +1,141 @@ +`default_nettype none +module latch_002_gate (dword, vect, sel, st); + output reg [63:0] dword; + input wire [7:0] vect; + input wire [7:0] sel; + input st; + always @* + case (|(st)) + 1'b 1: + case ((((8)*(sel)))+(0)) + 0: + dword[7:0] <= vect[7:0]; + 1: + dword[8:1] <= vect[7:0]; + 2: + dword[9:2] <= vect[7:0]; + 3: + dword[10:3] <= vect[7:0]; + 4: + dword[11:4] <= vect[7:0]; + 5: + dword[12:5] <= vect[7:0]; + 6: + dword[13:6] <= vect[7:0]; + 7: + dword[14:7] <= vect[7:0]; + 8: + dword[15:8] <= vect[7:0]; + 9: + dword[16:9] <= vect[7:0]; + 10: + dword[17:10] <= vect[7:0]; + 11: + dword[18:11] <= vect[7:0]; + 12: + dword[19:12] <= vect[7:0]; + 13: + dword[20:13] <= vect[7:0]; + 14: + dword[21:14] <= vect[7:0]; + 15: + dword[22:15] <= vect[7:0]; + 16: + dword[23:16] <= vect[7:0]; + 17: + dword[24:17] <= vect[7:0]; + 18: + dword[25:18] <= vect[7:0]; + 19: + dword[26:19] <= vect[7:0]; + 20: + dword[27:20] <= vect[7:0]; + 21: + dword[28:21] <= vect[7:0]; + 22: + dword[29:22] <= vect[7:0]; + 23: + dword[30:23] <= vect[7:0]; + 24: + dword[31:24] <= vect[7:0]; + 25: + dword[32:25] <= vect[7:0]; + 26: + dword[33:26] <= vect[7:0]; + 27: + dword[34:27] <= vect[7:0]; + 28: + dword[35:28] <= vect[7:0]; + 29: + dword[36:29] <= vect[7:0]; + 30: + dword[37:30] <= vect[7:0]; + 31: + dword[38:31] <= vect[7:0]; + 32: + dword[39:32] <= vect[7:0]; + 33: + dword[40:33] <= vect[7:0]; + 34: + dword[41:34] <= vect[7:0]; + 35: + dword[42:35] <= vect[7:0]; + 36: + dword[43:36] <= vect[7:0]; + 37: + dword[44:37] <= vect[7:0]; + 38: + dword[45:38] <= vect[7:0]; + 39: + dword[46:39] <= vect[7:0]; + 40: + dword[47:40] <= vect[7:0]; + 41: + dword[48:41] <= vect[7:0]; + 42: + dword[49:42] <= vect[7:0]; + 43: + dword[50:43] <= vect[7:0]; + 44: + dword[51:44] <= vect[7:0]; + 45: + dword[52:45] <= vect[7:0]; + 46: + dword[53:46] <= vect[7:0]; + 47: + dword[54:47] <= vect[7:0]; + 48: + dword[55:48] <= vect[7:0]; + 49: + dword[56:49] <= vect[7:0]; + 50: + dword[57:50] <= vect[7:0]; + 51: + dword[58:51] <= vect[7:0]; + 52: + dword[59:52] <= vect[7:0]; + 53: + dword[60:53] <= vect[7:0]; + 54: + dword[61:54] <= vect[7:0]; + 55: + dword[62:55] <= vect[7:0]; + 56: + dword[63:56] <= vect[7:0]; + 57: + dword[63:57] <= vect[7:0]; + 58: + dword[63:58] <= vect[7:0]; + 59: + dword[63:59] <= vect[7:0]; + 60: + dword[63:60] <= vect[7:0]; + 61: + dword[63:61] <= vect[7:0]; + 62: + dword[63:62] <= vect[7:0]; + 63: + dword[63:63] <= vect[7:0]; + endcase + endcase +endmodule diff --git a/tests/various/dynamic_part_select/latch_1990.v b/tests/various/dynamic_part_select/latch_1990.v new file mode 100644 index 00000000000..864c0524499 --- /dev/null +++ b/tests/various/dynamic_part_select/latch_1990.v @@ -0,0 +1,12 @@ +module latch_1990 #( + parameter BUG = 1 +) ( + (* nowrshmsk = !BUG *) + output reg [1:0] x +); + wire z = 0; + integer i; + always @* + for (i = 0; i < 2; i=i+1) + x[z^i] = z^i; +endmodule diff --git a/tests/various/dynamic_part_select/latch_1990_gate.v b/tests/various/dynamic_part_select/latch_1990_gate.v new file mode 100644 index 00000000000..a46183f23fa --- /dev/null +++ b/tests/various/dynamic_part_select/latch_1990_gate.v @@ -0,0 +1,6 @@ +`default_nettype none +module latch_1990_gate + (output wire [1:0] x); + assign x = 2'b10; +endmodule // latch_1990_gate + diff --git a/tests/various/dynamic_part_select/multiple_blocking.v b/tests/various/dynamic_part_select/multiple_blocking.v index 2858f774171..3bb249a7620 100644 --- a/tests/various/dynamic_part_select/multiple_blocking.v +++ b/tests/various/dynamic_part_select/multiple_blocking.v @@ -1,8 +1,9 @@ +`default_nettype none module multiple_blocking #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input [SELW-1:0] sel, + (input wire clk, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire [SELW-1:0] sel, output reg [WIDTH-1:0] dout); localparam SLICE = WIDTH/(SELW**2); diff --git a/tests/various/dynamic_part_select/multiple_blocking_gate.v b/tests/various/dynamic_part_select/multiple_blocking_gate.v index 073b559dc11..8409188765f 100644 --- a/tests/various/dynamic_part_select/multiple_blocking_gate.v +++ b/tests/various/dynamic_part_select/multiple_blocking_gate.v @@ -1,8 +1,9 @@ +`default_nettype none module multiple_blocking_gate (clk, ctrl, din, sel, dout); - input clk; - input [4:0] ctrl; - input [1:0] din; - input [0:0] sel; + input wire clk; + input wire [4:0] ctrl; + input wire [1:0] din; + input wire [0:0] sel; output reg [31:0] dout; reg [5:0] a; reg [0:0] b; diff --git a/tests/various/dynamic_part_select/nonblocking.v b/tests/various/dynamic_part_select/nonblocking.v index 0949b31a965..20f857cf971 100644 --- a/tests/various/dynamic_part_select/nonblocking.v +++ b/tests/various/dynamic_part_select/nonblocking.v @@ -1,8 +1,9 @@ +`default_nettype none module nonblocking #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input [SELW-1:0] sel, + (input wire clk, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire [SELW-1:0] sel, output reg [WIDTH-1:0] dout); localparam SLICE = WIDTH/(SELW**2); diff --git a/tests/various/dynamic_part_select/nonblocking_gate.v b/tests/various/dynamic_part_select/nonblocking_gate.v index ed1ee277660..212d446094a 100644 --- a/tests/various/dynamic_part_select/nonblocking_gate.v +++ b/tests/various/dynamic_part_select/nonblocking_gate.v @@ -1,8 +1,9 @@ +`default_nettype none module nonblocking_gate (clk, ctrl, din, sel, dout); - input clk; - input [4:0] ctrl; - input [1:0] din; - input [0:0] sel; + input wire clk; + input wire [4:0] ctrl; + input wire [1:0] din; + input wire [0:0] sel; output reg [31:0] dout; always @(posedge clk) begin diff --git a/tests/various/dynamic_part_select/original.v b/tests/various/dynamic_part_select/original.v index f7dfed1a13c..41310a21563 100644 --- a/tests/various/dynamic_part_select/original.v +++ b/tests/various/dynamic_part_select/original.v @@ -1,8 +1,9 @@ +`default_nettype none module original #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input [SELW-1:0] sel, + (input wire clk, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire [SELW-1:0] sel, output reg [WIDTH-1:0] dout); localparam SLICE = WIDTH/(SELW**2); always @(posedge clk) diff --git a/tests/various/dynamic_part_select/original_gate.v b/tests/various/dynamic_part_select/original_gate.v index 22093bf6375..963b4228c1a 100644 --- a/tests/various/dynamic_part_select/original_gate.v +++ b/tests/various/dynamic_part_select/original_gate.v @@ -1,8 +1,9 @@ +`default_nettype none module original_gate (clk, ctrl, din, sel, dout); - input clk; - input [4:0] ctrl; - input [1:0] din; - input [0:0] sel; + input wire clk; + input wire [4:0] ctrl; + input wire [1:0] din; + input wire [0:0] sel; output reg [31:0] dout; always @(posedge clk) case (({(ctrl)*(sel)})+(0)) diff --git a/tests/various/dynamic_part_select/reset_test.v b/tests/various/dynamic_part_select/reset_test.v index 29355aafb10..1bb9379f2f0 100644 --- a/tests/various/dynamic_part_select/reset_test.v +++ b/tests/various/dynamic_part_select/reset_test.v @@ -1,8 +1,10 @@ +`default_nettype none module reset_test #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input [SELW-1:0] sel, + (input wire clk, + input wire reset, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire [SELW-1:0] sel, output reg [WIDTH-1:0] dout); reg [SELW:0] i; @@ -16,8 +18,6 @@ module reset_test #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SE dout[i*rval+:SLICE] <= 32'hDEAD; end end - //else begin dout[ctrl*sel+:SLICE] <= din; - //end end endmodule diff --git a/tests/various/dynamic_part_select/reset_test_gate.v b/tests/various/dynamic_part_select/reset_test_gate.v index 96dff4135ac..4ae76c4f78c 100644 --- a/tests/various/dynamic_part_select/reset_test_gate.v +++ b/tests/various/dynamic_part_select/reset_test_gate.v @@ -1,8 +1,10 @@ -module reset_test_gate (clk, ctrl, din, sel, dout); - input clk; - input [4:0] ctrl; - input [1:0] din; - input [0:0] sel; +`default_nettype none +module reset_test_gate (clk, reset, ctrl, din, sel, dout); + input wire clk; + input wire reset; + input wire [4:0] ctrl; + input wire [1:0] din; + input wire [0:0] sel; output reg [31:0] dout; reg [1:0] i; wire [0:0] rval; diff --git a/tests/various/dynamic_part_select/reversed.v b/tests/various/dynamic_part_select/reversed.v index 8b114ac771f..0268fa6bb0d 100644 --- a/tests/various/dynamic_part_select/reversed.v +++ b/tests/various/dynamic_part_select/reversed.v @@ -1,8 +1,9 @@ +`default_nettype none module reversed #(parameter WIDTH=32, SELW=4, CTRLW=$clog2(WIDTH), DINW=2**SELW) - (input clk, - input [CTRLW-1:0] ctrl, - input [DINW-1:0] din, - input [SELW-1:0] sel, + (input wire clk, + input wire [CTRLW-1:0] ctrl, + input wire [DINW-1:0] din, + input wire [SELW-1:0] sel, output reg [WIDTH-1:0] dout); localparam SLICE = WIDTH/(SELW**2); diff --git a/tests/various/dynamic_part_select/reversed_gate.v b/tests/various/dynamic_part_select/reversed_gate.v index 9349d45eeea..5ffdcb4d791 100644 --- a/tests/various/dynamic_part_select/reversed_gate.v +++ b/tests/various/dynamic_part_select/reversed_gate.v @@ -1,8 +1,9 @@ +`default_nettype none module reversed_gate (clk, ctrl, din, sel, dout); - input clk; - input [4:0] ctrl; - input [15:0] din; - input [3:0] sel; + input wire clk; + input wire [4:0] ctrl; + input wire [15:0] din; + input wire [3:0] sel; output reg [31:0] dout; always @(posedge clk) case ((({(32)-((ctrl)*(sel))})+(1))-(2)) From d68a8f9e2b20d9c4120a69e1a632a2d86250be86 Mon Sep 17 00:00:00 2001 From: diego Date: Wed, 10 Jun 2020 10:35:40 -0500 Subject: [PATCH 0002/2410] Removing trailing whitespace --- tests/various/dynamic_part_select.ys | 60 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/various/dynamic_part_select.ys b/tests/various/dynamic_part_select.ys index 7db0f62c074..2dc061e899b 100644 --- a/tests/various/dynamic_part_select.ys +++ b/tests/various/dynamic_part_select.ys @@ -3,105 +3,105 @@ read_verilog ./dynamic_part_select/original.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/original_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + ### Multiple blocking assingments ### design -reset read_verilog ./dynamic_part_select/multiple_blocking.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/multiple_blocking_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + ### Non-blocking to the same output register ### design -reset read_verilog ./dynamic_part_select/nonblocking.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/nonblocking_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + ### For-loop select, one dynamic input design -reset read_verilog ./dynamic_part_select/forloop_select.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/forloop_select_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + #### Double loop (part-select, reset) ### design -reset read_verilog ./dynamic_part_select/reset_test.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/reset_test_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv - + ### Reversed part-select case ### design -reset read_verilog ./dynamic_part_select/reversed.v proc rename -top gold design -stash gold - + read_verilog ./dynamic_part_select/reversed_gate.v proc rename -top gate design -stash gate - + design -copy-from gold -as gold gold design -copy-from gate -as gate gate - + miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv @@ -120,8 +120,8 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - -miter -equiv -make_assert -make_outcmp -flatten gold gate equiv + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -show-public -verify -set-init-zero equiv ### @@ -139,8 +139,8 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - -miter -equiv -make_assert -make_outcmp -flatten gold gate equiv + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv sat -prove-asserts -seq 10 -show-public -falsify -set-init-zero equiv ## Part select + latch, with no shift&mask @@ -157,6 +157,6 @@ design -stash gate design -copy-from gold -as gold gold design -copy-from gate -as gate gate - -miter -equiv -make_assert -make_outcmp -flatten gold gate equiv -sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv + +miter -equiv -make_assert -make_outcmp -flatten gold gate equiv +sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv From 5f45fe51ea884e58f689bb876f7e6bafa0b86520 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 20 Apr 2020 21:13:59 +0000 Subject: [PATCH 0003/2410] glift: Add skeleton for `glift` command. --- passes/cmds/Makefile.inc | 1 + passes/cmds/glift.cc | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 passes/cmds/glift.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 53bfd40c64a..5ec2fb6adcf 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -18,6 +18,7 @@ OBJS += passes/cmds/setattr.o OBJS += passes/cmds/copy.o OBJS += passes/cmds/splice.o OBJS += passes/cmds/scc.o +OBJS += passes/cmds/glift.o OBJS += passes/cmds/torder.o OBJS += passes/cmds/logcmd.o OBJS += passes/cmds/tee.o diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc new file mode 100644 index 00000000000..8ef92ddf79c --- /dev/null +++ b/passes/cmds/glift.cc @@ -0,0 +1,50 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Alberto Gonzalez + * + * 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/register.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct GliftPass : public Pass { + GliftPass() : Pass("glift", "create and transform GLIFT models") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" glift [options] [selection]\n"); + log("\n"); + log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); + log("to the current or specified module.\n"); + log("\n"); + log("Options:"); + log("\n"); + log(" -create"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + } +} GliftPass; + +PRIVATE_NAMESPACE_END From 09848b3b9f6de98a8663c48cb19d97b46bb0d620 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Tue, 21 Apr 2020 03:21:28 +0000 Subject: [PATCH 0004/2410] glift: Initial implementation of GLIFT model construction. --- passes/cmds/glift.cc | 175 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 2 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 8ef92ddf79c..58a5ec1c333 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -25,7 +25,158 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { - GliftPass() : Pass("glift", "create and transform GLIFT models") { } + private: + + bool opt_create, opt_taintconstants; + std::vector args; + std::vector::size_type argidx; + RTLIL::Module *module; + + void parse_args() { + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-create") { + opt_create = true; + continue; + } + if (args[argidx] == "-taint-constants") { + opt_taintconstants = true; + continue; + } + break; + } + } + + RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { + RTLIL::SigSpec ret; + + //Get the connected wire for the cell port: + log_assert(sig.is_wire() || sig.is_fully_const()); + log_assert(sig.is_wire() || sig.is_fully_const()); + + //Get a SigSpec for the corresponding taint signal for the cell port, creating one if necessary: + if (sig.is_wire()) { + RTLIL::Wire *w = module->wire(sig.as_wire()->name.str() + "_t"); + if (w == nullptr) w = module->addWire(sig.as_wire()->name.str() + "_t", 1); + ret = w; + } + else if (sig.is_fully_const() && opt_taintconstants) + ret = RTLIL::State::S1; + else if (sig.is_fully_const()) + ret = RTLIL::State::S0; + else + log_cmd_error("Cell port SigSpec has unexpected type.\n"); + + //Finally, if the cell port was a module input or output, make sure the corresponding taint signal is marked, too: + if(sig.is_wire() && sig.as_wire()->port_input) + ret.as_wire()->port_input = true; + if(sig.is_wire() && sig.as_wire()->port_output) + ret.as_wire()->port_output = true; + + return ret; + } + + void create_precise_glift_logic() { + std::vector connections(module->connections()); + std::vector new_connections; + + for(auto &cell : module->cells().to_vector()) { + if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { + log_cmd_error("Invalid cell type \"%s\" found. Module must be techmapped.\n", cell->type.c_str()); + } + if (cell->type.in("$_AND_", "$_OR_")) { + const unsigned int A = 0, B = 1, Y = 2; + const unsigned int NUM_PORTS = 3; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (cell->type == "$_AND_") { + //We are basically trying to replace each AND cell with an AN2_SH2 cell: + //module AN2_SH2(A, A_t, B, B_t, Y, Y_t); + // input A, A_t, B, B_t; + // output Y, Y_t; + // + // assign Y = A & B; + // assign Y_t = A & B_t | B & A_t | A_t & B_t; + //endmodule + auto subexpr1 = module->And(cell->name.str() + "_t_1", ports[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_2", ports[B], port_taints[A], false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_3", port_taints[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_4", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_5", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + } + + else if (cell->type == "$_OR_") { + //We are basically trying to replace each OR cell with an OR2_SH2 cell: + //module OR2_SH2(A, A_t, B, B_t, Y, Y_t); + // input A, A_t, B, B_t; + // output Y, Y_t; + // + // assign Y = A | B; + // assign Y_t = ~A & B_t | ~B & A_t | A_t & B_t; + //endmodule + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1", ports[A], false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_2", ports[B], false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3", n_port_a, port_taints[B], false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_4", n_port_b, port_taints[A], false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_5", port_taints[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_6", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_7", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + } + + else log_cmd_error("This is a bug (1).\n"); + } + else if (cell->type.in("$_NOT_")) { + const unsigned int A = 0, Y = 1; + const unsigned int NUM_PORTS = 2; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (cell->type == "$_NOT_") { + //We are basically trying to replace each NOT cell with an IV_SH2 cell: + //module IV_SH2(A, A_t, Y, Y_t); + // input A, A_t; + // output Y, Y_t; + // + // assign Y = ~A; + // assign Y_t = A_t; + //endmodule + new_connections.emplace_back(port_taints[Y], port_taints[A]); + } + else log_cmd_error("This is a bug (1).\n"); + } + } //end foreach cell in cells + + for (auto &conn : connections) { + RTLIL::SigSpec first = get_corresponding_taint_signal(conn.first); + RTLIL::SigSpec second = get_corresponding_taint_signal(conn.second); + + module->connect(get_corresponding_taint_signal(conn.first), get_corresponding_taint_signal(conn.second)); + + if(conn.second.is_wire() && conn.second.as_wire()->port_input) + second.as_wire()->port_input = true; + if(conn.first.is_wire() && conn.first.as_wire()->port_output) + first.as_wire()->port_output = true; + } //end foreach conn in connections + + for (auto &conn : new_connections) + module->connect(conn); + + module->fixup_ports(); //we have some new taint signals in the module interface + } + + public: + + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_taintconstants(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -41,9 +192,29 @@ struct GliftPass : public Pass { log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); + log(" -taint-constants"); + log(" Constant values in the design are labeled as tainted.\n"); + log(" (default: label constants as un-tainted)\n"); + log("\n"); } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE { + log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + + args = _args; + parse_args(); + extra_args(args, argidx, design); + + for (auto mod : design->selected_modules()) { + if (module) + log_cmd_error("Only one module may be selected for the glift pass! Flatten the design if necessary. (selected: %s and %s)\n", log_id(module), log_id(mod)); + module = mod; + } + if (module == nullptr) + log_cmd_error("Can't operate on an empty selection!\n"); + + if (opt_create) + create_precise_glift_logic(); } } GliftPass; From 19dafcd4f10f944d6d28acc0b02d0f7e2bd69a03 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 22 Apr 2020 06:16:12 +0000 Subject: [PATCH 0005/2410] glift: Initial implementation of the `-sketchify` option. --- passes/cmds/glift.cc | 121 +++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 50 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 58a5ec1c333..bf3f6a73ef3 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_taintconstants; + bool opt_create, opt_sketchify, opt_taintconstants; std::vector args; std::vector::size_type argidx; RTLIL::Module *module; @@ -38,12 +38,18 @@ struct GliftPass : public Pass { opt_create = true; continue; } + if (args[argidx] == "-sketchify") { + opt_sketchify = true; + continue; + } if (args[argidx] == "-taint-constants") { opt_taintconstants = true; continue; } break; } + if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); + if(opt_create && opt_sketchify) log_cmd_error("Only one of `-create` or `-sketchify` may be specified.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -75,7 +81,37 @@ struct GliftPass : public Pass { return ret; } - void create_precise_glift_logic() { + void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH2 or OR2_SH2 + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_1_3", (cell->type == "$_AND_")? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_1_4", (cell->type == "$_AND_")? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_1_5", port_a_taint, port_b_taint, false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_1_6", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_1_7", subexpr4, subexpr3, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH3 or OR2_SH3 + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_2_2", (cell->type == "$_AND_")? port_b : n_port_a, (cell->type == "$_AND_")? port_a_taint : port_b_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_2_3", (cell->type == "$_AND_")? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH4 or OR2_SH4 + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3_2", (cell->type == "$_AND_")? port_a : n_port_b, (cell->type == "$_AND_")? port_b_taint : port_a_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_3_3", (cell->type == "$_AND_")? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH5 or OR2_SH5 + module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); + } + + void create_glift_logic() { std::vector connections(module->connections()); std::vector new_connections; @@ -94,41 +130,27 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (cell->type == "$_AND_") { - //We are basically trying to replace each AND cell with an AN2_SH2 cell: - //module AN2_SH2(A, A_t, B, B_t, Y, Y_t); - // input A, A_t, B, B_t; - // output Y, Y_t; - // - // assign Y = A & B; - // assign Y_t = A & B_t | B & A_t | A_t & B_t; - //endmodule - auto subexpr1 = module->And(cell->name.str() + "_t_1", ports[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_2", ports[B], port_taints[A], false, cell->get_src_attribute()); - auto subexpr3 = module->And(cell->name.str() + "_t_3", port_taints[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr4 = module->Or(cell->name.str() + "_t_4", subexpr1, subexpr2, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_5", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); - } - - else if (cell->type == "$_OR_") { - //We are basically trying to replace each OR cell with an OR2_SH2 cell: - //module OR2_SH2(A, A_t, B, B_t, Y, Y_t); - // input A, A_t, B, B_t; - // output Y, Y_t; - // - // assign Y = A | B; - // assign Y_t = ~A & B_t | ~B & A_t | A_t & B_t; - //endmodule - RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1", ports[A], false, cell->get_src_attribute()); - RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_2", ports[B], false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_3", n_port_a, port_taints[B], false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_4", n_port_b, port_taints[A], false, cell->get_src_attribute()); - auto subexpr3 = module->And(cell->name.str() + "_t_5", port_taints[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr4 = module->Or(cell->name.str() + "_t_6", subexpr1, subexpr2, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_7", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + if (opt_create) + add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); + else if (opt_sketchify) { + RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), + imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), + imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), + imprecise_3_y(module->addWire(cell->name.str() + "_y4", 1)); + + add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], precise_y); + add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_1_y); + add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_2_y); + add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], imprecise_3_y); + + RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", 2)); + meta_mux_select.as_wire()->set_bool_attribute("\\maximize"); + new_connections.emplace_back(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", 2, cell->get_src_attribute())); + RTLIL::SigSpec meta_mux1(module->Mux(cell->name.str() + "_mux1", precise_y, imprecise_1_y, meta_mux_select[1])); + RTLIL::SigSpec meta_mux2(module->Mux(cell->name.str() + "_mux2", imprecise_2_y, imprecise_3_y, meta_mux_select[1])); + module->addMux(cell->name.str() + "_mux3", meta_mux1, meta_mux2, meta_mux_select[0], port_taints[Y]); } - - else log_cmd_error("This is a bug (1).\n"); + else log_cmd_error("This is a bug (2).\n"); } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; @@ -142,17 +164,9 @@ struct GliftPass : public Pass { port_taints[i] = get_corresponding_taint_signal(ports[i]); if (cell->type == "$_NOT_") { - //We are basically trying to replace each NOT cell with an IV_SH2 cell: - //module IV_SH2(A, A_t, Y, Y_t); - // input A, A_t; - // output Y, Y_t; - // - // assign Y = ~A; - // assign Y_t = A_t; - //endmodule new_connections.emplace_back(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (1).\n"); + else log_cmd_error("This is a bug (3).\n"); } } //end foreach cell in cells @@ -176,22 +190,30 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_taintconstants(false), module(nullptr) { } + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" glift [options] [selection]\n"); + log(" glift -create|-sketchify [options] [selection]\n"); log("\n"); log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); log("to the current or specified module.\n"); log("\n"); - log("Options:"); + log("Commands:"); log("\n"); log(" -create"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); + log(" -sketchify"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); + log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); + log(" selected by an $anyconst cell.\n"); + log("\n"); + log("Options:"); + log("\n"); log(" -taint-constants"); log(" Constant values in the design are labeled as tainted.\n"); log(" (default: label constants as un-tainted)\n"); @@ -213,8 +235,7 @@ struct GliftPass : public Pass { if (module == nullptr) log_cmd_error("Can't operate on an empty selection!\n"); - if (opt_create) - create_precise_glift_logic(); + create_glift_logic(); } } GliftPass; From c36440a7ee158f6d9072913358d2cb15badc4a75 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 22 Apr 2020 21:33:22 +0000 Subject: [PATCH 0006/2410] glift: Remove outputs by default; add `-keep-outputs` option; properly reset internal state between calls. --- passes/cmds/glift.cc | 55 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index bf3f6a73ef3..b8c33a3f1d8 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,9 +27,10 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_sketchify, opt_taintconstants; + bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs; std::vector args; std::vector::size_type argidx; + std::vector new_taint_outputs; RTLIL::Module *module; void parse_args() { @@ -46,6 +47,10 @@ struct GliftPass : public Pass { opt_taintconstants = true; continue; } + if (args[argidx] == "-keep-outputs") { + opt_keepoutputs = true; + continue; + } break; } if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); @@ -76,7 +81,7 @@ struct GliftPass : public Pass { if(sig.is_wire() && sig.as_wire()->port_input) ret.as_wire()->port_input = true; if(sig.is_wire() && sig.as_wire()->port_output) - ret.as_wire()->port_output = true; + new_taint_outputs.push_back(ret.as_wire()); return ret; } @@ -144,13 +149,13 @@ struct GliftPass : public Pass { add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], imprecise_3_y); RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", 2)); - meta_mux_select.as_wire()->set_bool_attribute("\\maximize"); + //meta_mux_select.as_wire()->set_bool_attribute("\\maximize"); new_connections.emplace_back(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", 2, cell->get_src_attribute())); RTLIL::SigSpec meta_mux1(module->Mux(cell->name.str() + "_mux1", precise_y, imprecise_1_y, meta_mux_select[1])); RTLIL::SigSpec meta_mux2(module->Mux(cell->name.str() + "_mux2", imprecise_2_y, imprecise_3_y, meta_mux_select[1])); module->addMux(cell->name.str() + "_mux3", meta_mux1, meta_mux2, meta_mux_select[0], port_taints[Y]); } - else log_cmd_error("This is a bug (2).\n"); + else log_cmd_error("This is a bug (1).\n"); } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; @@ -166,7 +171,7 @@ struct GliftPass : public Pass { if (cell->type == "$_NOT_") { new_connections.emplace_back(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (3).\n"); + else log_cmd_error("This is a bug (2).\n"); } } //end foreach cell in cells @@ -179,18 +184,38 @@ struct GliftPass : public Pass { if(conn.second.is_wire() && conn.second.as_wire()->port_input) second.as_wire()->port_input = true; if(conn.first.is_wire() && conn.first.as_wire()->port_output) - first.as_wire()->port_output = true; + new_taint_outputs.push_back(first.as_wire()); } //end foreach conn in connections for (auto &conn : new_connections) module->connect(conn); + for (auto &port_name : module->ports) { + RTLIL::Wire *port = module->wire(port_name); + log_assert(port != nullptr); + if (port->port_output && !opt_keepoutputs) + port->port_output = false; + } + for (auto &output : new_taint_outputs) + output->port_output = true; module->fixup_ports(); //we have some new taint signals in the module interface } + void reset() { + opt_create = false; + opt_sketchify = false; + opt_taintconstants = false; + opt_keepoutputs = false; + module = nullptr; + args.clear(); + argidx = 0; + new_taint_outputs.clear(); + } + public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), module(nullptr) { } + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), module(nullptr) { } + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -200,29 +225,35 @@ struct GliftPass : public Pass { log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); log("to the current or specified module.\n"); log("\n"); - log("Commands:"); + log("Commands:\n"); log("\n"); - log(" -create"); + log(" -create\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -sketchify"); + log(" -sketchify\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); log(" selected by an $anyconst cell.\n"); log("\n"); - log("Options:"); + log("Options:\n"); log("\n"); - log(" -taint-constants"); + log(" -taint-constants\n"); log(" Constant values in the design are labeled as tainted.\n"); log(" (default: label constants as un-tainted)\n"); log("\n"); + log(" -keep-outputs\n"); + log(" Do not remove module outputs. Taint tracking outputs will appear in the module ports\n"); + log(" alongside the orignal outputs.\n"); + log(" (default: original module outputs are removed)\n"); + log("\n"); } void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + reset(); args = _args; parse_args(); extra_args(args, argidx, design); From 72cebef279357435cde115851bc095375763108c Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Thu, 23 Apr 2020 06:41:58 +0000 Subject: [PATCH 0007/2410] glift: Add replacement scoring and area minimization option. --- passes/cmds/glift.cc | 59 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index b8c33a3f1d8..b35179fd155 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,10 +27,11 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs; + bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs, opt_nomodeloptimize; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; + std::vector meta_mux_selects; RTLIL::Module *module; void parse_args() { @@ -51,6 +52,10 @@ struct GliftPass : public Pass { opt_keepoutputs = true; continue; } + if (args[argidx] == "-no-model-optimize") { + opt_nomodeloptimize = true; + continue; + } break; } if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); @@ -116,6 +121,22 @@ struct GliftPass : public Pass { module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); } + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { + log_assert(metamux_select.is_wire()); + log_assert(metamux_select.as_wire()->width == 2); + + RTLIL::Const precise_y_cost(5); //5 AND/OR gates + RTLIL::Const imprecise_1_y_cost(2); + RTLIL::Const imprecise_2_y_cost(2); + RTLIL::Const imprecise_3_y_cost(1); + + RTLIL::SigSpec meta_mux1 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux1", precise_y_cost, imprecise_1_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute()); + RTLIL::SigSpec meta_mux2 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux2", imprecise_2_y_cost, imprecise_3_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute()); + RTLIL::SigSpec ret = module->Pmux(metamux_select.as_wire()->name.str() + "_mux3", meta_mux1, meta_mux2, metamux_select[0], metamux_select.as_wire()->get_src_attribute()); + + return ret; + } + void create_glift_logic() { std::vector connections(module->connections()); std::vector new_connections; @@ -149,8 +170,9 @@ struct GliftPass : public Pass { add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], imprecise_3_y); RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", 2)); - //meta_mux_select.as_wire()->set_bool_attribute("\\maximize"); + meta_mux_selects.push_back(meta_mux_select); new_connections.emplace_back(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", 2, cell->get_src_attribute())); + RTLIL::SigSpec meta_mux1(module->Mux(cell->name.str() + "_mux1", precise_y, imprecise_1_y, meta_mux_select[1])); RTLIL::SigSpec meta_mux2(module->Mux(cell->name.str() + "_mux2", imprecise_2_y, imprecise_3_y, meta_mux_select[1])); module->addMux(cell->name.str() + "_mux3", meta_mux1, meta_mux2, meta_mux_select[0], port_taints[Y]); @@ -187,6 +209,30 @@ struct GliftPass : public Pass { new_taint_outputs.push_back(first.as_wire()); } //end foreach conn in connections + //Create a rough model of area by summing the "weight" score of each meta-mux select: + if (!opt_nomodeloptimize) { + std::vector meta_mux_select_sums; + std::vector meta_mux_select_sums_buf; + for (auto &wire : meta_mux_selects) { + meta_mux_select_sums.emplace_back(score_metamux_select(wire)); + } + for (unsigned int i = 0; meta_mux_select_sums.size() > 1; ) { + meta_mux_select_sums_buf.clear(); + for (i = 0; i + 1 < meta_mux_select_sums.size(); i += 2) { + meta_mux_select_sums_buf.push_back(module->Add(meta_mux_select_sums[i].as_wire()->name.str() + "_add", meta_mux_select_sums[i], meta_mux_select_sums[i+1], false)); + } + if (meta_mux_select_sums.size() % 2 == 1) + meta_mux_select_sums_buf.push_back(meta_mux_select_sums[meta_mux_select_sums.size()-1]); + meta_mux_select_sums.swap(meta_mux_select_sums_buf); + } + if (meta_mux_select_sums.size() > 0) { + meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\minimize"); + meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\keep"); + module->rename(meta_mux_select_sums[0].as_wire(), ID(__glift_weight)); + } + } + + //Add new connections and mark new module outputs: for (auto &conn : new_connections) module->connect(conn); @@ -206,15 +252,17 @@ struct GliftPass : public Pass { opt_sketchify = false; opt_taintconstants = false; opt_keepoutputs = false; + opt_nomodeloptimize = false; module = nullptr; args.clear(); argidx = 0; new_taint_outputs.clear(); + meta_mux_selects.clear(); } public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), module(nullptr) { } + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nomodeloptimize(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -248,7 +296,12 @@ struct GliftPass : public Pass { log(" alongside the orignal outputs.\n"); log(" (default: original module outputs are removed)\n"); log("\n"); + log(" -no-model-optimize\n"); + log(" Do not model imprecise taint tracking logic area and attempt to minimize it.\n"); + log(" (default: model area and give that signal the \"minimize\" attribute)\n"); + log("\n"); } + void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); From ca3844d44e07a86d22d6026861cd405f80b0d321 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Fri, 24 Apr 2020 08:23:08 +0000 Subject: [PATCH 0008/2410] glift: Add examples, including a number of benchmarks used in some academic works. --- examples/smtbmc/Makefile | 6 +- examples/smtbmc/glift/C7552.v | 4194 ++++++++++++++++++++++++++++ examples/smtbmc/glift/C7552.ys | 45 + examples/smtbmc/glift/C880.v | 451 +++ examples/smtbmc/glift/C880.ys | 45 + examples/smtbmc/glift/alu2.v | 400 +++ examples/smtbmc/glift/alu2.ys | 45 + examples/smtbmc/glift/alu4.v | 802 ++++++ examples/smtbmc/glift/alu4.ys | 45 + examples/smtbmc/glift/mux2.ys | 39 + examples/smtbmc/glift/t481.v | 83 + examples/smtbmc/glift/t481.ys | 45 + examples/smtbmc/glift/too_large.v | 345 +++ examples/smtbmc/glift/too_large.ys | 45 + examples/smtbmc/glift/ttt2.v | 220 ++ examples/smtbmc/glift/ttt2.ys | 45 + examples/smtbmc/glift/x1.v | 380 +++ examples/smtbmc/glift/x1.ys | 45 + 18 files changed, 7279 insertions(+), 1 deletion(-) create mode 100755 examples/smtbmc/glift/C7552.v create mode 100644 examples/smtbmc/glift/C7552.ys create mode 100755 examples/smtbmc/glift/C880.v create mode 100644 examples/smtbmc/glift/C880.ys create mode 100755 examples/smtbmc/glift/alu2.v create mode 100644 examples/smtbmc/glift/alu2.ys create mode 100755 examples/smtbmc/glift/alu4.v create mode 100644 examples/smtbmc/glift/alu4.ys create mode 100644 examples/smtbmc/glift/mux2.ys create mode 100755 examples/smtbmc/glift/t481.v create mode 100644 examples/smtbmc/glift/t481.ys create mode 100755 examples/smtbmc/glift/too_large.v create mode 100644 examples/smtbmc/glift/too_large.ys create mode 100755 examples/smtbmc/glift/ttt2.v create mode 100644 examples/smtbmc/glift/ttt2.ys create mode 100755 examples/smtbmc/glift/x1.v create mode 100644 examples/smtbmc/glift/x1.ys diff --git a/examples/smtbmc/Makefile b/examples/smtbmc/Makefile index 61994f942fb..af937ea74d0 100644 --- a/examples/smtbmc/Makefile +++ b/examples/smtbmc/Makefile @@ -1,5 +1,5 @@ -all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 +all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 glift_mux demo1: demo1.smt2 yosys-smtbmc --dump-vcd demo1.vcd demo1.smt2 @@ -31,6 +31,9 @@ demo8: demo8.smt2 demo9: demo9.smt2 yosys-smtbmc -s z3 -t 1 -g demo9.smt2 +glift_mux: + yosys -ql glift_mux.yslog glift/mux2.ys + demo1.smt2: demo1.v yosys -ql demo1.yslog -p 'read_verilog -formal demo1.v; prep -top demo1 -nordff; write_smt2 -wires demo1.smt2' @@ -68,6 +71,7 @@ clean: rm -f demo7.yslog demo7.smt2 rm -f demo8.yslog demo8.smt2 rm -f demo9.yslog demo9.smt2 + rm -f glift_mux.ys .PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 clean diff --git a/examples/smtbmc/glift/C7552.v b/examples/smtbmc/glift/C7552.v new file mode 100755 index 00000000000..47a8b0d37d7 --- /dev/null +++ b/examples/smtbmc/glift/C7552.v @@ -0,0 +1,4194 @@ +module C7552_lev2(pi000, pi001, pi002, pi003, pi004, pi005, pi006, pi007, pi008, pi009, + pi010, pi011, pi012, pi013, pi014, pi015, pi016, pi017, pi018, pi019, + pi020, pi021, pi022, pi023, pi024, pi025, pi026, pi027, pi028, pi029, + pi030, pi031, pi032, pi033, pi034, pi035, pi036, pi037, pi038, pi039, + pi040, pi041, pi042, pi043, pi044, pi045, pi046, pi047, pi048, pi049, + pi050, pi051, pi052, pi053, pi054, pi055, pi056, pi057, pi058, pi059, + pi060, pi061, pi062, pi063, pi064, pi065, pi066, pi067, pi068, pi069, + pi070, pi071, pi072, pi073, pi074, pi075, pi076, pi077, pi078, pi079, + pi080, pi081, pi082, pi083, pi084, pi085, pi086, pi087, pi088, pi089, + pi090, pi091, pi092, pi093, pi094, pi095, pi096, pi097, pi098, pi099, + pi100, pi101, pi102, pi103, pi104, pi105, pi106, pi107, pi108, pi109, + pi110, pi111, pi112, pi113, pi114, pi115, pi116, pi117, pi118, pi119, + pi120, pi121, pi122, pi123, pi124, pi125, pi126, pi127, pi128, pi129, + pi130, pi131, pi132, pi133, pi134, pi135, pi136, pi137, pi138, pi139, + pi140, pi141, pi142, pi143, pi144, pi145, pi146, pi147, pi148, pi149, + pi150, pi151, pi152, pi153, pi154, pi155, pi156, pi157, pi158, pi159, + pi160, pi161, pi162, pi163, pi164, pi165, pi166, pi167, pi168, pi169, + pi170, pi171, pi172, pi173, pi174, pi175, pi176, pi177, pi178, pi179, + pi180, pi181, pi182, pi183, pi184, pi185, pi186, pi187, pi188, pi189, + pi190, pi191, pi192, pi193, pi194, pi195, pi196, pi197, pi198, pi199, + pi200, pi201, pi202, pi203, pi204, pi205, pi206, po000, po001, po002, + po003, po004, po005, po006, po007, po008, po009, po010, po011, po012, + po013, po014, po015, po016, po017, po018, po019, po020, po021, po022, + po023, po024, po025, po026, po027, po028, po029, po030, po031, po032, + po033, po034, po035, po036, po037, po038, po039, po040, po041, po042, + po043, po044, po045, po046, po047, po048, po049, po050, po051, po052, + po053, po054, po055, po056, po057, po058, po059, po060, po061, po062, + po063, po064, po065, po066, po067, po068, po069, po070, po071, po072, + po073, po074, po075, po076, po077, po078, po079, po080, po081, po082, + po083, po084, po085, po086, po087, po088, po089, po090, po091, po092, + po093, po094, po095, po096, po097, po098, po099, po100, po101, po102, + po103, po104, po105, po106, po107); + +input pi000, pi001, pi002, pi003, pi004, pi005, pi006, pi007, pi008, pi009, + pi010, pi011, pi012, pi013, pi014, pi015, pi016, pi017, pi018, pi019, + pi020, pi021, pi022, pi023, pi024, pi025, pi026, pi027, pi028, pi029, + pi030, pi031, pi032, pi033, pi034, pi035, pi036, pi037, pi038, pi039, + pi040, pi041, pi042, pi043, pi044, pi045, pi046, pi047, pi048, pi049, + pi050, pi051, pi052, pi053, pi054, pi055, pi056, pi057, pi058, pi059, + pi060, pi061, pi062, pi063, pi064, pi065, pi066, pi067, pi068, pi069, + pi070, pi071, pi072, pi073, pi074, pi075, pi076, pi077, pi078, pi079, + pi080, pi081, pi082, pi083, pi084, pi085, pi086, pi087, pi088, pi089, + pi090, pi091, pi092, pi093, pi094, pi095, pi096, pi097, pi098, pi099, + pi100, pi101, pi102, pi103, pi104, pi105, pi106, pi107, pi108, pi109, + pi110, pi111, pi112, pi113, pi114, pi115, pi116, pi117, pi118, pi119, + pi120, pi121, pi122, pi123, pi124, pi125, pi126, pi127, pi128, pi129, + pi130, pi131, pi132, pi133, pi134, pi135, pi136, pi137, pi138, pi139, + pi140, pi141, pi142, pi143, pi144, pi145, pi146, pi147, pi148, pi149, + pi150, pi151, pi152, pi153, pi154, pi155, pi156, pi157, pi158, pi159, + pi160, pi161, pi162, pi163, pi164, pi165, pi166, pi167, pi168, pi169, + pi170, pi171, pi172, pi173, pi174, pi175, pi176, pi177, pi178, pi179, + pi180, pi181, pi182, pi183, pi184, pi185, pi186, pi187, pi188, pi189, + pi190, pi191, pi192, pi193, pi194, pi195, pi196, pi197, pi198, pi199, + pi200, pi201, pi202, pi203, pi204, pi205, pi206; + +output po000, po001, po002, po003, po004, po005, po006, po007, po008, po009, + po010, po011, po012, po013, po014, po015, po016, po017, po018, po019, + po020, po021, po022, po023, po024, po025, po026, po027, po028, po029, + po030, po031, po032, po033, po034, po035, po036, po037, po038, po039, + po040, po041, po042, po043, po044, po045, po046, po047, po048, po049, + po050, po051, po052, po053, po054, po055, po056, po057, po058, po059, + po060, po061, po062, po063, po064, po065, po066, po067, po068, po069, + po070, po071, po072, po073, po074, po075, po076, po077, po078, po079, + po080, po081, po082, po083, po084, po085, po086, po087, po088, po089, + po090, po091, po092, po093, po094, po095, po096, po097, po098, po099, + po100, po101, po102, po103, po104, po105, po106, po107; + +wire n2822, n2823, n2824, n2825, n2826, n2827, n2828, n2829, n2830, n2831, + n2832, n2833, n2834, n2835, n2836, n2837, n2838, n2839, n2840, n2841, + n2842, n2843, n2844, n2845, n2846, n2847, n2848, n2849, n2850, n2851, + n2852, n2853, n2854, n2855, n2856, n2857, n2858, n2859, n2860, n2861, + n2862, n2863, n2864, n2865, n2866, n2867, n2868, n2869, n2870, n2871, + n2872, n2873, n2874, n2875, n2876, n2877, n2878, n2879, n2880, n2881, + n2882, n2883, n2884, n2885, n2886, n2887, n2888, n2889, n2890, n2891, + n2892, n2893, n2894, n2895, n2896, n2897, n2898, n2899, n2900, n2901, + n2902, n2903, n2904, n2905, n2906, n2907, n2908, n2909, n2910, n2911, + n2912, n2913, n2914, n2915, n2916, n2917, n2918, n2919, n2920, n2921, + n2922, n2923, n2924, n2925, n2926, n2927, n2928, n2929, n2930, n2931, + n2932, n2933, n2934, n2935, n2936, n2937, n2938, n2939, n2940, n2941, + n2942, n2943, n2944, n2945, n2946, n2947, n2948, n2949, n2950, n2951, + n2952, n2953, n2954, n2955, n2956, n2957, n2958, n2959, n2960, n2961, + n2962, n2963, n2964, n2965, n2966, n2967, n2968, n2969, n2970, n2971, + n2972, n2973, n2974, n2975, n2976, n2977, n2978, n2979, n2980, n2981, + n2982, n2983, n2984, n2985, n2986, n2987, n2988, n2989, n2990, n2991, + n2992, n2993, n2994, n2995, n2996, n2997, n2998, n2999, n3000, n3001, + n3002, n3003, n3004, n3005, n3006, n3007, n3008, n3009, n3010, n3011, + n3012, n3013, n3014, n3015, n3016, n3017, n3018, n3019, n3020, n3021, + n3022, n3023, n3024, n3025, n3026, n3027, n3028, n3029, n3030, n3031, + n3032, n3033, n3034, n3035, n3036, n3037, n3038, n3039, n3040, n3041, + n3042, n3043, n3044, n3045, n3046, n3047, n3048, n3049, n3050, n3051, + n3052, n3053, n3054, n3055, n3056, n3057, n3058, n3059, n3060, n3061, + n3062, n3063, n3064, n3065, n3066, n3067, n3068, n3069, n3070, n3071, + n3072, n3073, n3074, n3075, n3076, n3077, n3078, n3079, n3080, n3081, + n3082, n3083, n3084, n3085, n3086, n3087, n3088, n3089, n3090, n3091, + n3092, n3093, n3094, n3095, n3096, n3097, n3098, n3099, n3100, n3101, + n3102, n3103, n3104, n3105, n3106, n3107, n3108, n3109, n3110, n3111, + n3112, n3113, n3114, n3115, n3116, n3117, n3118, n3119, n3120, n3121, + n3122, n3123, n3124, n3125, n3126, n3127, n3128, n3129, n3130, n3131, + n3132, n3133, n3134, n3135, n3136, n3137, n3138, n3139, n3140, n3141, + n3142, n3143, n3144, n3145, n3146, n3147, n3148, n3149, n3150, n3151, + n3152, n3153, n3154, n3155, n3156, n3157, n3158, n3159, n3160, n3161, + n3162, n3163, n3164, n3165, n3166, n3167, n3168, n3169, n3170, n3171, + n3172, n3173, n3174, n3175, n3176, n3177, n3178, n3179, n3180, n3181, + n3182, n3183, n3184, n3185, n3186, n3187, n3188, n3189, n3190, n3191, + n3192, n3193, n3194, n3195, n3196, n3197, n3198, n3199, n3200, n3201, + n3202, n3203, n3204, n3205, n3206, n3207, n3208, n3209, n3210, n3211, + n3212, n3213, n3214, n3215, n3216, n3217, n3218, n3219, n3220, n3221, + n3222, n3223, n3224, n3225, n3226, n3227, n3228, n3229, n3230, n3231, + n3232, n3233, n3234, n3235, n3236, n3237, n3238, n3239, n3240, n3241, + n3242, n3243, n3244, n3245, n3246, n3247, n3248, n3249, n3250, n3251, + n3252, n3253, n3254, n3255, n3256, n3257, n3258, n3259, n3260, n3261, + n3262, n3263, n3264, n3265, n3266, n3267, n3268, n3269, n3270, n3271, + n3272, n3273, n3274, n3275, n3276, n3277, n3278, n3279, n3280, n3281, + n3282, n3283, n3284, n3285, n3286, n3287, n3288, n3289, n3290, n3291, + n3292, n3293, n3294, n3295, n3296, n3297, n3298, n3299, n3300, n3301, + n3302, n3303, n3304, n3305, n3306, n3307, n3308, n3309, n3310, n3311, + n3312, n3313, n3314, n3315, n3316, n3317, n3318, n3319, n3320, n3321, + n3322, n3323, n3324, n3325, n3326, n3327, n3328, n3329, n3330, n3331, + n3332, n3333, n3334, n3335, n3336, n3337, n3338, n3339, n3340, n3341, + n3342, n3343, n3344, n3345, n3346, n3347, n3348, n3349, n3350, n3351, + n3352, n3353, n3354, n3355, n3356, n3357, n3358, n3359, n3360, n3361, + n3362, n3363, n3364, n3365, n3366, n3367, n3368, n3369, n3370, n3371, + n3372, n3373, n3374, n3375, n3376, n3377, n3378, n3379, n3380, n3381, + n3382, n3383, n3384, n3385, n3386, n3387, n3388, n3389, n3390, n3391, + n3392, n3393, n3394, n3395, n3396, n3397, n3398, n3399, n3400, n3401, + n3402, n3403, n3404, n3405, n3406, n3407, n3408, n3409, n3410, n3411, + n3412, n3413, n3414, n3415, n3416, n3417, n3418, n3419, n3420, n3421, + n3422, n3423, n3424, n3425, n3426, n3427, n3428, n3429, n3430, n3431, + n3432, n3433, n3434, n3435, n3436, n3437, n3438, n3439, n3440, n3441, + n3442, n3443, n3444, n3445, n3446, n3447, n3448, n3449, n3450, n3451, + n3452, n3453, n3454, n3455, n3456, n3457, n3458, n3459, n3460, n3461, + n3462, n3463, n3464, n3465, n3466, n3467, n3468, n3469, n3470, n3471, + n3472, n3473, n3474, n3475, n3476, n3477, n3478, n3479, n3480, n3481, + n3482, n3483, n3484, n3485, n3486, n3487, n3488, n3489, n3490, n3491, + n3492, n3493, n3494, n3495, n3496, n3497, n3498, n3499, n3500, n3501, + n3502, n3503, n3504, n3505, n3506, n3507, n3508, n3509, n3510, n3511, + n3512, n3513, n3514, n3515, n3516, n3517, n3518, n3519, n3520, n3521, + n3522, n3523, n3524, n3525, n3526, n3527, n3528, n3529, n3530, n3531, + n3532, n3533, n3534, n3535, n3536, n3537, n3538, n3539, n3540, n3541, + n3542, n3543, n3544, n3545, n3546, n3547, n3548, n3549, n3550, n3551, + n3552, n3553, n3554, n3555, n3556, n3557, n3558, n3559, n3560, n3561, + n3562, n3563, n3564, n3565, n3566, n3567, n3568, n3569, n3570, n3571, + n3572, n3573, n3574, n3575, n3576, n3577, n3578, n3579, n3580, n3581, + n3582, n3583, n3584, n3585, n3586, n3587, n3588, n3589, n3590, n3591, + n3592, n3593, n3594, n3595, n3596, n3597, n3598, n3599, n3600, n3601, + n3602, n3603, n3604, n3605, n3606, n3607, n3608, n3609, n3610, n3611, + n3612, n3613, n3614, n3615, n3616, n3617, n3618, n3619, n3620, n3621, + n3622, n3623, n3624, n3625, n3626, n3627, n3628, n3629, n3630, n3631, + n3632, n3633, n3634, n3635, n3636, n3637, n3638, n3639, n3640, n3641, + n3642, n3643, n3644, n3645, n3646, n3647, n3648, n3649, n3650, n3651, + n3652, n3653, n3654, n3655, n3656, n3657, n3658, n3659, n3660, n3661, + n3662, n3663, n3664, n3665, n3666, n3667, n3668, n3669, n3670, n3671, + n3672, n3673, n3674, n3675, n3676, n3677, n3678, n3679, n3680, n3681, + n3682, n3683, n3684, n3685, n3686, n3687, n3688, n3689, n3690, n3691, + n3692, n3693, n3694, n3695, n3696, n3697, n3698, n3699, n3700, n3701, + n3702, n3703, n3704, n3705, n3706, n3707, n3708, n3709, n3710, n3711, + n3712, n3713, n3714, n3715, n3716, n3717, n3718, n3719, n3720, n3721, + n3722, n3723, n3724, n3725, n3726, n3727, n3728, n3729, n3730, n3731, + n3732, n3733, n3734, n3735, n3736, n3737, n3738, n3739, n3740, n3741, + n3742, n3743, n3744, n3745, n3746, n3747, n3748, n3749, n3750, n3751, + n3752, n3753, n3754, n3755, n3756, n3757, n3758, n3759, n3760, n3761, + n3762, n3763, n3764, n3765, n3766, n3767, n3768, n3769, n3770, n3771, + n3772, n3773, n3774, n3775, n3776, n3777, n3778, n3779, n3780, n3781, + n3782, n3783, n3784, n3785, n3786, n3787, n3788, n3789, n3790, n3791, + n3792, n3793, n3794, n3795, n3796, n3797, n3798, n3799, n3800, n3801, + n3802, n3803, n3804, n3805, n3806, n3807, n3808, n3809, n3810, n3811, + n3812, n3813, n3814, n3815, n3816, n3817, n3818, n3819, n3820, n3821, + n3822, n3823, n3824, n3825, n3826, n3827, n3828, n3829, n3830, n3831, + n3832, n3833, n3834, n3835, n3836, n3837, n3838, n3839, n3840, n3841, + n3842, n3843, n3844, n3845, n3846, n3847, n3848, n3849, n3850, n3851, + n3852, n3853, n3854, n3855, n3856, n3857, n3858, n3859, n3860, n3861, + n3862, n3863, n3864, n3865, n3866, n3867, n3868, n3869, n3870, n3871, + n3872, n3873, n3874, n3875, n3876, n3877, n3878, n3879, n3880, n3881, + n3882, n3883, n3884, n3885, n3886, n3887, n3888, n3889, n3890, n3891, + n3892, n3893, n3894, n3895, n3896, n3897, n3898, n3899, n3900, n3901, + n3902, n3903, n3904, n3905, n3906, n3907, n3908, n3909, n3910, n3911, + n3912, n3913, n3914, n3915, n3916, n3917, n3918, n3919, n3920, n3921, + n3922, n3923, n3924, n3925, n3926, n3927, n3928, n3929, n3930, n3931, + n3932, n3933, n3934, n3935, n3936, n3937, n3938, n3939, n3940, n3941, + n3942, n3943, n3944, n3945, n3946, n3947, n3948, n3949, n3950, n3951, + n3952, n3953, n3954, n3955, n3956, n3957, n3958, n3959, n3960, n3961, + n3962, n3963, n3964, n3965, n3966, n3967, n3968, n3969, n3970, n3971, + n3972, n3973, n3974, n3975, n3976, n3977, n3978, n3979, n3980, n3981, + n3982, n3983, n3984, n3985, n3986, n3987, n3988, n3989, n3990, n3991, + n3992, n3993, n3994, n3995, n3996, n3997, n3998, n3999, n4000, n4001, + n4002, n4003, n4004, n4005, n4006, n4007, n4008, n4009, n4010, n4011, + n4012, n4013, n4014, n4015, n4016, n4017, n4018, n4019, n4020, n4021, + n4022, n4023, n4024, n4025, n4026, n4027, n4028, n4029, n4030, n4031, + n4032, n4033, n4034, n4035, n4036, n4037, n4038, n4039, n4040, n4041, + n4042, n4043, n4044, n4045, n4046, n4047, n4048, n4049, n4050, n4051, + n4052, n4053, n4054, n4055, n4056, n4057, n4058, n4059, n4060, n4061, + n4062, n4063, n4064, n4065, n4066, n4067, n4068, n4069, n4070, n4071, + n4072, n4073, n4074, n4075, n4076, n4077, n4078, n4079, n4080, n4081, + n4082, n4083, n4084, n4085, n4086, n4087, n4088, n4089, n4090, n4091, + n4092, n4093, n4094, n4095, n4096, n4097, n4098, n4099, n4100, n4101, + n4102, n4103, n4104, n4105, n4106, n4107, n4108, n4109, n4110, n4111, + n4112, n4113, n4114, n4115, n4116, n4117, n4118, n4119, n4120, n4121, + n4122, n4123, n4124, n4125, n4126, n4127, n4128, n4129, n4130, n4131, + n4132, n4133, n4134, n4135, n4136, n4137, n4138, n4139, n4140, n4141, + n4142, n4143, n4144, n4145, n4146, n4147, n4148, n4149, n4150, n4151, + n4152, n4153, n4154, n4155, n4156, n4157, n4158, n4159, n4160, n4161, + n4162, n4163, n4164, n4165, n4166, n4167, n4168, n4169, n4170, n4171, + n4172, n4173, n4174, n4175, n4176, n4177, n4178, n4179, n4180, n4181, + n4182, n4183, n4184, n4185, n4186, n4187, n4188, n4189, n4190, n4191, + n4192, n4193, n4194, n4195, n4196, n4197, n4198, n4199, n4200, n4201, + n4202, n4203, n4204, n4205, n4206, n4207, n4208, n4209, n4210, n4211, + n4212, n4213, n4214, n4215, n4216, n4217, n4218, n4219, n4220, n4221, + n4222, n4223, n4224, n4225, n4226, n4227, n4228, n4229, n4230, n4231, + n4232, n4233, n4234, n4235, n4236, n4237, n4238, n4239, n4240, n4241, + n4242, n4243, n4244, n4245, n4246, n4247, n4248, n4249, n4250, n4251, + n4252, n4253, n4254, n4255, n4256, n4257, n4258, n4259, n4260, n4261, + n4262, n4263, n4264, n4265, n4266, n4267, n4268, n4269, n4270, n4271, + n4272, n4273, n4274, n4275, n4276, n4277, n4278, n4279, n4280, n4281, + n4282, n4283, n4284, n4285, n4286, n4287, n4288, n4289, n4290, n4291, + n4292, n4293, n4294, n4295, n4296, n4297, n4298, n4299, n4300, n4301, + n4302, n4303, n4304, n4305, n4306, n4307, n4308, n4309, n4310, n4311, + n4312, n4313, n4314, n4315, n4316, n4317, n4318, n4319, n4320, n4321, + n4322, n4323, n4324, n4325, n4326, n4327, n4328, n4329, n4330, n4331, + n4332, n4333, n4334, n4335, n4336, n4337, n4338, n4339, n4340, n4341, + n4342, n4343, n4344, n4345, n4346, n4347, n4348, n4349, n4350, n4351, + n4352, n4353, n4354, n4355, n4356, n4357, n4358, n4359, n4360, n4361, + n4362, n4363, n4364, n4365, n4366, n4367, n4368, n4369, n4370, n4371, + n4372, n4373, n4374, n4375, n4376, n4377, n4378, n4379, n4380, n4381, + n4382, n4383, n4384, n4385, n4386, n4387, n4388, n4389, n4390, n4391, + n4392, n4393, n4394, n4395, n4396, n4397, n4398, n4399, n4400, n4401, + n4402, n4403, n4404, n4405, n4406, n4407, n4408, n4409, n4410, n4411, + n4412, n4413, n4414, n4415, n4416, n4417, n4418, n4419, n4420, n4421, + n4422, n4423, n4424, n4425, n4426, n4427, n4428, n4429, n4430, n4431, + n4432, n4433, n4434, n4435, n4436, n4437, n4438, n4439, n4440, n4441, + n4442, n4443, n4444, n4445, n4446, n4447, n4448, n4449, n4450, n4451, + n4452, n4453, n4454, n4455, n4456, n4457, n4458, n4459, n4460, n4461, + n4462, n4463, n4464, n4465, n4466, n4467, n4468, n4469, n4470, n4471, + n4472, n4473, n4474, n4475, n4476, n4477, n4478, n4479, n4480, n4481, + n4482, n4483, n4484, n4485, n4486, n4487, n4488, n4489, n4490, n4491, + n4492, n4493, n4494, n4495, n4496, n4497, n4498, n4499, n4500, n4501, + n4502, n4503, n4504, n4505, n4506, n4507, n4508, n4509, n4510, n4511, + n4512, n4513, n4514, n4515, n4516, n4517, n4518, n4519, n4520, n4521, + n4522, n4523, n4524, n4525, n4526, n4527, n4528, n4529, n4530, n4531, + n4532, n4533, n4534, n4535, n4536, n4537, n4538, n4539, n4540, n4541, + n4542, n4543, n4544, n4545, n4546, n4547, n4548, n4549, n4550, n4551, + n4552, n4553, n4554, n4555, n4556, n4557, n4558, n4559, n4560, n4561, + n4562, n4563, n4564, n4565, n4566, n4567, n4568, n4569, n4570, n4571, + n4572, n4573, n4574, n4575, n4576, n4577, n4578, n4579, n4580, n4581, + n4582, n4583, n4584, n4585, n4586, n4587, n4588, n4589, n4590, n4591, + n4592, n4593, n4594, n4595, n4596, n4597, n4598, n4599, n4600, n4601, + n4602, n4603, n4604, n4605, n4606, n4607, n4608, n4609, n4610, n4611, + n4612, n4613, n4614, n4615, n4616, n4617, n4618, n4619, n4620, n4621, + n4622, n4623, n4624, n4625, n4626, n4627, n4628, n4629, n4630, n4631, + n4632, n4633, n4634, n4635, n4636, n4637, n4638, n4639, n4640, n4641, + n4642, n4643, n4644, n4645, n4646, n4647, n4648, n4649, n4650, n4651, + n4652, n4653, n4654, n4655, n4656, n4657, n4658, n4659, n4660, n4661, + n4662, n4663, n4664, n4665, n4666, n4667, n4668, n4669, n4670, n4671, + n4672, n4673, n4674, n4675, n4676, n4677, n4678, n4679, n4680, n4681, + n4682, n4683, n4684, n4685, n4686, n4687, n4688, n4689, n4690, n4691, + n4692, n4693, n4694, n4695, n4696, n4697, n4698, n4699, n4700, n4701, + n4702, n4703, n4704, n4705, n4706, n4707, n4708, n4709, n4710, n4711, + n4712, n4713, n4714, n4715, n4716, n4717, n4718, n4719, n4720, n4721, + n4722, n4723, n4724, n4725, n4726, n4727, n4728, n4729, n4730, n4731, + n4732, n4733, n4734, n4735, n4736, n4737, n4738, n4739, n4740, n4741, + n4742, n4743, n4744, n4745, n4746, n4747, n4748, n4749, n4750, n4751, + n4752, n4753, n4754, n4755, n4756, n4757, n4758, n4759, n4760, n4761, + n4762, n4763, n4764, n4765, n4766, n4767, n4768, n4769, n4770, n4771, + n4772, n4773, n4774, n4775, n4776, n4777, n4778, n4779, n4780, n4781, + n4782, n4783, n4784, n4785, n4786, n4787, n4788, n4789, n4790, n4791, + n4792, n4793, n4794, n4795, n4796, n4797, n4798, n4799, n4800, n4801, + n4802, n4803, n4804, n4805, n4806, n4807, n4808, n4809, n4810, n4811, + n4812, n4813, n4814, n4815, n4816, n4817, n4818, n4819, n4820, n4821, + n4822, n4823, n4824, n4825, n4826, n4827, n4828, n4829, n4830, n4831, + n4832, n4833, n4834, n4835, n4836, n4837, n4838, n4839, n4840, n4841, + n4842, n4843, n4844, n4845, n4846, n4847, n4848, n4849, n4850, n4851, + n4852, n4853, n4854, n4855, n4856, n4857, n4858, n4859, n4860, n4861, + n4862, n4863, n4864, n4865, n4866, n4867, n4868, n4869, n4870, n4871, + n4872, n4873, n4874, n4875, n4876, n4877, n4878, n4879, n4880, n4881, + n4882, n4883, n4884, n4885, n4886, n4887, n4888, n4889, n4890, n4891, + n4892, n4893, n4894, n4895, n4896, n4897, n4898, n4899, n4900, n4901, + n4902, n4903, n4904, n4905, n4906, n4907, n4908, n4909, n4910, n4911, + n4912, n4913, n4914, n4915, n4916, n4917, n4918, n4919, n4920, n4921, + n4922, n4923, n4924, n4925, n4926, n4927, n4928, n4929, n4930, n4931, + n4932, n4933, n4934, n4935, n4936, n4937, n4938, n4939, n4940, n4941, + n4942, n4943, n4944, n4945, n4946, n4947, n4948, n4949, n4950, n4951, + n4952, n4953, n4954, n4955, n4956, n4957, n4958, n4959, n4960, n4961, + n4962, n4963, n4964, n4965, n4966, n4967, n4968, n4969, n4970, n4971, + n4972, n4973, n4974, n4975, n4976, n4977, n4978, n4979, n4980, n4981, + n4982, n4983, n4984, n4985, n4986, n4987, n4988, n4989, n4990, n4991, + n4992, n4993, n4994, n4995, n4996, n4997, n4998, n4999, n5000, n5001, + n5002, n5003, n5004, n5005, n5006, n5007, n5008, n5009, n5010, n5011, + n5012, n5013, n5014, n5015, n5016, n5017, n5018, n5019, n5020, n5021, + n5022, n5023, n5024, n5025, n5026, n5027, n5028, n5029, n5030, n5031, + n5032, n5033, n5034, n5035, n5036, n5037, n5038, n5039, n5040, n5041, + n5042, n5043, n5044, n5045, n5046, n5047, n5048, n5049, n5050, n5051, + n5052, n5053, n5054, n5055, n5056, n5057, n5058, n5059, n5060, n5061, + n5062, n5063, n5064, n5065, n5066, n5067, n5068, n5069, n5070, n5071, + n5072, n5073, n5074, n5075, n5076, n5077, n5078, n5079, n5080, n5081, + n5082, n5083, n5084, n5085, n5086, n5087, n5088, n5089, n5090, n5091, + n5092, n5093, n5094, n5095, n5096, n5097, n5098, n5099, n5100, n5101, + n5102, n5103, n5104, n5105, n5106, n5107, n5108, n5109, n5110, n5111, + n5112, n5113, n5114, n5115, n5116, n5117, n5118, n5119, n5120, n5121, + n5122, n5123, n5124, n5125, n5126, n5127, n5128, n5129, n5130, n5131, + n5132, n5133, n5134, n5135, n5136, n5137, n5138, n5139, n5140, n5141, + n5142, n5143, n5144, n5145, n5146, n5147, n5148, n5149, n5150, n5151, + n5152, n5153, n5154, n5155, n5156, n5157, n5158, n5159, n5160, n5161, + n5162, n5163, n5164, n5165, n5166, n5167, n5168, n5169, n5170, n5171, + n5172, n5173, n5174, n5175, n5176, n5177, n5178, n5179, n5180, n5181, + n5182, n5183, n5184, n5185, n5186, n5187, n5188, n5189, n5190, n5191, + n5192, n5193, n5194, n5195, n5196, n5197, n5198, n5199, n5200, n5201, + n5202, n5203, n5204, n5205, n5206, n5207, n5208, n5209, n5210, n5211, + n5212, n5213, n5214, n5215, n5216, n5217, n5218, n5219, n5220, n5221, + n5222, n5223, n5224, n5225, n5226, n5227, n5228, n5229, n5230, n5231, + n5232, n5233, n5234, n5235, n5236, n5237, n5238, n5239, n5240, n5241, + n5242, n5243, n5244, n5245, n5246, n5247, n5248, n5249, n5250, n5251, + n5252, n5253, n5254, n5255, n5256, n5257, n5258, n5259, n5260, n5261, + n5262, n5263, n5264, n5265, n5266, n5267, n5268, n5269, n5270, n5271, + n5272, n5273, n5274, n5275, n5276, n5277, n5278, n5279, n5280, n5281, + n5282, n5283, n5284, n5285, n5286, n5287, n5288, n5289, n5290, n5291, + n5292, n5293, n5294, n5295, n5296, n5297, n5298, n5299, n5300, n5301, + n5302, n5303, n5304, n5305, n5306, n5307, n5308, n5309, n5310, n5311, + n5312, n5313, n5314, n5315, n5316, n5317, n5318, n5319, n5320, n5321, + n5322, n5323, n5324, n5325, n5326, n5327, n5328, n5329, n5330, n5331, + n5332, n5333, n5334, n5335, n5336, n5337, n5338, n5339, n5340, n5341, + n5342, n5343, n5344, n5345, n5346, n5347, n5348, n5349, n5350, n5351, + n5352, n5353, n5354, n5355, n5356, n5357, n5358, n5359, n5360, n5361, + n5362, n5363, n5364, n5365, n5366, n5367, n5368, n5369, n5370, n5371, + n5372, n5373, n5374, n5375, n5376, n5377, n5378, n5379, n5380, n5381, + n5382, n5383, n5384, n5385, n5386, n5387, n5388, n5389, n5390, n5391, + n5392, n5393, n5394, n5395, n5396, n5397, n5398, n5399, n5400, n5401, + n5402, n5403, n5404, n5405, n5406, n5407, n5408, n5409, n5410, n5411, + n5412, n5413, n5414, n5415, n5416, n5417, n5418, n5419, n5420, n5421, + n5422, n5423, n5424, n5425, n5426, n5427, n5428, n5429, n5430, n5431, + n5432, n5433, n5434, n5435, n5436, n5437, n5438, n5439, n5440, n5441, + n5442, n5443, n5444, n5445, n5446, n5447, n5448, n5449, n5450, n5451, + n5452, n5453, n5454, n5455, n5456, n5457, n5458, n5459, n5460, n5461, + n5462, n5463, n5464, n5465, n5466, n5467, n5468, n5469, n5470, n5471, + n5472, n5473, n5474, n5475, n5476, n5477, n5478, n5479, n5480, n5481, + n5482, n5483, n5484, n5485, n5486, n5487, n5488, n5489, n5490, n5491, + n5492, n5493, n5494, n5495, n5496, n5497, n5498, n5499, n5500, n5501, + n5502, n5503, n5504, n5505, n5506, n5507, n5508, n5509, n5510, n5511, + n5512, n5513, n5514, n5515, n5516, n5517, n5518, n5519, n5520, n5521, + n5522, n5523, n5524, n5525, n5526, n5527, n5528, n5529, n5530, n5531, + n5532, n5533, n5534, n5535, n5536, n5537, n5538, n5539, n5540, n5541, + n5542, n5543, n5544, n5545, n5546, n5547, n5548, n5549, n5550, n5551, + n5552, n5553, n5554, n5555, n5556, n5557, n5558, n5559, n5560, n5561, + n5562, n5563, n5564, n5565, n5566, n5567, n5568, n5569, n5570, n5571, + n5572, n5573, n5574, n5575, n5576, n5577, n5578, n5579, n5580, n5581, + n5582, n5583, n5584, n5585, n5586, n5587, n5588, n5589, n5590, n5591, + n5592, n5593, n5594, n5595, n5596, n5597, n5598, n5599, n5600, n5601, + n5602, n5603, n5604, n5605, n5606, n5607, n5608, n5609, n5610, n5611, + n5612, n5613, n5614, n5615, n5616, n5617, n5618, n5619, n5620, n5621, + n5622, n5623, n5624, n5625, n5626, n5627, n5628, n5629, n5630, n5631, + n5632, n5633, n5634, n5635, n5636, n5637, n5638, n5639, n5640, n5641, + n5642, n5643, n5644, n5645, n5646, n5647, n5648, n5649, n5650, n5651, + n5652, n5653, n5654, n5655, n5656, n5657, n5658, n5659, n5660, n5661, + n5662, n5663, n5664, n5665, n5666, n5667, n5668, n5669, n5670, n5671, + n5672, n5673, n5674, n5675, n5676, n5677, n5678, n5679, n5680, n5681, + n5682, n5683, n5684, n5685, n5686, n5687, n5688, n5689, n5690, n5691, + n5692, n5693, n5694, n5695, n5696, n5697, n5698, n5699, n5700, n5701, + n5702, n5703, n5704, n5705, n5706, n5707, n5708, n5709, n5710, n5711, + n5712, n5713, n5714, n5715, n5716, n5717, n5718, n5719, n5720, n5721, + n5722, n5723, n5724, n5725, n5726, n5727, n5728, n5729, n5730, n5731, + n5732, n5733, n5734, n5735, n5736, n5737, n5738, n5739, n5740, n5741, + n5742, n5743, n5744, n5745, n5746, n5747, n5748, n5749, n5750, n5751, + n5752, n5753, n5754, n5755, n5756, n5757, n5758, n5759, n5760, n5761, + n5762, n5763, n5764, n5765, n5766, n5767, n5768, n5769, n5770, n5771, + n5772, n5773, n5774, n5775, n5776, n5777, n5778, n5779, n5780, n5781, + n5782, n5783, n5784, n5785, n5786, n5787, n5788, n5789, n5790, n5791, + n5792, n5793, n5794, n5795, n5796, n5797, n5798, n5799, n5800, n5801, + n5802, n5803, n5804, n5805, n5806, n5807, n5808, n5809, n5810, n5811, + n5812, n5813, n5814, n5815, n5816, n5817, n5818, n5819, n5820, n5821, + n5822, n5823, n5824, n5825, n5826, n5827, n5828, n5829, n5830, n5831, + n5832, n5833, n5834, n5835, n5836, n5837, n5838, n5839, n5840, n5841, + n5842, n5843, n5844, n5845, n5846, n5847, n5848, n5849, n5850, n5851, + n5852, n5853, n5854, n5855, n5856, n5857, n5858, n5859, n5860, n5861, + n5862, n5863, n5864, n5865, n5866, n5867, n5868, n5869, n5870, n5871, + n5872, n5873, n5874, n5875, n5876, n5877, n5878, n5879, n5880, n5881, + n5882, n5883, n5884, n5885, n5886, n5887, n5888, n5889, n5890, n5891, + n5892, n5893, n5894, n5895, n5896, n5897, n5898, n5899, n5900, n5901, + n5902, n5903, n5904, n5905, n5906, n5907, n5908, n5909, n5910, n5911, + n5912, n5913, n5914, n5915, n5916, n5917, n5918, n5919, n5920, n5921, + n5922, n5923, n5924, n5925, n5926, n5927, n5928, n5929, n5930, n5931, + n5932, n5933, n5934, n5935, n5936, n5937, n5938, n5939, n5940, n5941, + n5942, n5943, n5944, n5945, n5946, n5947, n5948, n5949, n5950, n5951, + n5952, n5953, n5954, n5955, n5956, n5957, n5958, n5959, n5960, n5961, + n5962, n5963, n5964, n5965, n5966, n5967, n5968, n5969, n5970, n5971, + n5972, n5973, n5974, n5975, n5976, n5977, n5978, n5979, n5980, n5981, + n5982, n5983, n5984, n5985, n5986, n5987, n5988, n5989, n5990, n5991, + n5992, n5993, n5994, n5995, n5996, n5997, n5998, n5999, n6000, n6001, + n6002, n6003, n6004, n6005, n6006, n6007, n6008, n6009, n6010, n6011, + n6012, n6013, n6014, n6015, n6016, n6017, n6018, n6019, n6020, n6021, + n6022, n6023, n6024, n6025, n6026, n6027, n6028, n6029, n6030, n6031, + n6032, n6033, n6034, n6035, n6036, n6037, n6038, n6039, n6040, n6041, + n6042, n6043, n6044, n6045, n6046, n6047, n6048, n6049, n6050, n6051, + n6052, n6053, n6054, n6055, n6056, n6057, n6058, n6059, n6060, n6061, + n6062, n6063, n6064, n6065, n6066, n6067, n6068, n6069, n6070, n6071, + n6072, n6073, n6074, n6075, n6076, n6077, n6078, n6079, n6080, n6081, + n6082, n6083, n6084, n6085, n6086, n6087, n6088, n6089, n6090, n6091, + n6092, n6093, n6094, n6095, n6096, n6097, n6098, n6099, n6100, n6101, + n6102, n6103, n6104, n6105, n6106, n6107, n6108, n6109, n6110, n6111, + n6112, n6113, n6114, n6115, n6116, n6117, n6118, n6119, n6120, n6121, + n6122, n6123, n6124, n6125, n6126, n6127, n6128, n6129, n6130, n6131, + n6132, n6133, n6134, n6135, n6136, n6137, n6138, n6139, n6140, n6141, + n6142, n6143, n6144, n6145, n6146, n6147, n6148, n6149, n6150, n6151, + n6152, n6153, n6154, n6155, n6156, n6157, n6158, n6159, n6160, n6161, + n6162, n6163, n6164, n6165, n6166, n6167, n6168, n6169, n6170, n6171, + n6172, n6173, n6174, n6175, n6176, n6177, n6178, n6179, n6180, n6181, + n6182, n6183, n6184, n6185, n6186, n6187, n6188, n6189, n6190, n6191, + n6192, n6193, n6194, n6195, n6196, n6197, n6198, n6199, n6200, n6201, + n6202, n6203, n6204, n6205, n6206, n6207, n6208, n6209, n6210, n6211, + n6212, n6213, n6214, n6215, n6216, n6217, n6218, n6219, n6220, n6221, + n6222, n6223, n6224, n6225, n6226, n6227, n6228, n6229, n6230, n6231, + n6232, n6233, n6234, n6235, n6236, n6237, n6238, n6239, n6240, n6241, + n6242, n6243, n6244, n6245, n6246, n6247, n6248, n6249, n6250, n6251, + n6252, n6253, n6254, n6255, n6256, n6257, n6258, n6259, n6260, n6261, + n6262, n6263, n6264, n6265, n6266, n6267, n6268, n6269, n6270, n6271, + n6272, n6273, n6274, n6275, n6276, n6277, n6278, n6279, n6280, n6281, + n6282, n6283, n6284, n6285, n6286, n6287, n6288, n6289, n6290, n6291, + n6292, n6293, n6294, n6295, n6296, n6297, n6298, n6299, n6300, n6301, + n6302, n6303, n6304, n6305, n6306, n6307, n6308, n6309, n6310, n6311, + n6312, n6313, n6314, n6315, n6316, n6317, n6318, n6319, n6320, n6321, + n6322, n6323, n6324, n6325, n6326, n6327, n6328, n6329, n6330, n6331, + n6332, n6333, n6334, n6335, n6336, n6337, n6338, n6339, n6340, n6341, + n6342, n6343, n6344, n6345, n6346, n6347, n6348, n6349, n6350, n6351, + n6352, n6353, n6354, n6355, n6356, n6357, n6358, n6359, n6360, n6361, + n6362, n6363, n6364, n6365, n6366, n6367, n6368, n6369, n6370, n6371, + n6372, n6373, n6374, n6375, n6376, n6377, n6378, n6379, n6380, n6381, + n6382, n6383, n6384, n6385, n6386, n6387, n6388, n6389, n6390, n6391, + n6392, n6393, n6394, n6395, n6396, n6397, n6398, n6399, n6400, n6401, + n6402, n6403, n6404, n6405; + +assign po001 = pi187; + +assign po015 = po003; + +assign po004 = pi106; + +assign po009 = pi136; + +assign po010 = pi022; + +assign po011 = pi112; + +assign po005 = po012; + +assign po013 = pi062; + +assign po014 = pi123; + +assign po101 = po023; + +assign po067 = po023; + +assign po066 = po023; + +assign po023 = pi119; + +assign po024 = pi152; + +assign po025 = pi125; + +assign po027 = pi102; + +assign po028 = pi031; + +assign po031 = pi155; + +assign po065 = po034; + +assign po035 = pi182; + +assign po036 = pi023; + +assign po038 = pi071; + +assign po039 = pi015; + +assign po040 = pi132; + +assign po044 = pi044; + +assign po052 = pi048; + +assign po057 = pi117; + +assign po059 = pi091; + +assign po063 = pi000; + +assign po064 = pi194; + +assign po069 = pi147; + +assign po070 = pi002; + +assign po071 = pi080; + +assign po072 = pi188; + +assign po018 = po074; + +assign po021 = po074; + +assign po079 = pi084; + +assign po082 = pi144; + +assign po084 = pi199; + +assign po085 = pi066; + +assign po091 = pi008; + +assign po092 = pi154; + +assign po099 = pi042; + +assign po102 = pi179; + +assign po103 = pi145; + +assign po104 = pi127; + +assign po106 = pi105; + +assign po107 = pi029; + +assign po020 = po041; + +assign po032 = po007; + +assign po089 = po076; + +assign po054 = po076; + + OR2 U2865 ( .A(n2822), .B(n2823), .Z(po100)); + AN2 U2866 ( .A(n2824), .B(pi192), .Z(n2823)); + OR2 U2867 ( .A(n2825), .B(n2826), .Z(n2824)); + AN2 U2868 ( .A(n2827), .B(n2828), .Z(n2826)); + IV2 U2869 ( .A(n2829), .Z(n2825)); + OR2 U2870 ( .A(n2828), .B(n2827), .Z(n2829)); + OR2 U2871 ( .A(n2830), .B(n2831), .Z(n2827)); + AN2 U2872 ( .A(n2832), .B(n2833), .Z(n2831)); + AN2 U2873 ( .A(n2834), .B(n2835), .Z(n2830)); + AN2 U2874 ( .A(n2836), .B(n2837), .Z(n2822)); + OR2 U2875 ( .A(n2838), .B(n2839), .Z(n2836)); + AN2 U2876 ( .A(n2840), .B(n2828), .Z(n2839)); + IV2 U2877 ( .A(n2841), .Z(n2838)); + OR2 U2878 ( .A(n2828), .B(n2840), .Z(n2841)); + OR2 U2879 ( .A(n2842), .B(n2843), .Z(n2840)); + AN2 U2880 ( .A(n2844), .B(n2845), .Z(n2843)); + AN2 U2881 ( .A(n2846), .B(n2847), .Z(n2842)); + AN2 U2882 ( .A(n2848), .B(n2849), .Z(n2828)); + IV2 U2883 ( .A(n2850), .Z(n2849)); + AN2 U2884 ( .A(n2851), .B(n2852), .Z(n2850)); + OR2 U2885 ( .A(n2852), .B(n2851), .Z(n2848)); + OR2 U2886 ( .A(n2853), .B(n2854), .Z(n2851)); + AN2 U2887 ( .A(n2855), .B(n2856), .Z(n2854)); + IV2 U2888 ( .A(n2857), .Z(n2853)); + OR2 U2889 ( .A(n2856), .B(n2855), .Z(n2857)); + IV2 U2890 ( .A(n2858), .Z(n2855)); + OR2 U2891 ( .A(n2859), .B(n2860), .Z(n2858)); + AN2 U2892 ( .A(n2861), .B(n2862), .Z(n2859)); + OR2 U2893 ( .A(n2863), .B(n2864), .Z(n2856)); + OR2 U2894 ( .A(n2865), .B(n2866), .Z(n2864)); + AN2 U2895 ( .A(pi192), .B(n2867), .Z(n2866)); + OR2 U2896 ( .A(n2868), .B(n2869), .Z(n2867)); + OR2 U2897 ( .A(n2870), .B(n2871), .Z(n2869)); + AN2 U2898 ( .A(n2872), .B(n2873), .Z(n2871)); + AN2 U2899 ( .A(n2862), .B(n2874), .Z(n2872)); + OR2 U2900 ( .A(n2875), .B(n2876), .Z(n2874)); + AN2 U2901 ( .A(n2877), .B(n2878), .Z(n2875)); + AN2 U2902 ( .A(n2879), .B(n2880), .Z(n2870)); + AN2 U2903 ( .A(n2881), .B(n2882), .Z(n2868)); + OR2 U2904 ( .A(n2883), .B(n2884), .Z(n2881)); + AN2 U2905 ( .A(n2885), .B(n2886), .Z(n2884)); + AN2 U2906 ( .A(n2879), .B(n2887), .Z(n2883)); + IV2 U2907 ( .A(n2873), .Z(n2879)); + OR2 U2908 ( .A(n2888), .B(n2889), .Z(n2873)); + AN2 U2909 ( .A(n2890), .B(n2891), .Z(n2889)); + AN2 U2910 ( .A(n2892), .B(n2886), .Z(n2888)); + AN2 U2911 ( .A(n2893), .B(n2837), .Z(n2865)); + OR2 U2912 ( .A(n2894), .B(n2895), .Z(n2893)); + OR2 U2913 ( .A(n2896), .B(n2897), .Z(n2895)); + OR2 U2914 ( .A(n2898), .B(n2899), .Z(n2897)); + AN2 U2915 ( .A(n2900), .B(n2901), .Z(n2899)); + AN2 U2916 ( .A(n2902), .B(n2903), .Z(n2900)); + OR2 U2917 ( .A(n2904), .B(n2905), .Z(n2903)); + OR2 U2918 ( .A(n2906), .B(n2907), .Z(n2905)); + AN2 U2919 ( .A(n2890), .B(n2908), .Z(n2907)); + AN2 U2920 ( .A(n2909), .B(n2886), .Z(n2906)); + AN2 U2921 ( .A(n2910), .B(pi082), .Z(n2909)); + AN2 U2922 ( .A(pi200), .B(n2911), .Z(n2898)); + OR2 U2923 ( .A(n2912), .B(n2913), .Z(n2911)); + OR2 U2924 ( .A(n2914), .B(n2915), .Z(n2913)); + AN2 U2925 ( .A(n2916), .B(n2890), .Z(n2915)); + AN2 U2926 ( .A(n2910), .B(n2917), .Z(n2916)); + OR2 U2927 ( .A(n2918), .B(n2919), .Z(n2917)); + AN2 U2928 ( .A(n2920), .B(n2886), .Z(n2914)); + OR2 U2929 ( .A(n2921), .B(n2922), .Z(n2920)); + OR2 U2930 ( .A(n2923), .B(n2924), .Z(n2922)); + AN2 U2931 ( .A(n2918), .B(n2860), .Z(n2924)); + AN2 U2932 ( .A(n2925), .B(n2926), .Z(n2923)); + OR2 U2933 ( .A(n2927), .B(n2928), .Z(n2926)); + AN2 U2934 ( .A(n2844), .B(n2929), .Z(n2928)); + AN2 U2935 ( .A(n2930), .B(n2931), .Z(n2927)); + OR2 U2936 ( .A(n2932), .B(n2933), .Z(n2921)); + AN2 U2937 ( .A(n2934), .B(n2935), .Z(n2933)); + AN2 U2938 ( .A(n2936), .B(n2910), .Z(n2934)); + AN2 U2939 ( .A(n2937), .B(n2938), .Z(n2932)); + AN2 U2940 ( .A(n2929), .B(n2939), .Z(n2937)); + AN2 U2941 ( .A(n2935), .B(n2940), .Z(n2912)); + OR2 U2942 ( .A(n2904), .B(n2941), .Z(n2940)); + AN2 U2943 ( .A(n2890), .B(n2942), .Z(n2941)); + AN2 U2944 ( .A(n2943), .B(n2944), .Z(n2942)); + OR2 U2945 ( .A(n2945), .B(n2946), .Z(n2944)); + IV2 U2946 ( .A(n2910), .Z(n2945)); + OR2 U2947 ( .A(n2936), .B(n2947), .Z(n2943)); + IV2 U2948 ( .A(n2948), .Z(n2904)); + OR2 U2949 ( .A(n2949), .B(n2939), .Z(n2948)); + AN2 U2950 ( .A(n2950), .B(n2951), .Z(n2949)); + OR2 U2951 ( .A(n2890), .B(n2947), .Z(n2951)); + OR2 U2952 ( .A(n2929), .B(n2886), .Z(n2950)); + AN2 U2953 ( .A(n2952), .B(n2953), .Z(n2896)); + AN2 U2954 ( .A(n2954), .B(n2955), .Z(n2953)); + OR2 U2955 ( .A(n2956), .B(n2957), .Z(n2955)); + AN2 U2956 ( .A(n2890), .B(n2958), .Z(n2956)); + OR2 U2957 ( .A(n2959), .B(n2960), .Z(n2958)); + OR2 U2958 ( .A(pi082), .B(n2961), .Z(n2954)); + AN2 U2959 ( .A(n2901), .B(n2886), .Z(n2961)); + AN2 U2960 ( .A(n2910), .B(n2962), .Z(n2952)); + AN2 U2961 ( .A(n2947), .B(n2862), .Z(n2910)); + OR2 U2962 ( .A(n2963), .B(n2964), .Z(n2894)); + AN2 U2963 ( .A(n2965), .B(n2890), .Z(n2964)); + AN2 U2964 ( .A(n2929), .B(n2966), .Z(n2965)); + OR2 U2965 ( .A(n2967), .B(n2968), .Z(n2966)); + AN2 U2966 ( .A(n2969), .B(n2901), .Z(n2967)); + OR2 U2967 ( .A(n2970), .B(n2971), .Z(n2969)); + OR2 U2968 ( .A(n2972), .B(n2973), .Z(n2971)); + AN2 U2969 ( .A(n2902), .B(n2962), .Z(n2973)); + AN2 U2970 ( .A(n2974), .B(n2957), .Z(n2972)); + AN2 U2971 ( .A(pi082), .B(po031), .Z(n2970)); + AN2 U2972 ( .A(n2975), .B(n2886), .Z(n2963)); + OR2 U2973 ( .A(n2976), .B(n2977), .Z(n2975)); + AN2 U2974 ( .A(n2968), .B(n2947), .Z(n2977)); + AN2 U2975 ( .A(n2978), .B(n2979), .Z(n2968)); + OR2 U2976 ( .A(n2980), .B(n2981), .Z(n2979)); + AN2 U2977 ( .A(n2982), .B(n2931), .Z(n2980)); + AN2 U2978 ( .A(n2983), .B(n2929), .Z(n2976)); + AN2 U2979 ( .A(n2984), .B(n2936), .Z(n2983)); + AN2 U2980 ( .A(n2974), .B(n2901), .Z(n2984)); + OR2 U2981 ( .A(n2985), .B(n2986), .Z(n2863)); + AN2 U2982 ( .A(n2987), .B(n2890), .Z(n2986)); + AN2 U2983 ( .A(n2988), .B(n2989), .Z(n2987)); + AN2 U2984 ( .A(n2990), .B(n2962), .Z(n2989)); + AN2 U2985 ( .A(n2862), .B(n2877), .Z(n2988)); + AN2 U2986 ( .A(n2991), .B(n2886), .Z(n2985)); + OR2 U2987 ( .A(n2992), .B(n2993), .Z(n2991)); + AN2 U2988 ( .A(n2994), .B(n2995), .Z(n2993)); + AN2 U2989 ( .A(n2990), .B(n2901), .Z(n2995)); + AN2 U2990 ( .A(n2996), .B(n2974), .Z(n2994)); + OR2 U2991 ( .A(po031), .B(n2930), .Z(n2996)); + AN2 U2992 ( .A(n2997), .B(n2860), .Z(n2992)); + AN2 U2993 ( .A(n2998), .B(n2930), .Z(n2860)); + AN2 U2994 ( .A(n2877), .B(n2999), .Z(n2997)); + IV2 U2995 ( .A(n2882), .Z(n2877)); + AN2 U2996 ( .A(n3000), .B(n3001), .Z(n2852)); + OR2 U2997 ( .A(n3002), .B(n2925), .Z(n3001)); + OR2 U2998 ( .A(n3003), .B(n3004), .Z(n3000)); + IV2 U2999 ( .A(n3002), .Z(n3004)); + OR2 U3000 ( .A(n3005), .B(n3006), .Z(n3002)); + AN2 U3001 ( .A(n3007), .B(n3008), .Z(n3006)); + OR2 U3002 ( .A(n3009), .B(n3010), .Z(n3008)); + AN2 U3003 ( .A(n3011), .B(n3012), .Z(n3009)); + AN2 U3004 ( .A(n3013), .B(n3014), .Z(n3007)); + OR2 U3005 ( .A(n3015), .B(n3016), .Z(n3014)); + IV2 U3006 ( .A(n3017), .Z(n3016)); + OR2 U3007 ( .A(n3017), .B(n3018), .Z(n3013)); + OR2 U3008 ( .A(n3019), .B(n3020), .Z(n3017)); + AN2 U3009 ( .A(n3021), .B(n3022), .Z(n3020)); + OR2 U3010 ( .A(n3023), .B(n3024), .Z(n3022)); + OR2 U3011 ( .A(n3025), .B(n3026), .Z(n3024)); + OR2 U3012 ( .A(n3027), .B(n3028), .Z(n3026)); + AN2 U3013 ( .A(po010), .B(n3029), .Z(n3028)); + AN2 U3014 ( .A(n3030), .B(pi192), .Z(n3027)); + AN2 U3015 ( .A(n3031), .B(n3032), .Z(n3030)); + OR2 U3016 ( .A(n3033), .B(n3034), .Z(n3032)); + AN2 U3017 ( .A(n3035), .B(n3036), .Z(n3034)); + AN2 U3018 ( .A(n3015), .B(n3037), .Z(n3035)); + OR2 U3019 ( .A(n3038), .B(n3039), .Z(n3031)); + OR2 U3020 ( .A(n3040), .B(n3041), .Z(n3039)); + AN2 U3021 ( .A(po010), .B(n3042), .Z(n3040)); + OR2 U3022 ( .A(n3043), .B(n3044), .Z(n3025)); + AN2 U3023 ( .A(n3015), .B(n3045), .Z(n3044)); + OR2 U3024 ( .A(n3046), .B(n3047), .Z(n3045)); + AN2 U3025 ( .A(n3048), .B(n3049), .Z(n3047)); + OR2 U3026 ( .A(n3050), .B(n3051), .Z(n3048)); + AN2 U3027 ( .A(n3052), .B(po070), .Z(n3051)); + AN2 U3028 ( .A(n3053), .B(po099), .Z(n3050)); + AN2 U3029 ( .A(n3054), .B(n3055), .Z(n3046)); + AN2 U3030 ( .A(n3018), .B(n3056), .Z(n3043)); + OR2 U3031 ( .A(n3057), .B(n3058), .Z(n3056)); + OR2 U3032 ( .A(n3059), .B(n3060), .Z(n3058)); + AN2 U3033 ( .A(n3061), .B(n3042), .Z(n3060)); + AN2 U3034 ( .A(n3062), .B(n3063), .Z(n3059)); + AN2 U3035 ( .A(n3064), .B(n3049), .Z(n3062)); + AN2 U3036 ( .A(n3065), .B(n3066), .Z(n3057)); + OR2 U3037 ( .A(n3067), .B(n3068), .Z(n3023)); + OR2 U3038 ( .A(n3069), .B(n3070), .Z(n3068)); + AN2 U3039 ( .A(n3071), .B(n3072), .Z(n3070)); + AN2 U3040 ( .A(n3053), .B(n3073), .Z(n3069)); + OR2 U3041 ( .A(n3074), .B(n3075), .Z(n3067)); + AN2 U3042 ( .A(n3076), .B(n3077), .Z(n3075)); + OR2 U3043 ( .A(n3078), .B(n3079), .Z(n3077)); + AN2 U3044 ( .A(n3080), .B(n3066), .Z(n3078)); + AN2 U3045 ( .A(n3081), .B(n3061), .Z(n3074)); + AN2 U3046 ( .A(n3082), .B(n3038), .Z(n3081)); + AN2 U3047 ( .A(n3083), .B(n3084), .Z(n3019)); + OR2 U3048 ( .A(n3085), .B(n3086), .Z(n3084)); + OR2 U3049 ( .A(n3087), .B(n3088), .Z(n3086)); + OR2 U3050 ( .A(n3089), .B(n3090), .Z(n3088)); + AN2 U3051 ( .A(n3091), .B(n3049), .Z(n3089)); + OR2 U3052 ( .A(n3092), .B(n3093), .Z(n3087)); + AN2 U3053 ( .A(n3015), .B(n3094), .Z(n3093)); + OR2 U3054 ( .A(n3095), .B(n3096), .Z(n3094)); + OR2 U3055 ( .A(n3097), .B(n3098), .Z(n3096)); + AN2 U3056 ( .A(n3099), .B(n3100), .Z(n3098)); + AN2 U3057 ( .A(po010), .B(po070), .Z(n3099)); + AN2 U3058 ( .A(n3101), .B(pi192), .Z(n3097)); + AN2 U3059 ( .A(n3041), .B(n3038), .Z(n3101)); + OR2 U3060 ( .A(n3102), .B(n3103), .Z(n3041)); + AN2 U3061 ( .A(n3104), .B(pi166), .Z(n3103)); + AN2 U3062 ( .A(n3037), .B(n3049), .Z(n3104)); + AN2 U3063 ( .A(n3105), .B(n3106), .Z(n3102)); + OR2 U3064 ( .A(n3107), .B(n3042), .Z(n3105)); + AN2 U3065 ( .A(po010), .B(n3108), .Z(n3107)); + AN2 U3066 ( .A(n3079), .B(n3109), .Z(n3095)); + OR2 U3067 ( .A(n3110), .B(n3111), .Z(n3079)); + AN2 U3068 ( .A(n3071), .B(n3112), .Z(n3111)); + AN2 U3069 ( .A(n3065), .B(n3113), .Z(n3110)); + OR2 U3070 ( .A(n3114), .B(n3066), .Z(n3113)); + AN2 U3071 ( .A(po010), .B(n3115), .Z(n3114)); + AN2 U3072 ( .A(n3018), .B(n3116), .Z(n3092)); + OR2 U3073 ( .A(n3117), .B(n3118), .Z(n3116)); + AN2 U3074 ( .A(n3065), .B(n3119), .Z(n3118)); + AN2 U3075 ( .A(n3063), .B(n3120), .Z(n3117)); + OR2 U3076 ( .A(n3121), .B(n3122), .Z(n3085)); + OR2 U3077 ( .A(n3123), .B(n3124), .Z(n3122)); + AN2 U3078 ( .A(n3125), .B(n3055), .Z(n3124)); + AN2 U3079 ( .A(n3076), .B(n3112), .Z(n3125)); + AN2 U3080 ( .A(n3126), .B(n3127), .Z(n3123)); + AN2 U3081 ( .A(n3033), .B(n3037), .Z(n3126)); + AN2 U3082 ( .A(n3080), .B(n3072), .Z(n3121)); + AN2 U3083 ( .A(n3119), .B(n3018), .Z(n3072)); + AN2 U3084 ( .A(n3128), .B(n3129), .Z(n3005)); + OR2 U3085 ( .A(n3130), .B(n3131), .Z(n3129)); + OR2 U3086 ( .A(n3132), .B(n3133), .Z(n3131)); + AN2 U3087 ( .A(n3134), .B(pi192), .Z(n3133)); + AN2 U3088 ( .A(n3135), .B(n3136), .Z(n3134)); + OR2 U3089 ( .A(n3137), .B(po044), .Z(n3135)); + AN2 U3090 ( .A(n3138), .B(n2886), .Z(n3137)); + AN2 U3091 ( .A(n3139), .B(n2837), .Z(n3132)); + AN2 U3092 ( .A(n3140), .B(n3141), .Z(n3139)); + OR2 U3093 ( .A(n3142), .B(po044), .Z(n3140)); + AN2 U3094 ( .A(n3143), .B(n2886), .Z(n3142)); + AN2 U3095 ( .A(n3144), .B(n3145), .Z(n3130)); + OR2 U3096 ( .A(n3146), .B(n3147), .Z(n3145)); + IV2 U3097 ( .A(n3012), .Z(n3144)); + AN2 U3098 ( .A(n3148), .B(n3149), .Z(n3128)); + OR2 U3099 ( .A(n3150), .B(n3018), .Z(n3149)); + OR2 U3100 ( .A(n3015), .B(n3151), .Z(n3148)); + IV2 U3101 ( .A(n3150), .Z(n3151)); + OR2 U3102 ( .A(n3152), .B(n3153), .Z(n3150)); + AN2 U3103 ( .A(n3021), .B(n3154), .Z(n3153)); + AN2 U3104 ( .A(n3155), .B(n3083), .Z(n3152)); + IV2 U3105 ( .A(n3154), .Z(n3155)); + OR2 U3106 ( .A(n3156), .B(n3157), .Z(n3154)); + OR2 U3107 ( .A(n3091), .B(n3158), .Z(n3157)); + OR2 U3108 ( .A(n3159), .B(n3160), .Z(n3158)); + AN2 U3109 ( .A(n3161), .B(n3049), .Z(n3160)); + OR2 U3110 ( .A(n3162), .B(n3029), .Z(n3161)); + OR2 U3111 ( .A(n3163), .B(n3164), .Z(n3029)); + AN2 U3112 ( .A(po099), .B(n3165), .Z(n3164)); + OR2 U3113 ( .A(n3166), .B(n3167), .Z(n3165)); + OR2 U3114 ( .A(n3168), .B(n3169), .Z(n3167)); + AN2 U3115 ( .A(n3170), .B(pi192), .Z(n3169)); + AN2 U3116 ( .A(n3038), .B(n3171), .Z(n3170)); + AN2 U3117 ( .A(n3054), .B(n2837), .Z(n3168)); + AN2 U3118 ( .A(n3172), .B(n3173), .Z(n3166)); + AN2 U3119 ( .A(n3015), .B(n3109), .Z(n3172)); + AN2 U3120 ( .A(n3100), .B(n3018), .Z(n3163)); + AN2 U3121 ( .A(n3015), .B(n3174), .Z(n3162)); + OR2 U3122 ( .A(n3175), .B(n3176), .Z(n3174)); + AN2 U3123 ( .A(n3054), .B(n3173), .Z(n3176)); + AN2 U3124 ( .A(n3177), .B(n3109), .Z(n3054)); + AN2 U3125 ( .A(n3178), .B(n3064), .Z(n3175)); + AN2 U3126 ( .A(n3038), .B(n3037), .Z(n3178)); + AN2 U3127 ( .A(po010), .B(n3179), .Z(n3159)); + OR2 U3128 ( .A(n3090), .B(n3180), .Z(n3179)); + OR2 U3129 ( .A(n3181), .B(n3182), .Z(n3180)); + AN2 U3130 ( .A(n3053), .B(n3183), .Z(n3182)); + OR2 U3131 ( .A(n3184), .B(n3119), .Z(n3183)); + AN2 U3132 ( .A(pi141), .B(n3015), .Z(n3184)); + AN2 U3133 ( .A(n3109), .B(n3065), .Z(n3053)); + AN2 U3134 ( .A(n3185), .B(n3061), .Z(n3181)); + AN2 U3135 ( .A(n3186), .B(n3038), .Z(n3185)); + OR2 U3136 ( .A(n3187), .B(n3063), .Z(n3186)); + AN2 U3137 ( .A(pi033), .B(n3015), .Z(n3187)); + OR2 U3138 ( .A(n3188), .B(n3189), .Z(n3090)); + AN2 U3139 ( .A(n3190), .B(n3065), .Z(n3189)); + AN2 U3140 ( .A(n3073), .B(n3076), .Z(n3190)); + AN2 U3141 ( .A(n3191), .B(n3061), .Z(n3188)); + AN2 U3142 ( .A(n3082), .B(n3033), .Z(n3191)); + OR2 U3143 ( .A(n3192), .B(n3193), .Z(n3091)); + OR2 U3144 ( .A(n3194), .B(n3195), .Z(n3193)); + AN2 U3145 ( .A(n3052), .B(n3018), .Z(n3195)); + AN2 U3146 ( .A(n3064), .B(n3196), .Z(n3194)); + OR2 U3147 ( .A(n3197), .B(n3198), .Z(n3196)); + AN2 U3148 ( .A(n3082), .B(n3199), .Z(n3198)); + AN2 U3149 ( .A(n3042), .B(n3033), .Z(n3197)); + OR2 U3150 ( .A(n3200), .B(n3201), .Z(n3192)); + AN2 U3151 ( .A(n3173), .B(n3202), .Z(n3201)); + OR2 U3152 ( .A(n3203), .B(n3204), .Z(n3202)); + AN2 U3153 ( .A(n3073), .B(n3205), .Z(n3204)); + AN2 U3154 ( .A(n3076), .B(n3066), .Z(n3203)); + AN2 U3155 ( .A(n3206), .B(po099), .Z(n3200)); + AN2 U3156 ( .A(po070), .B(n3207), .Z(n3206)); + OR2 U3157 ( .A(n3208), .B(n3209), .Z(n3156)); + AN2 U3158 ( .A(n3210), .B(n3055), .Z(n3209)); + AN2 U3159 ( .A(n3076), .B(n3115), .Z(n3210)); + AN2 U3160 ( .A(n3211), .B(n3127), .Z(n3208)); + AN2 U3161 ( .A(n3033), .B(n3108), .Z(n3211)); + OR2 U3162 ( .A(n3212), .B(n3213), .Z(po098)); + AN2 U3163 ( .A(n3214), .B(pi192), .Z(n3213)); + OR2 U3164 ( .A(n3215), .B(n3216), .Z(n3214)); + AN2 U3165 ( .A(n2832), .B(n2901), .Z(n3216)); + IV2 U3166 ( .A(n2835), .Z(n2832)); + AN2 U3167 ( .A(pi200), .B(n2835), .Z(n3215)); + OR2 U3168 ( .A(n2880), .B(n2876), .Z(n2835)); + AN2 U3169 ( .A(n3217), .B(n2837), .Z(n3212)); + OR2 U3170 ( .A(n3218), .B(n3219), .Z(n3217)); + AN2 U3171 ( .A(n3220), .B(n2847), .Z(n3219)); + OR2 U3172 ( .A(n3221), .B(n2902), .Z(n3220)); + AN2 U3173 ( .A(pi200), .B(n2938), .Z(n3221)); + AN2 U3174 ( .A(n2844), .B(n3222), .Z(n3218)); + IV2 U3175 ( .A(n2847), .Z(n2844)); + OR2 U3176 ( .A(n2936), .B(n2978), .Z(n2847)); + OR2 U3177 ( .A(n3223), .B(n3224), .Z(po097)); + AN2 U3178 ( .A(n3225), .B(n3226), .Z(n3224)); + OR2 U3179 ( .A(n3227), .B(n3228), .Z(n3226)); + OR2 U3180 ( .A(n3229), .B(n3230), .Z(n3228)); + OR2 U3181 ( .A(n3231), .B(n3232), .Z(n3230)); + AN2 U3182 ( .A(n3233), .B(n3234), .Z(n3232)); + AN2 U3183 ( .A(n3235), .B(n3236), .Z(n3231)); + OR2 U3184 ( .A(n3237), .B(n3238), .Z(n3227)); + OR2 U3185 ( .A(n3239), .B(n3240), .Z(n3238)); + AN2 U3186 ( .A(n3241), .B(n3242), .Z(n3240)); + AN2 U3187 ( .A(n3243), .B(n3244), .Z(n3239)); + AN2 U3188 ( .A(po082), .B(n3245), .Z(n3237)); + AN2 U3189 ( .A(n3246), .B(n3247), .Z(n3223)); + OR2 U3190 ( .A(n3248), .B(n3249), .Z(n3246)); + AN2 U3191 ( .A(n3250), .B(n3251), .Z(n3249)); + OR2 U3192 ( .A(n3252), .B(n3253), .Z(po096)); + AN2 U3193 ( .A(n3254), .B(n3255), .Z(n3252)); + OR2 U3194 ( .A(n3256), .B(n3257), .Z(n3254)); + AN2 U3195 ( .A(n3258), .B(n3259), .Z(n3256)); + AN2 U3196 ( .A(n3260), .B(n3261), .Z(n3258)); + OR2 U3197 ( .A(n3262), .B(n3263), .Z(n3260)); + AN2 U3198 ( .A(n3264), .B(n3265), .Z(n3262)); + OR2 U3199 ( .A(n3266), .B(n3267), .Z(po095)); + OR2 U3200 ( .A(n3268), .B(n3269), .Z(n3267)); + AN2 U3201 ( .A(n3270), .B(n3119), .Z(n3269)); + OR2 U3202 ( .A(n3271), .B(n3272), .Z(n3270)); + AN2 U3203 ( .A(n3273), .B(n2837), .Z(n3272)); + AN2 U3204 ( .A(n3065), .B(n3274), .Z(n3271)); + AN2 U3205 ( .A(n3063), .B(n3275), .Z(n3268)); + OR2 U3206 ( .A(n3276), .B(n3277), .Z(n3275)); + AN2 U3207 ( .A(n3273), .B(pi192), .Z(n3277)); + AN2 U3208 ( .A(n3061), .B(n3274), .Z(n3276)); + OR2 U3209 ( .A(n3278), .B(n3279), .Z(n3266)); + AN2 U3210 ( .A(n3280), .B(n3281), .Z(n3279)); + OR2 U3211 ( .A(n3282), .B(n3100), .Z(n3281)); + AN2 U3212 ( .A(n3283), .B(n3284), .Z(n3278)); + OR2 U3213 ( .A(n3285), .B(n3052), .Z(n3283)); + AN2 U3214 ( .A(n3286), .B(n3287), .Z(n3052)); + AN2 U3215 ( .A(po099), .B(n3207), .Z(n3285)); + AN2 U3216 ( .A(n3288), .B(n3289), .Z(po094)); + OR2 U3217 ( .A(n3290), .B(n3291), .Z(n3289)); + OR2 U3218 ( .A(n3234), .B(n3292), .Z(n3288)); + OR2 U3219 ( .A(n3293), .B(n3294), .Z(po093)); + AN2 U3220 ( .A(n3295), .B(n3296), .Z(n3294)); + OR2 U3221 ( .A(n3297), .B(n3298), .Z(n3296)); + AN2 U3222 ( .A(n3299), .B(n3300), .Z(n3297)); + AN2 U3223 ( .A(n3301), .B(n3302), .Z(n3293)); + IV2 U3224 ( .A(n3303), .Z(n3302)); + AN2 U3225 ( .A(n3304), .B(n3299), .Z(n3303)); + OR2 U3226 ( .A(n3305), .B(n3306), .Z(n3299)); + OR2 U3227 ( .A(n3300), .B(n3298), .Z(n3304)); + AN2 U3228 ( .A(n3305), .B(n3306), .Z(n3298)); + OR2 U3229 ( .A(n3307), .B(n3308), .Z(po090)); + OR2 U3230 ( .A(n3309), .B(n3310), .Z(n3308)); + AN2 U3231 ( .A(n3311), .B(n3312), .Z(n3310)); + AN2 U3232 ( .A(n3313), .B(n3314), .Z(n3309)); + OR2 U3233 ( .A(n3315), .B(n3316), .Z(n3313)); + OR2 U3234 ( .A(n3317), .B(n3318), .Z(n3316)); + AN2 U3235 ( .A(n3319), .B(n3320), .Z(n3315)); + OR2 U3236 ( .A(n3321), .B(n3322), .Z(n3319)); + OR2 U3237 ( .A(n3323), .B(n3324), .Z(n3307)); + AN2 U3238 ( .A(n3325), .B(n3326), .Z(n3324)); + AN2 U3239 ( .A(n3327), .B(n3328), .Z(n3323)); + OR2 U3240 ( .A(n3329), .B(n3330), .Z(n3327)); + OR2 U3241 ( .A(n3331), .B(n3332), .Z(po088)); + IV2 U3242 ( .A(n3333), .Z(n3332)); + OR2 U3243 ( .A(n3334), .B(n3335), .Z(n3333)); + AN2 U3244 ( .A(n3335), .B(n3334), .Z(n3331)); + AN2 U3245 ( .A(n3336), .B(n3337), .Z(n3334)); + OR2 U3246 ( .A(n3338), .B(n3339), .Z(n3337)); + IV2 U3247 ( .A(n3340), .Z(n3338)); + OR2 U3248 ( .A(n3341), .B(n3340), .Z(n3336)); + OR2 U3249 ( .A(n3342), .B(n3343), .Z(n3340)); + AN2 U3250 ( .A(n3291), .B(n3250), .Z(n3343)); + AN2 U3251 ( .A(n3344), .B(n3292), .Z(n3342)); + OR2 U3252 ( .A(n3345), .B(n3346), .Z(n3335)); + IV2 U3253 ( .A(n3347), .Z(n3346)); + OR2 U3254 ( .A(n3348), .B(n3349), .Z(n3347)); + AN2 U3255 ( .A(n3349), .B(n3348), .Z(n3345)); + AN2 U3256 ( .A(n3350), .B(n3351), .Z(n3348)); + OR2 U3257 ( .A(n3352), .B(n3353), .Z(n3351)); + IV2 U3258 ( .A(n3354), .Z(n3353)); + OR2 U3259 ( .A(n3354), .B(n3355), .Z(n3350)); + OR2 U3260 ( .A(n3356), .B(n3357), .Z(n3354)); + OR2 U3261 ( .A(n3358), .B(n3359), .Z(n3357)); + AN2 U3262 ( .A(n3360), .B(n3361), .Z(n3359)); + AN2 U3263 ( .A(n3362), .B(n3363), .Z(n3360)); + OR2 U3264 ( .A(n3364), .B(n3365), .Z(n3362)); + OR2 U3265 ( .A(n3366), .B(n3367), .Z(n3365)); + AN2 U3266 ( .A(n3368), .B(n3369), .Z(n3367)); + AN2 U3267 ( .A(n3370), .B(n3371), .Z(n3368)); + AN2 U3268 ( .A(n3372), .B(n3373), .Z(n3366)); + AN2 U3269 ( .A(n3374), .B(n3375), .Z(n3372)); + OR2 U3270 ( .A(n3376), .B(n3377), .Z(n3374)); + OR2 U3271 ( .A(n3378), .B(n3379), .Z(n3377)); + AN2 U3272 ( .A(n2837), .B(n3380), .Z(n3379)); + AN2 U3273 ( .A(pi060), .B(n3381), .Z(n3378)); + AN2 U3274 ( .A(n3382), .B(n3369), .Z(n3364)); + AN2 U3275 ( .A(n3369), .B(n3383), .Z(n3358)); + OR2 U3276 ( .A(n3384), .B(n3385), .Z(n3383)); + OR2 U3277 ( .A(n3386), .B(n3387), .Z(n3385)); + AN2 U3278 ( .A(n3370), .B(n3388), .Z(n3387)); + OR2 U3279 ( .A(n3389), .B(n3390), .Z(n3388)); + AN2 U3280 ( .A(n3391), .B(n3392), .Z(n3390)); + AN2 U3281 ( .A(n3393), .B(n3394), .Z(n3386)); + OR2 U3282 ( .A(n3395), .B(n3396), .Z(n3394)); + OR2 U3283 ( .A(n3321), .B(n3397), .Z(n3396)); + AN2 U3284 ( .A(n3398), .B(n3399), .Z(n3397)); + AN2 U3285 ( .A(n3400), .B(n3401), .Z(n3395)); + OR2 U3286 ( .A(n3402), .B(n3371), .Z(n3400)); + AN2 U3287 ( .A(n3403), .B(n3404), .Z(n3402)); + AN2 U3288 ( .A(pi060), .B(po071), .Z(n3403)); + OR2 U3289 ( .A(n3405), .B(n3406), .Z(n3384)); + AN2 U3290 ( .A(n3407), .B(n3363), .Z(n3406)); + AN2 U3291 ( .A(n3408), .B(n3401), .Z(n3407)); + OR2 U3292 ( .A(n3409), .B(n3410), .Z(n3408)); + AN2 U3293 ( .A(n3411), .B(n3412), .Z(n3409)); + OR2 U3294 ( .A(n3413), .B(n3414), .Z(n3411)); + AN2 U3295 ( .A(n3415), .B(n3370), .Z(n3414)); + OR2 U3296 ( .A(n3416), .B(n3417), .Z(n3415)); + AN2 U3297 ( .A(n3418), .B(n3381), .Z(n3413)); + AN2 U3298 ( .A(n3393), .B(n3419), .Z(n3418)); + AN2 U3299 ( .A(n3420), .B(po027), .Z(n3405)); + OR2 U3300 ( .A(n3421), .B(n3422), .Z(n3420)); + OR2 U3301 ( .A(n3423), .B(n3424), .Z(n3422)); + AN2 U3302 ( .A(n3410), .B(n3361), .Z(n3424)); + IV2 U3303 ( .A(n3425), .Z(n3410)); + AN2 U3304 ( .A(n3426), .B(n3401), .Z(n3423)); + OR2 U3305 ( .A(n3427), .B(n3382), .Z(n3426)); + IV2 U3306 ( .A(n3428), .Z(n3382)); + OR2 U3307 ( .A(n3429), .B(n3430), .Z(n3421)); + AN2 U3308 ( .A(n3431), .B(n3370), .Z(n3430)); + AN2 U3309 ( .A(n3393), .B(n3432), .Z(n3429)); + OR2 U3310 ( .A(n3433), .B(n3434), .Z(n3432)); + AN2 U3311 ( .A(po071), .B(n3419), .Z(n3434)); + IV2 U3312 ( .A(n3435), .Z(n3369)); + OR2 U3313 ( .A(n3436), .B(n3375), .Z(n3435)); + AN2 U3314 ( .A(n3437), .B(n3438), .Z(n3436)); + AN2 U3315 ( .A(n3439), .B(n3440), .Z(n3438)); + OR2 U3316 ( .A(n3361), .B(n3441), .Z(n3440)); + AN2 U3317 ( .A(n3442), .B(n3443), .Z(n3441)); + OR2 U3318 ( .A(n3444), .B(n3445), .Z(n3443)); + OR2 U3319 ( .A(n3370), .B(n3446), .Z(n3445)); + OR2 U3320 ( .A(n3371), .B(n3380), .Z(n3444)); + AN2 U3321 ( .A(n3447), .B(n3448), .Z(n3442)); + OR2 U3322 ( .A(po027), .B(n3449), .Z(n3448)); + AN2 U3323 ( .A(n3450), .B(n3428), .Z(n3449)); + OR2 U3324 ( .A(n3371), .B(n3451), .Z(n3428)); + OR2 U3325 ( .A(n3370), .B(n3412), .Z(n3450)); + OR2 U3326 ( .A(n3363), .B(n3425), .Z(n3447)); + OR2 U3327 ( .A(n3427), .B(n3452), .Z(n3425)); + AN2 U3328 ( .A(n3453), .B(n3412), .Z(n3452)); + AN2 U3329 ( .A(n3371), .B(n3451), .Z(n3427)); + OR2 U3330 ( .A(n3401), .B(n3454), .Z(n3439)); + IV2 U3331 ( .A(n3455), .Z(n3454)); + AN2 U3332 ( .A(n3412), .B(n3456), .Z(n3455)); + OR2 U3333 ( .A(n3457), .B(n3458), .Z(n3456)); + AN2 U3334 ( .A(n3392), .B(n3393), .Z(n3458)); + AN2 U3335 ( .A(n3459), .B(n3460), .Z(n3437)); + OR2 U3336 ( .A(n3457), .B(n3461), .Z(n3460)); + AN2 U3337 ( .A(n3462), .B(n3463), .Z(n3459)); + OR2 U3338 ( .A(n3464), .B(n3370), .Z(n3463)); + IV2 U3339 ( .A(n3465), .Z(n3464)); + OR2 U3340 ( .A(n3389), .B(n3431), .Z(n3465)); + AN2 U3341 ( .A(n3466), .B(n3419), .Z(n3431)); + AN2 U3342 ( .A(n3467), .B(n3468), .Z(n3389)); + IV2 U3343 ( .A(n3469), .Z(n3468)); + OR2 U3344 ( .A(n3417), .B(n3470), .Z(n3469)); + AN2 U3345 ( .A(n3471), .B(n3399), .Z(n3470)); + OR2 U3346 ( .A(n3371), .B(n3446), .Z(n3471)); + OR2 U3347 ( .A(n3472), .B(n3393), .Z(n3462)); + AN2 U3348 ( .A(n3473), .B(n3474), .Z(n3472)); + AN2 U3349 ( .A(n3475), .B(n3476), .Z(n3474)); + OR2 U3350 ( .A(n3412), .B(n3477), .Z(n3476)); + AN2 U3351 ( .A(n3478), .B(n3261), .Z(n3475)); + IV2 U3352 ( .A(n3479), .Z(n3478)); + AN2 U3353 ( .A(n3361), .B(n3480), .Z(n3479)); + AN2 U3354 ( .A(n3481), .B(n3482), .Z(n3473)); + OR2 U3355 ( .A(n3483), .B(n3380), .Z(n3482)); + AN2 U3356 ( .A(n3484), .B(n3461), .Z(n3483)); + OR2 U3357 ( .A(n3371), .B(n3485), .Z(n3484)); + IV2 U3358 ( .A(n3433), .Z(n3481)); + OR2 U3359 ( .A(n3486), .B(n3417), .Z(n3433)); + AN2 U3360 ( .A(n3404), .B(n3381), .Z(n3417)); + AN2 U3361 ( .A(n3487), .B(n3380), .Z(n3486)); + AN2 U3362 ( .A(n3488), .B(n3375), .Z(n3356)); + OR2 U3363 ( .A(n3489), .B(n3490), .Z(n3375)); + AN2 U3364 ( .A(n3225), .B(n3491), .Z(n3489)); + OR2 U3365 ( .A(n3492), .B(n3493), .Z(n3491)); + AN2 U3366 ( .A(n3494), .B(n3495), .Z(n3492)); + OR2 U3367 ( .A(n3496), .B(n3497), .Z(n3488)); + OR2 U3368 ( .A(n3498), .B(n3499), .Z(n3497)); + AN2 U3369 ( .A(n3371), .B(n3500), .Z(n3499)); + OR2 U3370 ( .A(n3501), .B(n3502), .Z(n3500)); + OR2 U3371 ( .A(n3503), .B(n3504), .Z(n3502)); + AN2 U3372 ( .A(n3505), .B(n3401), .Z(n3504)); + OR2 U3373 ( .A(n3506), .B(n3507), .Z(n3505)); + AN2 U3374 ( .A(n3508), .B(n3509), .Z(n3507)); + OR2 U3375 ( .A(n3510), .B(n3511), .Z(n3509)); + OR2 U3376 ( .A(n3398), .B(n3487), .Z(n3511)); + AN2 U3377 ( .A(n3512), .B(n2837), .Z(n3487)); + AN2 U3378 ( .A(n3404), .B(pi060), .Z(n3510)); + AN2 U3379 ( .A(n3513), .B(po027), .Z(n3506)); + AN2 U3380 ( .A(n3514), .B(n3515), .Z(n3513)); + OR2 U3381 ( .A(n3516), .B(n3517), .Z(n3515)); + OR2 U3382 ( .A(n3321), .B(n3373), .Z(n3514)); + AN2 U3383 ( .A(n3518), .B(n3467), .Z(n3503)); + AN2 U3384 ( .A(n3404), .B(n3519), .Z(n3518)); + OR2 U3385 ( .A(n3520), .B(n3521), .Z(n3501)); + AN2 U3386 ( .A(n3522), .B(n3517), .Z(n3521)); + AN2 U3387 ( .A(n3516), .B(n3363), .Z(n3522)); + AN2 U3388 ( .A(n3373), .B(n3523), .Z(n3520)); + OR2 U3389 ( .A(n3524), .B(n3525), .Z(n3523)); + AN2 U3390 ( .A(n3361), .B(n3526), .Z(n3524)); + OR2 U3391 ( .A(n3527), .B(n3321), .Z(n3526)); + AN2 U3392 ( .A(n3519), .B(n3528), .Z(n3498)); + OR2 U3393 ( .A(n3529), .B(n3530), .Z(n3528)); + OR2 U3394 ( .A(n3392), .B(n3531), .Z(n3530)); + AN2 U3395 ( .A(n3376), .B(n3412), .Z(n3531)); + OR2 U3396 ( .A(n3532), .B(n3321), .Z(n3376)); + AN2 U3397 ( .A(n3533), .B(n3399), .Z(n3532)); + AN2 U3398 ( .A(n3534), .B(n3381), .Z(n3529)); + OR2 U3399 ( .A(n3535), .B(n3536), .Z(n3519)); + AN2 U3400 ( .A(n3537), .B(po027), .Z(n3536)); + AN2 U3401 ( .A(n3538), .B(n3363), .Z(n3535)); + AN2 U3402 ( .A(n3517), .B(n3401), .Z(n3538)); + OR2 U3403 ( .A(n3539), .B(n3540), .Z(n3496)); + AN2 U3404 ( .A(n3541), .B(n3542), .Z(n3540)); + OR2 U3405 ( .A(n3543), .B(n3544), .Z(n3542)); + AN2 U3406 ( .A(n3453), .B(po071), .Z(n3544)); + AN2 U3407 ( .A(n3480), .B(n3534), .Z(n3543)); + AN2 U3408 ( .A(n3545), .B(n3546), .Z(n3541)); + OR2 U3409 ( .A(n3361), .B(n3547), .Z(n3546)); + AN2 U3410 ( .A(n3508), .B(n3412), .Z(n3547)); + OR2 U3411 ( .A(n3401), .B(n3548), .Z(n3545)); + IV2 U3412 ( .A(n3508), .Z(n3548)); + OR2 U3413 ( .A(n3549), .B(n3550), .Z(n3508)); + AN2 U3414 ( .A(n3373), .B(n3363), .Z(n3550)); + AN2 U3415 ( .A(n3517), .B(po027), .Z(n3549)); + AN2 U3416 ( .A(n3551), .B(n3467), .Z(n3539)); + AN2 U3417 ( .A(n3552), .B(n3381), .Z(n3551)); + OR2 U3418 ( .A(n3553), .B(n3554), .Z(n3552)); + AN2 U3419 ( .A(n3537), .B(n3363), .Z(n3554)); + AN2 U3420 ( .A(n3555), .B(po027), .Z(n3553)); + IV2 U3421 ( .A(n3537), .Z(n3555)); + OR2 U3422 ( .A(n3556), .B(n3557), .Z(n3537)); + AN2 U3423 ( .A(n3373), .B(n3401), .Z(n3557)); + AN2 U3424 ( .A(n3517), .B(n3361), .Z(n3556)); + IV2 U3425 ( .A(n3373), .Z(n3517)); + OR2 U3426 ( .A(n3558), .B(n3559), .Z(n3373)); + AN2 U3427 ( .A(n3370), .B(n3560), .Z(n3559)); + OR2 U3428 ( .A(n3561), .B(n3562), .Z(n3560)); + OR2 U3429 ( .A(n3361), .B(n3563), .Z(n3562)); + AN2 U3430 ( .A(n3321), .B(po027), .Z(n3563)); + OR2 U3431 ( .A(n3564), .B(n3565), .Z(n3561)); + OR2 U3432 ( .A(n3527), .B(n3566), .Z(n3565)); + AN2 U3433 ( .A(po027), .B(n3398), .Z(n3527)); + AN2 U3434 ( .A(n3404), .B(n3567), .Z(n3564)); + AN2 U3435 ( .A(n3393), .B(n3568), .Z(n3558)); + OR2 U3436 ( .A(n3569), .B(n3570), .Z(n3568)); + AN2 U3437 ( .A(n3571), .B(n3401), .Z(n3570)); + OR2 U3438 ( .A(n3516), .B(n3572), .Z(n3571)); + AN2 U3439 ( .A(n3419), .B(n3363), .Z(n3572)); + AN2 U3440 ( .A(po104), .B(n3453), .Z(n3516)); + AN2 U3441 ( .A(n3573), .B(n3467), .Z(n3569)); + AN2 U3442 ( .A(n3261), .B(n3533), .Z(n3467)); + AN2 U3443 ( .A(n3404), .B(po027), .Z(n3573)); + OR2 U3444 ( .A(n3574), .B(n3575), .Z(n3349)); + AN2 U3445 ( .A(n3576), .B(n3247), .Z(n3575)); + IV2 U3446 ( .A(n3577), .Z(n3576)); + AN2 U3447 ( .A(n3225), .B(n3577), .Z(n3574)); + OR2 U3448 ( .A(n3578), .B(n3579), .Z(n3577)); + OR2 U3449 ( .A(n3580), .B(n3581), .Z(n3579)); + OR2 U3450 ( .A(n3582), .B(n3583), .Z(n3581)); + AN2 U3451 ( .A(n3584), .B(n2837), .Z(n3583)); + OR2 U3452 ( .A(n3585), .B(n3586), .Z(n3584)); + OR2 U3453 ( .A(n3587), .B(n3588), .Z(n3586)); + AN2 U3454 ( .A(n3589), .B(n3590), .Z(n3588)); + AN2 U3455 ( .A(n3591), .B(n3592), .Z(n3589)); + OR2 U3456 ( .A(n3593), .B(n3355), .Z(n3592)); + AN2 U3457 ( .A(n3594), .B(n3595), .Z(n3591)); + OR2 U3458 ( .A(n3596), .B(n3597), .Z(n3595)); + OR2 U3459 ( .A(pi003), .B(n3598), .Z(n3594)); + AN2 U3460 ( .A(n3599), .B(n3600), .Z(n3587)); + OR2 U3461 ( .A(n3601), .B(n3602), .Z(n3600)); + OR2 U3462 ( .A(n3603), .B(n3604), .Z(n3602)); + AN2 U3463 ( .A(n3605), .B(n3593), .Z(n3604)); + AN2 U3464 ( .A(n3606), .B(n3607), .Z(n3603)); + OR2 U3465 ( .A(n3608), .B(n3609), .Z(n3601)); + AN2 U3466 ( .A(n3610), .B(pi003), .Z(n3609)); + AN2 U3467 ( .A(n3611), .B(n3612), .Z(n3610)); + AN2 U3468 ( .A(n3613), .B(n3597), .Z(n3608)); + OR2 U3469 ( .A(n3614), .B(n3615), .Z(n3613)); + AN2 U3470 ( .A(n3598), .B(n3616), .Z(n3615)); + AN2 U3471 ( .A(n3617), .B(n3593), .Z(n3614)); + AN2 U3472 ( .A(n3618), .B(n3619), .Z(n3585)); + AN2 U3473 ( .A(n3620), .B(n3590), .Z(n3618)); + OR2 U3474 ( .A(n3621), .B(n3622), .Z(n3620)); + OR2 U3475 ( .A(n3494), .B(n3606), .Z(n3622)); + AN2 U3476 ( .A(pi003), .B(n3623), .Z(n3606)); + AN2 U3477 ( .A(n3616), .B(po011), .Z(n3623)); + AN2 U3478 ( .A(n3624), .B(n3625), .Z(n3621)); + AN2 U3479 ( .A(n3616), .B(n3597), .Z(n3624)); + AN2 U3480 ( .A(pi192), .B(n3626), .Z(n3582)); + OR2 U3481 ( .A(n3627), .B(n3628), .Z(n3626)); + OR2 U3482 ( .A(n3629), .B(n3630), .Z(n3628)); + AN2 U3483 ( .A(n3631), .B(n3632), .Z(n3630)); + AN2 U3484 ( .A(n3633), .B(n3634), .Z(n3631)); + OR2 U3485 ( .A(n3635), .B(n3355), .Z(n3634)); + AN2 U3486 ( .A(n3636), .B(n3637), .Z(n3633)); + OR2 U3487 ( .A(n3596), .B(n3638), .Z(n3637)); + AN2 U3488 ( .A(n3639), .B(n3339), .Z(n3596)); + OR2 U3489 ( .A(pi098), .B(n3598), .Z(n3636)); + AN2 U3490 ( .A(n3640), .B(n3641), .Z(n3629)); + OR2 U3491 ( .A(n3642), .B(n3643), .Z(n3641)); + OR2 U3492 ( .A(n3644), .B(n3645), .Z(n3643)); + AN2 U3493 ( .A(n3605), .B(n3635), .Z(n3645)); + OR2 U3494 ( .A(n3646), .B(n3647), .Z(n3605)); + AN2 U3495 ( .A(n3648), .B(n3493), .Z(n3647)); + AN2 U3496 ( .A(n3341), .B(n3639), .Z(n3646)); + AN2 U3497 ( .A(n3649), .B(n3607), .Z(n3644)); + OR2 U3498 ( .A(n3650), .B(n3651), .Z(n3642)); + AN2 U3499 ( .A(n3652), .B(pi098), .Z(n3651)); + AN2 U3500 ( .A(n3653), .B(n3612), .Z(n3652)); + AN2 U3501 ( .A(n3654), .B(n3638), .Z(n3650)); + OR2 U3502 ( .A(n3655), .B(n3656), .Z(n3654)); + AN2 U3503 ( .A(n3598), .B(n3657), .Z(n3656)); + OR2 U3504 ( .A(n3658), .B(n3659), .Z(n3598)); + AN2 U3505 ( .A(n3660), .B(n3493), .Z(n3659)); + AN2 U3506 ( .A(po011), .B(n3612), .Z(n3660)); + AN2 U3507 ( .A(n3625), .B(n3661), .Z(n3658)); + AN2 U3508 ( .A(n3617), .B(n3635), .Z(n3655)); + AN2 U3509 ( .A(n3625), .B(n3493), .Z(n3617)); + AN2 U3510 ( .A(n3662), .B(n3619), .Z(n3627)); + AN2 U3511 ( .A(n3663), .B(n3632), .Z(n3662)); + OR2 U3512 ( .A(n3664), .B(n3665), .Z(n3663)); + OR2 U3513 ( .A(n3494), .B(n3649), .Z(n3665)); + AN2 U3514 ( .A(pi098), .B(n3666), .Z(n3649)); + AN2 U3515 ( .A(n3657), .B(po011), .Z(n3666)); + AN2 U3516 ( .A(n3612), .B(n3667), .Z(n3494)); + AN2 U3517 ( .A(n3668), .B(n3625), .Z(n3664)); + AN2 U3518 ( .A(n3657), .B(n3638), .Z(n3668)); + OR2 U3519 ( .A(n3669), .B(n3670), .Z(n3580)); + AN2 U3520 ( .A(n3671), .B(po011), .Z(n3670)); + AN2 U3521 ( .A(n3672), .B(n3612), .Z(n3671)); + AN2 U3522 ( .A(n3673), .B(n3674), .Z(n3672)); + OR2 U3523 ( .A(pi192), .B(n3675), .Z(n3674)); + AN2 U3524 ( .A(n3676), .B(n3597), .Z(n3675)); + OR2 U3525 ( .A(n3677), .B(n3678), .Z(n3676)); + AN2 U3526 ( .A(n3679), .B(n3680), .Z(n3677)); + AN2 U3527 ( .A(n3599), .B(n3661), .Z(n3679)); + OR2 U3528 ( .A(n2837), .B(n3681), .Z(n3673)); + AN2 U3529 ( .A(n3682), .B(n3638), .Z(n3681)); + OR2 U3530 ( .A(n3683), .B(n3684), .Z(n3682)); + AN2 U3531 ( .A(n3685), .B(n3686), .Z(n3683)); + AN2 U3532 ( .A(n3640), .B(n3661), .Z(n3685)); + AN2 U3533 ( .A(n3687), .B(n3688), .Z(n3669)); + OR2 U3534 ( .A(n3689), .B(n3690), .Z(n3687)); + OR2 U3535 ( .A(n3691), .B(n3692), .Z(n3690)); + AN2 U3536 ( .A(n3693), .B(n3612), .Z(n3692)); + AN2 U3537 ( .A(n3619), .B(n3694), .Z(n3693)); + OR2 U3538 ( .A(n3695), .B(n3696), .Z(n3694)); + OR2 U3539 ( .A(n3697), .B(n3698), .Z(n3696)); + AN2 U3540 ( .A(n3699), .B(n3616), .Z(n3698)); + AN2 U3541 ( .A(n3700), .B(n3657), .Z(n3697)); + AN2 U3542 ( .A(n3341), .B(n3701), .Z(n3695)); + AN2 U3543 ( .A(n3493), .B(n3352), .Z(n3619)); + AN2 U3544 ( .A(n3625), .B(n3702), .Z(n3691)); + OR2 U3545 ( .A(n3703), .B(n3704), .Z(n3702)); + AN2 U3546 ( .A(n3705), .B(n3706), .Z(n3704)); + OR2 U3547 ( .A(n3684), .B(n3707), .Z(n3706)); + OR2 U3548 ( .A(n3708), .B(n3709), .Z(n3707)); + AN2 U3549 ( .A(n3710), .B(n3640), .Z(n3709)); + OR2 U3550 ( .A(n3711), .B(n3712), .Z(n3710)); + AN2 U3551 ( .A(n3607), .B(n3686), .Z(n3712)); + AN2 U3552 ( .A(n3493), .B(n3713), .Z(n3711)); + IV2 U3553 ( .A(n3686), .Z(n3713)); + AN2 U3554 ( .A(n3653), .B(n3632), .Z(n3708)); + OR2 U3555 ( .A(n3714), .B(n3715), .Z(n3653)); + AN2 U3556 ( .A(n3686), .B(n3493), .Z(n3714)); + AN2 U3557 ( .A(n3635), .B(n3339), .Z(n3686)); + AN2 U3558 ( .A(n3607), .B(n3716), .Z(n3684)); + AN2 U3559 ( .A(n3632), .B(n3657), .Z(n3716)); + AN2 U3560 ( .A(n3717), .B(n3718), .Z(n3703)); + OR2 U3561 ( .A(n3678), .B(n3719), .Z(n3718)); + OR2 U3562 ( .A(n3720), .B(n3721), .Z(n3719)); + AN2 U3563 ( .A(n3722), .B(n3599), .Z(n3721)); + OR2 U3564 ( .A(n3723), .B(n3724), .Z(n3722)); + AN2 U3565 ( .A(n3680), .B(n3607), .Z(n3724)); + AN2 U3566 ( .A(n3493), .B(n3725), .Z(n3723)); + IV2 U3567 ( .A(n3680), .Z(n3725)); + AN2 U3568 ( .A(n3611), .B(n3590), .Z(n3720)); + OR2 U3569 ( .A(n3726), .B(n3715), .Z(n3611)); + AN2 U3570 ( .A(n3341), .B(n3607), .Z(n3715)); + AN2 U3571 ( .A(n3680), .B(n3493), .Z(n3726)); + AN2 U3572 ( .A(n3593), .B(n3339), .Z(n3680)); + AN2 U3573 ( .A(n3607), .B(n3727), .Z(n3678)); + AN2 U3574 ( .A(n3590), .B(n3616), .Z(n3727)); + AN2 U3575 ( .A(n3661), .B(n3352), .Z(n3607)); + AN2 U3576 ( .A(n3639), .B(n3728), .Z(n3689)); + OR2 U3577 ( .A(n3729), .B(n3730), .Z(n3728)); + OR2 U3578 ( .A(n3731), .B(n3732), .Z(n3730)); + AN2 U3579 ( .A(n3733), .B(pi192), .Z(n3732)); + AN2 U3580 ( .A(n3640), .B(n3657), .Z(n3733)); + AN2 U3581 ( .A(n3734), .B(n2837), .Z(n3731)); + AN2 U3582 ( .A(n3599), .B(n3616), .Z(n3734)); + IV2 U3583 ( .A(n3590), .Z(n3599)); + AN2 U3584 ( .A(n3735), .B(n3355), .Z(n3729)); + OR2 U3585 ( .A(n3339), .B(n3736), .Z(n3735)); + OR2 U3586 ( .A(n3737), .B(n3738), .Z(n3578)); + AN2 U3587 ( .A(n3355), .B(n3739), .Z(n3738)); + OR2 U3588 ( .A(n3740), .B(n3741), .Z(n3739)); + AN2 U3589 ( .A(n3742), .B(n3625), .Z(n3741)); + AN2 U3590 ( .A(n3743), .B(n3744), .Z(n3742)); + OR2 U3591 ( .A(n3661), .B(n3688), .Z(n3744)); + OR2 U3592 ( .A(po011), .B(n3745), .Z(n3743)); + AN2 U3593 ( .A(n3493), .B(n3746), .Z(n3745)); + AN2 U3594 ( .A(n3747), .B(n3639), .Z(n3740)); + AN2 U3595 ( .A(n3661), .B(n3612), .Z(n3639)); + AN2 U3596 ( .A(n3736), .B(n3746), .Z(n3747)); + OR2 U3597 ( .A(n3292), .B(n3344), .Z(n3736)); + IV2 U3598 ( .A(n3291), .Z(n3292)); + AN2 U3599 ( .A(n3748), .B(n3648), .Z(n3737)); + OR2 U3600 ( .A(n3749), .B(n3750), .Z(n3648)); + AN2 U3601 ( .A(n3625), .B(po011), .Z(n3750)); + IV2 U3602 ( .A(n3612), .Z(n3625)); + AN2 U3603 ( .A(n3751), .B(n3688), .Z(n3749)); + AN2 U3604 ( .A(n3339), .B(n3612), .Z(n3751)); + OR2 U3605 ( .A(n3752), .B(n3753), .Z(n3612)); + OR2 U3606 ( .A(n3754), .B(n3755), .Z(n3753)); + AN2 U3607 ( .A(n3756), .B(n3757), .Z(n3755)); + OR2 U3608 ( .A(n3758), .B(n3759), .Z(n3752)); + AN2 U3609 ( .A(n3760), .B(n3761), .Z(n3759)); + AN2 U3610 ( .A(n3661), .B(n3762), .Z(n3748)); + OR2 U3611 ( .A(n3763), .B(n3764), .Z(po087)); + OR2 U3612 ( .A(po042), .B(n3765), .Z(n3764)); + OR2 U3613 ( .A(po029), .B(po022), .Z(n3765)); + OR2 U3614 ( .A(n3766), .B(n3767), .Z(n3763)); + OR2 U3615 ( .A(po080), .B(po056), .Z(n3767)); + OR2 U3616 ( .A(po105), .B(po083), .Z(n3766)); + IV2 U3617 ( .A(n3768), .Z(po105)); + AN2 U3618 ( .A(n3769), .B(n3770), .Z(n3768)); + AN2 U3619 ( .A(pi034), .B(pi007), .Z(n3770)); + AN2 U3620 ( .A(pi139), .B(pi120), .Z(n3769)); + OR2 U3621 ( .A(n3771), .B(n3772), .Z(po086)); + AN2 U3622 ( .A(n3773), .B(n3774), .Z(n3772)); + OR2 U3623 ( .A(n3775), .B(n3776), .Z(n3774)); + AN2 U3624 ( .A(n3777), .B(n3778), .Z(n3771)); + AN2 U3625 ( .A(n3779), .B(n3780), .Z(n3777)); + OR2 U3626 ( .A(po025), .B(n3781), .Z(n3779)); + IV2 U3627 ( .A(n3782), .Z(po083)); + AN2 U3628 ( .A(n3783), .B(n3784), .Z(n3782)); + AN2 U3629 ( .A(pi067), .B(pi041), .Z(n3784)); + AN2 U3630 ( .A(pi104), .B(pi070), .Z(n3783)); + OR2 U3631 ( .A(n3785), .B(n3786), .Z(po081)); + AN2 U3632 ( .A(n2862), .B(n3787), .Z(n3786)); + AN2 U3633 ( .A(n2930), .B(n3788), .Z(n3785)); + OR2 U3634 ( .A(n3146), .B(n3789), .Z(n3788)); + OR2 U3635 ( .A(n3790), .B(n3791), .Z(n3789)); + AN2 U3636 ( .A(n3792), .B(n2901), .Z(n3791)); + OR2 U3637 ( .A(n3793), .B(n3794), .Z(n3792)); + AN2 U3638 ( .A(pi192), .B(n2887), .Z(n3794)); + AN2 U3639 ( .A(n3795), .B(n2974), .Z(n3793)); + OR2 U3640 ( .A(n3796), .B(po031), .Z(n3795)); + AN2 U3641 ( .A(n2957), .B(n2837), .Z(n3796)); + AN2 U3642 ( .A(n3797), .B(n2935), .Z(n3790)); + AN2 U3643 ( .A(n2946), .B(n2837), .Z(n3797)); + OR2 U3644 ( .A(n3798), .B(n3799), .Z(po080)); + OR2 U3645 ( .A(n3800), .B(n3801), .Z(n3799)); + OR2 U3646 ( .A(n3802), .B(n3803), .Z(n3801)); + AN2 U3647 ( .A(n3804), .B(n2837), .Z(n3803)); + OR2 U3648 ( .A(n3805), .B(n3806), .Z(n3804)); + OR2 U3649 ( .A(n3807), .B(n3808), .Z(n3806)); + AN2 U3650 ( .A(n3809), .B(n3810), .Z(n3808)); + AN2 U3651 ( .A(n3811), .B(n3812), .Z(n3807)); + AN2 U3652 ( .A(n3813), .B(n3814), .Z(n3805)); + OR2 U3653 ( .A(n3815), .B(n3816), .Z(n3814)); + OR2 U3654 ( .A(n3817), .B(n3818), .Z(n3813)); + AN2 U3655 ( .A(pi192), .B(n3819), .Z(n3802)); + OR2 U3656 ( .A(n3820), .B(n3821), .Z(n3819)); + OR2 U3657 ( .A(n3822), .B(n3823), .Z(n3821)); + AN2 U3658 ( .A(n3824), .B(n3825), .Z(n3823)); + OR2 U3659 ( .A(n3826), .B(n3827), .Z(n3825)); + IV2 U3660 ( .A(n3828), .Z(n3824)); + AN2 U3661 ( .A(n3827), .B(n3826), .Z(n3828)); + OR2 U3662 ( .A(n3829), .B(n3830), .Z(n3826)); + AN2 U3663 ( .A(n3817), .B(n3171), .Z(n3830)); + AN2 U3664 ( .A(n3816), .B(pi033), .Z(n3829)); + IV2 U3665 ( .A(n3817), .Z(n3816)); + OR2 U3666 ( .A(n3831), .B(n3832), .Z(n3817)); + AN2 U3667 ( .A(n3833), .B(pi192), .Z(n3832)); + OR2 U3668 ( .A(n3834), .B(n3835), .Z(n3833)); + IV2 U3669 ( .A(n3836), .Z(n3835)); + OR2 U3670 ( .A(n3837), .B(n3838), .Z(n3836)); + AN2 U3671 ( .A(n3838), .B(n3837), .Z(n3834)); + AN2 U3672 ( .A(n3839), .B(n3840), .Z(n3837)); + OR2 U3673 ( .A(n3841), .B(pi013), .Z(n3840)); + IV2 U3674 ( .A(n3842), .Z(n3841)); + OR2 U3675 ( .A(n3843), .B(n3842), .Z(n3839)); + OR2 U3676 ( .A(n3844), .B(n3845), .Z(n3842)); + AN2 U3677 ( .A(pi026), .B(n3846), .Z(n3845)); + AN2 U3678 ( .A(pi077), .B(n3847), .Z(n3844)); + IV2 U3679 ( .A(pi013), .Z(n3843)); + OR2 U3680 ( .A(n3848), .B(n3849), .Z(n3838)); + AN2 U3681 ( .A(n3850), .B(n3136), .Z(n3849)); + AN2 U3682 ( .A(n3851), .B(pi088), .Z(n3848)); + IV2 U3683 ( .A(n3850), .Z(n3851)); + OR2 U3684 ( .A(n3852), .B(n3853), .Z(n3850)); + IV2 U3685 ( .A(n3854), .Z(n3853)); + OR2 U3686 ( .A(n3855), .B(pi157), .Z(n3854)); + AN2 U3687 ( .A(pi157), .B(n3855), .Z(n3852)); + IV2 U3688 ( .A(pi137), .Z(n3855)); + AN2 U3689 ( .A(n3856), .B(n3857), .Z(n3827)); + OR2 U3690 ( .A(n3858), .B(pi096), .Z(n3857)); + IV2 U3691 ( .A(n3859), .Z(n3858)); + OR2 U3692 ( .A(n3859), .B(n3199), .Z(n3856)); + OR2 U3693 ( .A(n3860), .B(n3861), .Z(n3859)); + AN2 U3694 ( .A(pi166), .B(n3862), .Z(n3861)); + IV2 U3695 ( .A(pi175), .Z(n3862)); + AN2 U3696 ( .A(pi175), .B(n3106), .Z(n3860)); + OR2 U3697 ( .A(n3863), .B(n3864), .Z(n3822)); + AN2 U3698 ( .A(n3865), .B(n3866), .Z(n3864)); + IV2 U3699 ( .A(n3867), .Z(n3863)); + OR2 U3700 ( .A(n3866), .B(n3865), .Z(n3867)); + OR2 U3701 ( .A(n3868), .B(n3869), .Z(n3865)); + AN2 U3702 ( .A(n3811), .B(n3870), .Z(n3869)); + IV2 U3703 ( .A(n3810), .Z(n3811)); + AN2 U3704 ( .A(pi016), .B(n3810), .Z(n3868)); + OR2 U3705 ( .A(n3871), .B(n3872), .Z(n3810)); + OR2 U3706 ( .A(n3873), .B(n3874), .Z(n3872)); + AN2 U3707 ( .A(n3875), .B(pi148), .Z(n3874)); + OR2 U3708 ( .A(n3876), .B(n3877), .Z(n3875)); + AN2 U3709 ( .A(n3878), .B(pi135), .Z(n3877)); + AN2 U3710 ( .A(n3879), .B(n3880), .Z(n3876)); + AN2 U3711 ( .A(n3881), .B(n3882), .Z(n3873)); + IV2 U3712 ( .A(pi148), .Z(n3882)); + OR2 U3713 ( .A(n3883), .B(n3884), .Z(n3881)); + AN2 U3714 ( .A(n3879), .B(pi135), .Z(n3884)); + OR2 U3715 ( .A(n3885), .B(n3886), .Z(n3879)); + AN2 U3716 ( .A(n3887), .B(n3888), .Z(n3886)); + AN2 U3717 ( .A(n3889), .B(n3890), .Z(n3885)); + AN2 U3718 ( .A(n3878), .B(n3880), .Z(n3883)); + OR2 U3719 ( .A(n3891), .B(n3892), .Z(n3878)); + AN2 U3720 ( .A(n3887), .B(n3890), .Z(n3892)); + AN2 U3721 ( .A(n3889), .B(n3888), .Z(n3891)); + IV2 U3722 ( .A(n3887), .Z(n3889)); + OR2 U3723 ( .A(n3893), .B(n3894), .Z(n3887)); + AN2 U3724 ( .A(n3895), .B(n3896), .Z(n3894)); + AN2 U3725 ( .A(n3897), .B(pi005), .Z(n3893)); + IV2 U3726 ( .A(n3895), .Z(n3897)); + OR2 U3727 ( .A(n3898), .B(n3899), .Z(n3895)); + AN2 U3728 ( .A(pi069), .B(n3900), .Z(n3899)); + IV2 U3729 ( .A(pi072), .Z(n3900)); + AN2 U3730 ( .A(pi072), .B(n3901), .Z(n3898)); + AN2 U3731 ( .A(n3902), .B(n3903), .Z(n3866)); + OR2 U3732 ( .A(n3904), .B(pi045), .Z(n3903)); + IV2 U3733 ( .A(n3905), .Z(n3902)); + AN2 U3734 ( .A(n3904), .B(pi045), .Z(n3905)); + AN2 U3735 ( .A(n3906), .B(n3907), .Z(n3904)); + OR2 U3736 ( .A(n3908), .B(pi158), .Z(n3907)); + OR2 U3737 ( .A(n3909), .B(pi079), .Z(n3906)); + OR2 U3738 ( .A(n3910), .B(n3911), .Z(n3820)); + AN2 U3739 ( .A(n3912), .B(n3913), .Z(n3911)); + AN2 U3740 ( .A(n3534), .B(n3914), .Z(n3912)); + AN2 U3741 ( .A(pi118), .B(n3915), .Z(n3910)); + OR2 U3742 ( .A(n3916), .B(n3917), .Z(n3915)); + AN2 U3743 ( .A(n3918), .B(pi060), .Z(n3917)); + AN2 U3744 ( .A(n3919), .B(n3534), .Z(n3916)); + AN2 U3745 ( .A(n3920), .B(n3921), .Z(n3919)); + AN2 U3746 ( .A(n3922), .B(n3923), .Z(n3800)); + OR2 U3747 ( .A(n3924), .B(n3925), .Z(n3923)); + OR2 U3748 ( .A(n3321), .B(n3926), .Z(n3925)); + AN2 U3749 ( .A(n3927), .B(n3928), .Z(n3924)); + AN2 U3750 ( .A(pi050), .B(pi118), .Z(n3928)); + AN2 U3751 ( .A(pi196), .B(n3534), .Z(n3927)); + OR2 U3752 ( .A(n3929), .B(n3930), .Z(n3798)); + OR2 U3753 ( .A(n3931), .B(n3932), .Z(n3930)); + AN2 U3754 ( .A(n3933), .B(n3533), .Z(n3932)); + AN2 U3755 ( .A(n3934), .B(n3913), .Z(n3933)); + OR2 U3756 ( .A(n3918), .B(n3935), .Z(n3934)); + OR2 U3757 ( .A(n3936), .B(n3937), .Z(n3935)); + AN2 U3758 ( .A(n3938), .B(n3921), .Z(n3937)); + AN2 U3759 ( .A(n3920), .B(n3261), .Z(n3938)); + AN2 U3760 ( .A(n3939), .B(n3922), .Z(n3936)); + AN2 U3761 ( .A(pi196), .B(n3940), .Z(n3939)); + AN2 U3762 ( .A(n3922), .B(n3941), .Z(n3918)); + AN2 U3763 ( .A(n3942), .B(n3943), .Z(n3941)); + AN2 U3764 ( .A(n3944), .B(n3945), .Z(n3931)); + AN2 U3765 ( .A(pi204), .B(n3946), .Z(n3944)); + IV2 U3766 ( .A(n3947), .Z(n3946)); + AN2 U3767 ( .A(n3948), .B(n3261), .Z(n3929)); + OR2 U3768 ( .A(n3949), .B(n3950), .Z(n3948)); + AN2 U3769 ( .A(n3947), .B(n3951), .Z(n3950)); + AN2 U3770 ( .A(n3952), .B(n3953), .Z(n3947)); + IV2 U3771 ( .A(n3954), .Z(n3953)); + AN2 U3772 ( .A(n3955), .B(n3956), .Z(n3954)); + OR2 U3773 ( .A(n3956), .B(n3955), .Z(n3952)); + OR2 U3774 ( .A(n3957), .B(n3958), .Z(n3955)); + AN2 U3775 ( .A(n3959), .B(n3960), .Z(n3958)); + IV2 U3776 ( .A(pi009), .Z(n3960)); + AN2 U3777 ( .A(pi009), .B(n3961), .Z(n3957)); + AN2 U3778 ( .A(n3962), .B(n3963), .Z(n3956)); + OR2 U3779 ( .A(n3964), .B(pi129), .Z(n3963)); + IV2 U3780 ( .A(n3965), .Z(n3964)); + OR2 U3781 ( .A(n3965), .B(n3966), .Z(n3962)); + OR2 U3782 ( .A(n3967), .B(n3968), .Z(n3965)); + AN2 U3783 ( .A(pi138), .B(n3969), .Z(n3968)); + AN2 U3784 ( .A(pi169), .B(n3970), .Z(n3967)); + IV2 U3785 ( .A(pi138), .Z(n3970)); + AN2 U3786 ( .A(n3971), .B(n3533), .Z(n3949)); + AN2 U3787 ( .A(n3914), .B(pi118), .Z(n3971)); + OR2 U3788 ( .A(n3972), .B(n3973), .Z(n3914)); + AN2 U3789 ( .A(n3920), .B(n3922), .Z(n3973)); + IV2 U3790 ( .A(n3921), .Z(n3922)); + AN2 U3791 ( .A(n3921), .B(n3974), .Z(n3972)); + IV2 U3792 ( .A(n3920), .Z(n3974)); + OR2 U3793 ( .A(n3975), .B(n3976), .Z(n3920)); + AN2 U3794 ( .A(pi050), .B(n3942), .Z(n3976)); + AN2 U3795 ( .A(pi196), .B(n3943), .Z(n3975)); + OR2 U3796 ( .A(n3977), .B(n3978), .Z(n3921)); + AN2 U3797 ( .A(n3979), .B(pi192), .Z(n3978)); + OR2 U3798 ( .A(n3980), .B(n3981), .Z(n3979)); + AN2 U3799 ( .A(n3982), .B(n3983), .Z(n3981)); + IV2 U3800 ( .A(n3984), .Z(n3980)); + OR2 U3801 ( .A(n3983), .B(n3982), .Z(n3984)); + OR2 U3802 ( .A(n3985), .B(n3986), .Z(n3982)); + IV2 U3803 ( .A(n3987), .Z(n3986)); + OR2 U3804 ( .A(n3988), .B(n3989), .Z(n3987)); + AN2 U3805 ( .A(n3988), .B(n3989), .Z(n3985)); + AN2 U3806 ( .A(n3990), .B(n3991), .Z(n3988)); + OR2 U3807 ( .A(n3992), .B(pi039), .Z(n3991)); + OR2 U3808 ( .A(n3993), .B(pi004), .Z(n3990)); + IV2 U3809 ( .A(pi039), .Z(n3993)); + AN2 U3810 ( .A(n3994), .B(n3995), .Z(n3983)); + OR2 U3811 ( .A(n3996), .B(pi068), .Z(n3995)); + IV2 U3812 ( .A(n3997), .Z(n3996)); + OR2 U3813 ( .A(n3997), .B(n3998), .Z(n3994)); + OR2 U3814 ( .A(n3999), .B(n4000), .Z(n3997)); + AN2 U3815 ( .A(pi098), .B(n4001), .Z(n4000)); + AN2 U3816 ( .A(pi171), .B(n3638), .Z(n3999)); + OR2 U3817 ( .A(pi037), .B(pi043), .Z(po078)); + OR2 U3818 ( .A(n4002), .B(n4003), .Z(po077)); + AN2 U3819 ( .A(n4004), .B(n4005), .Z(n4003)); + AN2 U3820 ( .A(n4006), .B(n4007), .Z(n4002)); + OR2 U3821 ( .A(n4008), .B(n4009), .Z(n4007)); + IV2 U3822 ( .A(pi090), .Z(po076)); + OR2 U3823 ( .A(n4010), .B(n4011), .Z(po075)); + AN2 U3824 ( .A(n4012), .B(n4013), .Z(n4011)); + OR2 U3825 ( .A(n4014), .B(n4015), .Z(n4012)); + OR2 U3826 ( .A(n4016), .B(n4017), .Z(n4015)); + OR2 U3827 ( .A(n4018), .B(n4019), .Z(n4014)); + AN2 U3828 ( .A(n4020), .B(n3314), .Z(n4019)); + OR2 U3829 ( .A(n4021), .B(n4022), .Z(n4020)); + AN2 U3830 ( .A(n3926), .B(n3328), .Z(n4022)); + OR2 U3831 ( .A(n3265), .B(n3326), .Z(n3328)); + AN2 U3832 ( .A(n4023), .B(pi204), .Z(n4021)); + AN2 U3833 ( .A(n3312), .B(n3261), .Z(n4023)); + OR2 U3834 ( .A(n4024), .B(n4025), .Z(n3312)); + AN2 U3835 ( .A(n3326), .B(n4026), .Z(n4024)); + AN2 U3836 ( .A(n4027), .B(n3320), .Z(n4018)); + OR2 U3837 ( .A(n4028), .B(n3321), .Z(n4027)); + AN2 U3838 ( .A(po040), .B(n4029), .Z(n4010)); + OR2 U3839 ( .A(n4030), .B(n4031), .Z(n4029)); + OR2 U3840 ( .A(n4032), .B(n4033), .Z(n4031)); + AN2 U3841 ( .A(n4034), .B(n3261), .Z(n4032)); + OR2 U3842 ( .A(n4035), .B(n4036), .Z(n4034)); + OR2 U3843 ( .A(n4037), .B(n4038), .Z(n4036)); + AN2 U3844 ( .A(n4039), .B(n3951), .Z(n4038)); + AN2 U3845 ( .A(n4025), .B(n3314), .Z(n4039)); + AN2 U3846 ( .A(n4040), .B(n4041), .Z(n4037)); + AN2 U3847 ( .A(n4042), .B(n3320), .Z(n4035)); + OR2 U3848 ( .A(n4043), .B(n4044), .Z(n4042)); + AN2 U3849 ( .A(pi204), .B(n4045), .Z(n4044)); + AN2 U3850 ( .A(n4046), .B(n4041), .Z(n4043)); + OR2 U3851 ( .A(n4047), .B(n4048), .Z(n4030)); + AN2 U3852 ( .A(n4049), .B(n4050), .Z(n4048)); + OR2 U3853 ( .A(n4051), .B(n4052), .Z(n4050)); + AN2 U3854 ( .A(n3321), .B(n3265), .Z(n4052)); + AN2 U3855 ( .A(n3951), .B(n4053), .Z(n4051)); + AN2 U3856 ( .A(n3326), .B(n3314), .Z(n4049)); + AN2 U3857 ( .A(n4054), .B(n4055), .Z(n4047)); + AN2 U3858 ( .A(n4056), .B(n4057), .Z(n4055)); + AN2 U3859 ( .A(n3945), .B(pi204), .Z(n4054)); + OR2 U3860 ( .A(n4058), .B(n4059), .Z(po073)); + AN2 U3861 ( .A(n4060), .B(n4061), .Z(n4059)); + AN2 U3862 ( .A(n3457), .B(n4062), .Z(n4058)); + OR2 U3863 ( .A(n4063), .B(n4064), .Z(po068)); + AN2 U3864 ( .A(n4065), .B(n4066), .Z(n4064)); + OR2 U3865 ( .A(n4067), .B(n4068), .Z(n4065)); + OR2 U3866 ( .A(n4069), .B(n4070), .Z(n4068)); + AN2 U3867 ( .A(n4071), .B(n4072), .Z(n4070)); + OR2 U3868 ( .A(n4073), .B(po059), .Z(n4071)); + AN2 U3869 ( .A(n4074), .B(n2837), .Z(n4073)); + AN2 U3870 ( .A(n4075), .B(n4076), .Z(n4069)); + AN2 U3871 ( .A(n3780), .B(n4077), .Z(n4075)); + AN2 U3872 ( .A(n4078), .B(n4079), .Z(n4063)); + OR2 U3873 ( .A(n4080), .B(n4081), .Z(n4079)); + OR2 U3874 ( .A(n4082), .B(n4083), .Z(n4081)); + AN2 U3875 ( .A(n4084), .B(n2837), .Z(n4083)); + AN2 U3876 ( .A(n4085), .B(pi192), .Z(n4082)); + AN2 U3877 ( .A(n3778), .B(n3776), .Z(n4080)); + OR2 U3878 ( .A(n4086), .B(n4087), .Z(n3776)); + OR2 U3879 ( .A(n4088), .B(n4089), .Z(po061)); + AN2 U3880 ( .A(n2861), .B(n4090), .Z(n4089)); + OR2 U3881 ( .A(n4091), .B(n4092), .Z(n4090)); + OR2 U3882 ( .A(n4093), .B(n4094), .Z(n4092)); + AN2 U3883 ( .A(n4095), .B(n2901), .Z(n4094)); + AN2 U3884 ( .A(n2862), .B(n2990), .Z(n4093)); + OR2 U3885 ( .A(n4096), .B(n4097), .Z(n4091)); + AN2 U3886 ( .A(n2880), .B(n4098), .Z(n4097)); + AN2 U3887 ( .A(n4099), .B(n4100), .Z(n4096)); + OR2 U3888 ( .A(n4101), .B(n4102), .Z(n4100)); + OR2 U3889 ( .A(n2978), .B(n4103), .Z(n4102)); + AN2 U3890 ( .A(n3222), .B(n2957), .Z(n4103)); + AN2 U3891 ( .A(n2935), .B(po031), .Z(n4101)); + IV2 U3892 ( .A(n2938), .Z(n2935)); + AN2 U3893 ( .A(n4104), .B(n2998), .Z(n4088)); + OR2 U3894 ( .A(n4105), .B(n4106), .Z(n4104)); + OR2 U3895 ( .A(n4107), .B(n4108), .Z(n4106)); + AN2 U3896 ( .A(n2892), .B(pi192), .Z(n4108)); + AN2 U3897 ( .A(n2929), .B(n2837), .Z(n4107)); + AN2 U3898 ( .A(n2930), .B(n3787), .Z(n4105)); + OR2 U3899 ( .A(n4109), .B(n4110), .Z(n3787)); + OR2 U3900 ( .A(n4111), .B(n4112), .Z(n4110)); + AN2 U3901 ( .A(n4113), .B(n2837), .Z(n4112)); + AN2 U3902 ( .A(n2876), .B(pi192), .Z(n4111)); + AN2 U3903 ( .A(pi200), .B(n4114), .Z(n4109)); + OR2 U3904 ( .A(n4115), .B(n2999), .Z(n4114)); + OR2 U3905 ( .A(n4116), .B(n4117), .Z(n2999)); + AN2 U3906 ( .A(n2938), .B(n2962), .Z(n4117)); + AN2 U3907 ( .A(pi192), .B(n2878), .Z(n4116)); + AN2 U3908 ( .A(n2918), .B(n2837), .Z(n4115)); + AN2 U3909 ( .A(n2938), .B(pi082), .Z(n2918)); + OR2 U3910 ( .A(n4118), .B(n4119), .Z(po060)); + OR2 U3911 ( .A(n4120), .B(n4121), .Z(n4119)); + AN2 U3912 ( .A(n4122), .B(n4123), .Z(n4121)); + OR2 U3913 ( .A(n4124), .B(n4125), .Z(n4123)); + AN2 U3914 ( .A(n4126), .B(n4127), .Z(n4124)); + OR2 U3915 ( .A(n4128), .B(n4129), .Z(n4126)); + AN2 U3916 ( .A(n4130), .B(n4131), .Z(n4122)); + OR2 U3917 ( .A(n4132), .B(n4133), .Z(n4131)); + AN2 U3918 ( .A(pi052), .B(n4134), .Z(n4132)); + OR2 U3919 ( .A(po064), .B(n4135), .Z(n4130)); + AN2 U3920 ( .A(n4136), .B(n4137), .Z(n4120)); + OR2 U3921 ( .A(n4138), .B(n4139), .Z(n4137)); + AN2 U3922 ( .A(n4140), .B(n4141), .Z(n4139)); + OR2 U3923 ( .A(n4142), .B(n4143), .Z(n4140)); + OR2 U3924 ( .A(n4144), .B(n4145), .Z(n4143)); + AN2 U3925 ( .A(po040), .B(n3321), .Z(n4145)); + AN2 U3926 ( .A(po103), .B(n4146), .Z(n4144)); + OR2 U3927 ( .A(n4147), .B(n3321), .Z(n4146)); + AN2 U3928 ( .A(n4148), .B(n4149), .Z(n4147)); + OR2 U3929 ( .A(po004), .B(n4150), .Z(n4149)); + OR2 U3930 ( .A(n4151), .B(n4152), .Z(n4142)); + OR2 U3931 ( .A(n4153), .B(n4154), .Z(n4152)); + IV2 U3932 ( .A(n4155), .Z(n4154)); + OR2 U3933 ( .A(n4156), .B(n4157), .Z(n4155)); + AN2 U3934 ( .A(n4158), .B(n4159), .Z(n4153)); + AN2 U3935 ( .A(n4160), .B(po004), .Z(n4151)); + AN2 U3936 ( .A(n3951), .B(po040), .Z(n4160)); + AN2 U3937 ( .A(po004), .B(n4161), .Z(n4138)); + AN2 U3938 ( .A(n4162), .B(n4163), .Z(n4136)); + OR2 U3939 ( .A(n4164), .B(n4134), .Z(n4163)); + AN2 U3940 ( .A(n4165), .B(po064), .Z(n4164)); + IV2 U3941 ( .A(n4166), .Z(n4165)); + OR2 U3942 ( .A(n4167), .B(n4125), .Z(n4166)); + OR2 U3943 ( .A(n4135), .B(n4168), .Z(n4162)); + OR2 U3944 ( .A(n4169), .B(n4170), .Z(n4168)); + AN2 U3945 ( .A(pi054), .B(n4167), .Z(n4170)); + AN2 U3946 ( .A(n4171), .B(n4133), .Z(n4169)); + IV2 U3947 ( .A(n4172), .Z(n4171)); + OR2 U3948 ( .A(n4173), .B(n4174), .Z(n4118)); + AN2 U3949 ( .A(n4175), .B(pi054), .Z(n4174)); + AN2 U3950 ( .A(n4176), .B(n4177), .Z(n4175)); + OR2 U3951 ( .A(n4178), .B(n4179), .Z(n4176)); + AN2 U3952 ( .A(n4134), .B(n4133), .Z(n4179)); + AN2 U3953 ( .A(n4135), .B(po064), .Z(n4178)); + AN2 U3954 ( .A(n4180), .B(n4135), .Z(n4173)); + IV2 U3955 ( .A(n4134), .Z(n4135)); + OR2 U3956 ( .A(n4181), .B(n4182), .Z(n4134)); + AN2 U3957 ( .A(n4183), .B(n4184), .Z(n4182)); + OR2 U3958 ( .A(n4185), .B(n4186), .Z(n4183)); + AN2 U3959 ( .A(n4187), .B(n4188), .Z(n4186)); + IV2 U3960 ( .A(n4189), .Z(n4188)); + OR2 U3961 ( .A(n4190), .B(n4191), .Z(n4187)); + AN2 U3962 ( .A(n4192), .B(n4193), .Z(n4191)); + OR2 U3963 ( .A(n4194), .B(n4195), .Z(n4193)); + AN2 U3964 ( .A(n4196), .B(n3261), .Z(n4195)); + OR2 U3965 ( .A(n4197), .B(n4198), .Z(n4196)); + AN2 U3966 ( .A(n4199), .B(po103), .Z(n4198)); + AN2 U3967 ( .A(n4200), .B(n4201), .Z(n4199)); + AN2 U3968 ( .A(n4202), .B(n4025), .Z(n4197)); + AN2 U3969 ( .A(n4203), .B(po091), .Z(n4202)); + AN2 U3970 ( .A(n4204), .B(n4205), .Z(n4190)); + OR2 U3971 ( .A(n3317), .B(n4206), .Z(n4204)); + OR2 U3972 ( .A(n4207), .B(n4208), .Z(n4206)); + AN2 U3973 ( .A(n4209), .B(n3314), .Z(n4208)); + IV2 U3974 ( .A(n4210), .Z(n4209)); + AN2 U3975 ( .A(n4210), .B(n4057), .Z(n4207)); + AN2 U3976 ( .A(po103), .B(n4148), .Z(n4210)); + AN2 U3977 ( .A(n4189), .B(n4211), .Z(n4185)); + OR2 U3978 ( .A(n4212), .B(n4213), .Z(n4211)); + AN2 U3979 ( .A(n4214), .B(n4205), .Z(n4213)); + OR2 U3980 ( .A(n3325), .B(n4215), .Z(n4214)); + OR2 U3981 ( .A(n4216), .B(n3329), .Z(n4215)); + AN2 U3982 ( .A(n4040), .B(n4217), .Z(n3329)); + AN2 U3983 ( .A(n4192), .B(n4218), .Z(n4212)); + OR2 U3984 ( .A(n4219), .B(n4220), .Z(n4218)); + OR2 U3985 ( .A(n4221), .B(n4222), .Z(n4220)); + AN2 U3986 ( .A(n4025), .B(n4201), .Z(n4222)); + IV2 U3987 ( .A(n4223), .Z(n4025)); + AN2 U3988 ( .A(po091), .B(n4200), .Z(n4221)); + OR2 U3989 ( .A(n4224), .B(n4225), .Z(n4189)); + AN2 U3990 ( .A(n4226), .B(n4227), .Z(n4225)); + IV2 U3991 ( .A(n4228), .Z(n4224)); + OR2 U3992 ( .A(n4227), .B(n4226), .Z(n4228)); + AN2 U3993 ( .A(n4229), .B(n4230), .Z(n4181)); + OR2 U3994 ( .A(n4231), .B(n4232), .Z(n4230)); + OR2 U3995 ( .A(n4233), .B(n4234), .Z(n4232)); + AN2 U3996 ( .A(n4235), .B(n4236), .Z(n4234)); + OR2 U3997 ( .A(n4237), .B(n4238), .Z(n4235)); + AN2 U3998 ( .A(n4239), .B(n4240), .Z(n4238)); + OR2 U3999 ( .A(n3325), .B(n4216), .Z(n4240)); + AN2 U4000 ( .A(po103), .B(n4194), .Z(n4216)); + AN2 U4001 ( .A(n3265), .B(n4040), .Z(n3325)); + AN2 U4002 ( .A(n4241), .B(n4242), .Z(n4237)); + OR2 U4003 ( .A(n4243), .B(n4219), .Z(n4241)); + OR2 U4004 ( .A(n4244), .B(n3321), .Z(n4219)); + AN2 U4005 ( .A(n4203), .B(n4223), .Z(n4244)); + AN2 U4006 ( .A(n4245), .B(n3314), .Z(n4243)); + OR2 U4007 ( .A(n4246), .B(po091), .Z(n4245)); + AN2 U4008 ( .A(n4247), .B(n3265), .Z(n4246)); + AN2 U4009 ( .A(n4248), .B(n4249), .Z(n4233)); + OR2 U4010 ( .A(n4250), .B(n4251), .Z(n4249)); + OR2 U4011 ( .A(n4252), .B(n4253), .Z(n4251)); + AN2 U4012 ( .A(po103), .B(n4254), .Z(n4253)); + OR2 U4013 ( .A(n4255), .B(n3330), .Z(n4254)); + AN2 U4014 ( .A(n3311), .B(n4242), .Z(n4255)); + AN2 U4015 ( .A(n4194), .B(n3265), .Z(n4252)); + AN2 U4016 ( .A(n4148), .B(n3311), .Z(n4194)); + AN2 U4017 ( .A(n4239), .B(n4256), .Z(n4250)); + OR2 U4018 ( .A(n4257), .B(n4258), .Z(n4256)); + OR2 U4019 ( .A(n3926), .B(n4259), .Z(n4258)); + AN2 U4020 ( .A(n4260), .B(n3314), .Z(n4259)); + OR2 U4021 ( .A(n4261), .B(n4262), .Z(n4257)); + AN2 U4022 ( .A(pi058), .B(pi129), .Z(n4262)); + AN2 U4023 ( .A(n4056), .B(n3966), .Z(n4261)); + AN2 U4024 ( .A(n4263), .B(n4264), .Z(n4231)); + AN2 U4025 ( .A(n4265), .B(n4266), .Z(n4264)); + OR2 U4026 ( .A(n4267), .B(n4236), .Z(n4266)); + AN2 U4027 ( .A(n4268), .B(pi058), .Z(n4267)); + AN2 U4028 ( .A(n4242), .B(n3265), .Z(n4268)); + OR2 U4029 ( .A(n4269), .B(n4248), .Z(n4265)); + IV2 U4030 ( .A(n4236), .Z(n4248)); + AN2 U4031 ( .A(n4270), .B(n4271), .Z(n4236)); + IV2 U4032 ( .A(n4272), .Z(n4271)); + AN2 U4033 ( .A(n4226), .B(n4141), .Z(n4272)); + OR2 U4034 ( .A(n4226), .B(n4141), .Z(n4270)); + OR2 U4035 ( .A(n4273), .B(n4274), .Z(n4226)); + IV2 U4036 ( .A(n4275), .Z(n4274)); + OR2 U4037 ( .A(n4276), .B(n4277), .Z(n4275)); + AN2 U4038 ( .A(n4277), .B(n4276), .Z(n4273)); + AN2 U4039 ( .A(n4278), .B(n4279), .Z(n4276)); + OR2 U4040 ( .A(n4280), .B(n4281), .Z(n4279)); + IV2 U4041 ( .A(n4282), .Z(n4280)); + OR2 U4042 ( .A(n4283), .B(n4282), .Z(n4278)); + OR2 U4043 ( .A(n4284), .B(n4285), .Z(n4282)); + AN2 U4044 ( .A(po040), .B(n4286), .Z(n4285)); + OR2 U4045 ( .A(n4017), .B(n4287), .Z(n4286)); + OR2 U4046 ( .A(n4288), .B(n4289), .Z(n4287)); + AN2 U4047 ( .A(n4290), .B(n3314), .Z(n4289)); + OR2 U4048 ( .A(n4291), .B(n3321), .Z(n4290)); + IV2 U4049 ( .A(n4292), .Z(n4288)); + OR2 U4050 ( .A(n4293), .B(n3314), .Z(n4292)); + OR2 U4051 ( .A(n4294), .B(n3330), .Z(n4017)); + AN2 U4052 ( .A(n4201), .B(n3926), .Z(n3330)); + AN2 U4053 ( .A(n3311), .B(pi204), .Z(n4294)); + AN2 U4054 ( .A(n4295), .B(n4013), .Z(n4284)); + OR2 U4055 ( .A(n4033), .B(n4296), .Z(n4295)); + OR2 U4056 ( .A(n4297), .B(n4298), .Z(n4296)); + AN2 U4057 ( .A(n4299), .B(n3314), .Z(n4298)); + AN2 U4058 ( .A(n4300), .B(n3261), .Z(n4299)); + OR2 U4059 ( .A(n4301), .B(n4302), .Z(n4300)); + AN2 U4060 ( .A(pi204), .B(n4203), .Z(n4302)); + AN2 U4061 ( .A(po091), .B(n4041), .Z(n4301)); + AN2 U4062 ( .A(n4040), .B(n4293), .Z(n4297)); + AN2 U4063 ( .A(n3311), .B(n3951), .Z(n4033)); + IV2 U4064 ( .A(n4260), .Z(n3311)); + OR2 U4065 ( .A(n3321), .B(n4057), .Z(n4260)); + IV2 U4066 ( .A(n4281), .Z(n4283)); + OR2 U4067 ( .A(n4303), .B(n4304), .Z(n4281)); + AN2 U4068 ( .A(n4305), .B(n4306), .Z(n4304)); + AN2 U4069 ( .A(n4307), .B(n3261), .Z(n4305)); + OR2 U4070 ( .A(n4308), .B(n4309), .Z(n4307)); + AN2 U4071 ( .A(pi065), .B(n4148), .Z(n4309)); + AN2 U4072 ( .A(n4310), .B(pi058), .Z(n4308)); + AN2 U4073 ( .A(n4311), .B(n4312), .Z(n4303)); + OR2 U4074 ( .A(n3961), .B(n4313), .Z(n4311)); + IV2 U4075 ( .A(n3959), .Z(n3961)); + OR2 U4076 ( .A(n4314), .B(n4315), .Z(n3959)); + AN2 U4077 ( .A(pi058), .B(n4150), .Z(n4315)); + AN2 U4078 ( .A(pi065), .B(n4316), .Z(n4314)); + OR2 U4079 ( .A(n4317), .B(n4318), .Z(n4277)); + AN2 U4080 ( .A(po004), .B(n3265), .Z(n4318)); + AN2 U4081 ( .A(po103), .B(n4319), .Z(n4317)); + AN2 U4082 ( .A(n4239), .B(pi058), .Z(n4269)); + AN2 U4083 ( .A(n4040), .B(n3261), .Z(n4263)); + AN2 U4084 ( .A(n4320), .B(n4167), .Z(n4180)); + OR2 U4085 ( .A(n4129), .B(n4127), .Z(n4320)); + AN2 U4086 ( .A(po023), .B(pi183), .Z(po058)); + IV2 U4087 ( .A(n4321), .Z(po056)); + AN2 U4088 ( .A(n4322), .B(n4323), .Z(n4321)); + AN2 U4089 ( .A(pi063), .B(pi010), .Z(n4323)); + AN2 U4090 ( .A(pi203), .B(pi073), .Z(n4322)); + OR2 U4091 ( .A(n4324), .B(n4325), .Z(po055)); + AN2 U4092 ( .A(n3015), .B(n4326), .Z(n4325)); + AN2 U4093 ( .A(n3018), .B(n4327), .Z(n4324)); + AN2 U4094 ( .A(n4328), .B(n4329), .Z(po053)); + OR2 U4095 ( .A(n4306), .B(n4330), .Z(n4329)); + IV2 U4096 ( .A(n4312), .Z(n4306)); + OR2 U4097 ( .A(n4331), .B(n4312), .Z(n4328)); + AN2 U4098 ( .A(n4332), .B(n3780), .Z(po051)); + OR2 U4099 ( .A(n4333), .B(n4334), .Z(n4332)); + OR2 U4100 ( .A(n4335), .B(n4336), .Z(po050)); + AN2 U4101 ( .A(n4337), .B(n4338), .Z(n4336)); + OR2 U4102 ( .A(n4339), .B(n4340), .Z(n4338)); + AN2 U4103 ( .A(n4087), .B(n4341), .Z(n4339)); + AN2 U4104 ( .A(n4342), .B(n4343), .Z(n4335)); + OR2 U4105 ( .A(n4344), .B(n4345), .Z(n4343)); + OR2 U4106 ( .A(n4346), .B(n4347), .Z(n4345)); + AN2 U4107 ( .A(n4067), .B(n4348), .Z(n4346)); + OR2 U4108 ( .A(n4349), .B(n4350), .Z(n4067)); + AN2 U4109 ( .A(n4351), .B(pi192), .Z(n4350)); + AN2 U4110 ( .A(n4072), .B(n3880), .Z(n4351)); + AN2 U4111 ( .A(n4352), .B(n3890), .Z(n4349)); + AN2 U4112 ( .A(n4353), .B(n3780), .Z(n4352)); + OR2 U4113 ( .A(n4354), .B(n4355), .Z(n4344)); + AN2 U4114 ( .A(n4356), .B(n3780), .Z(n4355)); + AN2 U4115 ( .A(n4357), .B(n4076), .Z(n4354)); + AN2 U4116 ( .A(n4072), .B(n4358), .Z(n4357)); + OR2 U4117 ( .A(n4359), .B(n4360), .Z(po049)); + AN2 U4118 ( .A(n3361), .B(n4361), .Z(n4360)); + OR2 U4119 ( .A(n4362), .B(n4363), .Z(n4361)); + AN2 U4120 ( .A(n4364), .B(n3451), .Z(n4362)); + IV2 U4121 ( .A(n3401), .Z(n3361)); + AN2 U4122 ( .A(n4365), .B(n3401), .Z(n4359)); + OR2 U4123 ( .A(n4366), .B(n4367), .Z(n4365)); + AN2 U4124 ( .A(n3453), .B(n4368), .Z(n4366)); + OR2 U4125 ( .A(n4369), .B(n3253), .Z(po048)); + AN2 U4126 ( .A(n4370), .B(n3255), .Z(n4369)); + OR2 U4127 ( .A(n4371), .B(n4372), .Z(n4370)); + AN2 U4128 ( .A(n4373), .B(n3259), .Z(n4371)); + AN2 U4129 ( .A(n4374), .B(n4242), .Z(n4373)); + OR2 U4130 ( .A(n4375), .B(n4376), .Z(po047)); + OR2 U4131 ( .A(n4377), .B(n4378), .Z(n4376)); + AN2 U4132 ( .A(n4379), .B(n4380), .Z(n4378)); + AN2 U4133 ( .A(n4381), .B(n3259), .Z(n4377)); + AN2 U4134 ( .A(n4382), .B(n4383), .Z(n4381)); + OR2 U4135 ( .A(po004), .B(n4384), .Z(n4383)); + OR2 U4136 ( .A(n3926), .B(n4385), .Z(n4384)); + AN2 U4137 ( .A(n4386), .B(pi065), .Z(n4385)); + AN2 U4138 ( .A(n4387), .B(n4157), .Z(n4386)); + OR2 U4139 ( .A(n4319), .B(n4388), .Z(n4382)); + OR2 U4140 ( .A(n4389), .B(n4390), .Z(n4388)); + AN2 U4141 ( .A(n4391), .B(n3321), .Z(n4390)); + AN2 U4142 ( .A(n4392), .B(n4310), .Z(n4389)); + AN2 U4143 ( .A(pi204), .B(n4387), .Z(n4392)); + OR2 U4144 ( .A(n4393), .B(n4394), .Z(n4375)); + AN2 U4145 ( .A(n4395), .B(n4319), .Z(n4394)); + OR2 U4146 ( .A(n4396), .B(n4397), .Z(n4395)); + AN2 U4147 ( .A(n4227), .B(n4161), .Z(n4397)); + AN2 U4148 ( .A(po004), .B(n4398), .Z(n4393)); + OR2 U4149 ( .A(n4399), .B(n4400), .Z(n4398)); + OR2 U4150 ( .A(n4401), .B(n4402), .Z(n4400)); + AN2 U4151 ( .A(n4310), .B(n4403), .Z(n4402)); + AN2 U4152 ( .A(n4404), .B(n4227), .Z(n4401)); + AN2 U4153 ( .A(n4405), .B(n4406), .Z(n4399)); + AN2 U4154 ( .A(n4407), .B(n3261), .Z(n4405)); + OR2 U4155 ( .A(n4408), .B(n4409), .Z(n4407)); + AN2 U4156 ( .A(n4028), .B(pi065), .Z(n4409)); + AN2 U4157 ( .A(po040), .B(n4410), .Z(n4408)); + OR2 U4158 ( .A(n4411), .B(n4412), .Z(n4410)); + AN2 U4159 ( .A(pi065), .B(n4045), .Z(n4412)); + AN2 U4160 ( .A(n4046), .B(n4156), .Z(n4411)); + OR2 U4161 ( .A(n4413), .B(n4414), .Z(po046)); + OR2 U4162 ( .A(n4415), .B(n4416), .Z(n4414)); + AN2 U4163 ( .A(n3339), .B(n4417), .Z(n4416)); + AN2 U4164 ( .A(n3341), .B(n4418), .Z(n4415)); + OR2 U4165 ( .A(n4419), .B(n4420), .Z(n4413)); + AN2 U4166 ( .A(n4421), .B(pi192), .Z(n4420)); + OR2 U4167 ( .A(n4422), .B(n4423), .Z(n4421)); + AN2 U4168 ( .A(n4424), .B(pi098), .Z(n4423)); + AN2 U4169 ( .A(n4425), .B(n4426), .Z(n4424)); + OR2 U4170 ( .A(n3242), .B(n3657), .Z(n4425)); + IV2 U4171 ( .A(n3635), .Z(n3657)); + AN2 U4172 ( .A(n4427), .B(n3638), .Z(n4422)); + OR2 U4173 ( .A(n4428), .B(n4429), .Z(n4427)); + AN2 U4174 ( .A(n4430), .B(pi171), .Z(n4429)); + AN2 U4175 ( .A(n4431), .B(n4001), .Z(n4428)); + AN2 U4176 ( .A(n4432), .B(n2837), .Z(n4419)); + OR2 U4177 ( .A(n4433), .B(n4434), .Z(n4432)); + AN2 U4178 ( .A(n4435), .B(pi003), .Z(n4434)); + AN2 U4179 ( .A(n4436), .B(n4426), .Z(n4435)); + OR2 U4180 ( .A(n3244), .B(n3616), .Z(n4436)); + IV2 U4181 ( .A(n3593), .Z(n3616)); + AN2 U4182 ( .A(n4437), .B(n3597), .Z(n4433)); + OR2 U4183 ( .A(n4438), .B(n4439), .Z(n4437)); + AN2 U4184 ( .A(n4430), .B(pi142), .Z(n4439)); + AN2 U4185 ( .A(n4431), .B(n4440), .Z(n4438)); + AN2 U4186 ( .A(n3236), .B(n4441), .Z(n4431)); + OR2 U4187 ( .A(n4442), .B(n4443), .Z(po045)); + AN2 U4188 ( .A(n4444), .B(n4445), .Z(n4443)); + OR2 U4189 ( .A(n4446), .B(n3756), .Z(n4445)); + AN2 U4190 ( .A(n4006), .B(n4005), .Z(n4446)); + OR2 U4191 ( .A(n4447), .B(n4448), .Z(n4005)); + AN2 U4192 ( .A(n4449), .B(n3301), .Z(n4447)); + AN2 U4193 ( .A(n4450), .B(n3306), .Z(n4449)); + AN2 U4194 ( .A(n3757), .B(n4451), .Z(n4442)); + OR2 U4195 ( .A(n4452), .B(n4453), .Z(n4451)); + OR2 U4196 ( .A(n4454), .B(n4455), .Z(n4453)); + AN2 U4197 ( .A(po092), .B(n4456), .Z(n4455)); + OR2 U4198 ( .A(n4008), .B(n4004), .Z(n4456)); + AN2 U4199 ( .A(n4457), .B(n4458), .Z(n4008)); + AN2 U4200 ( .A(n4458), .B(n4459), .Z(n4454)); + OR2 U4201 ( .A(n4460), .B(n4461), .Z(n4459)); + AN2 U4202 ( .A(n4462), .B(n4463), .Z(n4461)); + AN2 U4203 ( .A(n4464), .B(n4465), .Z(n4462)); + AN2 U4204 ( .A(n4466), .B(n4467), .Z(n4460)); + AN2 U4205 ( .A(n4468), .B(n4469), .Z(n4466)); + OR2 U4206 ( .A(n4470), .B(n4471), .Z(po043)); + OR2 U4207 ( .A(n4472), .B(n4473), .Z(n4471)); + AN2 U4208 ( .A(n4474), .B(n4475), .Z(n4473)); + AN2 U4209 ( .A(n4476), .B(n4337), .Z(n4474)); + AN2 U4210 ( .A(n4477), .B(n4478), .Z(n4472)); + OR2 U4211 ( .A(n4479), .B(n4480), .Z(n4477)); + AN2 U4212 ( .A(n4337), .B(n4481), .Z(n4480)); + IV2 U4213 ( .A(n4342), .Z(n4337)); + AN2 U4214 ( .A(n4342), .B(n4476), .Z(n4479)); + IV2 U4215 ( .A(n4481), .Z(n4476)); + AN2 U4216 ( .A(n4482), .B(n4481), .Z(n4470)); + OR2 U4217 ( .A(n4483), .B(n4484), .Z(n4481)); + OR2 U4218 ( .A(n4485), .B(n4486), .Z(n4484)); + AN2 U4219 ( .A(n4487), .B(n4078), .Z(n4486)); + OR2 U4220 ( .A(n4488), .B(n4489), .Z(n4487)); + AN2 U4221 ( .A(n4490), .B(n3778), .Z(n4489)); + AN2 U4222 ( .A(n3773), .B(n4491), .Z(n4488)); + AN2 U4223 ( .A(n4492), .B(n4066), .Z(n4485)); + AN2 U4224 ( .A(n4490), .B(n3773), .Z(n4492)); + AN2 U4225 ( .A(n4491), .B(n4341), .Z(n4483)); + IV2 U4226 ( .A(n4490), .Z(n4491)); + OR2 U4227 ( .A(n4493), .B(n4494), .Z(n4490)); + IV2 U4228 ( .A(n4495), .Z(n4494)); + OR2 U4229 ( .A(n4496), .B(n4497), .Z(n4495)); + AN2 U4230 ( .A(n4497), .B(n4496), .Z(n4493)); + AN2 U4231 ( .A(n4498), .B(n4499), .Z(n4496)); + IV2 U4232 ( .A(n4500), .Z(n4499)); + AN2 U4233 ( .A(n4333), .B(n4501), .Z(n4500)); + OR2 U4234 ( .A(n4501), .B(n4333), .Z(n4498)); + OR2 U4235 ( .A(n4502), .B(n4503), .Z(n4501)); + OR2 U4236 ( .A(n4504), .B(n4505), .Z(n4503)); + OR2 U4237 ( .A(n4506), .B(n4507), .Z(n4505)); + AN2 U4238 ( .A(n4508), .B(n4509), .Z(n4507)); + AN2 U4239 ( .A(n4510), .B(n4511), .Z(n4506)); + AN2 U4240 ( .A(n4512), .B(n4513), .Z(n4504)); + OR2 U4241 ( .A(n4514), .B(n4515), .Z(n4502)); + AN2 U4242 ( .A(n4516), .B(n4517), .Z(n4515)); + AN2 U4243 ( .A(po102), .B(n4518), .Z(n4514)); + OR2 U4244 ( .A(n4519), .B(n4520), .Z(n4518)); + AN2 U4245 ( .A(n4513), .B(n4521), .Z(n4520)); + OR2 U4246 ( .A(n4522), .B(n4523), .Z(n4513)); + AN2 U4247 ( .A(n4508), .B(n3773), .Z(n4523)); + AN2 U4248 ( .A(po025), .B(n4516), .Z(n4522)); + AN2 U4249 ( .A(n4508), .B(n4524), .Z(n4519)); + IV2 U4250 ( .A(n4510), .Z(n4508)); + OR2 U4251 ( .A(n4525), .B(n4526), .Z(n4510)); + AN2 U4252 ( .A(n4527), .B(n4528), .Z(n4526)); + OR2 U4253 ( .A(n4529), .B(n4530), .Z(n4527)); + OR2 U4254 ( .A(n4531), .B(n4532), .Z(n4530)); + AN2 U4255 ( .A(po025), .B(n4533), .Z(n4532)); + OR2 U4256 ( .A(n4534), .B(n4535), .Z(n4533)); + OR2 U4257 ( .A(n4356), .B(n4536), .Z(n4535)); + AN2 U4258 ( .A(n4537), .B(n4538), .Z(n4536)); + AN2 U4259 ( .A(n4539), .B(n4540), .Z(n4537)); + AN2 U4260 ( .A(n3890), .B(n4541), .Z(n4534)); + OR2 U4261 ( .A(n4542), .B(n4543), .Z(n4541)); + AN2 U4262 ( .A(n4085), .B(n4544), .Z(n4542)); + AN2 U4263 ( .A(n3778), .B(n4545), .Z(n4531)); + OR2 U4264 ( .A(n4546), .B(n4547), .Z(n4545)); + OR2 U4265 ( .A(n4548), .B(n4549), .Z(n4547)); + AN2 U4266 ( .A(n3775), .B(n4550), .Z(n4549)); + AN2 U4267 ( .A(n4524), .B(n4333), .Z(n4548)); + AN2 U4268 ( .A(n4086), .B(n4551), .Z(n4546)); + OR2 U4269 ( .A(n4552), .B(n4553), .Z(n4529)); + AN2 U4270 ( .A(n4554), .B(n4555), .Z(n4553)); + OR2 U4271 ( .A(n4556), .B(n3888), .Z(n4555)); + AN2 U4272 ( .A(pi192), .B(n4557), .Z(n4556)); + AN2 U4273 ( .A(n4558), .B(n4559), .Z(n4554)); + OR2 U4274 ( .A(n4085), .B(n4560), .Z(n4558)); + AN2 U4275 ( .A(n4561), .B(n3773), .Z(n4560)); + AN2 U4276 ( .A(n4562), .B(n4563), .Z(n4552)); + OR2 U4277 ( .A(n4564), .B(n4565), .Z(n4563)); + AN2 U4278 ( .A(n4566), .B(n4567), .Z(n4564)); + AN2 U4279 ( .A(n3773), .B(n4076), .Z(n4566)); + OR2 U4280 ( .A(pi076), .B(n4557), .Z(n4562)); + AN2 U4281 ( .A(n4516), .B(n4568), .Z(n4525)); + OR2 U4282 ( .A(n4569), .B(n4570), .Z(n4568)); + OR2 U4283 ( .A(n4571), .B(n4572), .Z(n4570)); + OR2 U4284 ( .A(n4573), .B(n4574), .Z(n4572)); + AN2 U4285 ( .A(n4575), .B(n4576), .Z(n4574)); + AN2 U4286 ( .A(n4577), .B(n4076), .Z(n4575)); + AN2 U4287 ( .A(n3773), .B(n4578), .Z(n4577)); + AN2 U4288 ( .A(n4579), .B(n4580), .Z(n4573)); + OR2 U4289 ( .A(n4581), .B(n4565), .Z(n4579)); + AN2 U4290 ( .A(n4539), .B(n4582), .Z(n4565)); + AN2 U4291 ( .A(n2837), .B(n4550), .Z(n4582)); + IV2 U4292 ( .A(n4540), .Z(n4550)); + AN2 U4293 ( .A(n4567), .B(n4076), .Z(n4581)); + AN2 U4294 ( .A(n4086), .B(n4583), .Z(n4571)); + OR2 U4295 ( .A(n4584), .B(n4585), .Z(n4583)); + AN2 U4296 ( .A(n4543), .B(n3773), .Z(n4585)); + AN2 U4297 ( .A(n4586), .B(n4544), .Z(n4584)); + OR2 U4298 ( .A(n4085), .B(n3778), .Z(n4586)); + AN2 U4299 ( .A(n4557), .B(n3888), .Z(n4086)); + OR2 U4300 ( .A(n4587), .B(n4588), .Z(n4569)); + AN2 U4301 ( .A(n4589), .B(n4590), .Z(n4588)); + OR2 U4302 ( .A(n4591), .B(n3890), .Z(n4590)); + AN2 U4303 ( .A(po025), .B(pi192), .Z(n4591)); + AN2 U4304 ( .A(n4559), .B(n4592), .Z(n4589)); + OR2 U4305 ( .A(n4561), .B(n4085), .Z(n4592)); + OR2 U4306 ( .A(n4551), .B(n4353), .Z(n4559)); + AN2 U4307 ( .A(n4593), .B(n3775), .Z(n4587)); + AN2 U4308 ( .A(n2837), .B(n4576), .Z(n3775)); + AN2 U4309 ( .A(n4594), .B(n4540), .Z(n4593)); + OR2 U4310 ( .A(n4567), .B(n4066), .Z(n4540)); + OR2 U4311 ( .A(n4539), .B(n3778), .Z(n4594)); + IV2 U4312 ( .A(n4528), .Z(n4516)); + OR2 U4313 ( .A(n4595), .B(n4596), .Z(n4497)); + AN2 U4314 ( .A(n4597), .B(n4598), .Z(n4596)); + OR2 U4315 ( .A(n4599), .B(n4600), .Z(n4598)); + AN2 U4316 ( .A(n4601), .B(n4602), .Z(n4600)); + IV2 U4317 ( .A(n4603), .Z(n4599)); + OR2 U4318 ( .A(n4602), .B(n4601), .Z(n4603)); + OR2 U4319 ( .A(n4604), .B(n4605), .Z(n4601)); + AN2 U4320 ( .A(n3295), .B(n4606), .Z(n4605)); + AN2 U4321 ( .A(n4450), .B(n3301), .Z(n4604)); + AN2 U4322 ( .A(n4607), .B(n4608), .Z(n4602)); + OR2 U4323 ( .A(n4609), .B(n4610), .Z(n4608)); + IV2 U4324 ( .A(n4611), .Z(n4610)); + OR2 U4325 ( .A(n4611), .B(n4612), .Z(n4607)); + IV2 U4326 ( .A(n4609), .Z(n4612)); + OR2 U4327 ( .A(n4613), .B(n4614), .Z(n4609)); + OR2 U4328 ( .A(n4615), .B(n4616), .Z(n4614)); + AN2 U4329 ( .A(n4004), .B(n4617), .Z(n4616)); + OR2 U4330 ( .A(n4618), .B(n4619), .Z(n4617)); + AN2 U4331 ( .A(n4620), .B(n4463), .Z(n4619)); + AN2 U4332 ( .A(n4621), .B(n4464), .Z(n4620)); + AN2 U4333 ( .A(n4622), .B(n4467), .Z(n4618)); + AN2 U4334 ( .A(n4623), .B(n4468), .Z(n4622)); + AN2 U4335 ( .A(n4006), .B(n4624), .Z(n4615)); + OR2 U4336 ( .A(n4625), .B(n4626), .Z(n4613)); + AN2 U4337 ( .A(n4627), .B(n4628), .Z(n4626)); + OR2 U4338 ( .A(n4629), .B(n4630), .Z(n4627)); + AN2 U4339 ( .A(n4631), .B(pi192), .Z(n4630)); + AN2 U4340 ( .A(n4632), .B(pi158), .Z(n4631)); + AN2 U4341 ( .A(n4633), .B(n4634), .Z(n4632)); + OR2 U4342 ( .A(n4635), .B(n4465), .Z(n4634)); + OR2 U4343 ( .A(n4464), .B(n4636), .Z(n4633)); + OR2 U4344 ( .A(n4621), .B(n3301), .Z(n4636)); + AN2 U4345 ( .A(n4637), .B(n2837), .Z(n4629)); + AN2 U4346 ( .A(n4638), .B(pi151), .Z(n4637)); + AN2 U4347 ( .A(n4639), .B(n4640), .Z(n4638)); + OR2 U4348 ( .A(n4641), .B(n4469), .Z(n4640)); + OR2 U4349 ( .A(n4468), .B(n4642), .Z(n4639)); + OR2 U4350 ( .A(n4623), .B(n3301), .Z(n4642)); + AN2 U4351 ( .A(n4643), .B(po092), .Z(n4625)); + AN2 U4352 ( .A(n4644), .B(n3295), .Z(n4643)); + AN2 U4353 ( .A(n4645), .B(n4646), .Z(n4644)); + OR2 U4354 ( .A(pi192), .B(n4647), .Z(n4646)); + AN2 U4355 ( .A(n4641), .B(n4648), .Z(n4647)); + OR2 U4356 ( .A(n2837), .B(n4649), .Z(n4645)); + AN2 U4357 ( .A(n4635), .B(n3908), .Z(n4649)); + IV2 U4358 ( .A(n3761), .Z(n4597)); + AN2 U4359 ( .A(n4650), .B(n3761), .Z(n4595)); + OR2 U4360 ( .A(n4651), .B(n4652), .Z(n3761)); + AN2 U4361 ( .A(n4653), .B(n4654), .Z(n4651)); + AN2 U4362 ( .A(n4333), .B(n4528), .Z(n4654)); + OR2 U4363 ( .A(n4655), .B(n4656), .Z(n4528)); + AN2 U4364 ( .A(n4657), .B(n3083), .Z(n4655)); + AN2 U4365 ( .A(n3018), .B(n4658), .Z(n4657)); + OR2 U4366 ( .A(n4659), .B(n4660), .Z(n4658)); + OR2 U4367 ( .A(n4661), .B(n4662), .Z(n4660)); + AN2 U4368 ( .A(n4663), .B(n3010), .Z(n4662)); + AN2 U4369 ( .A(n4664), .B(n3049), .Z(n4661)); + OR2 U4370 ( .A(n4665), .B(n4663), .Z(n4664)); + AN2 U4371 ( .A(n4666), .B(n3010), .Z(n4665)); + OR2 U4372 ( .A(n3100), .B(n4667), .Z(n4659)); + AN2 U4373 ( .A(n4668), .B(n3012), .Z(n4667)); + OR2 U4374 ( .A(n4669), .B(n4670), .Z(n4668)); + AN2 U4375 ( .A(n4671), .B(pi201), .Z(n4670)); + AN2 U4376 ( .A(n4672), .B(n3115), .Z(n4671)); + OR2 U4377 ( .A(n4673), .B(n3173), .Z(n4672)); + AN2 U4378 ( .A(n2837), .B(n3049), .Z(n4673)); + AN2 U4379 ( .A(n4674), .B(pi088), .Z(n4669)); + AN2 U4380 ( .A(n4675), .B(n3108), .Z(n4674)); + OR2 U4381 ( .A(n4676), .B(n3064), .Z(n4675)); + AN2 U4382 ( .A(pi192), .B(n3049), .Z(n4676)); + AN2 U4383 ( .A(n4341), .B(n4482), .Z(n4653)); + OR2 U4384 ( .A(n4677), .B(n4678), .Z(n4650)); + OR2 U4385 ( .A(n4679), .B(n4680), .Z(n4678)); + OR2 U4386 ( .A(n4681), .B(n4682), .Z(n4680)); + AN2 U4387 ( .A(n4683), .B(n4684), .Z(n4682)); + AN2 U4388 ( .A(n4685), .B(n4648), .Z(n4683)); + AN2 U4389 ( .A(n4686), .B(n4687), .Z(n4681)); + OR2 U4390 ( .A(n4688), .B(n4689), .Z(n4687)); + OR2 U4391 ( .A(n4690), .B(n4691), .Z(n4689)); + AN2 U4392 ( .A(n4692), .B(n4621), .Z(n4691)); + AN2 U4393 ( .A(n4685), .B(n4623), .Z(n4690)); + AN2 U4394 ( .A(n4693), .B(n3300), .Z(n4688)); + IV2 U4395 ( .A(n4684), .Z(n4686)); + OR2 U4396 ( .A(n4694), .B(n4695), .Z(n4679)); + AN2 U4397 ( .A(n4696), .B(n3300), .Z(n4695)); + AN2 U4398 ( .A(po014), .B(n4684), .Z(n4696)); + OR2 U4399 ( .A(n4697), .B(n4698), .Z(n4684)); + AN2 U4400 ( .A(n4699), .B(n4450), .Z(n4697)); + AN2 U4401 ( .A(po039), .B(n4700), .Z(n4694)); + OR2 U4402 ( .A(n4701), .B(n4702), .Z(n4700)); + AN2 U4403 ( .A(n4698), .B(n4703), .Z(n4702)); + AN2 U4404 ( .A(n4704), .B(n4606), .Z(n4698)); + AN2 U4405 ( .A(n4705), .B(n4706), .Z(n4701)); + AN2 U4406 ( .A(n4707), .B(n4708), .Z(n4705)); + OR2 U4407 ( .A(n4704), .B(n3295), .Z(n4708)); + OR2 U4408 ( .A(n4699), .B(n3301), .Z(n4707)); + OR2 U4409 ( .A(n4709), .B(n4710), .Z(n4677)); + AN2 U4410 ( .A(n4711), .B(n4699), .Z(n4710)); + IV2 U4411 ( .A(n4704), .Z(n4699)); + AN2 U4412 ( .A(n4450), .B(n4712), .Z(n4711)); + OR2 U4413 ( .A(po014), .B(n3301), .Z(n4712)); + AN2 U4414 ( .A(n4713), .B(n4704), .Z(n4709)); + OR2 U4415 ( .A(n4714), .B(n4715), .Z(n4704)); + OR2 U4416 ( .A(n4716), .B(n4717), .Z(n4715)); + OR2 U4417 ( .A(n4718), .B(n4719), .Z(n4717)); + IV2 U4418 ( .A(n4720), .Z(n4719)); + OR2 U4419 ( .A(n4721), .B(n4006), .Z(n4720)); + OR2 U4420 ( .A(n4444), .B(n3756), .Z(n4721)); + AN2 U4421 ( .A(n4722), .B(n4006), .Z(n4718)); + AN2 U4422 ( .A(n4444), .B(n4452), .Z(n4722)); + OR2 U4423 ( .A(n4723), .B(n4724), .Z(n4452)); + OR2 U4424 ( .A(n4725), .B(n4726), .Z(n4724)); + AN2 U4425 ( .A(po092), .B(n4009), .Z(n4726)); + OR2 U4426 ( .A(n4727), .B(n4728), .Z(n4009)); + AN2 U4427 ( .A(n3295), .B(n4729), .Z(n4728)); + AN2 U4428 ( .A(n4606), .B(n4457), .Z(n4727)); + OR2 U4429 ( .A(n4730), .B(n4706), .Z(n4457)); + OR2 U4430 ( .A(n4731), .B(n4732), .Z(n4706)); + AN2 U4431 ( .A(n4733), .B(pi192), .Z(n4732)); + AN2 U4432 ( .A(n4465), .B(n3870), .Z(n4733)); + AN2 U4433 ( .A(n4734), .B(n2837), .Z(n4731)); + AN2 U4434 ( .A(n4469), .B(n4735), .Z(n4734)); + AN2 U4435 ( .A(po039), .B(n4729), .Z(n4730)); + OR2 U4436 ( .A(po014), .B(n4736), .Z(n4729)); + AN2 U4437 ( .A(n4737), .B(n4606), .Z(n4725)); + AN2 U4438 ( .A(po014), .B(n4738), .Z(n4737)); + OR2 U4439 ( .A(n4739), .B(n4740), .Z(n4738)); + AN2 U4440 ( .A(n4463), .B(n4464), .Z(n4740)); + AN2 U4441 ( .A(n4467), .B(n4468), .Z(n4739)); + OR2 U4442 ( .A(n4741), .B(n4742), .Z(n4723)); + AN2 U4443 ( .A(n4743), .B(n4463), .Z(n4742)); + AN2 U4444 ( .A(n3909), .B(pi192), .Z(n4463)); + IV2 U4445 ( .A(pi158), .Z(n3909)); + AN2 U4446 ( .A(n4744), .B(n3908), .Z(n4743)); + OR2 U4447 ( .A(n4745), .B(n3295), .Z(n4744)); + AN2 U4448 ( .A(n4606), .B(n4464), .Z(n4745)); + AN2 U4449 ( .A(n4746), .B(n4467), .Z(n4741)); + AN2 U4450 ( .A(n2837), .B(n4747), .Z(n4467)); + AN2 U4451 ( .A(n4748), .B(n4648), .Z(n4746)); + OR2 U4452 ( .A(n4749), .B(n3295), .Z(n4748)); + AN2 U4453 ( .A(n4606), .B(n4468), .Z(n4749)); + AN2 U4454 ( .A(n3756), .B(n4611), .Z(n4716)); + OR2 U4455 ( .A(n4750), .B(n4751), .Z(n4611)); + AN2 U4456 ( .A(n4004), .B(n4444), .Z(n4750)); + IV2 U4457 ( .A(n4006), .Z(n4004)); + AN2 U4458 ( .A(n4628), .B(n4752), .Z(n3756)); + OR2 U4459 ( .A(n3758), .B(n3760), .Z(n4714)); + AN2 U4460 ( .A(n4448), .B(n4751), .Z(n3758)); + OR2 U4461 ( .A(n4713), .B(n4693), .Z(n4448)); + OR2 U4462 ( .A(n4753), .B(n4754), .Z(n4693)); + AN2 U4463 ( .A(n4621), .B(pi192), .Z(n4754)); + AN2 U4464 ( .A(n4623), .B(n2837), .Z(n4753)); + AN2 U4465 ( .A(n3301), .B(n4624), .Z(n4713)); + OR2 U4466 ( .A(n4755), .B(n4756), .Z(po042)); + AN2 U4467 ( .A(n4757), .B(n2837), .Z(n4756)); + OR2 U4468 ( .A(n4758), .B(n4759), .Z(n4757)); + OR2 U4469 ( .A(n4760), .B(n4761), .Z(n4759)); + AN2 U4470 ( .A(n4762), .B(n4763), .Z(n4761)); + OR2 U4471 ( .A(n4764), .B(n4765), .Z(n4763)); + IV2 U4472 ( .A(n4766), .Z(n4762)); + AN2 U4473 ( .A(n4765), .B(n4764), .Z(n4766)); + OR2 U4474 ( .A(n4767), .B(n4768), .Z(n4764)); + AN2 U4475 ( .A(n4769), .B(n4770), .Z(n4768)); + AN2 U4476 ( .A(n4771), .B(pi028), .Z(n4767)); + AN2 U4477 ( .A(n4772), .B(n4773), .Z(n4765)); + OR2 U4478 ( .A(n4774), .B(pi094), .Z(n4773)); + IV2 U4479 ( .A(n4775), .Z(n4772)); + AN2 U4480 ( .A(n4774), .B(pi094), .Z(n4775)); + AN2 U4481 ( .A(n4776), .B(n4777), .Z(n4774)); + OR2 U4482 ( .A(n4778), .B(pi173), .Z(n4777)); + OR2 U4483 ( .A(n4779), .B(pi163), .Z(n4776)); + IV2 U4484 ( .A(pi173), .Z(n4779)); + AN2 U4485 ( .A(n4780), .B(n4781), .Z(n4760)); + IV2 U4486 ( .A(n4782), .Z(n4781)); + AN2 U4487 ( .A(n4783), .B(n4784), .Z(n4782)); + OR2 U4488 ( .A(n4784), .B(n4783), .Z(n4780)); + AN2 U4489 ( .A(n4785), .B(n4786), .Z(n4783)); + IV2 U4490 ( .A(n4787), .Z(n4786)); + AN2 U4491 ( .A(n4788), .B(n4789), .Z(n4787)); + OR2 U4492 ( .A(n4789), .B(n4788), .Z(n4785)); + OR2 U4493 ( .A(n4790), .B(n4791), .Z(n4788)); + AN2 U4494 ( .A(pi025), .B(n4792), .Z(n4791)); + IV2 U4495 ( .A(n4793), .Z(n4790)); + OR2 U4496 ( .A(n4792), .B(pi025), .Z(n4793)); + IV2 U4497 ( .A(pi035), .Z(n4792)); + AN2 U4498 ( .A(n4794), .B(n4795), .Z(n4789)); + IV2 U4499 ( .A(n4796), .Z(n4795)); + AN2 U4500 ( .A(pi056), .B(n4797), .Z(n4796)); + OR2 U4501 ( .A(n4797), .B(pi056), .Z(n4794)); + IV2 U4502 ( .A(pi100), .Z(n4797)); + OR2 U4503 ( .A(n4798), .B(n4799), .Z(n4784)); + IV2 U4504 ( .A(n4800), .Z(n4799)); + OR2 U4505 ( .A(n4801), .B(n4802), .Z(n4800)); + AN2 U4506 ( .A(n4802), .B(n4801), .Z(n4798)); + AN2 U4507 ( .A(n4803), .B(n4804), .Z(n4801)); + IV2 U4508 ( .A(n4805), .Z(n4804)); + AN2 U4509 ( .A(pi126), .B(n4806), .Z(n4805)); + OR2 U4510 ( .A(n4806), .B(pi126), .Z(n4803)); + IV2 U4511 ( .A(pi146), .Z(n4806)); + OR2 U4512 ( .A(n4807), .B(n4808), .Z(n4802)); + AN2 U4513 ( .A(pi190), .B(n4809), .Z(n4808)); + IV2 U4514 ( .A(pi202), .Z(n4809)); + AN2 U4515 ( .A(pi202), .B(n4810), .Z(n4807)); + IV2 U4516 ( .A(pi190), .Z(n4810)); + OR2 U4517 ( .A(n4811), .B(n4812), .Z(n4758)); + AN2 U4518 ( .A(n4813), .B(n4814), .Z(n4812)); + IV2 U4519 ( .A(n4815), .Z(n4814)); + AN2 U4520 ( .A(n4816), .B(n4817), .Z(n4815)); + OR2 U4521 ( .A(n4817), .B(n4816), .Z(n4813)); + AN2 U4522 ( .A(n4818), .B(n4819), .Z(n4816)); + OR2 U4523 ( .A(n4820), .B(pi019), .Z(n4819)); + OR2 U4524 ( .A(n4821), .B(n4822), .Z(n4818)); + IV2 U4525 ( .A(pi019), .Z(n4822)); + OR2 U4526 ( .A(n4823), .B(n4824), .Z(n4817)); + IV2 U4527 ( .A(n4825), .Z(n4824)); + OR2 U4528 ( .A(n4826), .B(pi085), .Z(n4825)); + AN2 U4529 ( .A(n4826), .B(pi085), .Z(n4823)); + AN2 U4530 ( .A(n4827), .B(n4828), .Z(n4826)); + OR2 U4531 ( .A(n4829), .B(pi167), .Z(n4828)); + IV2 U4532 ( .A(pi110), .Z(n4829)); + OR2 U4533 ( .A(n4830), .B(pi110), .Z(n4827)); + IV2 U4534 ( .A(pi167), .Z(n4830)); + AN2 U4535 ( .A(n4831), .B(n4832), .Z(n4811)); + IV2 U4536 ( .A(n4833), .Z(n4832)); + AN2 U4537 ( .A(n4834), .B(n4835), .Z(n4833)); + OR2 U4538 ( .A(n4835), .B(n4834), .Z(n4831)); + AN2 U4539 ( .A(n4836), .B(n4837), .Z(n4834)); + OR2 U4540 ( .A(n4838), .B(pi020), .Z(n4837)); + OR2 U4541 ( .A(n4839), .B(n4840), .Z(n4836)); + IV2 U4542 ( .A(pi020), .Z(n4840)); + OR2 U4543 ( .A(n4841), .B(n4842), .Z(n4835)); + IV2 U4544 ( .A(n4843), .Z(n4842)); + OR2 U4545 ( .A(n4844), .B(pi047), .Z(n4843)); + AN2 U4546 ( .A(n4844), .B(pi047), .Z(n4841)); + AN2 U4547 ( .A(n4845), .B(n4846), .Z(n4844)); + OR2 U4548 ( .A(n4847), .B(pi153), .Z(n4846)); + IV2 U4549 ( .A(pi075), .Z(n4847)); + OR2 U4550 ( .A(n4848), .B(pi075), .Z(n4845)); + IV2 U4551 ( .A(pi153), .Z(n4848)); + AN2 U4552 ( .A(pi192), .B(n4849), .Z(n4755)); + OR2 U4553 ( .A(n4850), .B(n4851), .Z(n4849)); + OR2 U4554 ( .A(n4852), .B(n4853), .Z(n4851)); + AN2 U4555 ( .A(n4854), .B(n4855), .Z(n4853)); + OR2 U4556 ( .A(n4856), .B(n4857), .Z(n4855)); + IV2 U4557 ( .A(n4858), .Z(n4854)); + AN2 U4558 ( .A(n4857), .B(n4856), .Z(n4858)); + OR2 U4559 ( .A(n4859), .B(n4860), .Z(n4856)); + AN2 U4560 ( .A(n4839), .B(n4861), .Z(n4860)); + AN2 U4561 ( .A(n4838), .B(po014), .Z(n4859)); + IV2 U4562 ( .A(n4839), .Z(n4838)); + OR2 U4563 ( .A(n4862), .B(n4863), .Z(n4839)); + AN2 U4564 ( .A(n4864), .B(pi192), .Z(n4863)); + OR2 U4565 ( .A(n4865), .B(n4866), .Z(n4864)); + IV2 U4566 ( .A(n4867), .Z(n4866)); + OR2 U4567 ( .A(n4868), .B(n4869), .Z(n4867)); + AN2 U4568 ( .A(n4869), .B(n4868), .Z(n4865)); + AN2 U4569 ( .A(n4870), .B(n4871), .Z(n4868)); + OR2 U4570 ( .A(n4872), .B(po024), .Z(n4871)); + IV2 U4571 ( .A(n4873), .Z(n4872)); + OR2 U4572 ( .A(n4873), .B(n4874), .Z(n4870)); + OR2 U4573 ( .A(n4875), .B(n4876), .Z(n4873)); + AN2 U4574 ( .A(po025), .B(n4877), .Z(n4876)); + AN2 U4575 ( .A(po059), .B(n4557), .Z(n4875)); + OR2 U4576 ( .A(n4878), .B(n4879), .Z(n4869)); + AN2 U4577 ( .A(n4880), .B(n4881), .Z(n4879)); + AN2 U4578 ( .A(n4882), .B(po072), .Z(n4878)); + IV2 U4579 ( .A(n4880), .Z(n4882)); + OR2 U4580 ( .A(n4883), .B(n4884), .Z(n4880)); + AN2 U4581 ( .A(po084), .B(n4885), .Z(n4884)); + AN2 U4582 ( .A(po102), .B(n4886), .Z(n4883)); + IV2 U4583 ( .A(po084), .Z(n4886)); + AN2 U4584 ( .A(n4887), .B(n2837), .Z(n4862)); + OR2 U4585 ( .A(n4888), .B(n4889), .Z(n4887)); + AN2 U4586 ( .A(n4890), .B(n4891), .Z(n4889)); + IV2 U4587 ( .A(n4892), .Z(n4888)); + OR2 U4588 ( .A(n4891), .B(n4890), .Z(n4892)); + OR2 U4589 ( .A(n4893), .B(n4894), .Z(n4890)); + IV2 U4590 ( .A(n4895), .Z(n4894)); + OR2 U4591 ( .A(n4896), .B(pi014), .Z(n4895)); + AN2 U4592 ( .A(n4896), .B(pi014), .Z(n4893)); + AN2 U4593 ( .A(n4897), .B(n4898), .Z(n4896)); + OR2 U4594 ( .A(n4899), .B(pi111), .Z(n4898)); + OR2 U4595 ( .A(n4900), .B(pi097), .Z(n4897)); + IV2 U4596 ( .A(pi111), .Z(n4900)); + AN2 U4597 ( .A(n4901), .B(n4902), .Z(n4891)); + OR2 U4598 ( .A(n4903), .B(pi143), .Z(n4902)); + IV2 U4599 ( .A(n4904), .Z(n4901)); + AN2 U4600 ( .A(n4903), .B(pi143), .Z(n4904)); + AN2 U4601 ( .A(n4905), .B(n4906), .Z(n4903)); + OR2 U4602 ( .A(n4907), .B(pi189), .Z(n4906)); + IV2 U4603 ( .A(n4908), .Z(n4905)); + AN2 U4604 ( .A(pi189), .B(n4907), .Z(n4908)); + IV2 U4605 ( .A(pi176), .Z(n4907)); + AN2 U4606 ( .A(n4909), .B(n4910), .Z(n4857)); + OR2 U4607 ( .A(n4911), .B(po039), .Z(n4910)); + IV2 U4608 ( .A(n4912), .Z(n4911)); + OR2 U4609 ( .A(n4912), .B(n3300), .Z(n4909)); + OR2 U4610 ( .A(n4913), .B(n4914), .Z(n4912)); + AN2 U4611 ( .A(po063), .B(n4628), .Z(n4914)); + AN2 U4612 ( .A(po092), .B(n4915), .Z(n4913)); + AN2 U4613 ( .A(n4916), .B(n4917), .Z(n4852)); + IV2 U4614 ( .A(n4918), .Z(n4917)); + AN2 U4615 ( .A(n4919), .B(n4920), .Z(n4918)); + OR2 U4616 ( .A(n4920), .B(n4919), .Z(n4916)); + IV2 U4617 ( .A(n4921), .Z(n4919)); + OR2 U4618 ( .A(n4922), .B(n4923), .Z(n4921)); + AN2 U4619 ( .A(n4821), .B(n3391), .Z(n4923)); + IV2 U4620 ( .A(n4924), .Z(n3391)); + AN2 U4621 ( .A(n4924), .B(n4820), .Z(n4922)); + IV2 U4622 ( .A(n4821), .Z(n4820)); + OR2 U4623 ( .A(n4925), .B(n4926), .Z(n4821)); + AN2 U4624 ( .A(n4927), .B(pi192), .Z(n4926)); + OR2 U4625 ( .A(n4928), .B(n4929), .Z(n4927)); + IV2 U4626 ( .A(n4930), .Z(n4929)); + OR2 U4627 ( .A(n4931), .B(n4932), .Z(n4930)); + AN2 U4628 ( .A(n4932), .B(n4931), .Z(n4928)); + AN2 U4629 ( .A(n4933), .B(n4934), .Z(n4931)); + OR2 U4630 ( .A(n4935), .B(po001), .Z(n4934)); + IV2 U4631 ( .A(n4936), .Z(n4935)); + OR2 U4632 ( .A(n4936), .B(n4937), .Z(n4933)); + OR2 U4633 ( .A(n4938), .B(n4939), .Z(n4936)); + AN2 U4634 ( .A(po011), .B(n4441), .Z(n4939)); + AN2 U4635 ( .A(po036), .B(n3688), .Z(n4938)); + OR2 U4636 ( .A(n4940), .B(n4941), .Z(n4932)); + AN2 U4637 ( .A(n4942), .B(n4943), .Z(n4941)); + AN2 U4638 ( .A(n4944), .B(po057), .Z(n4940)); + IV2 U4639 ( .A(n4942), .Z(n4944)); + OR2 U4640 ( .A(n4945), .B(n4946), .Z(n4942)); + AN2 U4641 ( .A(po069), .B(n4947), .Z(n4946)); + AN2 U4642 ( .A(po082), .B(n4948), .Z(n4945)); + IV2 U4643 ( .A(po069), .Z(n4948)); + AN2 U4644 ( .A(n4949), .B(n2837), .Z(n4925)); + OR2 U4645 ( .A(n4950), .B(n4951), .Z(n4949)); + AN2 U4646 ( .A(n4952), .B(n4953), .Z(n4951)); + IV2 U4647 ( .A(n4954), .Z(n4950)); + OR2 U4648 ( .A(n4953), .B(n4952), .Z(n4954)); + OR2 U4649 ( .A(n4955), .B(n4956), .Z(n4952)); + IV2 U4650 ( .A(n4957), .Z(n4956)); + OR2 U4651 ( .A(n4958), .B(pi024), .Z(n4957)); + AN2 U4652 ( .A(n4958), .B(pi024), .Z(n4955)); + AN2 U4653 ( .A(n4959), .B(n4960), .Z(n4958)); + OR2 U4654 ( .A(n4961), .B(pi078), .Z(n4960)); + OR2 U4655 ( .A(n4962), .B(pi030), .Z(n4959)); + IV2 U4656 ( .A(pi078), .Z(n4962)); + AN2 U4657 ( .A(n4963), .B(n4964), .Z(n4953)); + OR2 U4658 ( .A(n4965), .B(pi087), .Z(n4964)); + IV2 U4659 ( .A(n4966), .Z(n4963)); + AN2 U4660 ( .A(n4965), .B(pi087), .Z(n4966)); + AN2 U4661 ( .A(n4967), .B(n4968), .Z(n4965)); + OR2 U4662 ( .A(n4969), .B(pi164), .Z(n4968)); + OR2 U4663 ( .A(n4970), .B(pi159), .Z(n4967)); + IV2 U4664 ( .A(pi164), .Z(n4970)); + OR2 U4665 ( .A(n4971), .B(n4972), .Z(n4924)); + AN2 U4666 ( .A(po027), .B(n3512), .Z(n4972)); + AN2 U4667 ( .A(po104), .B(n3363), .Z(n4971)); + OR2 U4668 ( .A(n4973), .B(n4974), .Z(n4920)); + AN2 U4669 ( .A(po038), .B(n3380), .Z(n4974)); + AN2 U4670 ( .A(po071), .B(n4975), .Z(n4973)); + OR2 U4671 ( .A(n4976), .B(n4977), .Z(n4850)); + AN2 U4672 ( .A(n4978), .B(n4979), .Z(n4977)); + OR2 U4673 ( .A(n4980), .B(n4981), .Z(n4979)); + IV2 U4674 ( .A(n4982), .Z(n4978)); + AN2 U4675 ( .A(n4981), .B(n4980), .Z(n4982)); + OR2 U4676 ( .A(n4983), .B(n4984), .Z(n4980)); + AN2 U4677 ( .A(n4769), .B(n3049), .Z(n4984)); + AN2 U4678 ( .A(n4771), .B(po010), .Z(n4983)); + IV2 U4679 ( .A(n4769), .Z(n4771)); + OR2 U4680 ( .A(n4985), .B(n4986), .Z(n4769)); + AN2 U4681 ( .A(n4987), .B(pi192), .Z(n4986)); + OR2 U4682 ( .A(n4988), .B(n4989), .Z(n4987)); + IV2 U4683 ( .A(n4990), .Z(n4989)); + OR2 U4684 ( .A(n4991), .B(n4992), .Z(n4990)); + AN2 U4685 ( .A(n4992), .B(n4991), .Z(n4988)); + AN2 U4686 ( .A(n4993), .B(n4994), .Z(n4991)); + OR2 U4687 ( .A(n4995), .B(po031), .Z(n4994)); + IV2 U4688 ( .A(n4996), .Z(n4995)); + OR2 U4689 ( .A(n4996), .B(n2962), .Z(n4993)); + OR2 U4690 ( .A(n4997), .B(n4998), .Z(n4996)); + AN2 U4691 ( .A(po044), .B(n4999), .Z(n4998)); + IV2 U4692 ( .A(po052), .Z(n4999)); + AN2 U4693 ( .A(po052), .B(n5000), .Z(n4997)); + OR2 U4694 ( .A(n5001), .B(n5002), .Z(n4992)); + AN2 U4695 ( .A(n5003), .B(n5004), .Z(n5002)); + AN2 U4696 ( .A(n5005), .B(po079), .Z(n5001)); + IV2 U4697 ( .A(n5003), .Z(n5005)); + OR2 U4698 ( .A(n5006), .B(n5007), .Z(n5003)); + AN2 U4699 ( .A(po106), .B(n2931), .Z(n5007)); + AN2 U4700 ( .A(po107), .B(n5008), .Z(n5006)); + AN2 U4701 ( .A(n5009), .B(n2837), .Z(n4985)); + OR2 U4702 ( .A(n5010), .B(n5011), .Z(n5009)); + IV2 U4703 ( .A(n5012), .Z(n5011)); + OR2 U4704 ( .A(n5013), .B(n5014), .Z(n5012)); + AN2 U4705 ( .A(n5014), .B(n5013), .Z(n5010)); + AN2 U4706 ( .A(n5015), .B(n5016), .Z(n5013)); + OR2 U4707 ( .A(n5017), .B(pi011), .Z(n5016)); + IV2 U4708 ( .A(n5018), .Z(n5017)); + OR2 U4709 ( .A(n5018), .B(n5019), .Z(n5015)); + OR2 U4710 ( .A(n5020), .B(n5021), .Z(n5018)); + AN2 U4711 ( .A(pi021), .B(n5022), .Z(n5021)); + AN2 U4712 ( .A(pi032), .B(n5023), .Z(n5020)); + IV2 U4713 ( .A(pi021), .Z(n5023)); + OR2 U4714 ( .A(n5024), .B(n5025), .Z(n5014)); + AN2 U4715 ( .A(n5026), .B(n5027), .Z(n5025)); + AN2 U4716 ( .A(n5028), .B(pi086), .Z(n5024)); + IV2 U4717 ( .A(n5026), .Z(n5028)); + OR2 U4718 ( .A(n5029), .B(n5030), .Z(n5026)); + AN2 U4719 ( .A(pi115), .B(n5031), .Z(n5030)); + AN2 U4720 ( .A(pi165), .B(n5032), .Z(n5029)); + IV2 U4721 ( .A(pi115), .Z(n5032)); + AN2 U4722 ( .A(n5033), .B(n5034), .Z(n4981)); + OR2 U4723 ( .A(n5035), .B(po035), .Z(n5034)); + IV2 U4724 ( .A(n5036), .Z(n5035)); + OR2 U4725 ( .A(n5036), .B(n5037), .Z(n5033)); + OR2 U4726 ( .A(n5038), .B(n5039), .Z(n5036)); + AN2 U4727 ( .A(po070), .B(n3286), .Z(n5039)); + AN2 U4728 ( .A(po099), .B(n5040), .Z(n5038)); + AN2 U4729 ( .A(n5041), .B(n5042), .Z(n4976)); + OR2 U4730 ( .A(n5043), .B(n5044), .Z(n5042)); + IV2 U4731 ( .A(n5045), .Z(n5041)); + AN2 U4732 ( .A(n5044), .B(n5043), .Z(n5045)); + OR2 U4733 ( .A(n5046), .B(n5047), .Z(n5043)); + IV2 U4734 ( .A(n5048), .Z(n5047)); + OR2 U4735 ( .A(n5049), .B(n5050), .Z(n5048)); + AN2 U4736 ( .A(n5050), .B(n5049), .Z(n5046)); + AN2 U4737 ( .A(n5051), .B(n5052), .Z(n5049)); + OR2 U4738 ( .A(n4319), .B(po013), .Z(n5052)); + OR2 U4739 ( .A(n5053), .B(po004), .Z(n5051)); + IV2 U4740 ( .A(po013), .Z(n5053)); + OR2 U4741 ( .A(n5054), .B(n5055), .Z(n5050)); + AN2 U4742 ( .A(po028), .B(n4013), .Z(n5055)); + AN2 U4743 ( .A(po040), .B(n5056), .Z(n5054)); + AN2 U4744 ( .A(n5057), .B(n5058), .Z(n5044)); + OR2 U4745 ( .A(n5059), .B(n5060), .Z(n5058)); + IV2 U4746 ( .A(n5061), .Z(n5059)); + OR2 U4747 ( .A(n5062), .B(n5061), .Z(n5057)); + OR2 U4748 ( .A(n5063), .B(n5064), .Z(n5061)); + AN2 U4749 ( .A(po064), .B(n4128), .Z(n5064)); + AN2 U4750 ( .A(po085), .B(n4133), .Z(n5063)); + IV2 U4751 ( .A(n5060), .Z(n5062)); + OR2 U4752 ( .A(n5065), .B(n5066), .Z(n5060)); + AN2 U4753 ( .A(po091), .B(n3265), .Z(n5066)); + AN2 U4754 ( .A(po103), .B(n4201), .Z(n5065)); + IV2 U4755 ( .A(n5067), .Z(po041)); + AN2 U4756 ( .A(n5068), .B(pi193), .Z(n5067)); + AN2 U4757 ( .A(pi057), .B(n5069), .Z(n5068)); + IV2 U4758 ( .A(pi037), .Z(n5069)); + OR2 U4759 ( .A(n5070), .B(n5071), .Z(po037)); + AN2 U4760 ( .A(n3021), .B(n5072), .Z(n5071)); + OR2 U4761 ( .A(n5073), .B(n5074), .Z(n5072)); + AN2 U4762 ( .A(n3018), .B(n5075), .Z(n5073)); + OR2 U4763 ( .A(n5076), .B(n5077), .Z(n5075)); + AN2 U4764 ( .A(n4663), .B(n3284), .Z(n5076)); + OR2 U4765 ( .A(n5078), .B(n5079), .Z(n4663)); + AN2 U4766 ( .A(n3064), .B(n3108), .Z(n5079)); + AN2 U4767 ( .A(n3173), .B(n3115), .Z(n5078)); + AN2 U4768 ( .A(n3083), .B(n5080), .Z(n5070)); + OR2 U4769 ( .A(n5081), .B(n5082), .Z(n5080)); + OR2 U4770 ( .A(n5083), .B(n5084), .Z(n5082)); + AN2 U4771 ( .A(po070), .B(n4327), .Z(n5084)); + OR2 U4772 ( .A(n5085), .B(n5086), .Z(n4327)); + OR2 U4773 ( .A(n5087), .B(n5088), .Z(n5086)); + AN2 U4774 ( .A(n3273), .B(n5089), .Z(n5088)); + IV2 U4775 ( .A(n3284), .Z(n3273)); + AN2 U4776 ( .A(n5090), .B(n3274), .Z(n5087)); + OR2 U4777 ( .A(n5091), .B(n3282), .Z(n5085)); + IV2 U4778 ( .A(n4666), .Z(n3282)); + AN2 U4779 ( .A(n5092), .B(n3199), .Z(n5083)); + OR2 U4780 ( .A(n5093), .B(n5094), .Z(n5092)); + OR2 U4781 ( .A(n5095), .B(n5096), .Z(n5094)); + AN2 U4782 ( .A(n5090), .B(po010), .Z(n5096)); + AN2 U4783 ( .A(n3037), .B(n3061), .Z(n5090)); + AN2 U4784 ( .A(n5097), .B(n5098), .Z(n5095)); + AN2 U4785 ( .A(n3037), .B(n5099), .Z(n5098)); + AN2 U4786 ( .A(n5100), .B(n3120), .Z(n5097)); + OR2 U4787 ( .A(n5101), .B(n3061), .Z(n3120)); + AN2 U4788 ( .A(n3106), .B(pi192), .Z(n3061)); + AN2 U4789 ( .A(po010), .B(pi192), .Z(n5101)); + AN2 U4790 ( .A(n3082), .B(pi192), .Z(n5093)); + IV2 U4791 ( .A(n3108), .Z(n3082)); + OR2 U4792 ( .A(pi033), .B(n3286), .Z(n3108)); + OR2 U4793 ( .A(n5102), .B(n5103), .Z(n5081)); + AN2 U4794 ( .A(n3015), .B(n5104), .Z(n5103)); + IV2 U4795 ( .A(n3018), .Z(n3015)); + AN2 U4796 ( .A(n5105), .B(n3205), .Z(n5102)); + OR2 U4797 ( .A(n5106), .B(n5107), .Z(n5105)); + OR2 U4798 ( .A(n5091), .B(n5108), .Z(n5107)); + AN2 U4799 ( .A(n5100), .B(n5109), .Z(n5108)); + OR2 U4800 ( .A(n5110), .B(n5111), .Z(n5109)); + AN2 U4801 ( .A(n5112), .B(n2925), .Z(n5111)); + AN2 U4802 ( .A(po010), .B(n5089), .Z(n5112)); + IV2 U4803 ( .A(n3100), .Z(n5089)); + AN2 U4804 ( .A(n5113), .B(n3080), .Z(n5110)); + AN2 U4805 ( .A(n2837), .B(po010), .Z(n3080)); + AN2 U4806 ( .A(n3112), .B(n5099), .Z(n5113)); + AN2 U4807 ( .A(n3065), .B(n5114), .Z(n5091)); + AN2 U4808 ( .A(n3112), .B(n3274), .Z(n5114)); + IV2 U4809 ( .A(n3280), .Z(n3274)); + AN2 U4810 ( .A(n2837), .B(n5115), .Z(n3065)); + AN2 U4811 ( .A(n3073), .B(n2837), .Z(n5106)); + IV2 U4812 ( .A(n3115), .Z(n3073)); + OR2 U4813 ( .A(pi141), .B(n3286), .Z(n3115)); + OR2 U4814 ( .A(n5116), .B(n5117), .Z(po034)); + OR2 U4815 ( .A(n5118), .B(n5119), .Z(n5117)); + AN2 U4816 ( .A(pi054), .B(n5120), .Z(n5119)); + AN2 U4817 ( .A(n5121), .B(n5122), .Z(n5118)); + AN2 U4818 ( .A(n5123), .B(n5124), .Z(n5122)); + OR2 U4819 ( .A(po085), .B(po064), .Z(n5124)); + OR2 U4820 ( .A(n4125), .B(n4133), .Z(n5123)); + AN2 U4821 ( .A(n4129), .B(n4128), .Z(n4125)); + AN2 U4822 ( .A(pi052), .B(n5125), .Z(n5121)); + AN2 U4823 ( .A(n5126), .B(n5127), .Z(n5116)); + OR2 U4824 ( .A(n4167), .B(n5128), .Z(n5127)); + OR2 U4825 ( .A(n5129), .B(n5130), .Z(n5128)); + AN2 U4826 ( .A(n5131), .B(po064), .Z(n5130)); + AN2 U4827 ( .A(pi054), .B(po085), .Z(n5131)); + AN2 U4828 ( .A(n4129), .B(n4133), .Z(n5129)); + OR2 U4829 ( .A(n5132), .B(n5133), .Z(po033)); + AN2 U4830 ( .A(n3371), .B(n5134), .Z(n5133)); + OR2 U4831 ( .A(n5135), .B(n5136), .Z(n5134)); + AN2 U4832 ( .A(n5137), .B(n3412), .Z(n5132)); + OR2 U4833 ( .A(n5138), .B(n5139), .Z(n5137)); + OR2 U4834 ( .A(n5140), .B(n5141), .Z(po030)); + AN2 U4835 ( .A(n5142), .B(pi192), .Z(n5141)); + OR2 U4836 ( .A(n5143), .B(n5144), .Z(n5142)); + AN2 U4837 ( .A(n2834), .B(n5145), .Z(n5144)); + OR2 U4838 ( .A(n5146), .B(n5147), .Z(n5145)); + AN2 U4839 ( .A(n2998), .B(n3847), .Z(n5147)); + AN2 U4840 ( .A(n5148), .B(n5149), .Z(n5146)); + OR2 U4841 ( .A(n2862), .B(n5150), .Z(n5149)); + OR2 U4842 ( .A(n2880), .B(n5151), .Z(n5150)); + AN2 U4843 ( .A(n2887), .B(n2901), .Z(n5151)); + AN2 U4844 ( .A(n2891), .B(n5152), .Z(n5148)); + IV2 U4845 ( .A(n5153), .Z(n5152)); + AN2 U4846 ( .A(n5154), .B(n2833), .Z(n5143)); + OR2 U4847 ( .A(n5155), .B(n5156), .Z(n5154)); + AN2 U4848 ( .A(n5157), .B(n5158), .Z(n5155)); + AN2 U4849 ( .A(n2930), .B(n2878), .Z(n5158)); + AN2 U4850 ( .A(n5159), .B(n2837), .Z(n5140)); + OR2 U4851 ( .A(n5160), .B(n5161), .Z(n5159)); + AN2 U4852 ( .A(n2846), .B(n5162), .Z(n5161)); + OR2 U4853 ( .A(n5163), .B(n5164), .Z(n5162)); + AN2 U4854 ( .A(n2998), .B(n5165), .Z(n5164)); + AN2 U4855 ( .A(n5166), .B(n5167), .Z(n5163)); + OR2 U4856 ( .A(n5168), .B(n5169), .Z(n5167)); + AN2 U4857 ( .A(n3222), .B(n2946), .Z(n5168)); + OR2 U4858 ( .A(n5170), .B(n2959), .Z(n3222)); + AN2 U4859 ( .A(n2982), .B(n2901), .Z(n2959)); + AN2 U4860 ( .A(po107), .B(n5171), .Z(n5170)); + IV2 U4861 ( .A(n2981), .Z(n5171)); + AN2 U4862 ( .A(pi081), .B(pi200), .Z(n2981)); + AN2 U4863 ( .A(n2947), .B(n5172), .Z(n5166)); + AN2 U4864 ( .A(n5173), .B(n2845), .Z(n5160)); + OR2 U4865 ( .A(n5174), .B(n5175), .Z(n5173)); + AN2 U4866 ( .A(n5157), .B(n5176), .Z(n5174)); + AN2 U4867 ( .A(n2908), .B(n2938), .Z(n5176)); + OR2 U4868 ( .A(pi081), .B(n2931), .Z(n2938)); + IV2 U4869 ( .A(n5169), .Z(n2908)); + AN2 U4870 ( .A(n2861), .B(pi200), .Z(n5157)); + OR2 U4871 ( .A(n5177), .B(n5178), .Z(po029)); + OR2 U4872 ( .A(n5179), .B(n5180), .Z(n5178)); + AN2 U4873 ( .A(n5181), .B(n4313), .Z(n5180)); + AN2 U4874 ( .A(n3945), .B(n5182), .Z(n5179)); + OR2 U4875 ( .A(n5183), .B(n5184), .Z(n5182)); + OR2 U4876 ( .A(n5185), .B(n5186), .Z(n5184)); + AN2 U4877 ( .A(n5187), .B(pi186), .Z(n5186)); + OR2 U4878 ( .A(n5188), .B(n5189), .Z(n5187)); + AN2 U4879 ( .A(n5190), .B(n5191), .Z(n5189)); + AN2 U4880 ( .A(n5192), .B(pi124), .Z(n5188)); + IV2 U4881 ( .A(n5190), .Z(n5192)); + AN2 U4882 ( .A(n5193), .B(n5194), .Z(n5185)); + OR2 U4883 ( .A(n5195), .B(n5196), .Z(n5193)); + AN2 U4884 ( .A(n5190), .B(pi124), .Z(n5196)); + OR2 U4885 ( .A(n5197), .B(n5198), .Z(n5190)); + AN2 U4886 ( .A(n5199), .B(n5200), .Z(n5198)); + AN2 U4887 ( .A(n5201), .B(pi109), .Z(n5197)); + IV2 U4888 ( .A(n5199), .Z(n5201)); + AN2 U4889 ( .A(n5202), .B(n5191), .Z(n5195)); + OR2 U4890 ( .A(n5203), .B(n5204), .Z(n5202)); + AN2 U4891 ( .A(n5199), .B(pi109), .Z(n5204)); + OR2 U4892 ( .A(n5205), .B(n5206), .Z(n5199)); + AN2 U4893 ( .A(n5207), .B(n5208), .Z(n5206)); + AN2 U4894 ( .A(n5181), .B(pi055), .Z(n5205)); + AN2 U4895 ( .A(n5209), .B(n5200), .Z(n5203)); + AN2 U4896 ( .A(pi055), .B(n5207), .Z(n5209)); + AN2 U4897 ( .A(n5210), .B(n5211), .Z(n5183)); + OR2 U4898 ( .A(n5212), .B(n5213), .Z(n5211)); + IV2 U4899 ( .A(n5214), .Z(n5210)); + AN2 U4900 ( .A(n5213), .B(n5212), .Z(n5214)); + OR2 U4901 ( .A(n5215), .B(n5216), .Z(n5212)); + IV2 U4902 ( .A(n5217), .Z(n5216)); + OR2 U4903 ( .A(n5218), .B(pi006), .Z(n5217)); + AN2 U4904 ( .A(n5218), .B(pi006), .Z(n5215)); + AN2 U4905 ( .A(n5219), .B(n5220), .Z(n5218)); + OR2 U4906 ( .A(n5221), .B(pi061), .Z(n5220)); + IV2 U4907 ( .A(pi051), .Z(n5221)); + OR2 U4908 ( .A(n5222), .B(pi051), .Z(n5219)); + IV2 U4909 ( .A(pi061), .Z(n5222)); + AN2 U4910 ( .A(n5223), .B(n5224), .Z(n5213)); + IV2 U4911 ( .A(n5225), .Z(n5224)); + AN2 U4912 ( .A(n5226), .B(n5227), .Z(n5225)); + OR2 U4913 ( .A(n5227), .B(n5226), .Z(n5223)); + OR2 U4914 ( .A(n5228), .B(n5229), .Z(n5226)); + AN2 U4915 ( .A(pi093), .B(n5230), .Z(n5229)); + IV2 U4916 ( .A(n5231), .Z(n5228)); + OR2 U4917 ( .A(n5230), .B(pi093), .Z(n5231)); + IV2 U4918 ( .A(pi122), .Z(n5230)); + AN2 U4919 ( .A(n5232), .B(n5233), .Z(n5227)); + IV2 U4920 ( .A(n5234), .Z(n5233)); + AN2 U4921 ( .A(pi134), .B(n5235), .Z(n5234)); + OR2 U4922 ( .A(n5235), .B(pi134), .Z(n5232)); + IV2 U4923 ( .A(pi198), .Z(n5235)); + OR2 U4924 ( .A(n5236), .B(n5237), .Z(n5177)); + AN2 U4925 ( .A(n5238), .B(n2837), .Z(n5237)); + OR2 U4926 ( .A(n5239), .B(n5240), .Z(n5238)); + AN2 U4927 ( .A(n5241), .B(n5242), .Z(n5240)); + OR2 U4928 ( .A(n3809), .B(n5243), .Z(n5242)); + IV2 U4929 ( .A(n3812), .Z(n3809)); + OR2 U4930 ( .A(n5244), .B(n3812), .Z(n5241)); + AN2 U4931 ( .A(n5245), .B(n5246), .Z(n3812)); + IV2 U4932 ( .A(n5247), .Z(n5246)); + AN2 U4933 ( .A(n5248), .B(n5249), .Z(n5247)); + OR2 U4934 ( .A(n5249), .B(n5248), .Z(n5245)); + OR2 U4935 ( .A(n5250), .B(n5251), .Z(n5248)); + AN2 U4936 ( .A(pi040), .B(n5252), .Z(n5251)); + IV2 U4937 ( .A(pi095), .Z(n5252)); + AN2 U4938 ( .A(pi095), .B(n4735), .Z(n5250)); + AN2 U4939 ( .A(n5253), .B(n5254), .Z(n5249)); + OR2 U4940 ( .A(n4747), .B(pi156), .Z(n5254)); + IV2 U4941 ( .A(pi151), .Z(n4747)); + OR2 U4942 ( .A(n4648), .B(pi151), .Z(n5253)); + AN2 U4943 ( .A(n5255), .B(n5256), .Z(n5239)); + OR2 U4944 ( .A(n3815), .B(n5257), .Z(n5256)); + OR2 U4945 ( .A(n5258), .B(n3818), .Z(n5255)); + IV2 U4946 ( .A(n3815), .Z(n3818)); + OR2 U4947 ( .A(n5259), .B(n5260), .Z(n3815)); + AN2 U4948 ( .A(n5261), .B(n5262), .Z(n5260)); + IV2 U4949 ( .A(n5263), .Z(n5259)); + OR2 U4950 ( .A(n5262), .B(n5261), .Z(n5263)); + OR2 U4951 ( .A(n5264), .B(n5265), .Z(n5261)); + AN2 U4952 ( .A(pi128), .B(n3177), .Z(n5265)); + AN2 U4953 ( .A(pi141), .B(n3205), .Z(n5264)); + AN2 U4954 ( .A(n5266), .B(n5267), .Z(n5262)); + OR2 U4955 ( .A(n5115), .B(pi185), .Z(n5267)); + OR2 U4956 ( .A(n5268), .B(pi174), .Z(n5266)); + IV2 U4957 ( .A(pi185), .Z(n5268)); + AN2 U4958 ( .A(pi192), .B(n5269), .Z(n5236)); + OR2 U4959 ( .A(n5270), .B(n5271), .Z(n5269)); + OR2 U4960 ( .A(n5272), .B(n5273), .Z(n5271)); + AN2 U4961 ( .A(n5274), .B(n5275), .Z(n5273)); + IV2 U4962 ( .A(n5276), .Z(n5275)); + AN2 U4963 ( .A(n5277), .B(n5278), .Z(n5276)); + OR2 U4964 ( .A(n5278), .B(n5277), .Z(n5274)); + AN2 U4965 ( .A(n5279), .B(n5280), .Z(n5277)); + OR2 U4966 ( .A(n5243), .B(pi036), .Z(n5280)); + IV2 U4967 ( .A(n5244), .Z(n5243)); + OR2 U4968 ( .A(n5244), .B(n5281), .Z(n5279)); + IV2 U4969 ( .A(pi036), .Z(n5281)); + OR2 U4970 ( .A(n3871), .B(n5282), .Z(n5244)); + AN2 U4971 ( .A(n5283), .B(pi192), .Z(n5282)); + OR2 U4972 ( .A(n5284), .B(n5285), .Z(n5283)); + AN2 U4973 ( .A(n5286), .B(n5287), .Z(n5285)); + IV2 U4974 ( .A(n5288), .Z(n5284)); + OR2 U4975 ( .A(n5287), .B(n5286), .Z(n5288)); + OR2 U4976 ( .A(n5289), .B(n5290), .Z(n5286)); + IV2 U4977 ( .A(n5291), .Z(n5290)); + OR2 U4978 ( .A(n5292), .B(pi017), .Z(n5291)); + AN2 U4979 ( .A(pi017), .B(n5292), .Z(n5289)); + AN2 U4980 ( .A(n5293), .B(n5294), .Z(n5292)); + OR2 U4981 ( .A(n5295), .B(pi083), .Z(n5294)); + IV2 U4982 ( .A(pi027), .Z(n5295)); + OR2 U4983 ( .A(n5296), .B(pi027), .Z(n5293)); + IV2 U4984 ( .A(pi083), .Z(n5296)); + AN2 U4985 ( .A(n5297), .B(n5298), .Z(n5287)); + OR2 U4986 ( .A(n5299), .B(pi089), .Z(n5298)); + IV2 U4987 ( .A(n5300), .Z(n5297)); + AN2 U4988 ( .A(n5299), .B(pi089), .Z(n5300)); + AN2 U4989 ( .A(n5301), .B(n5302), .Z(n5299)); + OR2 U4990 ( .A(n5303), .B(pi162), .Z(n5302)); + OR2 U4991 ( .A(n5304), .B(pi140), .Z(n5301)); + IV2 U4992 ( .A(pi162), .Z(n5304)); + AN2 U4993 ( .A(n5305), .B(n2837), .Z(n3871)); + OR2 U4994 ( .A(n5306), .B(n5307), .Z(n5305)); + AN2 U4995 ( .A(n5308), .B(n5309), .Z(n5307)); + IV2 U4996 ( .A(n5310), .Z(n5306)); + OR2 U4997 ( .A(n5309), .B(n5308), .Z(n5310)); + OR2 U4998 ( .A(n5311), .B(n5312), .Z(n5308)); + IV2 U4999 ( .A(n5313), .Z(n5312)); + OR2 U5000 ( .A(n5314), .B(pi064), .Z(n5313)); + AN2 U5001 ( .A(pi064), .B(n5314), .Z(n5311)); + AN2 U5002 ( .A(n5315), .B(n5316), .Z(n5314)); + OR2 U5003 ( .A(n4077), .B(pi108), .Z(n5316)); + OR2 U5004 ( .A(n5317), .B(pi076), .Z(n5315)); + IV2 U5005 ( .A(pi108), .Z(n5317)); + AN2 U5006 ( .A(n5318), .B(n5319), .Z(n5309)); + OR2 U5007 ( .A(n5320), .B(pi114), .Z(n5319)); + IV2 U5008 ( .A(n5321), .Z(n5320)); + OR2 U5009 ( .A(n5321), .B(n5322), .Z(n5318)); + OR2 U5010 ( .A(n5323), .B(n5324), .Z(n5321)); + AN2 U5011 ( .A(pi160), .B(n4074), .Z(n5324)); + AN2 U5012 ( .A(pi170), .B(n4358), .Z(n5323)); + OR2 U5013 ( .A(n5325), .B(n5326), .Z(n5278)); + IV2 U5014 ( .A(n5327), .Z(n5326)); + OR2 U5015 ( .A(n5328), .B(pi101), .Z(n5327)); + AN2 U5016 ( .A(n5328), .B(pi101), .Z(n5325)); + AN2 U5017 ( .A(n5329), .B(n5330), .Z(n5328)); + OR2 U5018 ( .A(n5331), .B(pi205), .Z(n5330)); + OR2 U5019 ( .A(n5332), .B(pi168), .Z(n5329)); + IV2 U5020 ( .A(pi205), .Z(n5332)); + AN2 U5021 ( .A(n5333), .B(n5334), .Z(n5272)); + AN2 U5022 ( .A(n5335), .B(n5200), .Z(n5334)); + IV2 U5023 ( .A(pi109), .Z(n5200)); + AN2 U5024 ( .A(n5191), .B(n5194), .Z(n5335)); + IV2 U5025 ( .A(pi186), .Z(n5194)); + IV2 U5026 ( .A(pi124), .Z(n5191)); + AN2 U5027 ( .A(n5181), .B(n5208), .Z(n5333)); + IV2 U5028 ( .A(pi055), .Z(n5208)); + IV2 U5029 ( .A(n5207), .Z(n5181)); + OR2 U5030 ( .A(n3977), .B(n5336), .Z(n5207)); + AN2 U5031 ( .A(n5337), .B(pi192), .Z(n5336)); + OR2 U5032 ( .A(n5338), .B(n5339), .Z(n5337)); + AN2 U5033 ( .A(n5340), .B(n5341), .Z(n5339)); + IV2 U5034 ( .A(n5342), .Z(n5338)); + OR2 U5035 ( .A(n5341), .B(n5340), .Z(n5342)); + OR2 U5036 ( .A(n5343), .B(n5344), .Z(n5340)); + IV2 U5037 ( .A(n5345), .Z(n5344)); + OR2 U5038 ( .A(n5346), .B(n5347), .Z(n5345)); + AN2 U5039 ( .A(n5346), .B(n5347), .Z(n5343)); + AN2 U5040 ( .A(n5348), .B(n5349), .Z(n5346)); + OR2 U5041 ( .A(n5350), .B(pi099), .Z(n5349)); + OR2 U5042 ( .A(n5351), .B(pi018), .Z(n5348)); + IV2 U5043 ( .A(pi099), .Z(n5351)); + AN2 U5044 ( .A(n5352), .B(n5353), .Z(n5341)); + OR2 U5045 ( .A(n5354), .B(pi150), .Z(n5353)); + IV2 U5046 ( .A(n5355), .Z(n5352)); + AN2 U5047 ( .A(pi150), .B(n5354), .Z(n5355)); + AN2 U5048 ( .A(n5356), .B(n5357), .Z(n5354)); + OR2 U5049 ( .A(n5358), .B(pi180), .Z(n5357)); + OR2 U5050 ( .A(n5359), .B(pi172), .Z(n5356)); + IV2 U5051 ( .A(pi180), .Z(n5359)); + AN2 U5052 ( .A(n5360), .B(n2837), .Z(n3977)); + AN2 U5053 ( .A(n5361), .B(n5362), .Z(n5360)); + IV2 U5054 ( .A(n5363), .Z(n5362)); + AN2 U5055 ( .A(n5364), .B(n5365), .Z(n5363)); + OR2 U5056 ( .A(n5365), .B(n5364), .Z(n5361)); + OR2 U5057 ( .A(n5366), .B(n5367), .Z(n5364)); + AN2 U5058 ( .A(n5368), .B(n3261), .Z(n5367)); + AN2 U5059 ( .A(n5369), .B(n3321), .Z(n5366)); + IV2 U5060 ( .A(n5368), .Z(n5369)); + OR2 U5061 ( .A(n5370), .B(n5371), .Z(n5368)); + AN2 U5062 ( .A(pi003), .B(n5372), .Z(n5371)); + AN2 U5063 ( .A(pi130), .B(n3597), .Z(n5370)); + AN2 U5064 ( .A(n5373), .B(n5374), .Z(n5365)); + OR2 U5065 ( .A(n5375), .B(pi142), .Z(n5374)); + IV2 U5066 ( .A(n5376), .Z(n5375)); + OR2 U5067 ( .A(n5376), .B(n4440), .Z(n5373)); + OR2 U5068 ( .A(n5377), .B(n5378), .Z(n5376)); + AN2 U5069 ( .A(pi177), .B(n5379), .Z(n5378)); + AN2 U5070 ( .A(pi195), .B(n5380), .Z(n5377)); + IV2 U5071 ( .A(pi177), .Z(n5380)); + AN2 U5072 ( .A(n5381), .B(n5382), .Z(n5270)); + IV2 U5073 ( .A(n5383), .Z(n5382)); + AN2 U5074 ( .A(n5384), .B(n5385), .Z(n5383)); + OR2 U5075 ( .A(n5385), .B(n5384), .Z(n5381)); + AN2 U5076 ( .A(n5386), .B(n5387), .Z(n5384)); + OR2 U5077 ( .A(n5257), .B(pi001), .Z(n5387)); + IV2 U5078 ( .A(n5258), .Z(n5257)); + OR2 U5079 ( .A(n5258), .B(n5388), .Z(n5386)); + IV2 U5080 ( .A(pi001), .Z(n5388)); + OR2 U5081 ( .A(n3831), .B(n5389), .Z(n5258)); + AN2 U5082 ( .A(n5390), .B(pi192), .Z(n5389)); + OR2 U5083 ( .A(n5391), .B(n5392), .Z(n5390)); + AN2 U5084 ( .A(n5393), .B(n5394), .Z(n5392)); + IV2 U5085 ( .A(n5395), .Z(n5391)); + OR2 U5086 ( .A(n5394), .B(n5393), .Z(n5395)); + OR2 U5087 ( .A(n5396), .B(n5397), .Z(n5393)); + IV2 U5088 ( .A(n5398), .Z(n5397)); + OR2 U5089 ( .A(n5399), .B(pi038), .Z(n5398)); + AN2 U5090 ( .A(pi038), .B(n5399), .Z(n5396)); + AN2 U5091 ( .A(n5400), .B(n5401), .Z(n5399)); + OR2 U5092 ( .A(n5402), .B(pi103), .Z(n5401)); + IV2 U5093 ( .A(pi053), .Z(n5402)); + OR2 U5094 ( .A(n5403), .B(pi053), .Z(n5400)); + IV2 U5095 ( .A(pi103), .Z(n5403)); + AN2 U5096 ( .A(n5404), .B(n5405), .Z(n5394)); + OR2 U5097 ( .A(n5406), .B(pi121), .Z(n5405)); + IV2 U5098 ( .A(n5407), .Z(n5404)); + AN2 U5099 ( .A(n5406), .B(pi121), .Z(n5407)); + AN2 U5100 ( .A(n5408), .B(n5409), .Z(n5406)); + OR2 U5101 ( .A(n5410), .B(pi184), .Z(n5409)); + IV2 U5102 ( .A(pi149), .Z(n5410)); + OR2 U5103 ( .A(n5411), .B(pi149), .Z(n5408)); + IV2 U5104 ( .A(pi184), .Z(n5411)); + AN2 U5105 ( .A(n5412), .B(n2837), .Z(n3831)); + OR2 U5106 ( .A(n5413), .B(n5414), .Z(n5412)); + IV2 U5107 ( .A(n5415), .Z(n5414)); + OR2 U5108 ( .A(n5416), .B(n5417), .Z(n5415)); + AN2 U5109 ( .A(n5417), .B(n5416), .Z(n5413)); + AN2 U5110 ( .A(n5418), .B(n5419), .Z(n5416)); + OR2 U5111 ( .A(n5420), .B(pi081), .Z(n5419)); + IV2 U5112 ( .A(n5421), .Z(n5420)); + OR2 U5113 ( .A(n5421), .B(n2982), .Z(n5418)); + OR2 U5114 ( .A(n5422), .B(n5423), .Z(n5421)); + AN2 U5115 ( .A(pi082), .B(n5424), .Z(n5423)); + IV2 U5116 ( .A(pi092), .Z(n5424)); + AN2 U5117 ( .A(pi092), .B(n2957), .Z(n5422)); + OR2 U5118 ( .A(n5425), .B(n5426), .Z(n5417)); + AN2 U5119 ( .A(n5427), .B(n5165), .Z(n5426)); + AN2 U5120 ( .A(n5428), .B(pi107), .Z(n5425)); + IV2 U5121 ( .A(n5427), .Z(n5428)); + OR2 U5122 ( .A(n5429), .B(n5430), .Z(n5427)); + AN2 U5123 ( .A(pi201), .B(n5431), .Z(n5430)); + AN2 U5124 ( .A(pi206), .B(n3141), .Z(n5429)); + OR2 U5125 ( .A(n5432), .B(n5433), .Z(n5385)); + IV2 U5126 ( .A(n5434), .Z(n5433)); + OR2 U5127 ( .A(n5435), .B(pi059), .Z(n5434)); + AN2 U5128 ( .A(n5435), .B(pi059), .Z(n5432)); + AN2 U5129 ( .A(n5436), .B(n5437), .Z(n5435)); + OR2 U5130 ( .A(n5438), .B(pi197), .Z(n5437)); + IV2 U5131 ( .A(pi131), .Z(n5438)); + OR2 U5132 ( .A(n5439), .B(pi131), .Z(n5436)); + OR2 U5133 ( .A(n5440), .B(n5441), .Z(po026)); + AN2 U5134 ( .A(n3355), .B(n5442), .Z(n5441)); + OR2 U5135 ( .A(n5443), .B(n5444), .Z(n5442)); + OR2 U5136 ( .A(n5445), .B(n5446), .Z(n5444)); + AN2 U5137 ( .A(po036), .B(n5447), .Z(n5446)); + OR2 U5138 ( .A(n4418), .B(n5448), .Z(n5447)); + AN2 U5139 ( .A(n5449), .B(n3236), .Z(n5445)); + AN2 U5140 ( .A(n5450), .B(n5451), .Z(n5449)); + OR2 U5141 ( .A(n5452), .B(n2837), .Z(n5451)); + OR2 U5142 ( .A(pi192), .B(n5453), .Z(n5450)); + AN2 U5143 ( .A(n4418), .B(n5448), .Z(n5443)); + AN2 U5144 ( .A(n3352), .B(n5454), .Z(n5440)); + IV2 U5145 ( .A(n5455), .Z(po022)); + AN2 U5146 ( .A(n5456), .B(n5457), .Z(n5455)); + AN2 U5147 ( .A(pi074), .B(pi046), .Z(n5457)); + AN2 U5148 ( .A(pi178), .B(pi113), .Z(n5456)); + OR2 U5149 ( .A(n5458), .B(n5459), .Z(po019)); + AN2 U5150 ( .A(n4478), .B(n5460), .Z(n5459)); + OR2 U5151 ( .A(n5461), .B(n4511), .Z(n5460)); + OR2 U5152 ( .A(n5462), .B(n5463), .Z(n4511)); + OR2 U5153 ( .A(n5464), .B(n5465), .Z(n5463)); + AN2 U5154 ( .A(n5466), .B(pi192), .Z(n5465)); + AN2 U5155 ( .A(n5467), .B(n2837), .Z(n5464)); + AN2 U5156 ( .A(n4475), .B(n5468), .Z(n5458)); + OR2 U5157 ( .A(n5469), .B(n5470), .Z(n5468)); + OR2 U5158 ( .A(n5471), .B(n4509), .Z(n5470)); + OR2 U5159 ( .A(n5472), .B(n5473), .Z(n4509)); + OR2 U5160 ( .A(n5474), .B(n5475), .Z(n5473)); + AN2 U5161 ( .A(n5476), .B(n4078), .Z(n5475)); + AN2 U5162 ( .A(n5477), .B(n5322), .Z(n5476)); + AN2 U5163 ( .A(n5478), .B(n4551), .Z(n5472)); + IV2 U5164 ( .A(n4544), .Z(n4551)); + OR2 U5165 ( .A(n4561), .B(n4066), .Z(n4544)); + AN2 U5166 ( .A(pi192), .B(n3901), .Z(n5478)); + AN2 U5167 ( .A(po102), .B(n4347), .Z(n5471)); + OR2 U5168 ( .A(n5479), .B(n4524), .Z(n4347)); + AN2 U5169 ( .A(n5480), .B(n4078), .Z(n4524)); + IV2 U5170 ( .A(n4066), .Z(n4078)); + AN2 U5171 ( .A(n4521), .B(n4072), .Z(n5479)); + OR2 U5172 ( .A(n5481), .B(n5482), .Z(n4521)); + AN2 U5173 ( .A(po059), .B(n5480), .Z(n5482)); + OR2 U5174 ( .A(n5483), .B(po024), .Z(n5480)); + AN2 U5175 ( .A(n5477), .B(n4074), .Z(n5481)); + OR2 U5176 ( .A(n5484), .B(n5485), .Z(n5469)); + AN2 U5177 ( .A(n4517), .B(n3780), .Z(n5485)); + OR2 U5178 ( .A(n5486), .B(n5487), .Z(n4517)); + AN2 U5179 ( .A(n4356), .B(n5488), .Z(n5487)); + AN2 U5180 ( .A(n4076), .B(n5489), .Z(n4356)); + AN2 U5181 ( .A(n4077), .B(n4578), .Z(n5489)); + AN2 U5182 ( .A(n5490), .B(n4543), .Z(n5486)); + AN2 U5183 ( .A(n4348), .B(n4353), .Z(n4543)); + AN2 U5184 ( .A(n3890), .B(n5491), .Z(n5490)); + AN2 U5185 ( .A(n4512), .B(n4072), .Z(n5484)); + OR2 U5186 ( .A(n5492), .B(n3773), .Z(n4072)); + AN2 U5187 ( .A(po025), .B(n3780), .Z(n5492)); + IV2 U5188 ( .A(n4087), .Z(n3780)); + OR2 U5189 ( .A(n5493), .B(n5494), .Z(n4512)); + OR2 U5190 ( .A(n5495), .B(n5496), .Z(n5494)); + AN2 U5191 ( .A(n5497), .B(pi192), .Z(n5496)); + AN2 U5192 ( .A(n5498), .B(n4348), .Z(n5497)); + OR2 U5193 ( .A(n5499), .B(n5500), .Z(n5498)); + AN2 U5194 ( .A(po102), .B(n3880), .Z(n5500)); + AN2 U5195 ( .A(n4353), .B(n3901), .Z(n5499)); + AN2 U5196 ( .A(n5501), .B(n4076), .Z(n5495)); + AN2 U5197 ( .A(n5488), .B(n4358), .Z(n5501)); + AN2 U5198 ( .A(n5502), .B(n4076), .Z(n5493)); + AN2 U5199 ( .A(n2837), .B(n5503), .Z(n4076)); + AN2 U5200 ( .A(po024), .B(n5322), .Z(n5502)); + OR2 U5201 ( .A(n5504), .B(n5505), .Z(po074)); + AN2 U5202 ( .A(n5506), .B(n5507), .Z(n5505)); + OR2 U5203 ( .A(n4167), .B(n5508), .Z(n5507)); + OR2 U5204 ( .A(pi054), .B(n5509), .Z(n5508)); + AN2 U5205 ( .A(pi025), .B(pi146), .Z(n5509)); + OR2 U5206 ( .A(n5510), .B(n5511), .Z(n5506)); + OR2 U5207 ( .A(n5512), .B(n5513), .Z(n5511)); + AN2 U5208 ( .A(n3926), .B(n5514), .Z(n5513)); + OR2 U5209 ( .A(n5515), .B(n5516), .Z(n5514)); + OR2 U5210 ( .A(n5517), .B(n5518), .Z(n5516)); + OR2 U5211 ( .A(pi056), .B(pi035), .Z(n5518)); + OR2 U5212 ( .A(pi100), .B(n5519), .Z(n5515)); + OR2 U5213 ( .A(pi190), .B(pi126), .Z(n5519)); + AN2 U5214 ( .A(n5520), .B(n4319), .Z(n5512)); + OR2 U5215 ( .A(n5521), .B(n5522), .Z(n5520)); + AN2 U5216 ( .A(pi198), .B(n3945), .Z(n5522)); + AN2 U5217 ( .A(n5523), .B(n5524), .Z(n5521)); + AN2 U5218 ( .A(n5525), .B(n5517), .Z(n5524)); + AN2 U5219 ( .A(n5056), .B(n4201), .Z(n5525)); + AN2 U5220 ( .A(n4391), .B(pi192), .Z(n5523)); + OR2 U5221 ( .A(n5526), .B(n5527), .Z(n5510)); + AN2 U5222 ( .A(n5528), .B(n5529), .Z(n5527)); + OR2 U5223 ( .A(pi198), .B(n4319), .Z(n5529)); + OR2 U5224 ( .A(n5530), .B(n5531), .Z(n5528)); + AN2 U5225 ( .A(n3945), .B(n5532), .Z(n5531)); + OR2 U5226 ( .A(n5533), .B(n5534), .Z(n5532)); + AN2 U5227 ( .A(pi061), .B(n4013), .Z(n5534)); + AN2 U5228 ( .A(n5535), .B(pi134), .Z(n5533)); + AN2 U5229 ( .A(n5536), .B(n4201), .Z(n5535)); + AN2 U5230 ( .A(n5537), .B(n5538), .Z(n5530)); + AN2 U5231 ( .A(n5536), .B(n3261), .Z(n5538)); + OR2 U5232 ( .A(pi061), .B(n4013), .Z(n5536)); + AN2 U5233 ( .A(n5539), .B(n5540), .Z(n5537)); + OR2 U5234 ( .A(pi134), .B(n4201), .Z(n5540)); + OR2 U5235 ( .A(n5541), .B(n5542), .Z(n5539)); + AN2 U5236 ( .A(n5543), .B(n5517), .Z(n5542)); + AN2 U5237 ( .A(pi192), .B(n5544), .Z(n5541)); + OR2 U5238 ( .A(n5545), .B(n5546), .Z(n5544)); + AN2 U5239 ( .A(pi006), .B(n3265), .Z(n5546)); + AN2 U5240 ( .A(n5543), .B(n5056), .Z(n5545)); + OR2 U5241 ( .A(pi006), .B(n3265), .Z(n5543)); + AN2 U5242 ( .A(n5547), .B(n5548), .Z(n5526)); + AN2 U5243 ( .A(n5549), .B(n5550), .Z(n5548)); + AN2 U5244 ( .A(n5517), .B(n2837), .Z(n5550)); + OR2 U5245 ( .A(n5551), .B(n5552), .Z(n5517)); + OR2 U5246 ( .A(n5553), .B(n5554), .Z(n5552)); + AN2 U5247 ( .A(n3945), .B(n5555), .Z(n5554)); + OR2 U5248 ( .A(n5556), .B(n5557), .Z(n5555)); + OR2 U5249 ( .A(n5558), .B(n5559), .Z(n5557)); + AN2 U5250 ( .A(n5560), .B(n3380), .Z(n5559)); + AN2 U5251 ( .A(n5561), .B(n5562), .Z(n5558)); + OR2 U5252 ( .A(n5563), .B(n5564), .Z(n5561)); + AN2 U5253 ( .A(pi055), .B(n3512), .Z(n5564)); + AN2 U5254 ( .A(n5565), .B(pi124), .Z(n5563)); + AN2 U5255 ( .A(n5566), .B(n3363), .Z(n5565)); + AN2 U5256 ( .A(pi109), .B(n4975), .Z(n5556)); + AN2 U5257 ( .A(n5567), .B(n5568), .Z(n5553)); + OR2 U5258 ( .A(n5569), .B(n5570), .Z(n5568)); + OR2 U5259 ( .A(n5571), .B(n5572), .Z(n5570)); + AN2 U5260 ( .A(n5573), .B(n5566), .Z(n5572)); + OR2 U5261 ( .A(pi055), .B(n3512), .Z(n5566)); + AN2 U5262 ( .A(n5574), .B(n3261), .Z(n5573)); + OR2 U5263 ( .A(n5575), .B(n5576), .Z(n5574)); + AN2 U5264 ( .A(pi124), .B(n5562), .Z(n5576)); + OR2 U5265 ( .A(n5577), .B(n5560), .Z(n5562)); + AN2 U5266 ( .A(n5578), .B(n3380), .Z(n5577)); + AN2 U5267 ( .A(n5579), .B(n3363), .Z(n5575)); + OR2 U5268 ( .A(n5580), .B(n5560), .Z(n5579)); + AN2 U5269 ( .A(n5578), .B(pi186), .Z(n5560)); + OR2 U5270 ( .A(pi109), .B(n4975), .Z(n5578)); + AN2 U5271 ( .A(pi109), .B(n3380), .Z(n5580)); + AN2 U5272 ( .A(n5581), .B(n5582), .Z(n5571)); + AN2 U5273 ( .A(n4975), .B(n3380), .Z(n5582)); + AN2 U5274 ( .A(n5583), .B(n3363), .Z(n5581)); + OR2 U5275 ( .A(n5584), .B(n5585), .Z(n5583)); + AN2 U5276 ( .A(pi192), .B(n3512), .Z(n5585)); + AN2 U5277 ( .A(pi055), .B(n3261), .Z(n5584)); + OR2 U5278 ( .A(n3926), .B(n5586), .Z(n5569)); + AN2 U5279 ( .A(n5587), .B(n5588), .Z(n5586)); + AN2 U5280 ( .A(n5589), .B(pi110), .Z(n5588)); + AN2 U5281 ( .A(pi167), .B(n2837), .Z(n5589)); + AN2 U5282 ( .A(pi019), .B(pi085), .Z(n5587)); + AN2 U5283 ( .A(n5590), .B(n5591), .Z(n5567)); + OR2 U5284 ( .A(pi192), .B(n5592), .Z(n5591)); + AN2 U5285 ( .A(n5593), .B(n5594), .Z(n5592)); + OR2 U5286 ( .A(pi164), .B(n3261), .Z(n5594)); + OR2 U5287 ( .A(n5595), .B(n5596), .Z(n5593)); + OR2 U5288 ( .A(n5597), .B(n5598), .Z(n5596)); + AN2 U5289 ( .A(n5599), .B(pi024), .Z(n5598)); + AN2 U5290 ( .A(pi195), .B(n5600), .Z(n5597)); + OR2 U5291 ( .A(n5601), .B(n5599), .Z(n5600)); + AN2 U5292 ( .A(n5602), .B(n5603), .Z(n5599)); + IV2 U5293 ( .A(n5604), .Z(n5603)); + AN2 U5294 ( .A(n5605), .B(n5606), .Z(n5604)); + OR2 U5295 ( .A(n5607), .B(n5608), .Z(n5606)); + AN2 U5296 ( .A(n5609), .B(n5610), .Z(n5608)); + OR2 U5297 ( .A(n5611), .B(n4961), .Z(n5610)); + IV2 U5298 ( .A(pi030), .Z(n4961)); + AN2 U5299 ( .A(n5612), .B(n3597), .Z(n5611)); + OR2 U5300 ( .A(n5612), .B(n3597), .Z(n5609)); + AN2 U5301 ( .A(n4969), .B(n4440), .Z(n5607)); + OR2 U5302 ( .A(n4440), .B(n4969), .Z(n5605)); + IV2 U5303 ( .A(pi159), .Z(n4969)); + AN2 U5304 ( .A(pi024), .B(n5602), .Z(n5601)); + OR2 U5305 ( .A(pi087), .B(pi130), .Z(n5602)); + AN2 U5306 ( .A(pi087), .B(pi130), .Z(n5595)); + OR2 U5307 ( .A(n2837), .B(n5613), .Z(n5590)); + OR2 U5308 ( .A(n5614), .B(n5615), .Z(n5613)); + AN2 U5309 ( .A(n5347), .B(n5616), .Z(n5615)); + AN2 U5310 ( .A(n5617), .B(n4943), .Z(n5614)); + OR2 U5311 ( .A(n5347), .B(n5616), .Z(n5617)); + OR2 U5312 ( .A(n5618), .B(n5619), .Z(n5616)); + OR2 U5313 ( .A(n5620), .B(n5621), .Z(n5619)); + AN2 U5314 ( .A(n5622), .B(pi099), .Z(n5621)); + AN2 U5315 ( .A(n5623), .B(n4937), .Z(n5620)); + OR2 U5316 ( .A(n5624), .B(n5622), .Z(n5623)); + AN2 U5317 ( .A(n5625), .B(n5626), .Z(n5622)); + IV2 U5318 ( .A(n5627), .Z(n5626)); + AN2 U5319 ( .A(n5628), .B(n5629), .Z(n5627)); + OR2 U5320 ( .A(n5630), .B(n5631), .Z(n5629)); + AN2 U5321 ( .A(n5632), .B(n5633), .Z(n5631)); + OR2 U5322 ( .A(po011), .B(n5634), .Z(n5633)); + AN2 U5323 ( .A(n5612), .B(n5358), .Z(n5634)); + OR2 U5324 ( .A(n5612), .B(n5358), .Z(n5632)); + IV2 U5325 ( .A(pi172), .Z(n5358)); + IV2 U5326 ( .A(po062), .Z(n5612)); + OR2 U5327 ( .A(n5635), .B(n5636), .Z(po062)); + AN2 U5328 ( .A(n5637), .B(n2837), .Z(n5636)); + OR2 U5329 ( .A(n5638), .B(n5639), .Z(n5637)); + AN2 U5330 ( .A(pi020), .B(pi095), .Z(n5639)); + AN2 U5331 ( .A(n5640), .B(n5641), .Z(n5638)); + OR2 U5332 ( .A(pi020), .B(pi095), .Z(n5641)); + OR2 U5333 ( .A(n5642), .B(n5643), .Z(n5640)); + AN2 U5334 ( .A(pi151), .B(n5644), .Z(n5643)); + AN2 U5335 ( .A(pi153), .B(n5645), .Z(n5642)); + OR2 U5336 ( .A(pi151), .B(n5644), .Z(n5645)); + OR2 U5337 ( .A(n5646), .B(n5647), .Z(n5644)); + AN2 U5338 ( .A(pi075), .B(pi156), .Z(n5647)); + AN2 U5339 ( .A(n5648), .B(n5649), .Z(n5646)); + OR2 U5340 ( .A(pi075), .B(pi156), .Z(n5649)); + OR2 U5341 ( .A(n5650), .B(n5651), .Z(n5648)); + AN2 U5342 ( .A(pi040), .B(n5652), .Z(n5651)); + AN2 U5343 ( .A(pi047), .B(n5653), .Z(n5650)); + OR2 U5344 ( .A(pi040), .B(n5652), .Z(n5653)); + AN2 U5345 ( .A(pi192), .B(n5654), .Z(n5635)); + OR2 U5346 ( .A(n5655), .B(n5656), .Z(n5654)); + OR2 U5347 ( .A(n5657), .B(n5658), .Z(n5656)); + AN2 U5348 ( .A(pi101), .B(n5659), .Z(n5658)); + AN2 U5349 ( .A(n5660), .B(n4628), .Z(n5657)); + OR2 U5350 ( .A(n5661), .B(n5659), .Z(n5660)); + OR2 U5351 ( .A(n5662), .B(n5663), .Z(n5659)); + AN2 U5352 ( .A(n5664), .B(pi036), .Z(n5663)); + AN2 U5353 ( .A(n5665), .B(n4861), .Z(n5662)); + OR2 U5354 ( .A(n5666), .B(n5664), .Z(n5665)); + AN2 U5355 ( .A(n5667), .B(n5668), .Z(n5664)); + IV2 U5356 ( .A(n5669), .Z(n5668)); + AN2 U5357 ( .A(n5670), .B(n5671), .Z(n5669)); + OR2 U5358 ( .A(po039), .B(n5672), .Z(n5671)); + AN2 U5359 ( .A(n5673), .B(n5331), .Z(n5672)); + OR2 U5360 ( .A(n5673), .B(n5331), .Z(n5670)); + IV2 U5361 ( .A(pi168), .Z(n5331)); + IV2 U5362 ( .A(n5652), .Z(n5673)); + OR2 U5363 ( .A(n5674), .B(n5675), .Z(n5652)); + AN2 U5364 ( .A(n5676), .B(n2837), .Z(n5675)); + OR2 U5365 ( .A(n5677), .B(n5678), .Z(n5676)); + AN2 U5366 ( .A(pi143), .B(pi108), .Z(n5678)); + AN2 U5367 ( .A(n5679), .B(n5680), .Z(n5677)); + OR2 U5368 ( .A(pi108), .B(pi143), .Z(n5680)); + OR2 U5369 ( .A(n5681), .B(n5682), .Z(n5679)); + AN2 U5370 ( .A(pi014), .B(pi114), .Z(n5682)); + AN2 U5371 ( .A(n5683), .B(n5684), .Z(n5681)); + OR2 U5372 ( .A(pi014), .B(pi114), .Z(n5684)); + OR2 U5373 ( .A(n5685), .B(n5686), .Z(n5683)); + OR2 U5374 ( .A(n5687), .B(n5688), .Z(n5686)); + AN2 U5375 ( .A(n5689), .B(pi170), .Z(n5688)); + AN2 U5376 ( .A(pi176), .B(n5690), .Z(n5687)); + OR2 U5377 ( .A(n5691), .B(n5689), .Z(n5690)); + AN2 U5378 ( .A(n5692), .B(n5693), .Z(n5689)); + IV2 U5379 ( .A(n5694), .Z(n5693)); + AN2 U5380 ( .A(n5695), .B(n5696), .Z(n5694)); + OR2 U5381 ( .A(n5697), .B(n4899), .Z(n5696)); + IV2 U5382 ( .A(pi097), .Z(n4899)); + AN2 U5383 ( .A(n5698), .B(n4077), .Z(n5697)); + OR2 U5384 ( .A(n5698), .B(n4077), .Z(n5695)); + AN2 U5385 ( .A(pi170), .B(n5692), .Z(n5691)); + OR2 U5386 ( .A(pi160), .B(pi189), .Z(n5692)); + AN2 U5387 ( .A(pi189), .B(pi160), .Z(n5685)); + AN2 U5388 ( .A(pi192), .B(n5699), .Z(n5674)); + OR2 U5389 ( .A(n5700), .B(n5701), .Z(n5699)); + AN2 U5390 ( .A(pi089), .B(n4881), .Z(n5701)); + AN2 U5391 ( .A(n5702), .B(n5703), .Z(n5700)); + OR2 U5392 ( .A(pi089), .B(n4881), .Z(n5703)); + OR2 U5393 ( .A(n5704), .B(n5705), .Z(n5702)); + AN2 U5394 ( .A(pi027), .B(n4885), .Z(n5705)); + AN2 U5395 ( .A(n5706), .B(n5707), .Z(n5704)); + OR2 U5396 ( .A(pi027), .B(n4885), .Z(n5707)); + OR2 U5397 ( .A(n5708), .B(n5709), .Z(n5706)); + OR2 U5398 ( .A(n5710), .B(n5711), .Z(n5709)); + AN2 U5399 ( .A(n5712), .B(pi083), .Z(n5711)); + AN2 U5400 ( .A(n5713), .B(n4877), .Z(n5710)); + OR2 U5401 ( .A(n5714), .B(n5712), .Z(n5713)); + AN2 U5402 ( .A(n5715), .B(n5716), .Z(n5712)); + IV2 U5403 ( .A(n5717), .Z(n5716)); + AN2 U5404 ( .A(n5718), .B(n5719), .Z(n5717)); + OR2 U5405 ( .A(po025), .B(n5720), .Z(n5719)); + AN2 U5406 ( .A(n5698), .B(n5303), .Z(n5720)); + OR2 U5407 ( .A(n5698), .B(n5303), .Z(n5718)); + IV2 U5408 ( .A(pi140), .Z(n5303)); + IV2 U5409 ( .A(n5721), .Z(n5698)); + OR2 U5410 ( .A(n5722), .B(n5723), .Z(n5721)); + AN2 U5411 ( .A(n5724), .B(n2837), .Z(n5723)); + OR2 U5412 ( .A(n5725), .B(n5726), .Z(n5724)); + OR2 U5413 ( .A(n5727), .B(n5728), .Z(n5726)); + AN2 U5414 ( .A(n5729), .B(pi094), .Z(n5728)); + AN2 U5415 ( .A(pi128), .B(n5730), .Z(n5727)); + OR2 U5416 ( .A(n5731), .B(n5729), .Z(n5730)); + AN2 U5417 ( .A(n5732), .B(n5733), .Z(n5729)); + IV2 U5418 ( .A(n5734), .Z(n5733)); + AN2 U5419 ( .A(n5735), .B(n5736), .Z(n5734)); + OR2 U5420 ( .A(n5737), .B(n5738), .Z(n5736)); + AN2 U5421 ( .A(n5739), .B(n5740), .Z(n5738)); + OR2 U5422 ( .A(n5741), .B(n5115), .Z(n5740)); + AN2 U5423 ( .A(n5742), .B(n4778), .Z(n5741)); + OR2 U5424 ( .A(n5742), .B(n4778), .Z(n5739)); + IV2 U5425 ( .A(pi163), .Z(n4778)); + AN2 U5426 ( .A(n3177), .B(n4770), .Z(n5737)); + OR2 U5427 ( .A(n3177), .B(n4770), .Z(n5735)); + IV2 U5428 ( .A(pi028), .Z(n4770)); + AN2 U5429 ( .A(pi094), .B(n5732), .Z(n5731)); + OR2 U5430 ( .A(pi173), .B(pi185), .Z(n5732)); + AN2 U5431 ( .A(pi173), .B(pi185), .Z(n5725)); + AN2 U5432 ( .A(pi192), .B(n5743), .Z(n5722)); + OR2 U5433 ( .A(n5744), .B(n5745), .Z(n5743)); + OR2 U5434 ( .A(n5746), .B(n5747), .Z(n5745)); + AN2 U5435 ( .A(pi131), .B(n5748), .Z(n5747)); + AN2 U5436 ( .A(n5749), .B(n5040), .Z(n5746)); + OR2 U5437 ( .A(n5750), .B(n5748), .Z(n5749)); + OR2 U5438 ( .A(n5751), .B(n5752), .Z(n5748)); + AN2 U5439 ( .A(n5753), .B(pi059), .Z(n5752)); + AN2 U5440 ( .A(n5754), .B(n3286), .Z(n5751)); + OR2 U5441 ( .A(n5755), .B(n5753), .Z(n5754)); + AN2 U5442 ( .A(n5756), .B(n5757), .Z(n5753)); + IV2 U5443 ( .A(n5758), .Z(n5757)); + AN2 U5444 ( .A(n5759), .B(n5760), .Z(n5758)); + OR2 U5445 ( .A(po010), .B(n5761), .Z(n5760)); + AN2 U5446 ( .A(n5742), .B(n5439), .Z(n5761)); + OR2 U5447 ( .A(n5742), .B(n5439), .Z(n5759)); + IV2 U5448 ( .A(pi197), .Z(n5439)); + IV2 U5449 ( .A(n5762), .Z(n5742)); + OR2 U5450 ( .A(n5763), .B(n5764), .Z(n5762)); + AN2 U5451 ( .A(n5765), .B(n2837), .Z(n5764)); + OR2 U5452 ( .A(n5766), .B(n5767), .Z(n5765)); + AN2 U5453 ( .A(pi021), .B(pi201), .Z(n5767)); + AN2 U5454 ( .A(n5768), .B(n5769), .Z(n5766)); + OR2 U5455 ( .A(pi021), .B(pi201), .Z(n5769)); + OR2 U5456 ( .A(n5770), .B(n5771), .Z(n5768)); + IV2 U5457 ( .A(n5772), .Z(n5771)); + AN2 U5458 ( .A(n5773), .B(n5774), .Z(n5772)); + OR2 U5459 ( .A(n5775), .B(n5022), .Z(n5774)); + OR2 U5460 ( .A(n5431), .B(n5776), .Z(n5773)); + AN2 U5461 ( .A(n5777), .B(n5775), .Z(n5776)); + OR2 U5462 ( .A(n5778), .B(n5779), .Z(n5775)); + AN2 U5463 ( .A(n5780), .B(n5781), .Z(n5779)); + OR2 U5464 ( .A(n5782), .B(n5783), .Z(n5781)); + AN2 U5465 ( .A(n5784), .B(n5785), .Z(n5783)); + OR2 U5466 ( .A(n5786), .B(n5787), .Z(n5785)); + IV2 U5467 ( .A(pi181), .Z(n5787)); + AN2 U5468 ( .A(n2982), .B(n5019), .Z(n5786)); + OR2 U5469 ( .A(n2982), .B(n5019), .Z(n5784)); + IV2 U5470 ( .A(pi011), .Z(n5019)); + AN2 U5471 ( .A(n5027), .B(n2957), .Z(n5782)); + OR2 U5472 ( .A(n2957), .B(n5027), .Z(n5780)); + IV2 U5473 ( .A(pi086), .Z(n5027)); + OR2 U5474 ( .A(n5022), .B(n5778), .Z(n5777)); + AN2 U5475 ( .A(n5165), .B(n5031), .Z(n5778)); + IV2 U5476 ( .A(pi165), .Z(n5031)); + IV2 U5477 ( .A(pi032), .Z(n5022)); + AN2 U5478 ( .A(pi165), .B(pi107), .Z(n5770)); + AN2 U5479 ( .A(pi192), .B(n5788), .Z(n5763)); + OR2 U5480 ( .A(n5789), .B(n5790), .Z(n5788)); + AN2 U5481 ( .A(pi121), .B(n5000), .Z(n5790)); + AN2 U5482 ( .A(n5791), .B(n5792), .Z(n5789)); + OR2 U5483 ( .A(pi121), .B(n5000), .Z(n5792)); + OR2 U5484 ( .A(n5793), .B(n5794), .Z(n5791)); + AN2 U5485 ( .A(pi053), .B(n5795), .Z(n5794)); + AN2 U5486 ( .A(n5796), .B(n5004), .Z(n5793)); + OR2 U5487 ( .A(pi053), .B(n5795), .Z(n5796)); + OR2 U5488 ( .A(n5797), .B(n5798), .Z(n5795)); + AN2 U5489 ( .A(pi184), .B(n5008), .Z(n5798)); + AN2 U5490 ( .A(n5799), .B(n5800), .Z(n5797)); + OR2 U5491 ( .A(pi184), .B(n5008), .Z(n5800)); + OR2 U5492 ( .A(n5801), .B(n5802), .Z(n5799)); + AN2 U5493 ( .A(pi181), .B(pi103), .Z(n5802)); + AN2 U5494 ( .A(n5803), .B(n2962), .Z(n5801)); + OR2 U5495 ( .A(pi103), .B(pi181), .Z(n5803)); + AN2 U5496 ( .A(pi059), .B(n5756), .Z(n5755)); + AN2 U5497 ( .A(pi131), .B(n5756), .Z(n5750)); + OR2 U5498 ( .A(pi001), .B(n5037), .Z(n5756)); + AN2 U5499 ( .A(pi001), .B(n5037), .Z(n5744)); + AN2 U5500 ( .A(pi083), .B(n5715), .Z(n5714)); + OR2 U5501 ( .A(pi162), .B(n4874), .Z(n5715)); + AN2 U5502 ( .A(pi162), .B(n4874), .Z(n5708)); + AN2 U5503 ( .A(pi036), .B(n5667), .Z(n5666)); + AN2 U5504 ( .A(pi101), .B(n5667), .Z(n5661)); + OR2 U5505 ( .A(pi205), .B(n4915), .Z(n5667)); + AN2 U5506 ( .A(pi205), .B(n4915), .Z(n5655)); + AN2 U5507 ( .A(po036), .B(n5350), .Z(n5630)); + OR2 U5508 ( .A(po036), .B(n5350), .Z(n5628)); + IV2 U5509 ( .A(pi018), .Z(n5350)); + AN2 U5510 ( .A(pi099), .B(n5625), .Z(n5624)); + OR2 U5511 ( .A(pi180), .B(n4947), .Z(n5625)); + AN2 U5512 ( .A(pi180), .B(n4947), .Z(n5618)); + AN2 U5513 ( .A(n3261), .B(pi049), .Z(n5347)); + AN2 U5514 ( .A(n3926), .B(n5804), .Z(n5551)); + OR2 U5515 ( .A(n5805), .B(n5806), .Z(n5804)); + OR2 U5516 ( .A(pi085), .B(pi019), .Z(n5806)); + OR2 U5517 ( .A(pi110), .B(n5807), .Z(n5805)); + OR2 U5518 ( .A(pi167), .B(pi164), .Z(n5807)); + AN2 U5519 ( .A(pi126), .B(pi190), .Z(n5549)); + AN2 U5520 ( .A(n5808), .B(pi035), .Z(n5547)); + AN2 U5521 ( .A(pi056), .B(pi100), .Z(n5808)); + AN2 U5522 ( .A(pi054), .B(n5809), .Z(n5504)); + OR2 U5523 ( .A(n4167), .B(n5810), .Z(n5809)); + OR2 U5524 ( .A(pi146), .B(pi025), .Z(n5810)); + AN2 U5525 ( .A(n5811), .B(n2882), .Z(po017)); + OR2 U5526 ( .A(pi200), .B(n3003), .Z(n5811)); + OR2 U5527 ( .A(n5812), .B(n5813), .Z(po016)); + OR2 U5528 ( .A(n5814), .B(n5815), .Z(n5813)); + AN2 U5529 ( .A(n3280), .B(n3064), .Z(n5815)); + AN2 U5530 ( .A(n5100), .B(n5816), .Z(n5814)); + OR2 U5531 ( .A(n5817), .B(n5818), .Z(n5816)); + AN2 U5532 ( .A(n3055), .B(n5819), .Z(n5818)); + OR2 U5533 ( .A(n2845), .B(n3143), .Z(n5819)); + OR2 U5534 ( .A(n2978), .B(n3147), .Z(n3143)); + AN2 U5535 ( .A(n3127), .B(n5820), .Z(n5817)); + OR2 U5536 ( .A(n2833), .B(n3138), .Z(n5820)); + OR2 U5537 ( .A(n2880), .B(n3147), .Z(n3138)); + OR2 U5538 ( .A(n2998), .B(n5821), .Z(n3147)); + OR2 U5539 ( .A(n2882), .B(n2862), .Z(n5821)); + OR2 U5540 ( .A(n2925), .B(n2901), .Z(n2882)); + AN2 U5541 ( .A(pi192), .B(n3036), .Z(n3127)); + IV2 U5542 ( .A(n5822), .Z(n5100)); + OR2 U5543 ( .A(n5823), .B(n5824), .Z(n5812)); + AN2 U5544 ( .A(n5825), .B(pi192), .Z(n5824)); + AN2 U5545 ( .A(n5826), .B(po010), .Z(n5825)); + AN2 U5546 ( .A(n5827), .B(n2837), .Z(n5823)); + AN2 U5547 ( .A(n5828), .B(n5829), .Z(n5827)); + OR2 U5548 ( .A(n5830), .B(n5831), .Z(po008)); + AN2 U5549 ( .A(n3344), .B(n3251), .Z(n5831)); + OR2 U5550 ( .A(n5832), .B(n5833), .Z(n3251)); + AN2 U5551 ( .A(n3355), .B(n5454), .Z(n5832)); + OR2 U5552 ( .A(n5834), .B(n5835), .Z(n5454)); + AN2 U5553 ( .A(n5836), .B(n4426), .Z(n5834)); + IV2 U5554 ( .A(n3352), .Z(n3355)); + AN2 U5555 ( .A(n3250), .B(n5837), .Z(n5830)); + OR2 U5556 ( .A(n5838), .B(n5839), .Z(n5837)); + OR2 U5557 ( .A(n5840), .B(n3245), .Z(n5839)); + OR2 U5558 ( .A(n5841), .B(n5842), .Z(n3245)); + AN2 U5559 ( .A(n3244), .B(n3699), .Z(n5842)); + AN2 U5560 ( .A(n3242), .B(n3700), .Z(n5841)); + IV2 U5561 ( .A(n5843), .Z(n3242)); + AN2 U5562 ( .A(n3352), .B(n3701), .Z(n5840)); + OR2 U5563 ( .A(n5844), .B(n5845), .Z(n5838)); + AN2 U5564 ( .A(n4418), .B(n3762), .Z(n5845)); + AN2 U5565 ( .A(n5846), .B(n3236), .Z(n5844)); + OR2 U5566 ( .A(pi037), .B(n5847), .Z(po007)); + IV2 U5567 ( .A(pi116), .Z(n5847)); + OR2 U5568 ( .A(n5848), .B(n5849), .Z(po006)); + AN2 U5569 ( .A(n3370), .B(n5850), .Z(n5849)); + OR2 U5570 ( .A(n5851), .B(n5852), .Z(n5850)); + OR2 U5571 ( .A(n5853), .B(n5138), .Z(n5852)); + OR2 U5572 ( .A(n5854), .B(n3566), .Z(n5138)); + AN2 U5573 ( .A(n3512), .B(n3926), .Z(n3566)); + AN2 U5574 ( .A(n3926), .B(n4368), .Z(n5854)); + OR2 U5575 ( .A(n5855), .B(n5856), .Z(n5851)); + AN2 U5576 ( .A(n5139), .B(n3380), .Z(n5856)); + OR2 U5577 ( .A(n5857), .B(n5858), .Z(n5139)); + AN2 U5578 ( .A(n5859), .B(n3261), .Z(n5857)); + AN2 U5579 ( .A(n5860), .B(pi118), .Z(n5855)); + AN2 U5580 ( .A(n5861), .B(n3261), .Z(n5860)); + OR2 U5581 ( .A(n5858), .B(n5859), .Z(n5861)); + OR2 U5582 ( .A(n5862), .B(n5863), .Z(n5859)); + OR2 U5583 ( .A(n3404), .B(n5864), .Z(n5863)); + AN2 U5584 ( .A(n5865), .B(pi060), .Z(n5864)); + AN2 U5585 ( .A(n4368), .B(n5866), .Z(n5865)); + IV2 U5586 ( .A(n3446), .Z(n3404)); + AN2 U5587 ( .A(n4367), .B(pi196), .Z(n5862)); + IV2 U5588 ( .A(n4364), .Z(n4367)); + IV2 U5589 ( .A(n5867), .Z(n5858)); + IV2 U5590 ( .A(n3393), .Z(n3370)); + AN2 U5591 ( .A(n3393), .B(n5868), .Z(n5848)); + OR2 U5592 ( .A(n5869), .B(n5870), .Z(n5868)); + OR2 U5593 ( .A(n5135), .B(n5871), .Z(n5870)); + AN2 U5594 ( .A(n3480), .B(n5872), .Z(n5871)); + AN2 U5595 ( .A(n5867), .B(n3321), .Z(n5135)); + OR2 U5596 ( .A(po104), .B(n4364), .Z(n5867)); + OR2 U5597 ( .A(n5873), .B(n5874), .Z(n5869)); + OR2 U5598 ( .A(n5875), .B(n5876), .Z(n5874)); + AN2 U5599 ( .A(n5877), .B(po071), .Z(n5876)); + OR2 U5600 ( .A(n5136), .B(n5878), .Z(n5877)); + OR2 U5601 ( .A(n5879), .B(n5880), .Z(n5136)); + OR2 U5602 ( .A(n5881), .B(n5882), .Z(n5880)); + AN2 U5603 ( .A(n3398), .B(n4364), .Z(n5882)); + AN2 U5604 ( .A(n4363), .B(n3419), .Z(n5879)); + AN2 U5605 ( .A(n5883), .B(n3398), .Z(n5875)); + AN2 U5606 ( .A(n3446), .B(n3533), .Z(n3398)); + AN2 U5607 ( .A(n4364), .B(n3913), .Z(n5883)); + OR2 U5608 ( .A(n4062), .B(po027), .Z(n4364)); + IV2 U5609 ( .A(n4061), .Z(n4062)); + AN2 U5610 ( .A(n3416), .B(n4363), .Z(n5873)); + IV2 U5611 ( .A(n4368), .Z(n4363)); + OR2 U5612 ( .A(n3363), .B(n4061), .Z(n4368)); + OR2 U5613 ( .A(n5884), .B(n5885), .Z(n4061)); + OR2 U5614 ( .A(n5886), .B(n5887), .Z(n5885)); + AN2 U5615 ( .A(n5888), .B(n4943), .Z(n5887)); + AN2 U5616 ( .A(n5889), .B(n3989), .Z(n5886)); + OR2 U5617 ( .A(n5890), .B(n5891), .Z(n5884)); + OR2 U5618 ( .A(n5892), .B(n3490), .Z(n5891)); + AN2 U5619 ( .A(n5893), .B(n5894), .Z(n5890)); + AN2 U5620 ( .A(n3495), .B(n5895), .Z(n5893)); + AN2 U5621 ( .A(n3446), .B(n3480), .Z(n3416)); + OR2 U5622 ( .A(po104), .B(n3942), .Z(n3446)); + OR2 U5623 ( .A(n5896), .B(n3253), .Z(po012)); + AN2 U5624 ( .A(n5897), .B(pi054), .Z(n3253)); + OR2 U5625 ( .A(n4133), .B(n5898), .Z(n5897)); + AN2 U5626 ( .A(n4127), .B(n3255), .Z(n5896)); + OR2 U5627 ( .A(pi054), .B(n5120), .Z(n3255)); + OR2 U5628 ( .A(n5899), .B(n4167), .Z(n5120)); + AN2 U5629 ( .A(n4133), .B(n4128), .Z(n5899)); + IV2 U5630 ( .A(po064), .Z(n4133)); + OR2 U5631 ( .A(n5900), .B(n4372), .Z(n4127)); + OR2 U5632 ( .A(n5901), .B(n5902), .Z(n4372)); + AN2 U5633 ( .A(n4380), .B(n4319), .Z(n5901)); + AN2 U5634 ( .A(n5903), .B(n4374), .Z(n5900)); + OR2 U5635 ( .A(n5904), .B(n5905), .Z(n4374)); + AN2 U5636 ( .A(n5906), .B(n3261), .Z(n5905)); + OR2 U5637 ( .A(n5907), .B(n5908), .Z(n5906)); + OR2 U5638 ( .A(n5909), .B(n5910), .Z(n5908)); + AN2 U5639 ( .A(n5911), .B(po103), .Z(n5910)); + AN2 U5640 ( .A(n5912), .B(pi058), .Z(n5911)); + AN2 U5641 ( .A(n5913), .B(n5914), .Z(n5912)); + AN2 U5642 ( .A(n5915), .B(n5916), .Z(n5913)); + OR2 U5643 ( .A(pi204), .B(n5917), .Z(n5916)); + AN2 U5644 ( .A(n4057), .B(n4013), .Z(n5917)); + OR2 U5645 ( .A(n5918), .B(n5919), .Z(n5915)); + AN2 U5646 ( .A(po040), .B(n3966), .Z(n5918)); + AN2 U5647 ( .A(n5920), .B(n3265), .Z(n5909)); + AN2 U5648 ( .A(n5921), .B(n5922), .Z(n5920)); + AN2 U5649 ( .A(n4057), .B(n4316), .Z(n5922)); + AN2 U5650 ( .A(n4157), .B(n5914), .Z(n5921)); + OR2 U5651 ( .A(n5923), .B(n4319), .Z(n5914)); + AN2 U5652 ( .A(pi065), .B(pi192), .Z(n5923)); + OR2 U5653 ( .A(pi204), .B(n4013), .Z(n4157)); + AN2 U5654 ( .A(n5924), .B(n4046), .Z(n5907)); + AN2 U5655 ( .A(po040), .B(n3263), .Z(n5924)); + OR2 U5656 ( .A(n5925), .B(n2837), .Z(n3263)); + AN2 U5657 ( .A(n3264), .B(pi058), .Z(n5925)); + AN2 U5658 ( .A(n4391), .B(n4319), .Z(n5904)); + AN2 U5659 ( .A(n3265), .B(n4013), .Z(n4391)); + IV2 U5660 ( .A(n4158), .Z(n5903)); + OR2 U5661 ( .A(n4312), .B(n5926), .Z(n4158)); + OR2 U5662 ( .A(n4040), .B(n4229), .Z(n5926)); + IV2 U5663 ( .A(n4184), .Z(n4229)); + OR2 U5664 ( .A(n5927), .B(n5928), .Z(n4184)); + OR2 U5665 ( .A(n5929), .B(n5930), .Z(n5928)); + AN2 U5666 ( .A(n5931), .B(n5932), .Z(n5929)); + OR2 U5667 ( .A(n5933), .B(n5934), .Z(n5932)); + AN2 U5668 ( .A(n3457), .B(n3493), .Z(n5934)); + IV2 U5669 ( .A(n3661), .Z(n3493)); + OR2 U5670 ( .A(n5935), .B(n5936), .Z(n3661)); + OR2 U5671 ( .A(n3229), .B(n3235), .Z(n5936)); + OR2 U5672 ( .A(n5937), .B(n5938), .Z(n3235)); + OR2 U5673 ( .A(n5939), .B(n5940), .Z(n5938)); + AN2 U5674 ( .A(n5452), .B(n3241), .Z(n5940)); + AN2 U5675 ( .A(n5453), .B(n3243), .Z(n5939)); + AN2 U5676 ( .A(po082), .B(n5846), .Z(n5937)); + OR2 U5677 ( .A(n5941), .B(n5942), .Z(n5846)); + AN2 U5678 ( .A(n5452), .B(n3700), .Z(n5942)); + AN2 U5679 ( .A(n3638), .B(n3635), .Z(n5452)); + IV2 U5680 ( .A(pi098), .Z(n3638)); + AN2 U5681 ( .A(n5453), .B(n3699), .Z(n5941)); + AN2 U5682 ( .A(n3597), .B(n3593), .Z(n5453)); + OR2 U5683 ( .A(n5943), .B(n5944), .Z(n3229)); + AN2 U5684 ( .A(po082), .B(n3344), .Z(n5944)); + AN2 U5685 ( .A(n3352), .B(n5945), .Z(n5943)); + OR2 U5686 ( .A(n5946), .B(n5947), .Z(n5945)); + OR2 U5687 ( .A(n3241), .B(n3243), .Z(n5947)); + AN2 U5688 ( .A(po082), .B(n3701), .Z(n5946)); + IV2 U5689 ( .A(n5833), .Z(n3701)); + OR2 U5690 ( .A(n3233), .B(n5948), .Z(n5935)); + AN2 U5691 ( .A(n3339), .B(n5949), .Z(n5948)); + AN2 U5692 ( .A(n5949), .B(po011), .Z(n3233)); + OR2 U5693 ( .A(n5950), .B(n5951), .Z(n5949)); + OR2 U5694 ( .A(n5952), .B(n5953), .Z(n5951)); + AN2 U5695 ( .A(n3241), .B(n3635), .Z(n5953)); + AN2 U5696 ( .A(n3992), .B(n3700), .Z(n3241)); + AN2 U5697 ( .A(n3632), .B(pi192), .Z(n3700)); + IV2 U5698 ( .A(pi004), .Z(n3992)); + AN2 U5699 ( .A(n3243), .B(n3593), .Z(n5952)); + OR2 U5700 ( .A(po036), .B(n4440), .Z(n3593)); + AN2 U5701 ( .A(n5372), .B(n3699), .Z(n3243)); + AN2 U5702 ( .A(po082), .B(n3762), .Z(n5950)); + OR2 U5703 ( .A(n5954), .B(n5955), .Z(n3762)); + OR2 U5704 ( .A(n5956), .B(n5957), .Z(n5955)); + AN2 U5705 ( .A(po036), .B(n5958), .Z(n5957)); + OR2 U5706 ( .A(n5959), .B(po001), .Z(n5958)); + AN2 U5707 ( .A(pi192), .B(n5960), .Z(n5956)); + OR2 U5708 ( .A(n5961), .B(n5962), .Z(n5960)); + AN2 U5709 ( .A(po001), .B(n4001), .Z(n5962)); + AN2 U5710 ( .A(n3635), .B(n3998), .Z(n5961)); + OR2 U5711 ( .A(po036), .B(n4001), .Z(n3635)); + IV2 U5712 ( .A(pi171), .Z(n4001)); + AN2 U5713 ( .A(n3699), .B(n4440), .Z(n5954)); + AN2 U5714 ( .A(n2837), .B(n3590), .Z(n3699)); + AN2 U5715 ( .A(n5963), .B(n3667), .Z(n5933)); + AN2 U5716 ( .A(n3291), .B(n3341), .Z(n3667)); + IV2 U5717 ( .A(n3339), .Z(n3341)); + OR2 U5718 ( .A(n5964), .B(n5965), .Z(n3339)); + AN2 U5719 ( .A(n5966), .B(n4441), .Z(n5965)); + AN2 U5720 ( .A(n5448), .B(po036), .Z(n5964)); + IV2 U5721 ( .A(n5966), .Z(n5448)); + OR2 U5722 ( .A(n5967), .B(n5968), .Z(n3291)); + AN2 U5723 ( .A(n5969), .B(n3688), .Z(n5968)); + IV2 U5724 ( .A(n3746), .Z(n5969)); + AN2 U5725 ( .A(po011), .B(n3746), .Z(n5967)); + OR2 U5726 ( .A(n3717), .B(n3705), .Z(n3746)); + AN2 U5727 ( .A(n3495), .B(n5970), .Z(n5963)); + OR2 U5728 ( .A(n5971), .B(n5972), .Z(n5970)); + OR2 U5729 ( .A(n5973), .B(n5974), .Z(n5972)); + AN2 U5730 ( .A(n5975), .B(pi192), .Z(n5974)); + AN2 U5731 ( .A(n3567), .B(n5976), .Z(n5975)); + OR2 U5732 ( .A(n5977), .B(n5978), .Z(n5976)); + OR2 U5733 ( .A(n5979), .B(n5980), .Z(n5978)); + AN2 U5734 ( .A(n4635), .B(n5981), .Z(n5979)); + IV2 U5735 ( .A(n4464), .Z(n4635)); + OR2 U5736 ( .A(po039), .B(n3870), .Z(n4464)); + IV2 U5737 ( .A(pi016), .Z(n3870)); + OR2 U5738 ( .A(n5982), .B(n5983), .Z(n5977)); + AN2 U5739 ( .A(n5984), .B(n3033), .Z(n5983)); + IV2 U5740 ( .A(n3038), .Z(n3033)); + OR2 U5741 ( .A(po070), .B(n3199), .Z(n3038)); + IV2 U5742 ( .A(pi096), .Z(n3199)); + AN2 U5743 ( .A(n5985), .B(n5986), .Z(n5982)); + OR2 U5744 ( .A(n5987), .B(n3042), .Z(n5986)); + IV2 U5745 ( .A(n3037), .Z(n3042)); + OR2 U5746 ( .A(po099), .B(n3171), .Z(n3037)); + AN2 U5747 ( .A(n3063), .B(n5988), .Z(n5987)); + OR2 U5748 ( .A(n5989), .B(n5990), .Z(n5988)); + AN2 U5749 ( .A(n3036), .B(n5991), .Z(n5989)); + OR2 U5750 ( .A(n5992), .B(n3010), .Z(n5991)); + OR2 U5751 ( .A(n5993), .B(n5994), .Z(n3010)); + AN2 U5752 ( .A(pi088), .B(n3012), .Z(n5992)); + IV2 U5753 ( .A(n5995), .Z(n3036)); + OR2 U5754 ( .A(n5996), .B(n5990), .Z(n5995)); + AN2 U5755 ( .A(pi166), .B(n3049), .Z(n5990)); + AN2 U5756 ( .A(po010), .B(n3106), .Z(n5996)); + OR2 U5757 ( .A(n3534), .B(n3363), .Z(n3567)); + AN2 U5758 ( .A(n5997), .B(n3457), .Z(n5973)); + IV2 U5759 ( .A(n4060), .Z(n3457)); + OR2 U5760 ( .A(n5998), .B(n5999), .Z(n4060)); + AN2 U5761 ( .A(po027), .B(n3451), .Z(n5998)); + AN2 U5762 ( .A(n3760), .B(n4652), .Z(n5997)); + AN2 U5763 ( .A(n6000), .B(n6001), .Z(n5971)); + OR2 U5764 ( .A(n3261), .B(n3525), .Z(n6001)); + AN2 U5765 ( .A(n3363), .B(n3321), .Z(n3525)); + OR2 U5766 ( .A(n6002), .B(n6003), .Z(n6000)); + AN2 U5767 ( .A(n6004), .B(n2837), .Z(n6003)); + OR2 U5768 ( .A(n6005), .B(n6006), .Z(n6004)); + OR2 U5769 ( .A(n6007), .B(n6008), .Z(n6006)); + AN2 U5770 ( .A(n4641), .B(n5981), .Z(n6007)); + IV2 U5771 ( .A(n4468), .Z(n4641)); + OR2 U5772 ( .A(po039), .B(n4735), .Z(n4468)); + IV2 U5773 ( .A(pi040), .Z(n4735)); + OR2 U5774 ( .A(n6009), .B(n6010), .Z(n6005)); + AN2 U5775 ( .A(n5985), .B(n6011), .Z(n6010)); + OR2 U5776 ( .A(n6012), .B(n6013), .Z(n6011)); + OR2 U5777 ( .A(n3066), .B(n6014), .Z(n6013)); + AN2 U5778 ( .A(n6015), .B(n6016), .Z(n6014)); + IV2 U5779 ( .A(n3112), .Z(n3066)); + OR2 U5780 ( .A(po099), .B(n3177), .Z(n3112)); + AN2 U5781 ( .A(n6017), .B(n6018), .Z(n6012)); + OR2 U5782 ( .A(n6019), .B(n6020), .Z(n6018)); + AN2 U5783 ( .A(n6021), .B(n3119), .Z(n6019)); + OR2 U5784 ( .A(n6022), .B(n5993), .Z(n6021)); + AN2 U5785 ( .A(n2890), .B(n5000), .Z(n5993)); + AN2 U5786 ( .A(pi201), .B(n3012), .Z(n6022)); + OR2 U5787 ( .A(n2890), .B(n5000), .Z(n3012)); + IV2 U5788 ( .A(n2886), .Z(n2890)); + OR2 U5789 ( .A(n6023), .B(n6024), .Z(n2886)); + OR2 U5790 ( .A(n6025), .B(n6026), .Z(n6024)); + AN2 U5791 ( .A(n6027), .B(n2998), .Z(n6026)); + AN2 U5792 ( .A(po079), .B(n6028), .Z(n6025)); + OR2 U5793 ( .A(n6029), .B(n4095), .Z(n6028)); + OR2 U5794 ( .A(n6030), .B(n6031), .Z(n4095)); + AN2 U5795 ( .A(n4098), .B(n2887), .Z(n6031)); + AN2 U5796 ( .A(n6032), .B(po031), .Z(n6030)); + AN2 U5797 ( .A(n2990), .B(n2974), .Z(n6032)); + AN2 U5798 ( .A(n2990), .B(n5169), .Z(n6029)); + OR2 U5799 ( .A(n6033), .B(po106), .Z(n2990)); + AN2 U5800 ( .A(n2837), .B(n5431), .Z(n6033)); + OR2 U5801 ( .A(n6034), .B(n6035), .Z(n6023)); + AN2 U5802 ( .A(n4099), .B(n6036), .Z(n6035)); + OR2 U5803 ( .A(n6037), .B(n6038), .Z(n6036)); + AN2 U5804 ( .A(n6039), .B(n5165), .Z(n6038)); + OR2 U5805 ( .A(n6040), .B(n5169), .Z(n6039)); + OR2 U5806 ( .A(n2978), .B(n2862), .Z(n5169)); + AN2 U5807 ( .A(po031), .B(n2974), .Z(n6040)); + AN2 U5808 ( .A(n6041), .B(n2974), .Z(n6037)); + AN2 U5809 ( .A(n5172), .B(n2957), .Z(n6041)); + AN2 U5810 ( .A(n2947), .B(n2837), .Z(n4099)); + AN2 U5811 ( .A(n6042), .B(n4098), .Z(n6034)); + AN2 U5812 ( .A(n2891), .B(pi192), .Z(n4098)); + IV2 U5813 ( .A(n2892), .Z(n2891)); + AN2 U5814 ( .A(n6043), .B(n3847), .Z(n6042)); + IV2 U5815 ( .A(n2885), .Z(n6043)); + AN2 U5816 ( .A(n5984), .B(n3076), .Z(n6009)); + IV2 U5817 ( .A(n3109), .Z(n3076)); + OR2 U5818 ( .A(po070), .B(n3205), .Z(n3109)); + IV2 U5819 ( .A(pi128), .Z(n3205)); + AN2 U5820 ( .A(n5985), .B(n6044), .Z(n6002)); + OR2 U5821 ( .A(n6045), .B(n6046), .Z(n5927)); + AN2 U5822 ( .A(n6047), .B(n3945), .Z(n6046)); + IV2 U5823 ( .A(n4313), .Z(n3945)); + OR2 U5824 ( .A(n3321), .B(n2837), .Z(n4313)); + AN2 U5825 ( .A(pi050), .B(n4975), .Z(n6047)); + AN2 U5826 ( .A(n6048), .B(n6049), .Z(n6045)); + AN2 U5827 ( .A(n6050), .B(n6051), .Z(n6049)); + OR2 U5828 ( .A(n3363), .B(n6052), .Z(n6051)); + OR2 U5829 ( .A(po027), .B(n3989), .Z(n6050)); + AN2 U5830 ( .A(n6053), .B(n4943), .Z(n6048)); + OR2 U5831 ( .A(n4239), .B(n4192), .Z(n4312)); + OR2 U5832 ( .A(n6054), .B(n6055), .Z(po003)); + OR2 U5833 ( .A(n6056), .B(n6057), .Z(n6055)); + AN2 U5834 ( .A(n6058), .B(pi054), .Z(n6057)); + OR2 U5835 ( .A(n6059), .B(n6060), .Z(n6058)); + AN2 U5836 ( .A(n4177), .B(n5126), .Z(n6060)); + AN2 U5837 ( .A(n5125), .B(n5898), .Z(n6059)); + AN2 U5838 ( .A(n6061), .B(n4129), .Z(n6056)); + AN2 U5839 ( .A(n4177), .B(n5125), .Z(n6061)); + OR2 U5840 ( .A(n6062), .B(n3257), .Z(n5125)); + OR2 U5841 ( .A(n5902), .B(n6063), .Z(n3257)); + OR2 U5842 ( .A(n6064), .B(n6065), .Z(n6063)); + AN2 U5843 ( .A(n4403), .B(n4319), .Z(n6065)); + IV2 U5844 ( .A(po004), .Z(n4319)); + OR2 U5845 ( .A(n6066), .B(n4380), .Z(n4403)); + AN2 U5846 ( .A(n6067), .B(n3259), .Z(n6066)); + AN2 U5847 ( .A(n4053), .B(n4013), .Z(n6067)); + OR2 U5848 ( .A(n6068), .B(n3265), .Z(n4053)); + AN2 U5849 ( .A(pi058), .B(n3261), .Z(n6068)); + AN2 U5850 ( .A(n6069), .B(n6070), .Z(n6064)); + AN2 U5851 ( .A(n4387), .B(n4013), .Z(n6070)); + IV2 U5852 ( .A(po040), .Z(n4013)); + AN2 U5853 ( .A(pi065), .B(n3259), .Z(n6069)); + OR2 U5854 ( .A(n6071), .B(n4379), .Z(n5902)); + IV2 U5855 ( .A(n4159), .Z(n4379)); + AN2 U5856 ( .A(n4380), .B(n4404), .Z(n6071)); + IV2 U5857 ( .A(n4161), .Z(n4404)); + IV2 U5858 ( .A(n4141), .Z(n4380)); + OR2 U5859 ( .A(n4016), .B(n6072), .Z(n4141)); + OR2 U5860 ( .A(n6073), .B(n6074), .Z(n6072)); + AN2 U5861 ( .A(n6075), .B(n4242), .Z(n6074)); + OR2 U5862 ( .A(n6076), .B(n6077), .Z(n4016)); + AN2 U5863 ( .A(n4040), .B(n3951), .Z(n6076)); + AN2 U5864 ( .A(n3259), .B(n6078), .Z(n6062)); + OR2 U5865 ( .A(n6079), .B(n3926), .Z(n6078)); + AN2 U5866 ( .A(n3264), .B(n4387), .Z(n6079)); + AN2 U5867 ( .A(n3261), .B(n4026), .Z(n4387)); + IV2 U5868 ( .A(n6080), .Z(n3264)); + OR2 U5869 ( .A(n6081), .B(n5919), .Z(n6080)); + AN2 U5870 ( .A(n4330), .B(n6082), .Z(n3259)); + AN2 U5871 ( .A(n4205), .B(n3314), .Z(n6082)); + IV2 U5872 ( .A(n5898), .Z(n4177)); + AN2 U5873 ( .A(n4172), .B(n5126), .Z(n6054)); + OR2 U5874 ( .A(n6083), .B(n6084), .Z(n5126)); + OR2 U5875 ( .A(n6085), .B(n6086), .Z(n6084)); + AN2 U5876 ( .A(n4227), .B(n4159), .Z(n6086)); + OR2 U5877 ( .A(po004), .B(n4161), .Z(n4159)); + OR2 U5878 ( .A(n4310), .B(n3321), .Z(n4161)); + OR2 U5879 ( .A(n6087), .B(n6088), .Z(n4227)); + OR2 U5880 ( .A(n6089), .B(n6077), .Z(n6088)); + OR2 U5881 ( .A(n6090), .B(n6091), .Z(n6077)); + OR2 U5882 ( .A(n3317), .B(n6092), .Z(n6091)); + AN2 U5883 ( .A(n4291), .B(n4056), .Z(n6092)); + AN2 U5884 ( .A(n3321), .B(po103), .Z(n3317)); + AN2 U5885 ( .A(n4040), .B(n3321), .Z(n6090)); + AN2 U5886 ( .A(n4192), .B(n6075), .Z(n6089)); + OR2 U5887 ( .A(n3321), .B(n6093), .Z(n6075)); + OR2 U5888 ( .A(n6073), .B(n6094), .Z(n6087)); + AN2 U5889 ( .A(n4040), .B(n4291), .Z(n6094)); + AN2 U5890 ( .A(po040), .B(n6095), .Z(n6073)); + OR2 U5891 ( .A(n4040), .B(n6096), .Z(n6095)); + OR2 U5892 ( .A(n3318), .B(n4293), .Z(n6096)); + OR2 U5893 ( .A(n3951), .B(n3321), .Z(n4293)); + AN2 U5894 ( .A(n4056), .B(n6097), .Z(n3318)); + AN2 U5895 ( .A(n4057), .B(pi192), .Z(n6097)); + IV2 U5896 ( .A(n4026), .Z(n4056)); + OR2 U5897 ( .A(pi058), .B(n3265), .Z(n4026)); + IV2 U5898 ( .A(n3314), .Z(n4040)); + OR2 U5899 ( .A(n6098), .B(n4201), .Z(n3314)); + IV2 U5900 ( .A(po091), .Z(n4201)); + AN2 U5901 ( .A(n3261), .B(n4200), .Z(n6098)); + AN2 U5902 ( .A(n6081), .B(pi192), .Z(n6085)); + AN2 U5903 ( .A(n4150), .B(po004), .Z(n6081)); + IV2 U5904 ( .A(pi065), .Z(n4150)); + OR2 U5905 ( .A(n6099), .B(n4396), .Z(n6083)); + AN2 U5906 ( .A(n4406), .B(n6100), .Z(n4396)); + OR2 U5907 ( .A(n6101), .B(n3321), .Z(n6100)); + AN2 U5908 ( .A(n6102), .B(n6103), .Z(n6101)); + AN2 U5909 ( .A(n4223), .B(n4057), .Z(n6103)); + AN2 U5910 ( .A(n4310), .B(n6104), .Z(n6102)); + OR2 U5911 ( .A(po040), .B(n5919), .Z(n6104)); + IV2 U5912 ( .A(pi204), .Z(n5919)); + IV2 U5913 ( .A(n4156), .Z(n4310)); + OR2 U5914 ( .A(pi065), .B(n2837), .Z(n4156)); + AN2 U5915 ( .A(po004), .B(n6105), .Z(n6099)); + OR2 U5916 ( .A(n6106), .B(n3321), .Z(n6105)); + AN2 U5917 ( .A(n4406), .B(n6093), .Z(n6106)); + OR2 U5918 ( .A(n6107), .B(n4028), .Z(n6093)); + AN2 U5919 ( .A(n4223), .B(n4291), .Z(n4028)); + AN2 U5920 ( .A(n4057), .B(n3951), .Z(n4291)); + IV2 U5921 ( .A(n4041), .Z(n3951)); + OR2 U5922 ( .A(pi204), .B(n2837), .Z(n4041)); + OR2 U5923 ( .A(po103), .B(n4316), .Z(n4223)); + IV2 U5924 ( .A(pi058), .Z(n4316)); + AN2 U5925 ( .A(po040), .B(n3322), .Z(n6107)); + OR2 U5926 ( .A(n4046), .B(n4045), .Z(n3322)); + OR2 U5927 ( .A(n6108), .B(n6109), .Z(n4045)); + AN2 U5928 ( .A(n4148), .B(n4057), .Z(n6109)); + OR2 U5929 ( .A(po091), .B(n3966), .Z(n4057)); + IV2 U5930 ( .A(pi129), .Z(n3966)); + AN2 U5931 ( .A(n4203), .B(po103), .Z(n6108)); + IV2 U5932 ( .A(n4200), .Z(n4203)); + OR2 U5933 ( .A(pi129), .B(n2837), .Z(n4200)); + AN2 U5934 ( .A(po103), .B(po091), .Z(n4046)); + AN2 U5935 ( .A(n5898), .B(n4129), .Z(n4172)); + IV2 U5936 ( .A(pi054), .Z(n4129)); + OR2 U5937 ( .A(n4167), .B(n4128), .Z(n5898)); + IV2 U5938 ( .A(po085), .Z(n4128)); + IV2 U5939 ( .A(pi052), .Z(n4167)); + AN2 U5940 ( .A(n6110), .B(n6111), .Z(po002)); + OR2 U5941 ( .A(n3306), .B(n4450), .Z(n6111)); + OR2 U5942 ( .A(n4458), .B(n4606), .Z(n6110)); + IV2 U5943 ( .A(n3306), .Z(n4458)); + OR2 U5944 ( .A(n6112), .B(n4652), .Z(n3306)); + OR2 U5945 ( .A(n6113), .B(n6114), .Z(n4652)); + AN2 U5946 ( .A(n6115), .B(n2837), .Z(n6114)); + OR2 U5947 ( .A(n6116), .B(n6117), .Z(n6115)); + AN2 U5948 ( .A(pi108), .B(n4881), .Z(n6117)); + AN2 U5949 ( .A(n4475), .B(n6118), .Z(n6116)); + OR2 U5950 ( .A(n5467), .B(n6119), .Z(n6118)); + IV2 U5951 ( .A(n5488), .Z(n6119)); + OR2 U5952 ( .A(po102), .B(n5322), .Z(n5488)); + IV2 U5953 ( .A(pi114), .Z(n5322)); + AN2 U5954 ( .A(n6120), .B(n6121), .Z(n5467)); + OR2 U5955 ( .A(pi114), .B(n4885), .Z(n6120)); + AN2 U5956 ( .A(pi192), .B(n6122), .Z(n6113)); + OR2 U5957 ( .A(n6123), .B(n6124), .Z(n6122)); + AN2 U5958 ( .A(pi148), .B(n4881), .Z(n6124)); + AN2 U5959 ( .A(n4475), .B(n6125), .Z(n6123)); + OR2 U5960 ( .A(n5466), .B(n6126), .Z(n6125)); + IV2 U5961 ( .A(n5491), .Z(n6126)); + OR2 U5962 ( .A(po102), .B(n3901), .Z(n5491)); + IV2 U5963 ( .A(pi069), .Z(n3901)); + AN2 U5964 ( .A(n6127), .B(n6128), .Z(n5466)); + OR2 U5965 ( .A(pi069), .B(n4885), .Z(n6127)); + AN2 U5966 ( .A(n5461), .B(n4475), .Z(n6112)); + AN2 U5967 ( .A(n4087), .B(n6129), .Z(n5461)); + AN2 U5968 ( .A(n6130), .B(n4341), .Z(n6129)); + IV2 U5969 ( .A(n5474), .Z(n6130)); + AN2 U5970 ( .A(n6131), .B(po102), .Z(n5474)); + AN2 U5971 ( .A(n4334), .B(n4333), .Z(n4087)); + OR2 U5972 ( .A(n6132), .B(n4656), .Z(n4334)); + OR2 U5973 ( .A(n6133), .B(n6134), .Z(n4656)); + AN2 U5974 ( .A(n5074), .B(n3083), .Z(n6133)); + AN2 U5975 ( .A(n6135), .B(n3083), .Z(n6132)); + AN2 U5976 ( .A(n3018), .B(n4326), .Z(n6135)); + OR2 U5977 ( .A(n6136), .B(n5077), .Z(n4326)); + OR2 U5978 ( .A(n6137), .B(n3100), .Z(n5077)); + AN2 U5979 ( .A(n3280), .B(n4666), .Z(n6137)); + OR2 U5980 ( .A(n3286), .B(n6138), .Z(n4666)); + AN2 U5981 ( .A(n5829), .B(n3049), .Z(n3280)); + AN2 U5982 ( .A(n6139), .B(n3284), .Z(n6136)); + OR2 U5983 ( .A(n3049), .B(n5829), .Z(n3284)); + OR2 U5984 ( .A(n6140), .B(n3287), .Z(n6139)); + OR2 U5985 ( .A(n6141), .B(n6142), .Z(n3287)); + AN2 U5986 ( .A(pi141), .B(n3173), .Z(n6141)); + AN2 U5987 ( .A(n6143), .B(n3286), .Z(n6140)); + OR2 U5988 ( .A(n3173), .B(n3064), .Z(n6143)); + OR2 U5989 ( .A(n6144), .B(n6145), .Z(po000)); + AN2 U5990 ( .A(n6146), .B(po103), .Z(n6145)); + OR2 U5991 ( .A(n6147), .B(n6148), .Z(n6146)); + AN2 U5992 ( .A(n6149), .B(n3326), .Z(n6148)); + AN2 U5993 ( .A(n4217), .B(n3320), .Z(n6147)); + AN2 U5994 ( .A(n6150), .B(n3265), .Z(n6144)); + IV2 U5995 ( .A(po103), .Z(n3265)); + OR2 U5996 ( .A(n6151), .B(n6152), .Z(n6150)); + AN2 U5997 ( .A(n6149), .B(n3320), .Z(n6152)); + OR2 U5998 ( .A(n4406), .B(n4192), .Z(n3320)); + IV2 U5999 ( .A(n4205), .Z(n4192)); + AN2 U6000 ( .A(n4242), .B(n4331), .Z(n4406)); + IV2 U6001 ( .A(n4330), .Z(n4331)); + AN2 U6002 ( .A(n4217), .B(n3326), .Z(n6151)); + OR2 U6003 ( .A(n6153), .B(n4239), .Z(n3326)); + IV2 U6004 ( .A(n4242), .Z(n4239)); + OR2 U6005 ( .A(po028), .B(n6154), .Z(n4242)); + AN2 U6006 ( .A(n6155), .B(n6156), .Z(n6154)); + OR2 U6007 ( .A(n3321), .B(n3969), .Z(n6156)); + IV2 U6008 ( .A(pi169), .Z(n3969)); + AN2 U6009 ( .A(n4330), .B(n4205), .Z(n6153)); + OR2 U6010 ( .A(n6157), .B(n5056), .Z(n4205)); + IV2 U6011 ( .A(po028), .Z(n5056)); + AN2 U6012 ( .A(n3261), .B(n6158), .Z(n6157)); + OR2 U6013 ( .A(pi169), .B(n2837), .Z(n6158)); + OR2 U6014 ( .A(n6159), .B(n6160), .Z(n4330)); + OR2 U6015 ( .A(n6161), .B(n5930), .Z(n6160)); + OR2 U6016 ( .A(n6162), .B(n6163), .Z(n5930)); + OR2 U6017 ( .A(n6164), .B(n6165), .Z(n6163)); + AN2 U6018 ( .A(n3393), .B(n6166), .Z(n6165)); + OR2 U6019 ( .A(n6167), .B(n5853), .Z(n6166)); + AN2 U6020 ( .A(n6168), .B(n3371), .Z(n6167)); + IV2 U6021 ( .A(n3412), .Z(n3371)); + AN2 U6022 ( .A(n5999), .B(n6053), .Z(n6164)); + AN2 U6023 ( .A(n3453), .B(n3363), .Z(n5999)); + AN2 U6024 ( .A(n3926), .B(n4975), .Z(n6162)); + AN2 U6025 ( .A(n3940), .B(n4975), .Z(n6161)); + OR2 U6026 ( .A(n6169), .B(n6170), .Z(n6159)); + AN2 U6027 ( .A(n5931), .B(n6171), .Z(n6170)); + OR2 U6028 ( .A(n6172), .B(n6173), .Z(n6171)); + OR2 U6029 ( .A(n6174), .B(n6175), .Z(n6173)); + AN2 U6030 ( .A(n5888), .B(n3363), .Z(n6175)); + OR2 U6031 ( .A(n6176), .B(n6177), .Z(n5888)); + OR2 U6032 ( .A(n3248), .B(n6178), .Z(n6177)); + AN2 U6033 ( .A(n5833), .B(n3250), .Z(n6178)); + AN2 U6034 ( .A(n4937), .B(n6179), .Z(n5833)); + OR2 U6035 ( .A(n6180), .B(n6181), .Z(n6176)); + AN2 U6036 ( .A(n3495), .B(n5835), .Z(n6181)); + OR2 U6037 ( .A(n6182), .B(n5894), .Z(n5835)); + AN2 U6038 ( .A(n5966), .B(n6183), .Z(n6182)); + OR2 U6039 ( .A(n6184), .B(n6185), .Z(n5966)); + AN2 U6040 ( .A(pi171), .B(pi192), .Z(n6185)); + AN2 U6041 ( .A(pi142), .B(n2837), .Z(n6184)); + AN2 U6042 ( .A(n6186), .B(n5836), .Z(n6180)); + OR2 U6043 ( .A(n6187), .B(n6188), .Z(n5836)); + AN2 U6044 ( .A(n3705), .B(n5843), .Z(n6188)); + AN2 U6045 ( .A(pi192), .B(pi098), .Z(n3705)); + AN2 U6046 ( .A(n3717), .B(n6189), .Z(n6187)); + AN2 U6047 ( .A(n2837), .B(pi003), .Z(n3717)); + AN2 U6048 ( .A(n5889), .B(n3534), .Z(n6174)); + AN2 U6049 ( .A(n3261), .B(pi060), .Z(n3534)); + AN2 U6050 ( .A(pi192), .B(n6190), .Z(n5889)); + OR2 U6051 ( .A(n6191), .B(n6192), .Z(n6190)); + OR2 U6052 ( .A(n6193), .B(n6194), .Z(n6192)); + AN2 U6053 ( .A(pi004), .B(n4947), .Z(n6194)); + AN2 U6054 ( .A(n3640), .B(n3250), .Z(n6193)); + IV2 U6055 ( .A(n3344), .Z(n3250)); + IV2 U6056 ( .A(n3632), .Z(n3640)); + OR2 U6057 ( .A(po001), .B(n3998), .Z(n3632)); + OR2 U6058 ( .A(n6195), .B(n6196), .Z(n6191)); + AN2 U6059 ( .A(n6197), .B(n3495), .Z(n6196)); + AN2 U6060 ( .A(pi171), .B(n6183), .Z(n6197)); + AN2 U6061 ( .A(n6198), .B(n6186), .Z(n6195)); + IV2 U6062 ( .A(n6199), .Z(n6186)); + AN2 U6063 ( .A(pi098), .B(n5843), .Z(n6198)); + OR2 U6064 ( .A(pi171), .B(n4441), .Z(n5843)); + OR2 U6065 ( .A(n5892), .B(n6200), .Z(n6172)); + AN2 U6066 ( .A(n6201), .B(n5894), .Z(n6200)); + AN2 U6067 ( .A(n4441), .B(n4417), .Z(n5894)); + AN2 U6068 ( .A(n3495), .B(n3453), .Z(n6201)); + IV2 U6069 ( .A(n3451), .Z(n3453)); + OR2 U6070 ( .A(n3533), .B(n3321), .Z(n3451)); + IV2 U6071 ( .A(n3477), .Z(n3533)); + OR2 U6072 ( .A(pi060), .B(n2837), .Z(n3477)); + IV2 U6073 ( .A(n6202), .Z(n3495)); + IV2 U6074 ( .A(n6203), .Z(n5892)); + OR2 U6075 ( .A(n6204), .B(n6155), .Z(n6203)); + AN2 U6076 ( .A(n6205), .B(n6206), .Z(n6204)); + AN2 U6077 ( .A(n6207), .B(n6208), .Z(n6206)); + OR2 U6078 ( .A(n6199), .B(n6209), .Z(n6208)); + OR2 U6079 ( .A(n3244), .B(n3597), .Z(n6209)); + IV2 U6080 ( .A(pi003), .Z(n3597)); + IV2 U6081 ( .A(n6189), .Z(n3244)); + OR2 U6082 ( .A(pi142), .B(n4441), .Z(n6189)); + OR2 U6083 ( .A(n4418), .B(n6202), .Z(n6199)); + IV2 U6084 ( .A(n4426), .Z(n4418)); + OR2 U6085 ( .A(n3688), .B(n3290), .Z(n4426)); + IV2 U6086 ( .A(po011), .Z(n3688)); + OR2 U6087 ( .A(n6202), .B(n6210), .Z(n6207)); + OR2 U6088 ( .A(n4430), .B(n4440), .Z(n6210)); + IV2 U6089 ( .A(pi142), .Z(n4440)); + IV2 U6090 ( .A(n6183), .Z(n4430)); + OR2 U6091 ( .A(n4417), .B(n4441), .Z(n6183)); + IV2 U6092 ( .A(po036), .Z(n4441)); + IV2 U6093 ( .A(n3236), .Z(n4417)); + OR2 U6094 ( .A(n3234), .B(po011), .Z(n3236)); + IV2 U6095 ( .A(n3290), .Z(n3234)); + OR2 U6096 ( .A(n6211), .B(n6212), .Z(n3290)); + OR2 U6097 ( .A(n6213), .B(n6214), .Z(n6212)); + OR2 U6098 ( .A(n6215), .B(n6216), .Z(n6214)); + AN2 U6099 ( .A(pi192), .B(n5980), .Z(n6216)); + OR2 U6100 ( .A(n6217), .B(n6218), .Z(n5980)); + OR2 U6101 ( .A(n6219), .B(n6220), .Z(n6218)); + AN2 U6102 ( .A(pi045), .B(n4915), .Z(n6220)); + AN2 U6103 ( .A(n4621), .B(n4751), .Z(n6219)); + IV2 U6104 ( .A(n4465), .Z(n4621)); + OR2 U6105 ( .A(po014), .B(n3908), .Z(n4465)); + IV2 U6106 ( .A(pi079), .Z(n3908)); + OR2 U6107 ( .A(n6221), .B(n6222), .Z(n6217)); + AN2 U6108 ( .A(n6223), .B(n3757), .Z(n6222)); + AN2 U6109 ( .A(pi158), .B(n4628), .Z(n6223)); + AN2 U6110 ( .A(n6224), .B(n6225), .Z(n6221)); + AN2 U6111 ( .A(pi175), .B(n5037), .Z(n6224)); + AN2 U6112 ( .A(n6008), .B(n2837), .Z(n6215)); + OR2 U6113 ( .A(n6226), .B(n6227), .Z(n6008)); + OR2 U6114 ( .A(n6228), .B(n6229), .Z(n6227)); + AN2 U6115 ( .A(pi095), .B(n4915), .Z(n6229)); + AN2 U6116 ( .A(n4623), .B(n4751), .Z(n6228)); + IV2 U6117 ( .A(n4469), .Z(n4623)); + OR2 U6118 ( .A(po014), .B(n4648), .Z(n4469)); + IV2 U6119 ( .A(pi156), .Z(n4648)); + OR2 U6120 ( .A(n6230), .B(n6231), .Z(n6226)); + AN2 U6121 ( .A(n6232), .B(n3757), .Z(n6231)); + AN2 U6122 ( .A(pi151), .B(n4628), .Z(n6232)); + AN2 U6123 ( .A(n6233), .B(n6225), .Z(n6230)); + AN2 U6124 ( .A(pi185), .B(n5037), .Z(n6233)); + AN2 U6125 ( .A(n5985), .B(n6234), .Z(n6213)); + OR2 U6126 ( .A(n6235), .B(n6236), .Z(n6234)); + OR2 U6127 ( .A(n6237), .B(n6238), .Z(n6236)); + OR2 U6128 ( .A(n6239), .B(n6240), .Z(n6238)); + AN2 U6129 ( .A(n6241), .B(n3055), .Z(n6240)); + AN2 U6130 ( .A(n5822), .B(n3119), .Z(n6241)); + OR2 U6131 ( .A(n6242), .B(n6016), .Z(n3119)); + AN2 U6132 ( .A(pi141), .B(po099), .Z(n6242)); + AN2 U6133 ( .A(n5994), .B(n6243), .Z(n6239)); + AN2 U6134 ( .A(n6244), .B(n3049), .Z(n6237)); + OR2 U6135 ( .A(n6243), .B(n6245), .Z(n6244)); + OR2 U6136 ( .A(n6020), .B(n6246), .Z(n6245)); + AN2 U6137 ( .A(n6247), .B(n5826), .Z(n6246)); + AN2 U6138 ( .A(n3106), .B(n5829), .Z(n5826)); + OR2 U6139 ( .A(n5994), .B(n5822), .Z(n5829)); + IV2 U6140 ( .A(pi166), .Z(n3106)); + AN2 U6141 ( .A(n3063), .B(pi192), .Z(n6247)); + AN2 U6142 ( .A(n6016), .B(n5994), .Z(n6020)); + AN2 U6143 ( .A(n3286), .B(n3177), .Z(n6016)); + OR2 U6144 ( .A(n6142), .B(n6248), .Z(n6243)); + AN2 U6145 ( .A(n3207), .B(n3286), .Z(n6248)); + OR2 U6146 ( .A(n6249), .B(n6250), .Z(n3207)); + AN2 U6147 ( .A(n3064), .B(n3171), .Z(n6250)); + AN2 U6148 ( .A(n3173), .B(n3177), .Z(n6249)); + IV2 U6149 ( .A(pi141), .Z(n3177)); + AN2 U6150 ( .A(pi033), .B(n3064), .Z(n6142)); + OR2 U6151 ( .A(n6251), .B(n6252), .Z(n6235)); + OR2 U6152 ( .A(n6044), .B(n3100), .Z(n6252)); + AN2 U6153 ( .A(n3286), .B(n6138), .Z(n3100)); + OR2 U6154 ( .A(n6253), .B(n6254), .Z(n6138)); + AN2 U6155 ( .A(pi033), .B(pi192), .Z(n6254)); + AN2 U6156 ( .A(pi141), .B(n2837), .Z(n6253)); + AN2 U6157 ( .A(n6255), .B(pi141), .Z(n6044)); + OR2 U6158 ( .A(n3071), .B(n6256), .Z(n6255)); + AN2 U6159 ( .A(n3055), .B(n5994), .Z(n6256)); + IV2 U6160 ( .A(n6257), .Z(n5994)); + OR2 U6161 ( .A(n2925), .B(n5099), .Z(n6257)); + OR2 U6162 ( .A(n6258), .B(n6259), .Z(n5099)); + OR2 U6163 ( .A(n3146), .B(n6260), .Z(n6259)); + OR2 U6164 ( .A(n6261), .B(n6262), .Z(n6260)); + AN2 U6165 ( .A(n2845), .B(n2837), .Z(n6262)); + IV2 U6166 ( .A(n2846), .Z(n2845)); + AN2 U6167 ( .A(n6263), .B(n6264), .Z(n2846)); + OR2 U6168 ( .A(n3141), .B(po044), .Z(n6263)); + IV2 U6169 ( .A(pi201), .Z(n3141)); + AN2 U6170 ( .A(pi192), .B(n2833), .Z(n6261)); + IV2 U6171 ( .A(n2834), .Z(n2833)); + AN2 U6172 ( .A(n6265), .B(n6266), .Z(n2834)); + OR2 U6173 ( .A(n3136), .B(po044), .Z(n6265)); + IV2 U6174 ( .A(pi088), .Z(n3136)); + OR2 U6175 ( .A(n6267), .B(n6268), .Z(n3146)); + AN2 U6176 ( .A(n2880), .B(pi192), .Z(n6268)); + IV2 U6177 ( .A(n2878), .Z(n2880)); + OR2 U6178 ( .A(pi077), .B(n2962), .Z(n2878)); + AN2 U6179 ( .A(n2978), .B(n2837), .Z(n6267)); + IV2 U6180 ( .A(n2939), .Z(n2978)); + OR2 U6181 ( .A(n2998), .B(n6269), .Z(n6258)); + OR2 U6182 ( .A(n2901), .B(n2862), .Z(n6269)); + IV2 U6183 ( .A(pi200), .Z(n2901)); + IV2 U6184 ( .A(n3003), .Z(n2925)); + OR2 U6185 ( .A(pi192), .B(n2960), .Z(n3003)); + IV2 U6186 ( .A(n6270), .Z(n2960)); + OR2 U6187 ( .A(n6271), .B(n6272), .Z(n6270)); + AN2 U6188 ( .A(pi081), .B(n2931), .Z(n6272)); + IV2 U6189 ( .A(po107), .Z(n2931)); + AN2 U6190 ( .A(po107), .B(n2982), .Z(n6271)); + AN2 U6191 ( .A(n2837), .B(n6017), .Z(n3055)); + IV2 U6192 ( .A(n5828), .Z(n6017)); + OR2 U6193 ( .A(n6273), .B(n6015), .Z(n5828)); + AN2 U6194 ( .A(pi174), .B(n3049), .Z(n6015)); + AN2 U6195 ( .A(po010), .B(n5115), .Z(n6273)); + IV2 U6196 ( .A(pi174), .Z(n5115)); + AN2 U6197 ( .A(n3049), .B(n3173), .Z(n3071)); + AN2 U6198 ( .A(n2837), .B(pi174), .Z(n3173)); + IV2 U6199 ( .A(po010), .Z(n3049)); + AN2 U6200 ( .A(n6274), .B(n3063), .Z(n6251)); + IV2 U6201 ( .A(n6275), .Z(n3063)); + OR2 U6202 ( .A(n6276), .B(n6277), .Z(n6275)); + AN2 U6203 ( .A(pi033), .B(n3286), .Z(n6277)); + IV2 U6204 ( .A(po099), .Z(n3286)); + AN2 U6205 ( .A(po099), .B(n3171), .Z(n6276)); + IV2 U6206 ( .A(pi033), .Z(n3171)); + AN2 U6207 ( .A(n3064), .B(n5822), .Z(n6274)); + OR2 U6208 ( .A(n6278), .B(n6279), .Z(n5822)); + OR2 U6209 ( .A(n6280), .B(n6281), .Z(n6279)); + AN2 U6210 ( .A(n6282), .B(pi192), .Z(n6281)); + AN2 U6211 ( .A(n5156), .B(n6266), .Z(n6282)); + OR2 U6212 ( .A(pi088), .B(n5000), .Z(n6266)); + OR2 U6213 ( .A(n6283), .B(n5153), .Z(n5156)); + AN2 U6214 ( .A(n2861), .B(n6284), .Z(n6283)); + OR2 U6215 ( .A(n2885), .B(n2892), .Z(n6284)); + AN2 U6216 ( .A(n5008), .B(pi157), .Z(n2892)); + AN2 U6217 ( .A(n2930), .B(n2876), .Z(n2885)); + IV2 U6218 ( .A(n2887), .Z(n2876)); + OR2 U6219 ( .A(po031), .B(n3846), .Z(n2887)); + IV2 U6220 ( .A(pi077), .Z(n3846)); + AN2 U6221 ( .A(n6285), .B(n2837), .Z(n6280)); + AN2 U6222 ( .A(n5175), .B(n6264), .Z(n6285)); + OR2 U6223 ( .A(pi201), .B(n5000), .Z(n6264)); + OR2 U6224 ( .A(n6286), .B(n6287), .Z(n5175)); + AN2 U6225 ( .A(n2861), .B(n6288), .Z(n6286)); + OR2 U6226 ( .A(n6289), .B(n2929), .Z(n6288)); + IV2 U6227 ( .A(n2947), .Z(n2929)); + OR2 U6228 ( .A(po106), .B(n5431), .Z(n2947)); + IV2 U6229 ( .A(pi206), .Z(n5431)); + AN2 U6230 ( .A(n2930), .B(n4113), .Z(n6289)); + OR2 U6231 ( .A(n2919), .B(n2936), .Z(n4113)); + IV2 U6232 ( .A(n2946), .Z(n2936)); + OR2 U6233 ( .A(po031), .B(n2957), .Z(n2946)); + IV2 U6234 ( .A(pi082), .Z(n2957)); + AN2 U6235 ( .A(n2902), .B(n2939), .Z(n2919)); + OR2 U6236 ( .A(pi082), .B(n2962), .Z(n2939)); + IV2 U6237 ( .A(po031), .Z(n2962)); + IV2 U6238 ( .A(n2974), .Z(n2902)); + OR2 U6239 ( .A(po107), .B(n2982), .Z(n2974)); + IV2 U6240 ( .A(pi081), .Z(n2982)); + IV2 U6241 ( .A(n2862), .Z(n2930)); + OR2 U6242 ( .A(n6290), .B(n6291), .Z(n2862)); + AN2 U6243 ( .A(n6292), .B(n5008), .Z(n6291)); + IV2 U6244 ( .A(po106), .Z(n5008)); + AN2 U6245 ( .A(n6293), .B(po106), .Z(n6290)); + IV2 U6246 ( .A(n6292), .Z(n6293)); + OR2 U6247 ( .A(n6294), .B(n6295), .Z(n6292)); + AN2 U6248 ( .A(pi192), .B(pi157), .Z(n6295)); + AN2 U6249 ( .A(pi206), .B(n2837), .Z(n6294)); + IV2 U6250 ( .A(n2998), .Z(n2861)); + OR2 U6251 ( .A(n6296), .B(n6297), .Z(n2998)); + OR2 U6252 ( .A(n6298), .B(n6299), .Z(n6297)); + AN2 U6253 ( .A(n5153), .B(pi192), .Z(n6299)); + AN2 U6254 ( .A(n5004), .B(pi026), .Z(n5153)); + IV2 U6255 ( .A(po079), .Z(n5004)); + AN2 U6256 ( .A(n6287), .B(n2837), .Z(n6298)); + IV2 U6257 ( .A(n5172), .Z(n6287)); + OR2 U6258 ( .A(po079), .B(n5165), .Z(n5172)); + AN2 U6259 ( .A(po079), .B(n6027), .Z(n6296)); + OR2 U6260 ( .A(n6300), .B(n6301), .Z(n6027)); + AN2 U6261 ( .A(pi192), .B(n3847), .Z(n6301)); + IV2 U6262 ( .A(pi026), .Z(n3847)); + AN2 U6263 ( .A(n5165), .B(n2837), .Z(n6300)); + IV2 U6264 ( .A(pi107), .Z(n5165)); + AN2 U6265 ( .A(n3011), .B(n5000), .Z(n6278)); + IV2 U6266 ( .A(po044), .Z(n5000)); + OR2 U6267 ( .A(n6302), .B(n6303), .Z(n3011)); + AN2 U6268 ( .A(pi088), .B(pi192), .Z(n6303)); + AN2 U6269 ( .A(pi201), .B(n2837), .Z(n6302)); + AN2 U6270 ( .A(pi192), .B(pi166), .Z(n3064)); + AN2 U6271 ( .A(n3018), .B(n5984), .Z(n5985)); + AN2 U6272 ( .A(n6304), .B(n5104), .Z(n3018)); + IV2 U6273 ( .A(n5074), .Z(n5104)); + OR2 U6274 ( .A(n6305), .B(n5040), .Z(n6304)); + OR2 U6275 ( .A(n6306), .B(n6307), .Z(n6211)); + OR2 U6276 ( .A(n6308), .B(n6309), .Z(n6307)); + AN2 U6277 ( .A(n4624), .B(n5981), .Z(n6309)); + AN2 U6278 ( .A(n3300), .B(n3305), .Z(n4624)); + AN2 U6279 ( .A(n5984), .B(n5074), .Z(n6308)); + AN2 U6280 ( .A(n5040), .B(n6305), .Z(n5074)); + OR2 U6281 ( .A(n6310), .B(n6311), .Z(n6305)); + AN2 U6282 ( .A(pi096), .B(pi192), .Z(n6311)); + AN2 U6283 ( .A(pi128), .B(n2837), .Z(n6310)); + IV2 U6284 ( .A(po070), .Z(n5040)); + AN2 U6285 ( .A(n3083), .B(n6225), .Z(n5984)); + AN2 U6286 ( .A(n6312), .B(n6313), .Z(n6225)); + AN2 U6287 ( .A(n3760), .B(n4341), .Z(n6313)); + AN2 U6288 ( .A(n4333), .B(n4482), .Z(n6312)); + OR2 U6289 ( .A(n6314), .B(n6315), .Z(n4333)); + AN2 U6290 ( .A(po025), .B(n6316), .Z(n6315)); + OR2 U6291 ( .A(n6317), .B(n3888), .Z(n6316)); + AN2 U6292 ( .A(pi192), .B(pi191), .Z(n3888)); + AN2 U6293 ( .A(pi076), .B(n2837), .Z(n6317)); + AN2 U6294 ( .A(n3781), .B(n4557), .Z(n6314)); + OR2 U6295 ( .A(n4538), .B(n3890), .Z(n3781)); + IV2 U6296 ( .A(n6318), .Z(n3890)); + OR2 U6297 ( .A(pi191), .B(n2837), .Z(n6318)); + AN2 U6298 ( .A(n4077), .B(n2837), .Z(n4538)); + IV2 U6299 ( .A(n3021), .Z(n3083)); + OR2 U6300 ( .A(n6319), .B(n6134), .Z(n3021)); + AN2 U6301 ( .A(n6320), .B(n5037), .Z(n6134)); + IV2 U6302 ( .A(po035), .Z(n5037)); + AN2 U6303 ( .A(n6321), .B(po035), .Z(n6319)); + IV2 U6304 ( .A(n6320), .Z(n6321)); + OR2 U6305 ( .A(n6322), .B(n6323), .Z(n6320)); + AN2 U6306 ( .A(pi175), .B(pi192), .Z(n6323)); + AN2 U6307 ( .A(pi185), .B(n2837), .Z(n6322)); + AN2 U6308 ( .A(n3760), .B(n6324), .Z(n6306)); + OR2 U6309 ( .A(n6325), .B(n6326), .Z(n6324)); + OR2 U6310 ( .A(n6327), .B(n6328), .Z(n6326)); + AN2 U6311 ( .A(n4482), .B(n4340), .Z(n6328)); + OR2 U6312 ( .A(n6329), .B(n6330), .Z(n4340)); + AN2 U6313 ( .A(n6121), .B(n2837), .Z(n6330)); + OR2 U6314 ( .A(n6331), .B(n4567), .Z(n6121)); + IV2 U6315 ( .A(n4578), .Z(n4567)); + OR2 U6316 ( .A(po024), .B(n4358), .Z(n4578)); + AN2 U6317 ( .A(n4084), .B(n4066), .Z(n6331)); + OR2 U6318 ( .A(n6332), .B(n4539), .Z(n4084)); + IV2 U6319 ( .A(n5503), .Z(n4539)); + OR2 U6320 ( .A(po059), .B(n4074), .Z(n5503)); + IV2 U6321 ( .A(pi170), .Z(n4074)); + AN2 U6322 ( .A(n4576), .B(n3778), .Z(n6332)); + IV2 U6323 ( .A(n4580), .Z(n4576)); + OR2 U6324 ( .A(po025), .B(n4077), .Z(n4580)); + IV2 U6325 ( .A(pi076), .Z(n4077)); + AN2 U6326 ( .A(pi192), .B(n6128), .Z(n6329)); + OR2 U6327 ( .A(n6333), .B(n6334), .Z(n6128)); + OR2 U6328 ( .A(n4561), .B(n6335), .Z(n6334)); + AN2 U6329 ( .A(n6336), .B(n4341), .Z(n6335)); + AN2 U6330 ( .A(n4066), .B(n3778), .Z(n4341)); + IV2 U6331 ( .A(n3773), .Z(n3778)); + OR2 U6332 ( .A(n6337), .B(n6338), .Z(n3773)); + AN2 U6333 ( .A(n6339), .B(n4877), .Z(n6338)); + IV2 U6334 ( .A(po059), .Z(n4877)); + AN2 U6335 ( .A(n6340), .B(po059), .Z(n6337)); + IV2 U6336 ( .A(n6339), .Z(n6340)); + OR2 U6337 ( .A(n6341), .B(n6342), .Z(n6339)); + AN2 U6338 ( .A(pi135), .B(pi192), .Z(n6342)); + AN2 U6339 ( .A(pi170), .B(n2837), .Z(n6341)); + AN2 U6340 ( .A(pi191), .B(n4557), .Z(n6336)); + IV2 U6341 ( .A(po025), .Z(n4557)); + IV2 U6342 ( .A(n4348), .Z(n4561)); + OR2 U6343 ( .A(po024), .B(n3896), .Z(n4348)); + AN2 U6344 ( .A(n4085), .B(n4066), .Z(n6333)); + OR2 U6345 ( .A(n6343), .B(n6344), .Z(n4066)); + OR2 U6346 ( .A(n6345), .B(n6346), .Z(n6344)); + AN2 U6347 ( .A(n6347), .B(po024), .Z(n6346)); + AN2 U6348 ( .A(pi005), .B(pi192), .Z(n6347)); + AN2 U6349 ( .A(n6348), .B(n4874), .Z(n6345)); + IV2 U6350 ( .A(po024), .Z(n4874)); + OR2 U6351 ( .A(n6349), .B(n5483), .Z(n6348)); + AN2 U6352 ( .A(pi192), .B(n3896), .Z(n5483)); + IV2 U6353 ( .A(pi005), .Z(n3896)); + AN2 U6354 ( .A(n4358), .B(n2837), .Z(n6349)); + IV2 U6355 ( .A(pi160), .Z(n4358)); + AN2 U6356 ( .A(pi160), .B(n5477), .Z(n6343)); + AN2 U6357 ( .A(n2837), .B(po024), .Z(n5477)); + IV2 U6358 ( .A(n4353), .Z(n4085)); + OR2 U6359 ( .A(po059), .B(n3880), .Z(n4353)); + IV2 U6360 ( .A(pi135), .Z(n3880)); + AN2 U6361 ( .A(n4342), .B(n4475), .Z(n4482)); + AN2 U6362 ( .A(n6350), .B(n6351), .Z(n4342)); + OR2 U6363 ( .A(n6131), .B(po102), .Z(n6351)); + IV2 U6364 ( .A(n6352), .Z(n6131)); + OR2 U6365 ( .A(n6352), .B(n4885), .Z(n6350)); + AN2 U6366 ( .A(n5462), .B(n4475), .Z(n6327)); + IV2 U6367 ( .A(n4478), .Z(n4475)); + OR2 U6368 ( .A(n6353), .B(n6325), .Z(n4478)); + AN2 U6369 ( .A(n6354), .B(po072), .Z(n6353)); + IV2 U6370 ( .A(n6355), .Z(n6354)); + AN2 U6371 ( .A(n6352), .B(n4885), .Z(n5462)); + IV2 U6372 ( .A(po102), .Z(n4885)); + OR2 U6373 ( .A(n6356), .B(n6357), .Z(n6352)); + AN2 U6374 ( .A(pi069), .B(pi192), .Z(n6357)); + AN2 U6375 ( .A(pi114), .B(n2837), .Z(n6356)); + AN2 U6376 ( .A(n6355), .B(n4881), .Z(n6325)); + IV2 U6377 ( .A(po072), .Z(n4881)); + OR2 U6378 ( .A(n6358), .B(n6359), .Z(n6355)); + AN2 U6379 ( .A(pi148), .B(pi192), .Z(n6359)); + AN2 U6380 ( .A(pi108), .B(n2837), .Z(n6358)); + AN2 U6381 ( .A(n4450), .B(n5981), .Z(n3760)); + AN2 U6382 ( .A(n3301), .B(n4751), .Z(n5981)); + AN2 U6383 ( .A(n4006), .B(n3757), .Z(n4751)); + IV2 U6384 ( .A(n4444), .Z(n3757)); + OR2 U6385 ( .A(n6360), .B(n3754), .Z(n4444)); + AN2 U6386 ( .A(n6361), .B(n4915), .Z(n3754)); + IV2 U6387 ( .A(po063), .Z(n4915)); + AN2 U6388 ( .A(n6362), .B(po063), .Z(n6360)); + IV2 U6389 ( .A(n6361), .Z(n6362)); + OR2 U6390 ( .A(n6363), .B(n6364), .Z(n6361)); + AN2 U6391 ( .A(pi045), .B(pi192), .Z(n6364)); + AN2 U6392 ( .A(pi095), .B(n2837), .Z(n6363)); + AN2 U6393 ( .A(n6365), .B(n6366), .Z(n4006)); + OR2 U6394 ( .A(n6367), .B(po092), .Z(n6366)); + IV2 U6395 ( .A(n4752), .Z(n6367)); + OR2 U6396 ( .A(n4752), .B(n4628), .Z(n6365)); + IV2 U6397 ( .A(po092), .Z(n4628)); + OR2 U6398 ( .A(n6368), .B(n6369), .Z(n4752)); + AN2 U6399 ( .A(pi158), .B(pi192), .Z(n6369)); + AN2 U6400 ( .A(pi151), .B(n2837), .Z(n6368)); + IV2 U6401 ( .A(n3295), .Z(n3301)); + OR2 U6402 ( .A(n6370), .B(n6371), .Z(n3295)); + AN2 U6403 ( .A(n4703), .B(n4861), .Z(n6371)); + IV2 U6404 ( .A(po014), .Z(n4861)); + AN2 U6405 ( .A(n4736), .B(po014), .Z(n6370)); + IV2 U6406 ( .A(n4703), .Z(n4736)); + OR2 U6407 ( .A(n6372), .B(n6373), .Z(n4703)); + AN2 U6408 ( .A(pi079), .B(pi192), .Z(n6373)); + AN2 U6409 ( .A(pi156), .B(n2837), .Z(n6372)); + IV2 U6410 ( .A(n4606), .Z(n4450)); + AN2 U6411 ( .A(n6374), .B(n6375), .Z(n4606)); + OR2 U6412 ( .A(n3305), .B(po039), .Z(n6375)); + OR2 U6413 ( .A(n3300), .B(n6376), .Z(n6374)); + IV2 U6414 ( .A(n3305), .Z(n6376)); + OR2 U6415 ( .A(n4685), .B(n4692), .Z(n3305)); + AN2 U6416 ( .A(pi192), .B(pi016), .Z(n4692)); + AN2 U6417 ( .A(n2837), .B(pi040), .Z(n4685)); + IV2 U6418 ( .A(po039), .Z(n3300)); + OR2 U6419 ( .A(n3352), .B(n3344), .Z(n6202)); + AN2 U6420 ( .A(n6377), .B(n6378), .Z(n3352)); + OR2 U6421 ( .A(n6179), .B(po001), .Z(n6378)); + IV2 U6422 ( .A(n6379), .Z(n6179)); + OR2 U6423 ( .A(n6379), .B(n4937), .Z(n6377)); + IV2 U6424 ( .A(po001), .Z(n4937)); + OR2 U6425 ( .A(n5959), .B(n6380), .Z(n6379)); + AN2 U6426 ( .A(pi192), .B(n3998), .Z(n6380)); + IV2 U6427 ( .A(pi068), .Z(n3998)); + AN2 U6428 ( .A(n2837), .B(n5379), .Z(n5959)); + AN2 U6429 ( .A(n6381), .B(n6382), .Z(n6205)); + OR2 U6430 ( .A(n3344), .B(n3590), .Z(n6382)); + OR2 U6431 ( .A(po001), .B(n5379), .Z(n3590)); + IV2 U6432 ( .A(pi195), .Z(n5379)); + OR2 U6433 ( .A(n6383), .B(n3248), .Z(n3344)); + AN2 U6434 ( .A(n6384), .B(n4947), .Z(n3248)); + IV2 U6435 ( .A(po082), .Z(n4947)); + AN2 U6436 ( .A(n6385), .B(po082), .Z(n6383)); + IV2 U6437 ( .A(n6384), .Z(n6385)); + OR2 U6438 ( .A(n6386), .B(n6387), .Z(n6384)); + AN2 U6439 ( .A(pi004), .B(pi192), .Z(n6387)); + AN2 U6440 ( .A(pi130), .B(n2837), .Z(n6386)); + OR2 U6441 ( .A(po082), .B(n5372), .Z(n6381)); + IV2 U6442 ( .A(pi130), .Z(n5372)); + AN2 U6443 ( .A(n3225), .B(n6053), .Z(n5931)); + IV2 U6444 ( .A(n3247), .Z(n3225)); + OR2 U6445 ( .A(n6388), .B(n3490), .Z(n3247)); + AN2 U6446 ( .A(n4943), .B(n5895), .Z(n3490)); + OR2 U6447 ( .A(n3926), .B(n3989), .Z(n5895)); + IV2 U6448 ( .A(n6389), .Z(n6388)); + OR2 U6449 ( .A(n4943), .B(n6390), .Z(n6389)); + AN2 U6450 ( .A(n6391), .B(n3261), .Z(n6390)); + OR2 U6451 ( .A(n2837), .B(pi133), .Z(n6391)); + AN2 U6452 ( .A(n6392), .B(n6053), .Z(n6169)); + AN2 U6453 ( .A(n3393), .B(n6393), .Z(n6053)); + IV2 U6454 ( .A(n3461), .Z(n6393)); + OR2 U6455 ( .A(n3401), .B(n3412), .Z(n3461)); + OR2 U6456 ( .A(n6394), .B(n5853), .Z(n3412)); + OR2 U6457 ( .A(n3466), .B(n3392), .Z(n5853)); + AN2 U6458 ( .A(n3380), .B(n3926), .Z(n3392)); + IV2 U6459 ( .A(po071), .Z(n3380)); + AN2 U6460 ( .A(n3261), .B(n3381), .Z(n3466)); + IV2 U6461 ( .A(n3399), .Z(n3381)); + OR2 U6462 ( .A(po071), .B(n3913), .Z(n3399)); + AN2 U6463 ( .A(po071), .B(n5878), .Z(n6394)); + OR2 U6464 ( .A(n3480), .B(n3321), .Z(n5878)); + AN2 U6465 ( .A(n3913), .B(pi192), .Z(n3480)); + IV2 U6466 ( .A(pi118), .Z(n3913)); + OR2 U6467 ( .A(n5881), .B(n6395), .Z(n3401)); + OR2 U6468 ( .A(n6168), .B(n6396), .Z(n6395)); + AN2 U6469 ( .A(po104), .B(n3321), .Z(n6396)); + AN2 U6470 ( .A(n3485), .B(n3261), .Z(n6168)); + IV2 U6471 ( .A(n3419), .Z(n3485)); + OR2 U6472 ( .A(n6397), .B(po104), .Z(n3419)); + AN2 U6473 ( .A(pi192), .B(n3942), .Z(n6397)); + IV2 U6474 ( .A(pi196), .Z(n3942)); + AN2 U6475 ( .A(pi192), .B(n5872), .Z(n5881)); + IV2 U6476 ( .A(n5866), .Z(n5872)); + OR2 U6477 ( .A(pi196), .B(n3512), .Z(n5866)); + IV2 U6478 ( .A(po104), .Z(n3512)); + OR2 U6479 ( .A(n6398), .B(n6399), .Z(n3393)); + AN2 U6480 ( .A(n6400), .B(n4975), .Z(n6399)); + IV2 U6481 ( .A(po038), .Z(n4975)); + OR2 U6482 ( .A(n6401), .B(n3321), .Z(n6400)); + AN2 U6483 ( .A(pi192), .B(n3943), .Z(n6401)); + IV2 U6484 ( .A(pi050), .Z(n3943)); + AN2 U6485 ( .A(po038), .B(n6402), .Z(n6398)); + OR2 U6486 ( .A(n3940), .B(n3926), .Z(n6402)); + AN2 U6487 ( .A(n3261), .B(pi050), .Z(n3940)); + AN2 U6488 ( .A(n6403), .B(n4943), .Z(n6392)); + IV2 U6489 ( .A(po057), .Z(n4943)); + OR2 U6490 ( .A(n6404), .B(n6052), .Z(n6403)); + OR2 U6491 ( .A(n6405), .B(n3926), .Z(n6052)); + IV2 U6492 ( .A(n6155), .Z(n3926)); + OR2 U6493 ( .A(pi192), .B(n3321), .Z(n6155)); + AN2 U6494 ( .A(pi060), .B(n3989), .Z(n6405)); + AN2 U6495 ( .A(n3989), .B(n3363), .Z(n6404)); + IV2 U6496 ( .A(po027), .Z(n3363)); + AN2 U6497 ( .A(n3261), .B(pi133), .Z(n3989)); + IV2 U6498 ( .A(n3321), .Z(n3261)); + IV2 U6499 ( .A(n6149), .Z(n4217)); + OR2 U6500 ( .A(n4148), .B(n3321), .Z(n6149)); + AN2 U6501 ( .A(pi161), .B(pi012), .Z(n3321)); + IV2 U6502 ( .A(n4247), .Z(n4148)); + OR2 U6503 ( .A(pi058), .B(n2837), .Z(n4247)); + IV2 U6504 ( .A(pi192), .Z(n2837)); + +endmodule + +module IV2(A, Z); + input A; + output Z; + + assign Z = ~A; +endmodule + +module AN2(A, B, Z); + input A, B; + output Z; + + assign Z = A & B; +endmodule + +module OR2(A, B, Z); + input A, B; + output Z; + + assign Z = A | B; +endmodule diff --git a/examples/smtbmc/glift/C7552.ys b/examples/smtbmc/glift/C7552.ys new file mode 100644 index 00000000000..0b39fadc7b5 --- /dev/null +++ b/examples/smtbmc/glift/C7552.ys @@ -0,0 +1,45 @@ +read_verilog C7552.v +techmap +flatten +select C7552_lev2 +glift -optimize-precise +techmap +opt +rename C7552_lev2 uut +cd .. +delete [AIONX][NVXR]2 +read_verilog C7552.v +techmap +flatten +select C7552_lev2 +glift -create-precise +techmap +opt +rename C7552_lev2 spec +cd .. +delete [AIONX][NVXR]2 + +design -push-copy +miter -equiv spec uut miter +flatten +delete uut spec +techmap +opt +stat miter +abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter +techmap +opt +stat +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C7552.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +design -pop +stat + +copy uut solved +qbfsat -specialize-from-file C7552.soln solved +opt solved +miter -equiv spec solved satmiter +flatten +sat -prove trigger 0 satmiter +delete satmiter +stat +shell diff --git a/examples/smtbmc/glift/C880.v b/examples/smtbmc/glift/C880.v new file mode 100755 index 00000000000..18dc24cc53c --- /dev/null +++ b/examples/smtbmc/glift/C880.v @@ -0,0 +1,451 @@ +module C880_lev2(pi00, pi01, pi02, pi03, pi04, pi05, pi06, pi07, pi08, pi09, + pi10, pi11, pi12, pi13, pi14, pi15, pi16, pi17, pi18, pi19, + pi20, pi21, pi22, pi23, pi24, pi25, pi26, pi27, pi28, pi29, + pi30, pi31, pi32, pi33, pi34, pi35, pi36, pi37, pi38, pi39, + pi40, pi41, pi42, pi43, pi44, pi45, pi46, pi47, pi48, pi49, + pi50, pi51, pi52, pi53, pi54, pi55, pi56, pi57, pi58, pi59, + po00, po01, po02, po03, po04, po05, po06, po07, po08, po09, + po10, po11, po12, po13, po14, po15, po16, po17, po18, po19, + po20, po21, po22, po23, po24, po25); + +input pi00, pi01, pi02, pi03, pi04, pi05, pi06, pi07, pi08, pi09, + pi10, pi11, pi12, pi13, pi14, pi15, pi16, pi17, pi18, pi19, + pi20, pi21, pi22, pi23, pi24, pi25, pi26, pi27, pi28, pi29, + pi30, pi31, pi32, pi33, pi34, pi35, pi36, pi37, pi38, pi39, + pi40, pi41, pi42, pi43, pi44, pi45, pi46, pi47, pi48, pi49, + pi50, pi51, pi52, pi53, pi54, pi55, pi56, pi57, pi58, pi59; + +output po00, po01, po02, po03, po04, po05, po06, po07, po08, po09, + po10, po11, po12, po13, po14, po15, po16, po17, po18, po19, + po20, po21, po22, po23, po24, po25; + +wire n137, n346, n364, n415, n295, n427, n351, n377, n454, n357, + n358, n359, n360, n361, n362, n363, n365, n366, n367, n368, + n369, n370, n371, n372, n373, n374, n375, n376, n378, n379, + n380, n381, n382, n383, n384, n385, n386, n387, n388, n389, + n390, n391, n392, n393, n394, n395, n396, n397, n398, n399, + n400, n401, n402, n403, n404, n405, n406, n407, n408, n409, + n410, n411, n412, n413, n414, n416, n417, n418, n419, n420, + n421, n422, n423, n424, n425, n426, n428, n429, n430, n431, + n432, n433, n434, n435, n436, n437, n438, n439, n440, n441, + n442, n443, n444, n445, n446, n447, n448, n449, n450, n451, + n452, n453, n455, n456, n457, n458, n459, n460, n461, n462, + n463, n464, n465, n466, n467, n468, n469, n470, n471, n472, + n473, n474, n475, n476, n477, n478, n479, n480, n481, n482, + n483, n484, n485, n486, n487, n488, n489, n490, n491, n492, + n493, n494, n495, n496, n497, n498, n499, n500, n501, n502, + n503, n504, n505, n506, n507, n508, n509, n510, n511, n512, + n513, n514, n515, n516, n517, n518, n519, n520, n521, n522, + n523, n524, n525, n526, n527, n528, n529, n530, n531, n532, + n533, n534, n535, n536, n537, n538, n539, n540, n541, n542, + n543, n544, n545, n546, n547, n548, n549, n550, n551, n552, + n553, n554, n555, n556, n557, n558, n559, n560, n561, n562, + n563, n564, n565, n566, n567, n568, n569, n570, n571, n572, + n573, n574, n575, n576, n577, n578, n579, n580, n581, n582, + n583, n584, n585, n586, n587, n588, n589, n590, n591, n592, + n593, n594, n595, n596, n597, n598, n599, n600, n601, n602, + n603, n604, n605, n606, n607, n608, n609, n610, n611, n612, + n613, n614, n615, n616, n617, n618, n619, n620, n621, n622, + n623, n624, n625, n626, n627, n628, n629, n630, n631, n632, + n633, n634, n635, n636, n637, n638, n639, n640, n641, n642, + n643, n644, n645, n646, n647, n648, n649, n650, n651, n652, + n653, n654, n655, n656, n657, n658, n659, n660, n661, n662, + n663, n664, n665, n666, n667, n668, n669, n670, n671, n672, + n673, n674, n675, n676, n677, n678, n679, n680, n681, n682, + n683, n684, n685, n686, n687, n688, n689, n690, n691, n692, + n693, n694, n695, n696; + + +assign po22 = n137; +assign po19 = n346; +assign po16 = n364; +assign po17 = n415; +assign po18 = n295; +assign po00 = n427; +assign po09 = n351; +assign po04 = n377; +assign po06 = n454; + AN2 U371 ( .A(pi11), .B(pi08), .Z(n357)); + AN2 U372 ( .A(pi28), .B(n357), .Z(n346)); + AN2 U373 ( .A(pi41), .B(pi25), .Z(n369)); + AN2 U374 ( .A(pi52), .B(n369), .Z(n361)); + AN2 U375 ( .A(pi51), .B(pi54), .Z(n359)); + AN2 U376 ( .A(pi28), .B(pi31), .Z(n604)); + AN2 U377 ( .A(n604), .B(pi55), .Z(n358)); + AN2 U378 ( .A(n359), .B(n358), .Z(n602)); + AN2 U379 ( .A(pi53), .B(n602), .Z(n360)); + AN2 U380 ( .A(n361), .B(n360), .Z(n577)); + IV2 U381 ( .A(pi20), .Z(n607)); + OR2 U382 ( .A(n607), .B(pi25), .Z(n362)); + IV2 U383 ( .A(n362), .Z(n365)); + AN2 U384 ( .A(pi25), .B(n607), .Z(n363)); + OR2 U385 ( .A(n365), .B(n363), .Z(n367)); + AN2 U386 ( .A(pi41), .B(pi24), .Z(n378)); + AN2 U387 ( .A(n346), .B(n378), .Z(n366)); + AN2 U388 ( .A(n367), .B(n366), .Z(n373)); + AN2 U389 ( .A(pi28), .B(pi54), .Z(n368)); + AN2 U390 ( .A(pi20), .B(n368), .Z(n603)); + AN2 U391 ( .A(pi08), .B(n603), .Z(n371)); + IV2 U392 ( .A(pi56), .Z(n694)); + IV2 U393 ( .A(n369), .Z(n692)); + OR2 U394 ( .A(n694), .B(n692), .Z(n370)); + AN2 U395 ( .A(n371), .B(n370), .Z(n372)); + OR2 U396 ( .A(n373), .B(n372), .Z(n424)); + AN2 U397 ( .A(pi14), .B(n424), .Z(n384)); + AN2 U398 ( .A(pi56), .B(pi48), .Z(n608)); + AN2 U399 ( .A(n608), .B(n346), .Z(n374)); + AN2 U400 ( .A(pi07), .B(n374), .Z(n376)); + IV2 U401 ( .A(pi43), .Z(n375)); + AN2 U402 ( .A(n376), .B(n375), .Z(n406)); + AN2 U403 ( .A(pi20), .B(n406), .Z(n403)); + IV2 U404 ( .A(n378), .Z(n379)); + AN2 U405 ( .A(n346), .B(n379), .Z(n407)); + AN2 U406 ( .A(pi55), .B(n407), .Z(n399)); + AN2 U407 ( .A(pi44), .B(n399), .Z(n381)); + AN2 U408 ( .A(pi37), .B(pi54), .Z(n380)); + OR2 U409 ( .A(n381), .B(n380), .Z(n382)); + OR2 U410 ( .A(n403), .B(n382), .Z(n383)); + OR2 U411 ( .A(n384), .B(n383), .Z(n436)); + AN2 U412 ( .A(pi26), .B(n436), .Z(n385)); + OR2 U413 ( .A(n577), .B(n385), .Z(n386)); + AN2 U414 ( .A(pi34), .B(n386), .Z(n448)); + AN2 U415 ( .A(pi43), .B(pi05), .Z(n388)); + AN2 U416 ( .A(pi32), .B(n436), .Z(n387)); + OR2 U417 ( .A(n388), .B(n387), .Z(n446)); + AN2 U418 ( .A(pi08), .B(pi37), .Z(n393)); + AN2 U419 ( .A(pi50), .B(n399), .Z(n390)); + AN2 U420 ( .A(pi18), .B(n424), .Z(n389)); + OR2 U421 ( .A(n390), .B(n389), .Z(n391)); + OR2 U422 ( .A(n403), .B(n391), .Z(n392)); + OR2 U423 ( .A(n393), .B(n392), .Z(n494)); + AN2 U424 ( .A(pi27), .B(n494), .Z(n497)); + OR2 U425 ( .A(pi27), .B(n494), .Z(n499)); + AN2 U426 ( .A(pi20), .B(pi37), .Z(n398)); + AN2 U427 ( .A(pi45), .B(n399), .Z(n395)); + AN2 U428 ( .A(pi22), .B(n424), .Z(n394)); + OR2 U429 ( .A(n395), .B(n394), .Z(n396)); + OR2 U430 ( .A(n403), .B(n396), .Z(n397)); + OR2 U431 ( .A(n398), .B(n397), .Z(n536)); + AN2 U432 ( .A(pi17), .B(n536), .Z(n539)); + OR2 U433 ( .A(pi17), .B(n536), .Z(n541)); + AN2 U434 ( .A(pi23), .B(n424), .Z(n405)); + AN2 U435 ( .A(pi30), .B(pi37), .Z(n401)); + AN2 U436 ( .A(pi29), .B(n399), .Z(n400)); + OR2 U437 ( .A(n401), .B(n400), .Z(n402)); + OR2 U438 ( .A(n403), .B(n402), .Z(n404)); + OR2 U439 ( .A(n405), .B(n404), .Z(n579)); + AN2 U440 ( .A(pi21), .B(n579), .Z(n582)); + OR2 U441 ( .A(pi21), .B(n579), .Z(n584)); + AN2 U442 ( .A(n406), .B(pi55), .Z(n429)); + IV2 U443 ( .A(pi28), .Z(n409)); + AN2 U444 ( .A(n407), .B(pi20), .Z(n408)); + OR2 U445 ( .A(n409), .B(n408), .Z(n423)); + AN2 U446 ( .A(pi50), .B(n423), .Z(n411)); + AN2 U447 ( .A(pi42), .B(n424), .Z(n410)); + OR2 U448 ( .A(n411), .B(n410), .Z(n412)); + OR2 U449 ( .A(n429), .B(n412), .Z(n514)); + AN2 U450 ( .A(pi15), .B(n514), .Z(n517)); + OR2 U451 ( .A(pi15), .B(n514), .Z(n519)); + AN2 U452 ( .A(pi45), .B(n423), .Z(n414)); + AN2 U453 ( .A(pi40), .B(n424), .Z(n413)); + OR2 U454 ( .A(n414), .B(n413), .Z(n416)); + OR2 U455 ( .A(n429), .B(n416), .Z(n556)); + AN2 U456 ( .A(pi03), .B(n556), .Z(n559)); + OR2 U457 ( .A(pi03), .B(n556), .Z(n561)); + AN2 U458 ( .A(pi29), .B(n423), .Z(n418)); + AN2 U459 ( .A(pi04), .B(n424), .Z(n417)); + OR2 U460 ( .A(n418), .B(n417), .Z(n419)); + OR2 U461 ( .A(n429), .B(n419), .Z(n471)); + AN2 U462 ( .A(pi10), .B(n471), .Z(n480)); + OR2 U463 ( .A(pi10), .B(n471), .Z(n482)); + AN2 U464 ( .A(pi46), .B(n482), .Z(n420)); + OR2 U465 ( .A(n480), .B(n420), .Z(n562)); + AN2 U466 ( .A(n561), .B(n562), .Z(n421)); + OR2 U467 ( .A(n559), .B(n421), .Z(n520)); + AN2 U468 ( .A(n519), .B(n520), .Z(n422)); + OR2 U469 ( .A(n517), .B(n422), .Z(n449)); + AN2 U470 ( .A(pi44), .B(n423), .Z(n426)); + AN2 U471 ( .A(pi49), .B(n424), .Z(n425)); + OR2 U472 ( .A(n426), .B(n425), .Z(n428)); + OR2 U473 ( .A(n429), .B(n428), .Z(n464)); + AN2 U474 ( .A(n449), .B(n464), .Z(n432)); + OR2 U475 ( .A(n449), .B(n464), .Z(n430)); + AN2 U476 ( .A(pi09), .B(n430), .Z(n431)); + OR2 U477 ( .A(n432), .B(n431), .Z(n585)); + AN2 U478 ( .A(n584), .B(n585), .Z(n433)); + OR2 U479 ( .A(n582), .B(n433), .Z(n542)); + AN2 U480 ( .A(n541), .B(n542), .Z(n434)); + OR2 U481 ( .A(n539), .B(n434), .Z(n500)); + AN2 U482 ( .A(n499), .B(n500), .Z(n435)); + OR2 U483 ( .A(n497), .B(n435), .Z(n597)); + OR2 U484 ( .A(pi34), .B(n436), .Z(n598)); + AN2 U485 ( .A(n436), .B(pi34), .Z(n600)); + IV2 U486 ( .A(n600), .Z(n437)); + AN2 U487 ( .A(n598), .B(n437), .Z(n442)); + OR2 U488 ( .A(n597), .B(n442), .Z(n440)); + AN2 U489 ( .A(n597), .B(n442), .Z(n438)); + IV2 U490 ( .A(n438), .Z(n439)); + AN2 U491 ( .A(n440), .B(n439), .Z(n441)); + AN2 U492 ( .A(pi12), .B(n441), .Z(n444)); + AN2 U493 ( .A(n442), .B(pi19), .Z(n443)); + OR2 U494 ( .A(n444), .B(n443), .Z(n445)); + OR2 U495 ( .A(n446), .B(n445), .Z(n447)); + OR2 U496 ( .A(n448), .B(n447), .Z(n137)); + IV2 U497 ( .A(n464), .Z(n459)); + AN2 U498 ( .A(pi12), .B(n449), .Z(n456)); + AN2 U499 ( .A(n459), .B(n456), .Z(n453)); + IV2 U500 ( .A(n449), .Z(n450)); + AN2 U501 ( .A(n450), .B(pi12), .Z(n451)); + OR2 U502 ( .A(pi19), .B(n451), .Z(n458)); + AN2 U503 ( .A(n464), .B(n458), .Z(n452)); + OR2 U504 ( .A(n453), .B(n452), .Z(n455)); + IV2 U505 ( .A(pi09), .Z(n612)); + AN2 U506 ( .A(n455), .B(n612), .Z(n470)); + OR2 U507 ( .A(pi26), .B(n456), .Z(n457)); + AN2 U508 ( .A(n464), .B(n457), .Z(n462)); + AN2 U509 ( .A(n459), .B(n458), .Z(n460)); + OR2 U510 ( .A(n577), .B(n460), .Z(n461)); + OR2 U511 ( .A(n462), .B(n461), .Z(n463)); + AN2 U512 ( .A(pi09), .B(n463), .Z(n468)); + AN2 U513 ( .A(pi23), .B(pi05), .Z(n466)); + AN2 U514 ( .A(pi32), .B(n464), .Z(n465)); + OR2 U515 ( .A(n466), .B(n465), .Z(n467)); + OR2 U516 ( .A(n468), .B(n467), .Z(n469)); + OR2 U517 ( .A(n470), .B(n469), .Z(n295)); + AN2 U518 ( .A(pi26), .B(n480), .Z(n479)); + AN2 U519 ( .A(pi40), .B(pi05), .Z(n473)); + AN2 U520 ( .A(pi32), .B(n471), .Z(n472)); + OR2 U521 ( .A(n473), .B(n472), .Z(n477)); + AN2 U522 ( .A(pi38), .B(pi36), .Z(n475)); + AN2 U523 ( .A(pi10), .B(n577), .Z(n474)); + OR2 U524 ( .A(n475), .B(n474), .Z(n476)); + OR2 U525 ( .A(n477), .B(n476), .Z(n478)); + OR2 U526 ( .A(n479), .B(n478), .Z(n491)); + IV2 U527 ( .A(n480), .Z(n481)); + AN2 U528 ( .A(n482), .B(n481), .Z(n487)); + OR2 U529 ( .A(pi46), .B(n487), .Z(n485)); + AN2 U530 ( .A(pi46), .B(n487), .Z(n483)); + IV2 U531 ( .A(n483), .Z(n484)); + AN2 U532 ( .A(n485), .B(n484), .Z(n486)); + AN2 U533 ( .A(pi12), .B(n486), .Z(n489)); + AN2 U534 ( .A(n487), .B(pi19), .Z(n488)); + OR2 U535 ( .A(n489), .B(n488), .Z(n490)); + OR2 U536 ( .A(n491), .B(n490), .Z(n351)); + AN2 U537 ( .A(pi26), .B(n494), .Z(n492)); + OR2 U538 ( .A(n577), .B(n492), .Z(n493)); + AN2 U539 ( .A(pi27), .B(n493), .Z(n511)); + AN2 U540 ( .A(pi14), .B(pi05), .Z(n496)); + AN2 U541 ( .A(pi32), .B(n494), .Z(n495)); + OR2 U542 ( .A(n496), .B(n495), .Z(n509)); + IV2 U543 ( .A(n497), .Z(n498)); + AN2 U544 ( .A(n499), .B(n498), .Z(n505)); + OR2 U545 ( .A(n500), .B(n505), .Z(n503)); + AN2 U546 ( .A(n500), .B(n505), .Z(n501)); + IV2 U547 ( .A(n501), .Z(n502)); + AN2 U548 ( .A(n503), .B(n502), .Z(n504)); + AN2 U549 ( .A(pi12), .B(n504), .Z(n507)); + AN2 U550 ( .A(n505), .B(pi19), .Z(n506)); + OR2 U551 ( .A(n507), .B(n506), .Z(n508)); + OR2 U552 ( .A(n509), .B(n508), .Z(n510)); + OR2 U553 ( .A(n511), .B(n510), .Z(n364)); + AN2 U554 ( .A(pi26), .B(n514), .Z(n512)); + OR2 U555 ( .A(n577), .B(n512), .Z(n513)); + AN2 U556 ( .A(pi15), .B(n513), .Z(n533)); + AN2 U557 ( .A(pi49), .B(pi05), .Z(n531)); + AN2 U558 ( .A(pi33), .B(pi36), .Z(n516)); + AN2 U559 ( .A(pi32), .B(n514), .Z(n515)); + OR2 U560 ( .A(n516), .B(n515), .Z(n529)); + IV2 U561 ( .A(n517), .Z(n518)); + AN2 U562 ( .A(n519), .B(n518), .Z(n525)); + OR2 U563 ( .A(n520), .B(n525), .Z(n523)); + AN2 U564 ( .A(n520), .B(n525), .Z(n521)); + IV2 U565 ( .A(n521), .Z(n522)); + AN2 U566 ( .A(n523), .B(n522), .Z(n524)); + AN2 U567 ( .A(pi12), .B(n524), .Z(n527)); + AN2 U568 ( .A(n525), .B(pi19), .Z(n526)); + OR2 U569 ( .A(n527), .B(n526), .Z(n528)); + OR2 U570 ( .A(n529), .B(n528), .Z(n530)); + OR2 U571 ( .A(n531), .B(n530), .Z(n532)); + OR2 U572 ( .A(n533), .B(n532), .Z(n377)); + AN2 U573 ( .A(pi26), .B(n536), .Z(n534)); + OR2 U574 ( .A(n577), .B(n534), .Z(n535)); + AN2 U575 ( .A(pi17), .B(n535), .Z(n553)); + AN2 U576 ( .A(pi18), .B(pi05), .Z(n538)); + AN2 U577 ( .A(pi32), .B(n536), .Z(n537)); + OR2 U578 ( .A(n538), .B(n537), .Z(n551)); + IV2 U579 ( .A(n539), .Z(n540)); + AN2 U580 ( .A(n541), .B(n540), .Z(n547)); + OR2 U581 ( .A(n542), .B(n547), .Z(n545)); + AN2 U582 ( .A(n542), .B(n547), .Z(n543)); + IV2 U583 ( .A(n543), .Z(n544)); + AN2 U584 ( .A(n545), .B(n544), .Z(n546)); + AN2 U585 ( .A(pi12), .B(n546), .Z(n549)); + AN2 U586 ( .A(n547), .B(pi19), .Z(n548)); + OR2 U587 ( .A(n549), .B(n548), .Z(n550)); + OR2 U588 ( .A(n551), .B(n550), .Z(n552)); + OR2 U589 ( .A(n553), .B(n552), .Z(n415)); + AN2 U590 ( .A(pi26), .B(n556), .Z(n554)); + OR2 U591 ( .A(n577), .B(n554), .Z(n555)); + AN2 U592 ( .A(pi03), .B(n555), .Z(n575)); + AN2 U593 ( .A(pi42), .B(pi05), .Z(n573)); + AN2 U594 ( .A(pi47), .B(pi36), .Z(n558)); + AN2 U595 ( .A(pi32), .B(n556), .Z(n557)); + OR2 U596 ( .A(n558), .B(n557), .Z(n571)); + IV2 U597 ( .A(n559), .Z(n560)); + AN2 U598 ( .A(n561), .B(n560), .Z(n567)); + OR2 U599 ( .A(n562), .B(n567), .Z(n565)); + AN2 U600 ( .A(n562), .B(n567), .Z(n563)); + IV2 U601 ( .A(n563), .Z(n564)); + AN2 U602 ( .A(n565), .B(n564), .Z(n566)); + AN2 U603 ( .A(pi12), .B(n566), .Z(n569)); + AN2 U604 ( .A(n567), .B(pi19), .Z(n568)); + OR2 U605 ( .A(n569), .B(n568), .Z(n570)); + OR2 U606 ( .A(n571), .B(n570), .Z(n572)); + OR2 U607 ( .A(n573), .B(n572), .Z(n574)); + OR2 U608 ( .A(n575), .B(n574), .Z(n427)); + AN2 U609 ( .A(pi26), .B(n579), .Z(n576)); + OR2 U610 ( .A(n577), .B(n576), .Z(n578)); + AN2 U611 ( .A(pi21), .B(n578), .Z(n596)); + AN2 U612 ( .A(pi22), .B(pi05), .Z(n581)); + AN2 U613 ( .A(pi32), .B(n579), .Z(n580)); + OR2 U614 ( .A(n581), .B(n580), .Z(n594)); + IV2 U615 ( .A(n582), .Z(n583)); + AN2 U616 ( .A(n584), .B(n583), .Z(n590)); + OR2 U617 ( .A(n585), .B(n590), .Z(n588)); + AN2 U618 ( .A(n585), .B(n590), .Z(n586)); + IV2 U619 ( .A(n586), .Z(n587)); + AN2 U620 ( .A(n588), .B(n587), .Z(n589)); + AN2 U621 ( .A(pi12), .B(n589), .Z(n592)); + AN2 U622 ( .A(n590), .B(pi19), .Z(n591)); + OR2 U623 ( .A(n592), .B(n591), .Z(n593)); + OR2 U624 ( .A(n594), .B(n593), .Z(n595)); + OR2 U625 ( .A(n596), .B(n595), .Z(n454)); + AN2 U626 ( .A(n598), .B(n597), .Z(n599)); + OR2 U627 ( .A(n600), .B(n599), .Z(po07)); + OR2 U628 ( .A(pi58), .B(pi00), .Z(n609)); + AN2 U629 ( .A(pi59), .B(n609), .Z(po24)); + AN2 U630 ( .A(n602), .B(pi57), .Z(n601)); + AN2 U631 ( .A(pi41), .B(n601), .Z(po13)); + AN2 U632 ( .A(pi48), .B(n602), .Z(po08)); + AN2 U633 ( .A(n603), .B(pi31), .Z(po03)); + AN2 U634 ( .A(pi48), .B(pi16), .Z(n610)); + AN2 U635 ( .A(pi25), .B(n610), .Z(po25)); + AN2 U636 ( .A(pi11), .B(n604), .Z(n605)); + IV2 U637 ( .A(n605), .Z(n606)); + OR2 U638 ( .A(n607), .B(n606), .Z(n691)); + OR2 U639 ( .A(po25), .B(n691), .Z(po02)); + AN2 U640 ( .A(n608), .B(pi25), .Z(po10)); + AN2 U641 ( .A(pi13), .B(n609), .Z(po12)); + AN2 U642 ( .A(pi07), .B(n610), .Z(po14)); + IV2 U643 ( .A(pi15), .Z(n611)); + AN2 U644 ( .A(pi09), .B(n611), .Z(n614)); + AN2 U645 ( .A(pi15), .B(n612), .Z(n613)); + OR2 U646 ( .A(n614), .B(n613), .Z(n618)); + IV2 U647 ( .A(pi35), .Z(n654)); + OR2 U648 ( .A(n654), .B(pi06), .Z(n617)); + IV2 U649 ( .A(pi06), .Z(n615)); + OR2 U650 ( .A(n615), .B(pi35), .Z(n616)); + AN2 U651 ( .A(n617), .B(n616), .Z(n619)); + OR2 U652 ( .A(n618), .B(n619), .Z(n622)); + AN2 U653 ( .A(n619), .B(n618), .Z(n620)); + IV2 U654 ( .A(n620), .Z(n621)); + AN2 U655 ( .A(n622), .B(n621), .Z(n628)); + IV2 U656 ( .A(pi10), .Z(n624)); + OR2 U657 ( .A(n624), .B(pi03), .Z(n623)); + IV2 U658 ( .A(n623), .Z(n626)); + AN2 U659 ( .A(pi03), .B(n624), .Z(n625)); + OR2 U660 ( .A(n626), .B(n625), .Z(n627)); + OR2 U661 ( .A(n628), .B(n627), .Z(n631)); + AN2 U662 ( .A(n628), .B(n627), .Z(n629)); + IV2 U663 ( .A(n629), .Z(n630)); + AN2 U664 ( .A(n631), .B(n630), .Z(n637)); + IV2 U665 ( .A(pi34), .Z(n632)); + AN2 U666 ( .A(pi27), .B(n632), .Z(n635)); + OR2 U667 ( .A(n632), .B(pi27), .Z(n633)); + IV2 U668 ( .A(n633), .Z(n634)); + OR2 U669 ( .A(n635), .B(n634), .Z(n636)); + OR2 U670 ( .A(n637), .B(n636), .Z(n640)); + AN2 U671 ( .A(n637), .B(n636), .Z(n638)); + IV2 U672 ( .A(n638), .Z(n639)); + AN2 U673 ( .A(n640), .B(n639), .Z(n647)); + IV2 U674 ( .A(pi21), .Z(n642)); + OR2 U675 ( .A(n642), .B(pi17), .Z(n641)); + IV2 U676 ( .A(n641), .Z(n644)); + AN2 U677 ( .A(pi17), .B(n642), .Z(n643)); + OR2 U678 ( .A(n644), .B(n643), .Z(n646)); + OR2 U679 ( .A(n647), .B(n646), .Z(n645)); + IV2 U680 ( .A(n645), .Z(n649)); + AN2 U681 ( .A(n647), .B(n646), .Z(n648)); + OR2 U682 ( .A(n649), .B(n648), .Z(po15)); + IV2 U683 ( .A(pi42), .Z(n650)); + AN2 U684 ( .A(pi49), .B(n650), .Z(n653)); + IV2 U685 ( .A(pi49), .Z(n651)); + AN2 U686 ( .A(pi42), .B(n651), .Z(n652)); + OR2 U687 ( .A(n653), .B(n652), .Z(n658)); + OR2 U688 ( .A(n654), .B(pi39), .Z(n657)); + IV2 U689 ( .A(pi39), .Z(n655)); + OR2 U690 ( .A(n655), .B(pi35), .Z(n656)); + AN2 U691 ( .A(n657), .B(n656), .Z(n659)); + OR2 U692 ( .A(n658), .B(n659), .Z(n662)); + AN2 U693 ( .A(n659), .B(n658), .Z(n660)); + IV2 U694 ( .A(n660), .Z(n661)); + AN2 U695 ( .A(n662), .B(n661), .Z(n668)); + IV2 U696 ( .A(pi04), .Z(n664)); + OR2 U697 ( .A(n664), .B(pi18), .Z(n663)); + IV2 U698 ( .A(n663), .Z(n666)); + AN2 U699 ( .A(pi18), .B(n664), .Z(n665)); + OR2 U700 ( .A(n666), .B(n665), .Z(n667)); + OR2 U701 ( .A(n668), .B(n667), .Z(n671)); + AN2 U702 ( .A(n668), .B(n667), .Z(n669)); + IV2 U703 ( .A(n669), .Z(n670)); + AN2 U704 ( .A(n671), .B(n670), .Z(n677)); + IV2 U705 ( .A(pi22), .Z(n673)); + OR2 U706 ( .A(n673), .B(pi14), .Z(n672)); + IV2 U707 ( .A(n672), .Z(n675)); + AN2 U708 ( .A(pi14), .B(n673), .Z(n674)); + OR2 U709 ( .A(n675), .B(n674), .Z(n676)); + OR2 U710 ( .A(n677), .B(n676), .Z(n680)); + AN2 U711 ( .A(n677), .B(n676), .Z(n678)); + IV2 U712 ( .A(n678), .Z(n679)); + AN2 U713 ( .A(n680), .B(n679), .Z(n687)); + IV2 U714 ( .A(pi40), .Z(n682)); + OR2 U715 ( .A(n682), .B(pi23), .Z(n681)); + IV2 U716 ( .A(n681), .Z(n684)); + AN2 U717 ( .A(pi23), .B(n682), .Z(n683)); + OR2 U718 ( .A(n684), .B(n683), .Z(n686)); + OR2 U719 ( .A(n687), .B(n686), .Z(n685)); + IV2 U720 ( .A(n685), .Z(n689)); + AN2 U721 ( .A(n687), .B(n686), .Z(n688)); + OR2 U722 ( .A(n689), .B(n688), .Z(po20)); + AN2 U723 ( .A(pi01), .B(pi02), .Z(po21)); + IV2 U724 ( .A(po25), .Z(n690)); + OR2 U725 ( .A(n691), .B(n690), .Z(po23)); + IV2 U726 ( .A(pi16), .Z(n696)); + OR2 U727 ( .A(n692), .B(n696), .Z(po11)); + AN2 U728 ( .A(pi07), .B(pi41), .Z(n693)); + IV2 U729 ( .A(n693), .Z(n695)); + OR2 U730 ( .A(n694), .B(n695), .Z(po01)); + OR2 U731 ( .A(n696), .B(n695), .Z(po05)); + +endmodule + +module IV2(A, Z); + input A; + output Z; + + assign Z = ~A; +endmodule + +module AN2(A, B, Z); + input A, B; + output Z; + + assign Z = A & B; +endmodule + +module OR2(A, B, Z); + input A, B; + output Z; + + assign Z = A | B; +endmodule diff --git a/examples/smtbmc/glift/C880.ys b/examples/smtbmc/glift/C880.ys new file mode 100644 index 00000000000..fe2678088b8 --- /dev/null +++ b/examples/smtbmc/glift/C880.ys @@ -0,0 +1,45 @@ +read_verilog C880.v +techmap +flatten +select C880_lev2 +glift -optimize-precise +techmap +opt +rename C880_lev2 uut +cd .. +delete [AIONX][NVXR]2 +read_verilog C880.v +techmap +flatten +select C880_lev2 +glift -create-precise +techmap +opt +rename C880_lev2 spec +cd .. +delete [AIONX][NVXR]2 + +design -push-copy +miter -equiv spec uut miter +flatten +delete uut spec +techmap +opt +stat miter +abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter +techmap +opt +stat +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C880.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +design -pop +stat + +copy uut solved +qbfsat -specialize-from-file C880.soln solved +opt solved +miter -equiv spec solved satmiter +flatten +sat -prove trigger 0 satmiter +delete satmiter +stat +shell diff --git a/examples/smtbmc/glift/alu2.v b/examples/smtbmc/glift/alu2.v new file mode 100755 index 00000000000..6b6e3d7af24 --- /dev/null +++ b/examples/smtbmc/glift/alu2.v @@ -0,0 +1,400 @@ +module alu2_lev2(pi0, pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8, pi9, + po0, po1, po2, po3, po4, po5); + +input pi0, pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8, pi9; + +output po0, po1, po2, po3, po4, po5; + +wire n358, n359, n360, n361, n362, n363, n364, n365, n366, n367, + n368, n369, n370, n371, n372, n373, n374, n375, n376, n377, + n378, n379, n380, n381, n382, n383, n384, n385, n386, n387, + n388, n389, n390, n391, n392, n393, n394, n395, n396, n397, + n398, n399, n400, n401, n402, n403, n404, n405, n406, n407, + n408, n409, n410, n411, n412, n413, n414, n415, n416, n417, + n418, n419, n420, n421, n422, n423, n424, n425, n426, n427, + n428, n429, n430, n431, n432, n433, n434, n435, n436, n437, + n438, n439, n440, n441, n442, n443, n444, n445, n446, n447, + n448, n449, n450, n451, n452, n453, n454, n455, n456, n457, + n458, n459, n460, n461, n462, n463, n464, n465, n466, n467, + n468, n469, n470, n471, n472, n473, n474, n475, n476, n477, + n478, n479, n480, n481, n482, n483, n484, n485, n486, n487, + n488, n489, n490, n491, n492, n493, n494, n495, n496, n497, + n498, n499, n500, n501, n502, n503, n504, n505, n506, n507, + n508, n509, n510, n511, n512, n513, n514, n515, n516, n517, + n518, n519, n520, n521, n522, n523, n524, n525, n526, n527, + n528, n529, n530, n531, n532, n533, n534, n535, n536, n537, + n538, n539, n540, n541, n542, n543, n544, n545, n546, n547, + n548, n549, n550, n551, n552, n553, n554, n555, n556, n557, + n558, n559, n560, n561, n562, n563, n564, n565, n566, n567, + n568, n569, n570, n571, n572, n573, n574, n575, n576, n577, + n578, n579, n580, n581, n582, n583, n584, n585, n586, n587, + n588, n589, n590, n591, n592, n593, n594, n595, n596, n597, + n598, n599, n600, n601, n602, n603, n604, n605, n606, n607, + n608, n609, n610, n611, n612, n613, n614, n615, n616, n617, + n618, n619, n620, n621, n622, n623, n624, n625, n626, n627, + n628, n629, n630, n631, n632, n633, n634, n635, n636, n637, + n638, n639, n640, n641, n642, n643, n644, n645, n646, n647, + n648, n649, n650, n651, n652, n653, n654, n655, n656, n657, + n658, n659, n660, n661, n662, n663, n664, n665, n666, n667, + n668, n669, n670, n671, n672, n673, n674, n675, n676, n677, + n678, n679, n680, n681, n682, n683, n684, n685, n686, n687; + + AN2 U363 ( .A(n358), .B(po2), .Z(po5)); + OR2 U364 ( .A(n359), .B(n360), .Z(n358)); + AN2 U365 ( .A(n361), .B(n362), .Z(n359)); + AN2 U366 ( .A(pi9), .B(n363), .Z(po4)); + OR2 U367 ( .A(n364), .B(n365), .Z(n363)); + OR2 U368 ( .A(n366), .B(n367), .Z(n365)); + AN2 U369 ( .A(pi6), .B(n368), .Z(n367)); + OR2 U370 ( .A(n369), .B(n370), .Z(n368)); + OR2 U371 ( .A(n371), .B(n372), .Z(n370)); + OR2 U372 ( .A(n373), .B(n374), .Z(n372)); + AN2 U373 ( .A(n375), .B(n376), .Z(n374)); + AN2 U374 ( .A(n377), .B(n378), .Z(n375)); + OR2 U375 ( .A(n379), .B(n380), .Z(n377)); + OR2 U376 ( .A(n381), .B(n382), .Z(n380)); + OR2 U377 ( .A(n383), .B(n384), .Z(n379)); + AN2 U378 ( .A(n385), .B(pi5), .Z(n384)); + AN2 U379 ( .A(n386), .B(n387), .Z(n383)); + AN2 U380 ( .A(pi4), .B(n361), .Z(n386)); + AN2 U381 ( .A(n388), .B(n389), .Z(n373)); + OR2 U382 ( .A(n390), .B(n391), .Z(n388)); + AN2 U383 ( .A(pi1), .B(n392), .Z(n390)); + OR2 U384 ( .A(n393), .B(n394), .Z(n392)); + OR2 U385 ( .A(pi7), .B(n395), .Z(n394)); + AN2 U386 ( .A(n381), .B(n396), .Z(n395)); + OR2 U387 ( .A(n397), .B(n398), .Z(n369)); + AN2 U388 ( .A(n399), .B(n400), .Z(n398)); + AN2 U389 ( .A(n387), .B(n401), .Z(n399)); + AN2 U390 ( .A(n402), .B(n403), .Z(n397)); + AN2 U391 ( .A(pi0), .B(n404), .Z(n402)); + OR2 U392 ( .A(pi1), .B(n389), .Z(n404)); + AN2 U393 ( .A(n405), .B(n406), .Z(n366)); + OR2 U394 ( .A(n407), .B(n408), .Z(n406)); + AN2 U395 ( .A(n360), .B(n409), .Z(n408)); + OR2 U396 ( .A(n410), .B(n411), .Z(n409)); + OR2 U397 ( .A(n412), .B(n413), .Z(n411)); + AN2 U398 ( .A(n414), .B(pi3), .Z(n413)); + AN2 U399 ( .A(n389), .B(n415), .Z(n410)); + AN2 U400 ( .A(po3), .B(n416), .Z(n407)); + OR2 U401 ( .A(n417), .B(n414), .Z(n416)); + OR2 U402 ( .A(n418), .B(n419), .Z(n364)); + OR2 U403 ( .A(n420), .B(n421), .Z(n419)); + AN2 U404 ( .A(n422), .B(n382), .Z(n421)); + AN2 U405 ( .A(pi7), .B(n389), .Z(n422)); + AN2 U406 ( .A(n423), .B(n424), .Z(n418)); + AN2 U407 ( .A(n425), .B(n426), .Z(n423)); + OR2 U408 ( .A(n427), .B(po3), .Z(po2)); + AN2 U409 ( .A(n428), .B(n429), .Z(n427)); + OR2 U410 ( .A(n430), .B(n431), .Z(po1)); + AN2 U411 ( .A(pi9), .B(n432), .Z(n431)); + OR2 U412 ( .A(n433), .B(n434), .Z(n432)); + OR2 U413 ( .A(n435), .B(n436), .Z(n434)); + AN2 U414 ( .A(n437), .B(n438), .Z(n436)); + IV2 U415 ( .A(n425), .Z(n438)); + AN2 U416 ( .A(n424), .B(n426), .Z(n437)); + OR2 U417 ( .A(n439), .B(n440), .Z(n424)); + OR2 U418 ( .A(n441), .B(n442), .Z(n440)); + AN2 U419 ( .A(n381), .B(n443), .Z(n442)); + OR2 U420 ( .A(n444), .B(n445), .Z(n443)); + AN2 U421 ( .A(n446), .B(n447), .Z(n441)); + AN2 U422 ( .A(n387), .B(n361), .Z(n446)); + AN2 U423 ( .A(n448), .B(n425), .Z(n435)); + OR2 U424 ( .A(n449), .B(n450), .Z(n425)); + OR2 U425 ( .A(n420), .B(n451), .Z(n450)); + OR2 U426 ( .A(n452), .B(n453), .Z(n451)); + AN2 U427 ( .A(pi6), .B(n454), .Z(n453)); + OR2 U428 ( .A(n371), .B(n455), .Z(n454)); + AN2 U429 ( .A(n376), .B(n456), .Z(n455)); + OR2 U430 ( .A(n457), .B(n458), .Z(n456)); + OR2 U431 ( .A(n459), .B(n460), .Z(n458)); + AN2 U432 ( .A(n461), .B(n378), .Z(n460)); + OR2 U433 ( .A(n462), .B(n463), .Z(n461)); + AN2 U434 ( .A(n385), .B(n464), .Z(n462)); + OR2 U435 ( .A(n465), .B(pi5), .Z(n464)); + AN2 U436 ( .A(pi7), .B(n466), .Z(n459)); + OR2 U437 ( .A(n467), .B(n468), .Z(n466)); + OR2 U438 ( .A(n469), .B(n470), .Z(n468)); + AN2 U439 ( .A(n381), .B(pi1), .Z(n470)); + AN2 U440 ( .A(n471), .B(n428), .Z(n469)); + AN2 U441 ( .A(pi0), .B(n387), .Z(n471)); + AN2 U442 ( .A(n412), .B(n361), .Z(n467)); + AN2 U443 ( .A(n472), .B(n473), .Z(n457)); + AN2 U444 ( .A(n360), .B(n428), .Z(n472)); + AN2 U445 ( .A(n463), .B(n428), .Z(n371)); + AN2 U446 ( .A(n474), .B(n475), .Z(n452)); + OR2 U447 ( .A(n476), .B(n477), .Z(n474)); + OR2 U448 ( .A(n478), .B(n479), .Z(n477)); + AN2 U449 ( .A(n480), .B(n428), .Z(n479)); + AN2 U450 ( .A(n481), .B(n482), .Z(n480)); + OR2 U451 ( .A(n360), .B(n389), .Z(n482)); + OR2 U452 ( .A(n401), .B(n483), .Z(n481)); + AN2 U453 ( .A(pi7), .B(n484), .Z(n483)); + OR2 U454 ( .A(n393), .B(n485), .Z(n484)); + AN2 U455 ( .A(n376), .B(n415), .Z(n485)); + AN2 U456 ( .A(n414), .B(n429), .Z(n393)); + AN2 U457 ( .A(n486), .B(n378), .Z(n478)); + OR2 U458 ( .A(n412), .B(n389), .Z(n486)); + AN2 U459 ( .A(n487), .B(pi1), .Z(n412)); + OR2 U460 ( .A(n488), .B(n489), .Z(n476)); + AN2 U461 ( .A(n490), .B(n401), .Z(n488)); + AN2 U462 ( .A(pi1), .B(n429), .Z(n490)); + AN2 U463 ( .A(n385), .B(n491), .Z(n420)); + IV2 U464 ( .A(n492), .Z(n491)); + OR2 U465 ( .A(n493), .B(n487), .Z(n492)); + AN2 U466 ( .A(n494), .B(n495), .Z(n493)); + OR2 U467 ( .A(pi6), .B(n389), .Z(n495)); + OR2 U468 ( .A(pi7), .B(pi1), .Z(n494)); + OR2 U469 ( .A(n496), .B(n497), .Z(n449)); + AN2 U470 ( .A(n498), .B(n376), .Z(n497)); + AN2 U471 ( .A(n381), .B(n382), .Z(n498)); + AN2 U472 ( .A(n499), .B(n389), .Z(n496)); + OR2 U473 ( .A(n500), .B(n501), .Z(n499)); + OR2 U474 ( .A(n502), .B(n503), .Z(n501)); + AN2 U475 ( .A(n385), .B(n504), .Z(n503)); + OR2 U476 ( .A(n505), .B(n506), .Z(n504)); + AN2 U477 ( .A(po3), .B(n400), .Z(n506)); + AN2 U478 ( .A(n507), .B(n428), .Z(n505)); + AN2 U479 ( .A(n508), .B(n387), .Z(n502)); + OR2 U480 ( .A(n509), .B(n510), .Z(n508)); + OR2 U481 ( .A(n489), .B(n511), .Z(n510)); + OR2 U482 ( .A(n465), .B(n512), .Z(n511)); + AN2 U483 ( .A(n513), .B(pi1), .Z(n512)); + AN2 U484 ( .A(pi0), .B(n514), .Z(n513)); + OR2 U485 ( .A(n507), .B(n515), .Z(n514)); + AN2 U486 ( .A(n361), .B(n428), .Z(n465)); + AN2 U487 ( .A(po3), .B(n360), .Z(n489)); + OR2 U488 ( .A(n516), .B(n517), .Z(n509)); + OR2 U489 ( .A(n518), .B(n519), .Z(n517)); + AN2 U490 ( .A(n391), .B(n362), .Z(n519)); + AN2 U491 ( .A(n428), .B(n400), .Z(n391)); + AN2 U492 ( .A(n520), .B(n521), .Z(n518)); + OR2 U493 ( .A(n522), .B(n362), .Z(n521)); + AN2 U494 ( .A(n429), .B(n523), .Z(n520)); + AN2 U495 ( .A(n417), .B(n378), .Z(n516)); + AN2 U496 ( .A(n522), .B(n382), .Z(n500)); + AN2 U497 ( .A(pi1), .B(n396), .Z(n382)); + AN2 U498 ( .A(n361), .B(n378), .Z(n522)); + OR2 U499 ( .A(n524), .B(n525), .Z(n448)); + OR2 U500 ( .A(n526), .B(n527), .Z(n525)); + OR2 U501 ( .A(pi8), .B(n528), .Z(n524)); + AN2 U502 ( .A(n529), .B(n530), .Z(n430)); + OR2 U503 ( .A(n531), .B(n532), .Z(n529)); + OR2 U504 ( .A(n533), .B(n534), .Z(n532)); + OR2 U505 ( .A(n535), .B(n536), .Z(n534)); + AN2 U506 ( .A(n537), .B(n376), .Z(n536)); + IV2 U507 ( .A(n389), .Z(n376)); + AN2 U508 ( .A(n538), .B(n389), .Z(n535)); + OR2 U509 ( .A(n539), .B(n540), .Z(n389)); + OR2 U510 ( .A(n541), .B(n542), .Z(n540)); + OR2 U511 ( .A(n543), .B(n544), .Z(n542)); + AN2 U512 ( .A(pi1), .B(n545), .Z(n544)); + AN2 U513 ( .A(n546), .B(n428), .Z(n543)); + AN2 U514 ( .A(n547), .B(n548), .Z(n546)); + OR2 U515 ( .A(pi3), .B(n396), .Z(n548)); + AN2 U516 ( .A(pi9), .B(n549), .Z(n541)); + OR2 U517 ( .A(n550), .B(n551), .Z(n549)); + OR2 U518 ( .A(n552), .B(n553), .Z(n551)); + AN2 U519 ( .A(n554), .B(n507), .Z(n553)); + AN2 U520 ( .A(n396), .B(pi0), .Z(n554)); + AN2 U521 ( .A(n555), .B(n556), .Z(n552)); + AN2 U522 ( .A(n557), .B(n415), .Z(n556)); + AN2 U523 ( .A(po3), .B(n558), .Z(n555)); + OR2 U524 ( .A(n559), .B(n560), .Z(n550)); + AN2 U525 ( .A(n561), .B(n429), .Z(n560)); + AN2 U526 ( .A(n417), .B(n562), .Z(n561)); + OR2 U527 ( .A(n563), .B(n564), .Z(n562)); + AN2 U528 ( .A(n558), .B(n428), .Z(n564)); + AN2 U529 ( .A(pi1), .B(n565), .Z(n563)); + AN2 U530 ( .A(pi3), .B(n566), .Z(n559)); + OR2 U531 ( .A(n567), .B(n414), .Z(n566)); + AN2 U532 ( .A(n568), .B(n569), .Z(n567)); + AN2 U533 ( .A(n565), .B(n428), .Z(n568)); + OR2 U534 ( .A(n570), .B(n571), .Z(n539)); + AN2 U535 ( .A(n572), .B(n429), .Z(n571)); + AN2 U536 ( .A(po3), .B(n573), .Z(n570)); + OR2 U537 ( .A(n574), .B(n575), .Z(n538)); + OR2 U538 ( .A(n445), .B(n576), .Z(n575)); + AN2 U539 ( .A(n577), .B(pi3), .Z(n576)); + AN2 U540 ( .A(n578), .B(pi1), .Z(n574)); + AN2 U541 ( .A(n507), .B(pi1), .Z(n533)); + OR2 U542 ( .A(n579), .B(n580), .Z(n531)); + OR2 U543 ( .A(n581), .B(n582), .Z(n580)); + AN2 U544 ( .A(n444), .B(po3), .Z(n582)); + AN2 U545 ( .A(pi1), .B(pi3), .Z(po3)); + AN2 U546 ( .A(n583), .B(n557), .Z(n581)); + AN2 U547 ( .A(n584), .B(n429), .Z(n583)); + OR2 U548 ( .A(n585), .B(n414), .Z(n584)); + AN2 U549 ( .A(n417), .B(n428), .Z(n585)); + AN2 U550 ( .A(n586), .B(pi7), .Z(n579)); + AN2 U551 ( .A(n587), .B(n588), .Z(n586)); + OR2 U552 ( .A(pi3), .B(n589), .Z(n588)); + AN2 U553 ( .A(pi1), .B(n523), .Z(n589)); + OR2 U554 ( .A(n429), .B(n590), .Z(n587)); + OR2 U555 ( .A(n417), .B(n591), .Z(n590)); + AN2 U556 ( .A(n592), .B(n428), .Z(n591)); + IV2 U557 ( .A(pi1), .Z(n428)); + IV2 U558 ( .A(pi3), .Z(n429)); + OR2 U559 ( .A(n593), .B(n594), .Z(po0)); + OR2 U560 ( .A(n595), .B(n596), .Z(n594)); + AN2 U561 ( .A(n597), .B(pi8), .Z(n596)); + AN2 U562 ( .A(n598), .B(n381), .Z(n597)); + AN2 U563 ( .A(pi0), .B(n385), .Z(n381)); + AN2 U564 ( .A(n507), .B(n487), .Z(n598)); + AN2 U565 ( .A(n528), .B(n426), .Z(n595)); + AN2 U566 ( .A(pi6), .B(n599), .Z(n528)); + IV2 U567 ( .A(n600), .Z(n599)); + OR2 U568 ( .A(n601), .B(n361), .Z(n600)); + AN2 U569 ( .A(n602), .B(n603), .Z(n601)); + AN2 U570 ( .A(n604), .B(n605), .Z(n603)); + OR2 U571 ( .A(pi7), .B(n606), .Z(n605)); + OR2 U572 ( .A(n607), .B(n387), .Z(n606)); + OR2 U573 ( .A(n378), .B(n487), .Z(n604)); + AN2 U574 ( .A(n608), .B(n609), .Z(n602)); + OR2 U575 ( .A(pi2), .B(n415), .Z(n608)); + OR2 U576 ( .A(n610), .B(n611), .Z(n593)); + AN2 U577 ( .A(pi9), .B(n612), .Z(n611)); + OR2 U578 ( .A(n613), .B(n614), .Z(n612)); + OR2 U579 ( .A(n433), .B(n615), .Z(n614)); + AN2 U580 ( .A(n527), .B(n426), .Z(n615)); + OR2 U581 ( .A(n616), .B(n617), .Z(n527)); + AN2 U582 ( .A(n618), .B(n361), .Z(n617)); + OR2 U583 ( .A(n619), .B(n620), .Z(n618)); + OR2 U584 ( .A(n621), .B(n622), .Z(n620)); + AN2 U585 ( .A(n592), .B(n362), .Z(n622)); + AN2 U586 ( .A(n385), .B(n623), .Z(n621)); + OR2 U587 ( .A(n624), .B(n625), .Z(n623)); + AN2 U588 ( .A(n626), .B(n415), .Z(n625)); + AN2 U589 ( .A(n507), .B(n523), .Z(n624)); + AN2 U590 ( .A(n473), .B(n557), .Z(n619)); + AN2 U591 ( .A(n523), .B(n387), .Z(n473)); + AN2 U592 ( .A(n569), .B(n387), .Z(n616)); + AN2 U593 ( .A(n578), .B(n627), .Z(n433)); + AN2 U594 ( .A(n378), .B(n475), .Z(n627)); + OR2 U595 ( .A(n628), .B(n629), .Z(n613)); + AN2 U596 ( .A(n526), .B(n426), .Z(n629)); + IV2 U597 ( .A(pi8), .Z(n426)); + AN2 U598 ( .A(n360), .B(n405), .Z(n526)); + AN2 U599 ( .A(pi8), .B(n630), .Z(n628)); + OR2 U600 ( .A(n631), .B(n439), .Z(n630)); + OR2 U601 ( .A(n632), .B(n633), .Z(n439)); + OR2 U602 ( .A(n634), .B(n635), .Z(n633)); + AN2 U603 ( .A(n636), .B(n378), .Z(n635)); + OR2 U604 ( .A(n637), .B(n360), .Z(n636)); + AN2 U605 ( .A(n387), .B(n475), .Z(n637)); + AN2 U606 ( .A(n638), .B(n475), .Z(n634)); + OR2 U607 ( .A(n639), .B(n640), .Z(n638)); + AN2 U608 ( .A(n558), .B(pi4), .Z(n639)); + OR2 U609 ( .A(n463), .B(n641), .Z(n632)); + AN2 U610 ( .A(n642), .B(n385), .Z(n641)); + AN2 U611 ( .A(n557), .B(n361), .Z(n642)); + AN2 U612 ( .A(n361), .B(n578), .Z(n463)); + AN2 U613 ( .A(n403), .B(n361), .Z(n631)); + IV2 U614 ( .A(n609), .Z(n403)); + OR2 U615 ( .A(n385), .B(n378), .Z(n609)); + AN2 U616 ( .A(n643), .B(n530), .Z(n610)); + OR2 U617 ( .A(n644), .B(n645), .Z(n643)); + OR2 U618 ( .A(n646), .B(n647), .Z(n645)); + OR2 U619 ( .A(n648), .B(n649), .Z(n647)); + AN2 U620 ( .A(n537), .B(n385), .Z(n649)); + IV2 U621 ( .A(n387), .Z(n385)); + OR2 U622 ( .A(n650), .B(n651), .Z(n537)); + AN2 U623 ( .A(n396), .B(pi6), .Z(n651)); + AN2 U624 ( .A(n400), .B(n475), .Z(n650)); + AN2 U625 ( .A(n652), .B(n387), .Z(n648)); + OR2 U626 ( .A(n653), .B(n654), .Z(n387)); + OR2 U627 ( .A(n655), .B(n656), .Z(n654)); + OR2 U628 ( .A(n657), .B(n658), .Z(n656)); + AN2 U629 ( .A(n360), .B(n573), .Z(n658)); + OR2 U630 ( .A(n659), .B(n660), .Z(n573)); + AN2 U631 ( .A(n405), .B(n578), .Z(n660)); + AN2 U632 ( .A(n396), .B(n661), .Z(n659)); + OR2 U633 ( .A(n405), .B(n557), .Z(n661)); + AN2 U634 ( .A(n475), .B(pi7), .Z(n405)); + IV2 U635 ( .A(n607), .Z(n396)); + OR2 U636 ( .A(pi5), .B(pi4), .Z(n607)); + AN2 U637 ( .A(n640), .B(n417), .Z(n657)); + AN2 U638 ( .A(n572), .B(n362), .Z(n655)); + OR2 U639 ( .A(n662), .B(n663), .Z(n572)); + OR2 U640 ( .A(n664), .B(n665), .Z(n663)); + AN2 U641 ( .A(n578), .B(n557), .Z(n665)); + AN2 U642 ( .A(n417), .B(n626), .Z(n664)); + AN2 U643 ( .A(n507), .B(n530), .Z(n662)); + OR2 U644 ( .A(n666), .B(n667), .Z(n653)); + OR2 U645 ( .A(n668), .B(n669), .Z(n667)); + AN2 U646 ( .A(n670), .B(n545), .Z(n669)); + OR2 U647 ( .A(n400), .B(n671), .Z(n545)); + AN2 U648 ( .A(pi9), .B(n414), .Z(n671)); + AN2 U649 ( .A(n378), .B(n414), .Z(n400)); + IV2 U650 ( .A(pi7), .Z(n378)); + OR2 U651 ( .A(pi0), .B(pi2), .Z(n670)); + AN2 U652 ( .A(n672), .B(n547), .Z(n668)); + AN2 U653 ( .A(n475), .B(n530), .Z(n547)); + IV2 U654 ( .A(pi9), .Z(n530)); + AN2 U655 ( .A(n361), .B(n415), .Z(n672)); + AN2 U656 ( .A(n558), .B(n569), .Z(n666)); + AN2 U657 ( .A(n557), .B(n417), .Z(n569)); + OR2 U658 ( .A(n673), .B(n674), .Z(n652)); + OR2 U659 ( .A(n445), .B(n675), .Z(n674)); + AN2 U660 ( .A(n577), .B(pi2), .Z(n675)); + AN2 U661 ( .A(n523), .B(n447), .Z(n445)); + OR2 U662 ( .A(n577), .B(n507), .Z(n447)); + AN2 U663 ( .A(n475), .B(n415), .Z(n577)); + AN2 U664 ( .A(n578), .B(pi0), .Z(n673)); + IV2 U665 ( .A(n487), .Z(n578)); + OR2 U666 ( .A(n415), .B(n523), .Z(n487)); + AN2 U667 ( .A(n507), .B(pi0), .Z(n646)); + AN2 U668 ( .A(pi6), .B(pi7), .Z(n507)); + OR2 U669 ( .A(n676), .B(n677), .Z(n644)); + OR2 U670 ( .A(n678), .B(n679), .Z(n677)); + AN2 U671 ( .A(n444), .B(n360), .Z(n679)); + IV2 U672 ( .A(n401), .Z(n360)); + OR2 U673 ( .A(n362), .B(n361), .Z(n401)); + AN2 U674 ( .A(pi6), .B(n417), .Z(n444)); + AN2 U675 ( .A(n680), .B(n557), .Z(n678)); + IV2 U676 ( .A(n626), .Z(n557)); + OR2 U677 ( .A(pi7), .B(n475), .Z(n626)); + AN2 U678 ( .A(n681), .B(n362), .Z(n680)); + OR2 U679 ( .A(n682), .B(n414), .Z(n681)); + AN2 U680 ( .A(n417), .B(n361), .Z(n682)); + IV2 U681 ( .A(pi0), .Z(n361)); + AN2 U682 ( .A(pi7), .B(n683), .Z(n676)); + OR2 U683 ( .A(n684), .B(n685), .Z(n683)); + OR2 U684 ( .A(n686), .B(n687), .Z(n685)); + AN2 U685 ( .A(n592), .B(n558), .Z(n687)); + IV2 U686 ( .A(n565), .Z(n558)); + OR2 U687 ( .A(pi0), .B(n362), .Z(n565)); + AN2 U688 ( .A(n475), .B(n414), .Z(n592)); + IV2 U689 ( .A(n515), .Z(n414)); + OR2 U690 ( .A(pi5), .B(n415), .Z(n515)); + IV2 U691 ( .A(pi6), .Z(n475)); + AN2 U692 ( .A(n640), .B(n523), .Z(n686)); + IV2 U693 ( .A(pi5), .Z(n523)); + AN2 U694 ( .A(n362), .B(pi0), .Z(n640)); + IV2 U695 ( .A(pi2), .Z(n362)); + AN2 U696 ( .A(n417), .B(pi2), .Z(n684)); + AN2 U697 ( .A(n415), .B(pi5), .Z(n417)); + IV2 U698 ( .A(pi4), .Z(n415)); + +endmodule + +module IV2(A, Z); + input A; + output Z; + + assign Z = ~A; +endmodule + +module AN2(A, B, Z); + input A, B; + output Z; + + assign Z = A & B; +endmodule + +module OR2(A, B, Z); + input A, B; + output Z; + + assign Z = A | B; +endmodule diff --git a/examples/smtbmc/glift/alu2.ys b/examples/smtbmc/glift/alu2.ys new file mode 100644 index 00000000000..b0d7b3164e5 --- /dev/null +++ b/examples/smtbmc/glift/alu2.ys @@ -0,0 +1,45 @@ +read_verilog alu2.v +techmap +flatten +select alu2_lev2 +glift -optimize-precise +techmap +opt +rename alu2_lev2 uut +cd .. +delete [AIONX][NVXR]2 +read_verilog alu2.v +techmap +flatten +select alu2_lev2 +glift -create-precise +techmap +opt +rename alu2_lev2 spec +cd .. +delete [AIONX][NVXR]2 + +design -push-copy +miter -equiv spec uut miter +flatten +delete uut spec +techmap +opt +stat miter +abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter +techmap +opt +stat +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu2.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +design -pop +stat + +copy uut solved +qbfsat -specialize-from-file alu2.soln solved +opt solved +miter -equiv spec solved satmiter +flatten +sat -prove trigger 0 satmiter +delete satmiter +stat +shell diff --git a/examples/smtbmc/glift/alu4.v b/examples/smtbmc/glift/alu4.v new file mode 100755 index 00000000000..e110612e53f --- /dev/null +++ b/examples/smtbmc/glift/alu4.v @@ -0,0 +1,802 @@ +module alu4_lev2(pi00, pi01, pi02, pi03, pi04, pi05, pi06, pi07, pi08, pi09, + pi10, pi11, pi12, pi13, po0, po1, po2, po3, po4, po5, po6, po7); + +input pi00, pi01, pi02, pi03, pi04, pi05, pi06, pi07, pi08, pi09, + pi10, pi11, pi12, pi13; + +output po0, po1, po2, po3, po4, po5, po6, po7; + +wire n705, n706, n707, n708, n709, n710, n711, n712, n713, n714, + n715, n716, n717, n718, n719, n720, n721, n722, n723, n724, + n725, n726, n727, n728, n729, n730, n731, n732, n733, n734, + n735, n736, n737, n738, n739, n740, n741, n742, n743, n744, + n745, n746, n747, n748, n749, n750, n751, n752, n753, n754, + n755, n756, n757, n758, n759, n760, n761, n762, n763, n764, + n765, n766, n767, n768, n769, n770, n771, n772, n773, n774, + n775, n776, n777, n778, n779, n780, n781, n782, n783, n784, + n785, n786, n787, n788, n789, n790, n791, n792, n793, n794, + n795, n796, n797, n798, n799, n800, n801, n802, n803, n804, + n805, n806, n807, n808, n809, n810, n811, n812, n813, n814, + n815, n816, n817, n818, n819, n820, n821, n822, n823, n824, + n825, n826, n827, n828, n829, n830, n831, n832, n833, n834, + n835, n836, n837, n838, n839, n840, n841, n842, n843, n844, + n845, n846, n847, n848, n849, n850, n851, n852, n853, n854, + n855, n856, n857, n858, n859, n860, n861, n862, n863, n864, + n865, n866, n867, n868, n869, n870, n871, n872, n873, n874, + n875, n876, n877, n878, n879, n880, n881, n882, n883, n884, + n885, n886, n887, n888, n889, n890, n891, n892, n893, n894, + n895, n896, n897, n898, n899, n900, n901, n902, n903, n904, + n905, n906, n907, n908, n909, n910, n911, n912, n913, n914, + n915, n916, n917, n918, n919, n920, n921, n922, n923, n924, + n925, n926, n927, n928, n929, n930, n931, n932, n933, n934, + n935, n936, n937, n938, n939, n940, n941, n942, n943, n944, + n945, n946, n947, n948, n949, n950, n951, n952, n953, n954, + n955, n956, n957, n958, n959, n960, n961, n962, n963, n964, + n965, n966, n967, n968, n969, n970, n971, n972, n973, n974, + n975, n976, n977, n978, n979, n980, n981, n982, n983, n984, + n985, n986, n987, n988, n989, n990, n991, n992, n993, n994, + n995, n996, n997, n998, n999, n1000, n1001, n1002, n1003, n1004, + n1005, n1006, n1007, n1008, n1009, n1010, n1011, n1012, n1013, n1014, + n1015, n1016, n1017, n1018, n1019, n1020, n1021, n1022, n1023, n1024, + n1025, n1026, n1027, n1028, n1029, n1030, n1031, n1032, n1033, n1034, + n1035, n1036, n1037, n1038, n1039, n1040, n1041, n1042, n1043, n1044, + n1045, n1046, n1047, n1048, n1049, n1050, n1051, n1052, n1053, n1054, + n1055, n1056, n1057, n1058, n1059, n1060, n1061, n1062, n1063, n1064, + n1065, n1066, n1067, n1068, n1069, n1070, n1071, n1072, n1073, n1074, + n1075, n1076, n1077, n1078, n1079, n1080, n1081, n1082, n1083, n1084, + n1085, n1086, n1087, n1088, n1089, n1090, n1091, n1092, n1093, n1094, + n1095, n1096, n1097, n1098, n1099, n1100, n1101, n1102, n1103, n1104, + n1105, n1106, n1107, n1108, n1109, n1110, n1111, n1112, n1113, n1114, + n1115, n1116, n1117, n1118, n1119, n1120, n1121, n1122, n1123, n1124, + n1125, n1126, n1127, n1128, n1129, n1130, n1131, n1132, n1133, n1134, + n1135, n1136, n1137, n1138, n1139, n1140, n1141, n1142, n1143, n1144, + n1145, n1146, n1147, n1148, n1149, n1150, n1151, n1152, n1153, n1154, + n1155, n1156, n1157, n1158, n1159, n1160, n1161, n1162, n1163, n1164, + n1165, n1166, n1167, n1168, n1169, n1170, n1171, n1172, n1173, n1174, + n1175, n1176, n1177, n1178, n1179, n1180, n1181, n1182, n1183, n1184, + n1185, n1186, n1187, n1188, n1189, n1190, n1191, n1192, n1193, n1194, + n1195, n1196, n1197, n1198, n1199, n1200, n1201, n1202, n1203, n1204, + n1205, n1206, n1207, n1208, n1209, n1210, n1211, n1212, n1213, n1214, + n1215, n1216, n1217, n1218, n1219, n1220, n1221, n1222, n1223, n1224, + n1225, n1226, n1227, n1228, n1229, n1230, n1231, n1232, n1233, n1234, + n1235, n1236, n1237, n1238, n1239, n1240, n1241, n1242, n1243, n1244, + n1245, n1246, n1247, n1248, n1249, n1250, n1251, n1252, n1253, n1254, + n1255, n1256, n1257, n1258, n1259, n1260, n1261, n1262, n1263, n1264, + n1265, n1266, n1267, n1268, n1269, n1270, n1271, n1272, n1273, n1274, + n1275, n1276, n1277, n1278, n1279, n1280, n1281, n1282, n1283, n1284, + n1285, n1286, n1287, n1288, n1289, n1290, n1291, n1292, n1293, n1294, + n1295, n1296, n1297, n1298, n1299, n1300, n1301, n1302, n1303, n1304, + n1305, n1306, n1307, n1308, n1309, n1310, n1311, n1312, n1313, n1314, + n1315, n1316, n1317, n1318, n1319, n1320, n1321, n1322, n1323, n1324, + n1325, n1326, n1327, n1328, n1329, n1330, n1331, n1332, n1333, n1334, + n1335, n1336, n1337, n1338, n1339, n1340, n1341, n1342, n1343, n1344, + n1345, n1346, n1347, n1348, n1349, n1350, n1351, n1352, n1353, n1354, + n1355, n1356, n1357, n1358, n1359, n1360, n1361, n1362, n1363, n1364, + n1365, n1366, n1367, n1368, n1369, n1370, n1371, n1372, n1373, n1374, + n1375, n1376, n1377, n1378, n1379, n1380, n1381, n1382, n1383, n1384, + n1385, n1386, n1387, n1388, n1389, n1390, n1391, n1392, n1393, n1394, + n1395, n1396; + + AN2 U712 ( .A(n705), .B(po4), .Z(po7)); + OR2 U713 ( .A(n706), .B(n707), .Z(n705)); + AN2 U714 ( .A(n708), .B(n709), .Z(n707)); + OR2 U715 ( .A(n710), .B(n711), .Z(n708)); + AN2 U716 ( .A(n712), .B(n713), .Z(n711)); + AN2 U717 ( .A(n714), .B(n715), .Z(n710)); + AN2 U718 ( .A(n716), .B(n717), .Z(n714)); + AN2 U719 ( .A(n718), .B(n719), .Z(n706)); + OR2 U720 ( .A(n720), .B(n712), .Z(n719)); + OR2 U721 ( .A(n721), .B(n722), .Z(n712)); + AN2 U722 ( .A(n723), .B(n724), .Z(n722)); + AN2 U723 ( .A(n725), .B(n726), .Z(n721)); + OR2 U724 ( .A(n724), .B(n727), .Z(n726)); + AN2 U725 ( .A(n727), .B(n723), .Z(n720)); + OR2 U726 ( .A(n728), .B(n729), .Z(po6)); + AN2 U727 ( .A(pi13), .B(n730), .Z(n729)); + OR2 U728 ( .A(n731), .B(n732), .Z(n730)); + OR2 U729 ( .A(n733), .B(n734), .Z(n732)); + OR2 U730 ( .A(n735), .B(n736), .Z(n734)); + AN2 U731 ( .A(n737), .B(n738), .Z(n736)); + OR2 U732 ( .A(n739), .B(n740), .Z(n737)); + OR2 U733 ( .A(n741), .B(n742), .Z(n740)); + AN2 U734 ( .A(n743), .B(n744), .Z(n742)); + OR2 U735 ( .A(n745), .B(n746), .Z(n743)); + AN2 U736 ( .A(pi03), .B(n747), .Z(n745)); + AN2 U737 ( .A(n748), .B(n749), .Z(n741)); + AN2 U738 ( .A(n750), .B(n751), .Z(n748)); + AN2 U739 ( .A(pi11), .B(n752), .Z(n735)); + OR2 U740 ( .A(n753), .B(n754), .Z(n752)); + OR2 U741 ( .A(n755), .B(n756), .Z(n754)); + AN2 U742 ( .A(n757), .B(n747), .Z(n756)); + OR2 U743 ( .A(n758), .B(n759), .Z(n757)); + IV2 U744 ( .A(n760), .Z(n755)); + AN2 U745 ( .A(n761), .B(n762), .Z(n753)); + OR2 U746 ( .A(n763), .B(po5), .Z(n762)); + AN2 U747 ( .A(n764), .B(n765), .Z(n763)); + AN2 U748 ( .A(n766), .B(n767), .Z(n733)); + OR2 U749 ( .A(n768), .B(n769), .Z(n767)); + AN2 U750 ( .A(n770), .B(n771), .Z(n768)); + IV2 U751 ( .A(n772), .Z(n766)); + OR2 U752 ( .A(n773), .B(n774), .Z(n731)); + AN2 U753 ( .A(n775), .B(n776), .Z(n774)); + AN2 U754 ( .A(n777), .B(n778), .Z(n775)); + AN2 U755 ( .A(n779), .B(n780), .Z(n773)); + AN2 U756 ( .A(n781), .B(n782), .Z(n779)); + AN2 U757 ( .A(n783), .B(n781), .Z(n728)); + AN2 U758 ( .A(n782), .B(n784), .Z(n783)); + OR2 U759 ( .A(n785), .B(n786), .Z(po3)); + OR2 U760 ( .A(n787), .B(n788), .Z(n786)); + OR2 U761 ( .A(n789), .B(n790), .Z(n788)); + OR2 U762 ( .A(n791), .B(n792), .Z(n790)); + AN2 U763 ( .A(n793), .B(n782), .Z(n792)); + AN2 U764 ( .A(n794), .B(n795), .Z(n791)); + OR2 U765 ( .A(n796), .B(n797), .Z(n789)); + IV2 U766 ( .A(n798), .Z(n797)); + OR2 U767 ( .A(n799), .B(n778), .Z(n798)); + AN2 U768 ( .A(n778), .B(n799), .Z(n796)); + OR2 U769 ( .A(n800), .B(n801), .Z(n799)); + IV2 U770 ( .A(n802), .Z(n778)); + OR2 U771 ( .A(n803), .B(n804), .Z(n802)); + AN2 U772 ( .A(n805), .B(n806), .Z(n803)); + AN2 U773 ( .A(n807), .B(n808), .Z(n806)); + AN2 U774 ( .A(n809), .B(n810), .Z(n808)); + OR2 U775 ( .A(pi11), .B(n811), .Z(n810)); + AN2 U776 ( .A(n812), .B(n813), .Z(n811)); + AN2 U777 ( .A(n814), .B(n815), .Z(n813)); + OR2 U778 ( .A(n782), .B(n816), .Z(n815)); + OR2 U779 ( .A(n817), .B(n818), .Z(n814)); + OR2 U780 ( .A(n819), .B(n820), .Z(n818)); + AN2 U781 ( .A(n750), .B(n821), .Z(n820)); + AN2 U782 ( .A(n749), .B(n747), .Z(n819)); + IV2 U783 ( .A(n821), .Z(n749)); + AN2 U784 ( .A(n822), .B(n823), .Z(n812)); + OR2 U785 ( .A(n824), .B(n825), .Z(n823)); + OR2 U786 ( .A(n826), .B(n827), .Z(n822)); + AN2 U787 ( .A(pi10), .B(n828), .Z(n826)); + OR2 U788 ( .A(n829), .B(n830), .Z(n828)); + OR2 U789 ( .A(n831), .B(n738), .Z(n809)); + AN2 U790 ( .A(n832), .B(n833), .Z(n831)); + AN2 U791 ( .A(n834), .B(n760), .Z(n833)); + OR2 U792 ( .A(n817), .B(n835), .Z(n760)); + OR2 U793 ( .A(pi03), .B(n836), .Z(n835)); + OR2 U794 ( .A(n817), .B(n837), .Z(n834)); + OR2 U795 ( .A(n715), .B(n827), .Z(n837)); + IV2 U796 ( .A(n836), .Z(n715)); + AN2 U797 ( .A(n838), .B(n839), .Z(n832)); + OR2 U798 ( .A(n765), .B(n840), .Z(n839)); + OR2 U799 ( .A(n841), .B(n825), .Z(n840)); + OR2 U800 ( .A(n816), .B(n842), .Z(n838)); + OR2 U801 ( .A(n843), .B(n844), .Z(n842)); + AN2 U802 ( .A(n845), .B(n846), .Z(n844)); + OR2 U803 ( .A(n847), .B(n848), .Z(n845)); + AN2 U804 ( .A(n758), .B(n747), .Z(n848)); + IV2 U805 ( .A(n849), .Z(n758)); + AN2 U806 ( .A(n750), .B(n849), .Z(n847)); + AN2 U807 ( .A(n849), .B(n759), .Z(n843)); + OR2 U808 ( .A(n850), .B(n851), .Z(n849)); + AN2 U809 ( .A(n852), .B(n853), .Z(n850)); + IV2 U810 ( .A(n854), .Z(n816)); + AN2 U811 ( .A(n855), .B(n856), .Z(n807)); + OR2 U812 ( .A(n857), .B(n858), .Z(n856)); + OR2 U813 ( .A(n859), .B(n860), .Z(n858)); + AN2 U814 ( .A(n861), .B(n739), .Z(n859)); + OR2 U815 ( .A(n862), .B(n863), .Z(n739)); + AN2 U816 ( .A(n759), .B(n795), .Z(n862)); + OR2 U817 ( .A(n846), .B(n864), .Z(n861)); + IV2 U818 ( .A(n865), .Z(n864)); + AN2 U819 ( .A(n795), .B(n863), .Z(n865)); + IV2 U820 ( .A(n759), .Z(n846)); + OR2 U821 ( .A(n866), .B(n867), .Z(n759)); + AN2 U822 ( .A(n868), .B(po5), .Z(n867)); + AN2 U823 ( .A(n750), .B(n869), .Z(n866)); + OR2 U824 ( .A(n825), .B(n870), .Z(n855)); + OR2 U825 ( .A(n871), .B(n872), .Z(n870)); + AN2 U826 ( .A(n764), .B(n873), .Z(n872)); + IV2 U827 ( .A(po5), .Z(n873)); + AN2 U828 ( .A(n841), .B(po4), .Z(n871)); + OR2 U829 ( .A(n874), .B(po5), .Z(po4)); + IV2 U830 ( .A(n764), .Z(n841)); + OR2 U831 ( .A(n875), .B(n724), .Z(n764)); + AN2 U832 ( .A(n876), .B(n877), .Z(n875)); + AN2 U833 ( .A(n878), .B(n879), .Z(n805)); + AN2 U834 ( .A(n880), .B(n881), .Z(n879)); + OR2 U835 ( .A(n782), .B(n882), .Z(n881)); + OR2 U836 ( .A(n781), .B(n883), .Z(n882)); + IV2 U837 ( .A(n884), .Z(n781)); + OR2 U838 ( .A(n795), .B(n885), .Z(n880)); + AN2 U839 ( .A(n886), .B(n887), .Z(n878)); + OR2 U840 ( .A(pi03), .B(n888), .Z(n887)); + AN2 U841 ( .A(n889), .B(n890), .Z(n888)); + IV2 U842 ( .A(n891), .Z(n890)); + AN2 U843 ( .A(n830), .B(n892), .Z(n891)); + OR2 U844 ( .A(n893), .B(n894), .Z(n830)); + IV2 U845 ( .A(n895), .Z(n894)); + OR2 U846 ( .A(n746), .B(n750), .Z(n895)); + AN2 U847 ( .A(n750), .B(n746), .Z(n893)); + OR2 U848 ( .A(n896), .B(n897), .Z(n746)); + AN2 U849 ( .A(pi02), .B(n898), .Z(n896)); + IV2 U850 ( .A(n747), .Z(n750)); + OR2 U851 ( .A(n899), .B(n900), .Z(n747)); + AN2 U852 ( .A(n901), .B(n771), .Z(n900)); + OR2 U853 ( .A(pi03), .B(n795), .Z(n771)); + AN2 U854 ( .A(n902), .B(n903), .Z(n899)); + OR2 U855 ( .A(n904), .B(n905), .Z(n903)); + OR2 U856 ( .A(n906), .B(n907), .Z(n905)); + AN2 U857 ( .A(n782), .B(n892), .Z(n907)); + AN2 U858 ( .A(n769), .B(n751), .Z(n906)); + AN2 U859 ( .A(po5), .B(n908), .Z(n904)); + OR2 U860 ( .A(n909), .B(n772), .Z(n889)); + AN2 U861 ( .A(n910), .B(n911), .Z(n909)); + OR2 U862 ( .A(n912), .B(n795), .Z(n911)); + OR2 U863 ( .A(n782), .B(n770), .Z(n910)); + OR2 U864 ( .A(n827), .B(n913), .Z(n886)); + OR2 U865 ( .A(n914), .B(n772), .Z(n913)); + OR2 U866 ( .A(n915), .B(n916), .Z(n914)); + AN2 U867 ( .A(n912), .B(n795), .Z(n916)); + IV2 U868 ( .A(n770), .Z(n912)); + AN2 U869 ( .A(n782), .B(n770), .Z(n915)); + OR2 U870 ( .A(n917), .B(n918), .Z(n770)); + AN2 U871 ( .A(n919), .B(n920), .Z(n917)); + IV2 U872 ( .A(n795), .Z(n782)); + OR2 U873 ( .A(n921), .B(n922), .Z(n787)); + AN2 U874 ( .A(n923), .B(n824), .Z(n922)); + AN2 U875 ( .A(n924), .B(n925), .Z(n923)); + OR2 U876 ( .A(n926), .B(n927), .Z(n925)); + AN2 U877 ( .A(pi11), .B(pi03), .Z(n926)); + AN2 U878 ( .A(pi07), .B(n928), .Z(n921)); + OR2 U879 ( .A(n929), .B(n930), .Z(n928)); + AN2 U880 ( .A(n931), .B(n804), .Z(n929)); + OR2 U881 ( .A(n932), .B(n933), .Z(n931)); + AN2 U882 ( .A(n854), .B(n795), .Z(n933)); + AN2 U883 ( .A(n934), .B(n827), .Z(n932)); + OR2 U884 ( .A(n935), .B(n936), .Z(n785)); + OR2 U885 ( .A(n937), .B(n938), .Z(n936)); + AN2 U886 ( .A(n939), .B(n940), .Z(n938)); + OR2 U887 ( .A(n941), .B(n942), .Z(n940)); + OR2 U888 ( .A(n769), .B(n943), .Z(n942)); + AN2 U889 ( .A(n874), .B(n944), .Z(n943)); + AN2 U890 ( .A(n795), .B(pi03), .Z(n769)); + OR2 U891 ( .A(n945), .B(n946), .Z(n795)); + OR2 U892 ( .A(n947), .B(n948), .Z(n946)); + AN2 U893 ( .A(n949), .B(n824), .Z(n948)); + AN2 U894 ( .A(n950), .B(n765), .Z(n947)); + IV2 U895 ( .A(n874), .Z(n765)); + OR2 U896 ( .A(n951), .B(n952), .Z(n945)); + OR2 U897 ( .A(n953), .B(n954), .Z(n952)); + AN2 U898 ( .A(n955), .B(n827), .Z(n954)); + OR2 U899 ( .A(n956), .B(n957), .Z(n955)); + AN2 U900 ( .A(n958), .B(n784), .Z(n956)); + AN2 U901 ( .A(pi07), .B(n959), .Z(n958)); + AN2 U902 ( .A(po5), .B(n960), .Z(n953)); + OR2 U903 ( .A(n961), .B(n962), .Z(n960)); + AN2 U904 ( .A(n892), .B(n963), .Z(n962)); + AN2 U905 ( .A(n964), .B(n965), .Z(n961)); + AN2 U906 ( .A(pi13), .B(n966), .Z(n951)); + OR2 U907 ( .A(n967), .B(n968), .Z(n966)); + OR2 U908 ( .A(n969), .B(n970), .Z(n968)); + AN2 U909 ( .A(n971), .B(pi02), .Z(n970)); + AN2 U910 ( .A(n972), .B(n973), .Z(n969)); + AN2 U911 ( .A(n974), .B(n975), .Z(n972)); + OR2 U912 ( .A(n874), .B(n959), .Z(n975)); + AN2 U913 ( .A(n827), .B(n824), .Z(n874)); + IV2 U914 ( .A(pi03), .Z(n827)); + OR2 U915 ( .A(n964), .B(n976), .Z(n974)); + AN2 U916 ( .A(pi03), .B(n824), .Z(n976)); + IV2 U917 ( .A(pi07), .Z(n824)); + IV2 U918 ( .A(n959), .Z(n964)); + OR2 U919 ( .A(n977), .B(n978), .Z(n959)); + AN2 U920 ( .A(n979), .B(pi02), .Z(n978)); + AN2 U921 ( .A(n980), .B(n717), .Z(n977)); + OR2 U922 ( .A(n979), .B(pi02), .Z(n980)); + AN2 U923 ( .A(n981), .B(po5), .Z(n967)); + AN2 U924 ( .A(po5), .B(n982), .Z(n941)); + AN2 U925 ( .A(pi03), .B(pi07), .Z(po5)); + AN2 U926 ( .A(n983), .B(pi03), .Z(n935)); + OR2 U927 ( .A(n984), .B(n985), .Z(po2)); + OR2 U928 ( .A(n986), .B(n987), .Z(n985)); + OR2 U929 ( .A(n988), .B(n989), .Z(n987)); + OR2 U930 ( .A(n990), .B(n991), .Z(n989)); + AN2 U931 ( .A(n793), .B(n992), .Z(n991)); + AN2 U932 ( .A(n794), .B(n993), .Z(n990)); + OR2 U933 ( .A(n994), .B(n995), .Z(n988)); + AN2 U934 ( .A(n777), .B(n801), .Z(n995)); + IV2 U935 ( .A(n800), .Z(n777)); + AN2 U936 ( .A(n776), .B(n800), .Z(n994)); + OR2 U937 ( .A(n996), .B(n804), .Z(n800)); + AN2 U938 ( .A(n997), .B(n998), .Z(n996)); + AN2 U939 ( .A(n999), .B(n1000), .Z(n998)); + AN2 U940 ( .A(n1001), .B(n1002), .Z(n1000)); + OR2 U941 ( .A(n1003), .B(n817), .Z(n1002)); + AN2 U942 ( .A(n1004), .B(n836), .Z(n1003)); + OR2 U943 ( .A(pi00), .B(n1005), .Z(n836)); + OR2 U944 ( .A(pi02), .B(pi01), .Z(n1005)); + AN2 U945 ( .A(n1006), .B(n1007), .Z(n1004)); + OR2 U946 ( .A(pi11), .B(n1008), .Z(n1007)); + AN2 U947 ( .A(n1009), .B(n821), .Z(n1008)); + OR2 U948 ( .A(n898), .B(n1010), .Z(n821)); + OR2 U949 ( .A(n1011), .B(n851), .Z(n1009)); + AN2 U950 ( .A(n1012), .B(n1013), .Z(n1011)); + OR2 U951 ( .A(n738), .B(n1014), .Z(n1006)); + OR2 U952 ( .A(n1015), .B(n1016), .Z(n1014)); + AN2 U953 ( .A(n713), .B(n1017), .Z(n1015)); + OR2 U954 ( .A(n1018), .B(n1019), .Z(n1001)); + OR2 U955 ( .A(n744), .B(n1020), .Z(n1019)); + OR2 U956 ( .A(n1021), .B(n1022), .Z(n1018)); + AN2 U957 ( .A(n717), .B(n1023), .Z(n1022)); + AN2 U958 ( .A(n863), .B(n1024), .Z(n1021)); + OR2 U959 ( .A(n1025), .B(n1026), .Z(n1024)); + OR2 U960 ( .A(n992), .B(n852), .Z(n1026)); + IV2 U961 ( .A(n1027), .Z(n1025)); + OR2 U962 ( .A(n1028), .B(n1027), .Z(n863)); + OR2 U963 ( .A(n1029), .B(n1030), .Z(n1027)); + AN2 U964 ( .A(n1031), .B(n1032), .Z(n1029)); + AN2 U965 ( .A(n1033), .B(n993), .Z(n1028)); + AN2 U966 ( .A(n885), .B(n1034), .Z(n999)); + OR2 U967 ( .A(n825), .B(n1035), .Z(n1034)); + OR2 U968 ( .A(n1036), .B(n1037), .Z(n1035)); + AN2 U969 ( .A(n1038), .B(n1039), .Z(n1037)); + IV2 U970 ( .A(n724), .Z(n1039)); + OR2 U971 ( .A(n877), .B(n738), .Z(n1038)); + IV2 U972 ( .A(n876), .Z(n1036)); + OR2 U973 ( .A(n1040), .B(n884), .Z(n885)); + OR2 U974 ( .A(n1041), .B(n1042), .Z(n884)); + OR2 U975 ( .A(n993), .B(n1032), .Z(n1042)); + AN2 U976 ( .A(n1043), .B(n1044), .Z(n997)); + AN2 U977 ( .A(n1045), .B(n1046), .Z(n1044)); + OR2 U978 ( .A(pi02), .B(n1047), .Z(n1046)); + AN2 U979 ( .A(n1048), .B(n1049), .Z(n1047)); + OR2 U980 ( .A(n876), .B(n1050), .Z(n1049)); + OR2 U981 ( .A(n717), .B(n825), .Z(n1050)); + AN2 U982 ( .A(n1051), .B(n1052), .Z(n1048)); + OR2 U983 ( .A(n1053), .B(n1054), .Z(n1052)); + OR2 U984 ( .A(n1055), .B(n772), .Z(n1051)); + AN2 U985 ( .A(n1056), .B(n1057), .Z(n1055)); + OR2 U986 ( .A(n1058), .B(n993), .Z(n1057)); + OR2 U987 ( .A(n992), .B(n919), .Z(n1056)); + OR2 U988 ( .A(n1059), .B(n1016), .Z(n1045)); + AN2 U989 ( .A(n1060), .B(n1061), .Z(n1059)); + AN2 U990 ( .A(n1062), .B(n1063), .Z(n1061)); + OR2 U991 ( .A(n876), .B(n1064), .Z(n1062)); + OR2 U992 ( .A(pi06), .B(n825), .Z(n1064)); + OR2 U993 ( .A(n1065), .B(n725), .Z(n876)); + AN2 U994 ( .A(n718), .B(n1066), .Z(n1065)); + AN2 U995 ( .A(n1067), .B(n1068), .Z(n1060)); + OR2 U996 ( .A(n772), .B(n1069), .Z(n1068)); + OR2 U997 ( .A(n1070), .B(n1071), .Z(n1069)); + AN2 U998 ( .A(n1058), .B(n993), .Z(n1071)); + IV2 U999 ( .A(n919), .Z(n1058)); + AN2 U1000 ( .A(n992), .B(n919), .Z(n1070)); + OR2 U1001 ( .A(n1072), .B(n1073), .Z(n919)); + AN2 U1002 ( .A(n1074), .B(n1075), .Z(n1072)); + OR2 U1003 ( .A(n1054), .B(n1076), .Z(n1067)); + IV2 U1004 ( .A(n1053), .Z(n1076)); + AN2 U1005 ( .A(n1077), .B(n1078), .Z(n1053)); + OR2 U1006 ( .A(n897), .B(n851), .Z(n1078)); + IV2 U1007 ( .A(n1079), .Z(n1077)); + AN2 U1008 ( .A(n851), .B(n897), .Z(n1079)); + OR2 U1009 ( .A(n1080), .B(n1081), .Z(n897)); + AN2 U1010 ( .A(pi01), .B(n1082), .Z(n1080)); + AN2 U1011 ( .A(n1083), .B(n1084), .Z(n1043)); + OR2 U1012 ( .A(pi10), .B(n1085), .Z(n1084)); + OR2 U1013 ( .A(n1086), .B(n1087), .Z(n1085)); + AN2 U1014 ( .A(n1088), .B(n1089), .Z(n1087)); + AN2 U1015 ( .A(n852), .B(n898), .Z(n1088)); + IV2 U1016 ( .A(n1033), .Z(n852)); + AN2 U1017 ( .A(n1090), .B(n853), .Z(n1086)); + IV2 U1018 ( .A(n1089), .Z(n853)); + AN2 U1019 ( .A(n1091), .B(n1082), .Z(n1089)); + OR2 U1020 ( .A(n1031), .B(n1092), .Z(n1091)); + OR2 U1021 ( .A(n851), .B(n1033), .Z(n1090)); + OR2 U1022 ( .A(n1093), .B(n1094), .Z(n1033)); + AN2 U1023 ( .A(n868), .B(n724), .Z(n1094)); + AN2 U1024 ( .A(n851), .B(n869), .Z(n1093)); + IV2 U1025 ( .A(n898), .Z(n851)); + OR2 U1026 ( .A(n1095), .B(n1096), .Z(n898)); + AN2 U1027 ( .A(n901), .B(n920), .Z(n1096)); + OR2 U1028 ( .A(pi02), .B(n993), .Z(n920)); + AN2 U1029 ( .A(n902), .B(n1097), .Z(n1095)); + OR2 U1030 ( .A(n1098), .B(n1099), .Z(n1097)); + OR2 U1031 ( .A(n1100), .B(n1101), .Z(n1099)); + AN2 U1032 ( .A(n992), .B(n892), .Z(n1101)); + AN2 U1033 ( .A(n918), .B(n751), .Z(n1100)); + AN2 U1034 ( .A(n908), .B(n724), .Z(n1098)); + OR2 U1035 ( .A(n1102), .B(n992), .Z(n1083)); + IV2 U1036 ( .A(n993), .Z(n992)); + AN2 U1037 ( .A(n1103), .B(n1104), .Z(n1102)); + OR2 U1038 ( .A(n883), .B(n1105), .Z(n1104)); + IV2 U1039 ( .A(n1106), .Z(n883)); + IV2 U1040 ( .A(n801), .Z(n776)); + OR2 U1041 ( .A(n1107), .B(n1108), .Z(n801)); + OR2 U1042 ( .A(pi12), .B(n1109), .Z(n1108)); + OR2 U1043 ( .A(n1110), .B(n1111), .Z(n986)); + AN2 U1044 ( .A(n1112), .B(n717), .Z(n1111)); + AN2 U1045 ( .A(n924), .B(n1113), .Z(n1112)); + OR2 U1046 ( .A(n1114), .B(n927), .Z(n1113)); + AN2 U1047 ( .A(pi11), .B(pi02), .Z(n1114)); + AN2 U1048 ( .A(pi06), .B(n1115), .Z(n1110)); + OR2 U1049 ( .A(n1116), .B(n930), .Z(n1115)); + AN2 U1050 ( .A(n1117), .B(n804), .Z(n1116)); + OR2 U1051 ( .A(n1118), .B(n1119), .Z(n1117)); + AN2 U1052 ( .A(n854), .B(n993), .Z(n1119)); + AN2 U1053 ( .A(n934), .B(n1016), .Z(n1118)); + OR2 U1054 ( .A(n1120), .B(n1121), .Z(n984)); + OR2 U1055 ( .A(n937), .B(n1122), .Z(n1121)); + AN2 U1056 ( .A(n939), .B(n1123), .Z(n1122)); + OR2 U1057 ( .A(n1124), .B(n1125), .Z(n1123)); + OR2 U1058 ( .A(n918), .B(n1126), .Z(n1125)); + AN2 U1059 ( .A(n724), .B(n982), .Z(n1126)); + AN2 U1060 ( .A(n993), .B(pi02), .Z(n918)); + OR2 U1061 ( .A(n1127), .B(n1128), .Z(n993)); + OR2 U1062 ( .A(n1129), .B(n1130), .Z(n1128)); + AN2 U1063 ( .A(n949), .B(n717), .Z(n1130)); + AN2 U1064 ( .A(n950), .B(n877), .Z(n1129)); + IV2 U1065 ( .A(n727), .Z(n877)); + OR2 U1066 ( .A(n1131), .B(n1132), .Z(n1127)); + OR2 U1067 ( .A(n1133), .B(n1134), .Z(n1132)); + AN2 U1068 ( .A(n1135), .B(n1016), .Z(n1134)); + OR2 U1069 ( .A(n1136), .B(n957), .Z(n1135)); + AN2 U1070 ( .A(n1137), .B(n979), .Z(n1136)); + AN2 U1071 ( .A(n784), .B(pi06), .Z(n1137)); + AN2 U1072 ( .A(n724), .B(n1138), .Z(n1133)); + OR2 U1073 ( .A(n1139), .B(n1140), .Z(n1138)); + AN2 U1074 ( .A(n965), .B(n1141), .Z(n1139)); + AN2 U1075 ( .A(pi02), .B(pi06), .Z(n724)); + AN2 U1076 ( .A(pi13), .B(n1142), .Z(n1131)); + OR2 U1077 ( .A(n1143), .B(n1144), .Z(n1142)); + AN2 U1078 ( .A(n971), .B(pi01), .Z(n1144)); + AN2 U1079 ( .A(n1145), .B(n973), .Z(n1143)); + AN2 U1080 ( .A(n1146), .B(n1147), .Z(n1145)); + OR2 U1081 ( .A(n727), .B(n979), .Z(n1147)); + IV2 U1082 ( .A(n1141), .Z(n979)); + OR2 U1083 ( .A(n1148), .B(n1141), .Z(n1146)); + OR2 U1084 ( .A(n1149), .B(n1150), .Z(n1141)); + AN2 U1085 ( .A(n1151), .B(n1017), .Z(n1150)); + AN2 U1086 ( .A(pi05), .B(n1152), .Z(n1149)); + OR2 U1087 ( .A(n1151), .B(n1017), .Z(n1152)); + AN2 U1088 ( .A(pi02), .B(n717), .Z(n1148)); + AN2 U1089 ( .A(n944), .B(n727), .Z(n1124)); + AN2 U1090 ( .A(n1016), .B(n717), .Z(n727)); + IV2 U1091 ( .A(pi06), .Z(n717)); + IV2 U1092 ( .A(pi02), .Z(n1016)); + AN2 U1093 ( .A(n983), .B(pi02), .Z(n1120)); + OR2 U1094 ( .A(n1153), .B(n1154), .Z(po1)); + OR2 U1095 ( .A(n1155), .B(n1156), .Z(n1154)); + OR2 U1096 ( .A(n1157), .B(n1158), .Z(n1156)); + OR2 U1097 ( .A(n1159), .B(n1160), .Z(n1158)); + AN2 U1098 ( .A(n793), .B(n1105), .Z(n1160)); + AN2 U1099 ( .A(n794), .B(n1032), .Z(n1159)); + OR2 U1100 ( .A(n1161), .B(n1162), .Z(n1157)); + AN2 U1101 ( .A(n1163), .B(n1107), .Z(n1162)); + IV2 U1102 ( .A(n1164), .Z(n1161)); + OR2 U1103 ( .A(n1107), .B(n1163), .Z(n1164)); + AN2 U1104 ( .A(n1165), .B(n1166), .Z(n1163)); + OR2 U1105 ( .A(n1167), .B(n804), .Z(n1107)); + AN2 U1106 ( .A(n1168), .B(n1169), .Z(n1167)); + AN2 U1107 ( .A(n1170), .B(n1171), .Z(n1169)); + OR2 U1108 ( .A(n817), .B(n1172), .Z(n1171)); + OR2 U1109 ( .A(pi11), .B(n1173), .Z(n1172)); + AN2 U1110 ( .A(n1010), .B(n1174), .Z(n1173)); + OR2 U1111 ( .A(n1012), .B(n1013), .Z(n1174)); + OR2 U1112 ( .A(n1175), .B(n1082), .Z(n1010)); + AN2 U1113 ( .A(n1176), .B(n1177), .Z(n1170)); + OR2 U1114 ( .A(pi10), .B(n1178), .Z(n1177)); + OR2 U1115 ( .A(n1179), .B(n1180), .Z(n1178)); + AN2 U1116 ( .A(n1181), .B(n1031), .Z(n1180)); + IV2 U1117 ( .A(n1182), .Z(n1179)); + OR2 U1118 ( .A(n1181), .B(n1031), .Z(n1182)); + OR2 U1119 ( .A(n1183), .B(n1184), .Z(n1181)); + AN2 U1120 ( .A(n1185), .B(n1082), .Z(n1184)); + AN2 U1121 ( .A(n1012), .B(n1092), .Z(n1183)); + OR2 U1122 ( .A(n825), .B(n1186), .Z(n1176)); + OR2 U1123 ( .A(n1187), .B(n1188), .Z(n1186)); + AN2 U1124 ( .A(n1189), .B(n1190), .Z(n1187)); + IV2 U1125 ( .A(n725), .Z(n1190)); + OR2 U1126 ( .A(n1066), .B(n738), .Z(n1189)); + AN2 U1127 ( .A(n1191), .B(n1192), .Z(n1168)); + AN2 U1128 ( .A(n1193), .B(n1194), .Z(n1192)); + OR2 U1129 ( .A(n1195), .B(n1017), .Z(n1194)); + AN2 U1130 ( .A(n1196), .B(n1197), .Z(n1195)); + AN2 U1131 ( .A(n1198), .B(n1199), .Z(n1197)); + OR2 U1132 ( .A(pi05), .B(n1200), .Z(n1199)); + AN2 U1133 ( .A(n1201), .B(n1063), .Z(n1198)); + OR2 U1134 ( .A(n1202), .B(n772), .Z(n1201)); + AN2 U1135 ( .A(n1203), .B(n1204), .Z(n1202)); + OR2 U1136 ( .A(n1074), .B(n1032), .Z(n1204)); + OR2 U1137 ( .A(n1105), .B(n1205), .Z(n1203)); + AN2 U1138 ( .A(n1206), .B(n1207), .Z(n1196)); + OR2 U1139 ( .A(n1208), .B(n1054), .Z(n1207)); + AN2 U1140 ( .A(n1209), .B(n1210), .Z(n1208)); + OR2 U1141 ( .A(n1081), .B(n1082), .Z(n1210)); + OR2 U1142 ( .A(n1012), .B(n1211), .Z(n1209)); + IV2 U1143 ( .A(n1081), .Z(n1211)); + OR2 U1144 ( .A(n817), .B(n1212), .Z(n1206)); + OR2 U1145 ( .A(n713), .B(n738), .Z(n1212)); + OR2 U1146 ( .A(pi01), .B(n1213), .Z(n1193)); + AN2 U1147 ( .A(n1214), .B(n1215), .Z(n1213)); + AN2 U1148 ( .A(n1216), .B(n1217), .Z(n1215)); + OR2 U1149 ( .A(n1054), .B(n1218), .Z(n1216)); + OR2 U1150 ( .A(n1012), .B(n1081), .Z(n1218)); + AN2 U1151 ( .A(pi00), .B(n1175), .Z(n1081)); + OR2 U1152 ( .A(pi08), .B(n1020), .Z(n1054)); + AN2 U1153 ( .A(n1219), .B(n1220), .Z(n1214)); + OR2 U1154 ( .A(n772), .B(n1221), .Z(n1220)); + OR2 U1155 ( .A(n1222), .B(n1223), .Z(n1221)); + AN2 U1156 ( .A(n1074), .B(n1032), .Z(n1223)); + AN2 U1157 ( .A(n1105), .B(n1205), .Z(n1222)); + OR2 U1158 ( .A(n1224), .B(n738), .Z(n772)); + AN2 U1159 ( .A(n1225), .B(n829), .Z(n1224)); + OR2 U1160 ( .A(n751), .B(n1023), .Z(n1225)); + OR2 U1161 ( .A(n716), .B(n1200), .Z(n1219)); + OR2 U1162 ( .A(n718), .B(n825), .Z(n1200)); + IV2 U1163 ( .A(n761), .Z(n825)); + AN2 U1164 ( .A(n1226), .B(n1227), .Z(n1191)); + OR2 U1165 ( .A(n1228), .B(n1229), .Z(n1227)); + OR2 U1166 ( .A(n1020), .B(n1230), .Z(n1229)); + OR2 U1167 ( .A(n1231), .B(n1232), .Z(n1230)); + AN2 U1168 ( .A(n1233), .B(n1234), .Z(n1232)); + AN2 U1169 ( .A(n1235), .B(n1031), .Z(n1233)); + OR2 U1170 ( .A(n1030), .B(n1032), .Z(n1235)); + AN2 U1171 ( .A(n1092), .B(n1041), .Z(n1030)); + IV2 U1172 ( .A(n1236), .Z(n1231)); + OR2 U1173 ( .A(n1234), .B(n1031), .Z(n1236)); + OR2 U1174 ( .A(n1237), .B(n1238), .Z(n1031)); + AN2 U1175 ( .A(n868), .B(n725), .Z(n1238)); + AN2 U1176 ( .A(n1012), .B(n869), .Z(n1237)); + IV2 U1177 ( .A(n1082), .Z(n1012)); + OR2 U1178 ( .A(n1239), .B(n1240), .Z(n1082)); + AN2 U1179 ( .A(n901), .B(n1075), .Z(n1240)); + OR2 U1180 ( .A(pi01), .B(n1032), .Z(n1075)); + AN2 U1181 ( .A(n902), .B(n1241), .Z(n1239)); + OR2 U1182 ( .A(n1242), .B(n1243), .Z(n1241)); + OR2 U1183 ( .A(n1244), .B(n1245), .Z(n1243)); + AN2 U1184 ( .A(n1105), .B(n892), .Z(n1245)); + AN2 U1185 ( .A(n1073), .B(n751), .Z(n1244)); + AN2 U1186 ( .A(n908), .B(n725), .Z(n1242)); + OR2 U1187 ( .A(n1185), .B(n1246), .Z(n1234)); + OR2 U1188 ( .A(n1247), .B(n1105), .Z(n1246)); + IV2 U1189 ( .A(n1248), .Z(n1020)); + OR2 U1190 ( .A(n1249), .B(n744), .Z(n1228)); + AN2 U1191 ( .A(n716), .B(n1023), .Z(n1249)); + AN2 U1192 ( .A(n1250), .B(n1251), .Z(n1226)); + OR2 U1193 ( .A(n1105), .B(n1103), .Z(n1251)); + IV2 U1194 ( .A(n1252), .Z(n1103)); + OR2 U1195 ( .A(n1253), .B(n1254), .Z(n1252)); + AN2 U1196 ( .A(n1106), .B(n1041), .Z(n1254)); + OR2 U1197 ( .A(n1255), .B(n780), .Z(n1106)); + AN2 U1198 ( .A(n973), .B(n738), .Z(n1255)); + AN2 U1199 ( .A(n854), .B(n738), .Z(n1253)); + IV2 U1200 ( .A(n1032), .Z(n1105)); + OR2 U1201 ( .A(n1032), .B(n1256), .Z(n1250)); + OR2 U1202 ( .A(n1040), .B(n1041), .Z(n1256)); + IV2 U1203 ( .A(n1257), .Z(n1040)); + OR2 U1204 ( .A(n1258), .B(n1259), .Z(n1155)); + AN2 U1205 ( .A(n1260), .B(n716), .Z(n1259)); + AN2 U1206 ( .A(n924), .B(n1261), .Z(n1260)); + OR2 U1207 ( .A(n1262), .B(n927), .Z(n1261)); + AN2 U1208 ( .A(pi11), .B(pi01), .Z(n1262)); + AN2 U1209 ( .A(pi05), .B(n1263), .Z(n1258)); + OR2 U1210 ( .A(n1264), .B(n930), .Z(n1263)); + AN2 U1211 ( .A(n1265), .B(n804), .Z(n1264)); + OR2 U1212 ( .A(n1266), .B(n1267), .Z(n1265)); + AN2 U1213 ( .A(n854), .B(n1032), .Z(n1267)); + AN2 U1214 ( .A(n934), .B(n1017), .Z(n1266)); + AN2 U1215 ( .A(pi11), .B(n761), .Z(n934)); + OR2 U1216 ( .A(n1268), .B(n1269), .Z(n1153)); + OR2 U1217 ( .A(n937), .B(n1270), .Z(n1269)); + AN2 U1218 ( .A(n939), .B(n1271), .Z(n1270)); + OR2 U1219 ( .A(n1272), .B(n1273), .Z(n1271)); + OR2 U1220 ( .A(n1073), .B(n1274), .Z(n1273)); + AN2 U1221 ( .A(n725), .B(n982), .Z(n1274)); + AN2 U1222 ( .A(n1032), .B(pi01), .Z(n1073)); + OR2 U1223 ( .A(n1275), .B(n1276), .Z(n1032)); + OR2 U1224 ( .A(n1277), .B(n1278), .Z(n1276)); + AN2 U1225 ( .A(n949), .B(n716), .Z(n1278)); + AN2 U1226 ( .A(n950), .B(n1066), .Z(n1277)); + IV2 U1227 ( .A(n723), .Z(n1066)); + OR2 U1228 ( .A(n1279), .B(n1280), .Z(n1275)); + OR2 U1229 ( .A(n1281), .B(n1282), .Z(n1280)); + AN2 U1230 ( .A(n1283), .B(n1017), .Z(n1282)); + OR2 U1231 ( .A(n1284), .B(n957), .Z(n1283)); + AN2 U1232 ( .A(n1285), .B(n784), .Z(n1284)); + AN2 U1233 ( .A(pi05), .B(n1286), .Z(n1285)); + AN2 U1234 ( .A(n725), .B(n1287), .Z(n1281)); + OR2 U1235 ( .A(n1288), .B(n1140), .Z(n1287)); + AN2 U1236 ( .A(n965), .B(n1151), .Z(n1288)); + AN2 U1237 ( .A(n744), .B(n902), .Z(n965)); + AN2 U1238 ( .A(pi01), .B(pi05), .Z(n725)); + AN2 U1239 ( .A(pi13), .B(n1289), .Z(n1279)); + OR2 U1240 ( .A(n1290), .B(n1291), .Z(n1289)); + AN2 U1241 ( .A(n971), .B(pi00), .Z(n1291)); + AN2 U1242 ( .A(n892), .B(n1292), .Z(n971)); + AN2 U1243 ( .A(pi10), .B(pi11), .Z(n1292)); + AN2 U1244 ( .A(n1293), .B(n973), .Z(n1290)); + AN2 U1245 ( .A(n1294), .B(n1295), .Z(n1293)); + OR2 U1246 ( .A(n723), .B(n1286), .Z(n1295)); + IV2 U1247 ( .A(n1151), .Z(n1286)); + OR2 U1248 ( .A(n1151), .B(n1296), .Z(n1294)); + AN2 U1249 ( .A(pi01), .B(n716), .Z(n1296)); + AN2 U1250 ( .A(n944), .B(n723), .Z(n1272)); + AN2 U1251 ( .A(n1017), .B(n716), .Z(n723)); + IV2 U1252 ( .A(pi05), .Z(n716)); + IV2 U1253 ( .A(pi01), .Z(n1017)); + AN2 U1254 ( .A(n983), .B(pi01), .Z(n1268)); + AN2 U1255 ( .A(pi11), .B(n1297), .Z(n983)); + OR2 U1256 ( .A(n1298), .B(n1299), .Z(po0)); + OR2 U1257 ( .A(n1300), .B(n1301), .Z(n1299)); + OR2 U1258 ( .A(n1302), .B(n1303), .Z(n1301)); + OR2 U1259 ( .A(n1304), .B(n1305), .Z(n1303)); + AN2 U1260 ( .A(n793), .B(n1247), .Z(n1305)); + AN2 U1261 ( .A(n924), .B(n1306), .Z(n793)); + IV2 U1262 ( .A(n1307), .Z(n1306)); + OR2 U1263 ( .A(n854), .B(n1308), .Z(n1307)); + AN2 U1264 ( .A(pi08), .B(n1063), .Z(n1308)); + IV2 U1265 ( .A(n1309), .Z(n1063)); + AN2 U1266 ( .A(n794), .B(n1041), .Z(n1304)); + AN2 U1267 ( .A(n1310), .B(n924), .Z(n794)); + OR2 U1268 ( .A(pi11), .B(n854), .Z(n1310)); + AN2 U1269 ( .A(pi11), .B(n1311), .Z(n1302)); + OR2 U1270 ( .A(n1312), .B(n1313), .Z(n1311)); + OR2 U1271 ( .A(n1314), .B(n1315), .Z(n1313)); + AN2 U1272 ( .A(n924), .B(n1316), .Z(n1315)); + AN2 U1273 ( .A(n1317), .B(n761), .Z(n1314)); + AN2 U1274 ( .A(n1023), .B(n908), .Z(n761)); + AN2 U1275 ( .A(n1151), .B(n804), .Z(n1317)); + AN2 U1276 ( .A(n1297), .B(pi00), .Z(n1312)); + AN2 U1277 ( .A(n804), .B(n1318), .Z(n1297)); + OR2 U1278 ( .A(pi10), .B(n892), .Z(n1318)); + OR2 U1279 ( .A(n1319), .B(n1320), .Z(n1300)); + AN2 U1280 ( .A(n1321), .B(n709), .Z(n1320)); + AN2 U1281 ( .A(n927), .B(n924), .Z(n1321)); + AN2 U1282 ( .A(pi04), .B(n1322), .Z(n1319)); + OR2 U1283 ( .A(n1323), .B(n930), .Z(n1322)); + AN2 U1284 ( .A(n939), .B(n1324), .Z(n930)); + AN2 U1285 ( .A(n744), .B(pi11), .Z(n1324)); + AN2 U1286 ( .A(n957), .B(n1041), .Z(n1323)); + OR2 U1287 ( .A(n1325), .B(n1326), .Z(n1298)); + OR2 U1288 ( .A(n937), .B(n1327), .Z(n1326)); + AN2 U1289 ( .A(pi13), .B(n1328), .Z(n1327)); + OR2 U1290 ( .A(n1329), .B(n1330), .Z(n1328)); + AN2 U1291 ( .A(n1109), .B(n1166), .Z(n1330)); + IV2 U1292 ( .A(pi12), .Z(n1166)); + IV2 U1293 ( .A(n1165), .Z(n1109)); + AN2 U1294 ( .A(pi12), .B(n1165), .Z(n1329)); + OR2 U1295 ( .A(n1331), .B(n1332), .Z(n1165)); + AN2 U1296 ( .A(pi13), .B(n1333), .Z(n1332)); + OR2 U1297 ( .A(n1334), .B(n1335), .Z(n1333)); + OR2 U1298 ( .A(n1336), .B(n1337), .Z(n1335)); + AN2 U1299 ( .A(n1247), .B(n1257), .Z(n1337)); + OR2 U1300 ( .A(n1338), .B(n780), .Z(n1257)); + AN2 U1301 ( .A(n1023), .B(n751), .Z(n780)); + AN2 U1302 ( .A(n944), .B(pi09), .Z(n1338)); + AN2 U1303 ( .A(pi11), .B(n1339), .Z(n1336)); + OR2 U1304 ( .A(n1340), .B(n1341), .Z(n1339)); + OR2 U1305 ( .A(n1342), .B(n1343), .Z(n1341)); + AN2 U1306 ( .A(n1344), .B(pi00), .Z(n1343)); + AN2 U1307 ( .A(n1345), .B(n1247), .Z(n1344)); + AN2 U1308 ( .A(pi10), .B(n1346), .Z(n1345)); + AN2 U1309 ( .A(n1041), .B(n713), .Z(n1342)); + IV2 U1310 ( .A(n1217), .Z(n1340)); + OR2 U1311 ( .A(pi00), .B(n817), .Z(n1217)); + OR2 U1312 ( .A(n1023), .B(n1346), .Z(n817)); + OR2 U1313 ( .A(n1347), .B(n1348), .Z(n1334)); + OR2 U1314 ( .A(n1349), .B(n1350), .Z(n1348)); + AN2 U1315 ( .A(n1316), .B(n1023), .Z(n1350)); + AN2 U1316 ( .A(n854), .B(n1351), .Z(n1349)); + OR2 U1317 ( .A(n1352), .B(n1353), .Z(n1351)); + AN2 U1318 ( .A(pi00), .B(n738), .Z(n1353)); + AN2 U1319 ( .A(pi09), .B(n1041), .Z(n1352)); + AN2 U1320 ( .A(n1248), .B(n1354), .Z(n1347)); + OR2 U1321 ( .A(n1355), .B(n1356), .Z(n1354)); + OR2 U1322 ( .A(n1357), .B(n1358), .Z(n1356)); + AN2 U1323 ( .A(n1185), .B(n1041), .Z(n1358)); + IV2 U1324 ( .A(n1092), .Z(n1185)); + AN2 U1325 ( .A(n1247), .B(n1092), .Z(n1357)); + OR2 U1326 ( .A(n1359), .B(n1360), .Z(n1092)); + AN2 U1327 ( .A(n868), .B(n718), .Z(n1360)); + AN2 U1328 ( .A(n1023), .B(n901), .Z(n868)); + AN2 U1329 ( .A(n973), .B(pi11), .Z(n901)); + AN2 U1330 ( .A(n869), .B(n1013), .Z(n1359)); + AN2 U1331 ( .A(n1361), .B(n927), .Z(n869)); + AN2 U1332 ( .A(n963), .B(pi08), .Z(n927)); + IV2 U1333 ( .A(n1041), .Z(n1247)); + AN2 U1334 ( .A(n1175), .B(n713), .Z(n1355)); + IV2 U1335 ( .A(n1013), .Z(n1175)); + AN2 U1336 ( .A(n1361), .B(n738), .Z(n1248)); + AN2 U1337 ( .A(n1362), .B(n751), .Z(n1331)); + AN2 U1338 ( .A(n902), .B(n1013), .Z(n1362)); + OR2 U1339 ( .A(n1363), .B(n1364), .Z(n1013)); + IV2 U1340 ( .A(n902), .Z(n1364)); + AN2 U1341 ( .A(n1365), .B(n1366), .Z(n1363)); + OR2 U1342 ( .A(n1188), .B(n857), .Z(n1366)); + IV2 U1343 ( .A(n908), .Z(n857)); + IV2 U1344 ( .A(n718), .Z(n1188)); + AN2 U1345 ( .A(n1367), .B(n1368), .Z(n1365)); + OR2 U1346 ( .A(n1346), .B(n1205), .Z(n1368)); + IV2 U1347 ( .A(n1074), .Z(n1205)); + IV2 U1348 ( .A(n751), .Z(n1346)); + OR2 U1349 ( .A(n829), .B(n1041), .Z(n1367)); + IV2 U1350 ( .A(n892), .Z(n829)); + AN2 U1351 ( .A(n1309), .B(n1369), .Z(n937)); + AN2 U1352 ( .A(pi13), .B(n751), .Z(n1369)); + AN2 U1353 ( .A(n939), .B(n1370), .Z(n1325)); + OR2 U1354 ( .A(n1371), .B(n1372), .Z(n1370)); + OR2 U1355 ( .A(n1074), .B(n1373), .Z(n1372)); + AN2 U1356 ( .A(n1374), .B(n944), .Z(n1373)); + AN2 U1357 ( .A(n713), .B(n709), .Z(n1374)); + AN2 U1358 ( .A(n1041), .B(pi00), .Z(n1074)); + OR2 U1359 ( .A(n1375), .B(n1376), .Z(n1041)); + OR2 U1360 ( .A(n1377), .B(n1378), .Z(n1376)); + OR2 U1361 ( .A(n1379), .B(n1380), .Z(n1378)); + AN2 U1362 ( .A(n949), .B(n709), .Z(n1380)); + OR2 U1363 ( .A(n1381), .B(n1382), .Z(n949)); + OR2 U1364 ( .A(n1383), .B(n1384), .Z(n1382)); + AN2 U1365 ( .A(n751), .B(n963), .Z(n1384)); + AN2 U1366 ( .A(n1385), .B(n860), .Z(n1383)); + IV2 U1367 ( .A(n963), .Z(n860)); + AN2 U1368 ( .A(n1386), .B(n924), .Z(n1381)); + AN2 U1369 ( .A(n804), .B(n1361), .Z(n924)); + AN2 U1370 ( .A(pi08), .B(pi10), .Z(n1386)); + AN2 U1371 ( .A(n718), .B(n1140), .Z(n1379)); + OR2 U1372 ( .A(n1387), .B(n981), .Z(n1140)); + AN2 U1373 ( .A(pi11), .B(n1388), .Z(n981)); + AN2 U1374 ( .A(n1023), .B(n1389), .Z(n1388)); + OR2 U1375 ( .A(n751), .B(n892), .Z(n1389)); + AN2 U1376 ( .A(n744), .B(n1361), .Z(n892)); + AN2 U1377 ( .A(pi09), .B(pi08), .Z(n751)); + AN2 U1378 ( .A(n944), .B(n1361), .Z(n1387)); + AN2 U1379 ( .A(n744), .B(n963), .Z(n944)); + AN2 U1380 ( .A(n784), .B(n1151), .Z(n1377)); + AN2 U1381 ( .A(n713), .B(pi04), .Z(n1151)); + AN2 U1382 ( .A(n973), .B(n902), .Z(n784)); + AN2 U1383 ( .A(n963), .B(pi13), .Z(n902)); + AN2 U1384 ( .A(n738), .B(pi10), .Z(n963)); + OR2 U1385 ( .A(n1390), .B(n1391), .Z(n1375)); + OR2 U1386 ( .A(n1392), .B(n1393), .Z(n1391)); + AN2 U1387 ( .A(n950), .B(n1394), .Z(n1393)); + OR2 U1388 ( .A(pi00), .B(pi04), .Z(n1394)); + AN2 U1389 ( .A(n1395), .B(n908), .Z(n950)); + AN2 U1390 ( .A(n1361), .B(pi08), .Z(n908)); + IV2 U1391 ( .A(pi09), .Z(n1361)); + OR2 U1392 ( .A(pi13), .B(n1309), .Z(n1395)); + AN2 U1393 ( .A(n1023), .B(n738), .Z(n1309)); + IV2 U1394 ( .A(pi11), .Z(n738)); + AN2 U1395 ( .A(n1385), .B(n1316), .Z(n1392)); + AN2 U1396 ( .A(n709), .B(pi00), .Z(n1316)); + IV2 U1397 ( .A(pi04), .Z(n709)); + AN2 U1398 ( .A(n973), .B(pi13), .Z(n1385)); + AN2 U1399 ( .A(n744), .B(pi09), .Z(n973)); + AN2 U1400 ( .A(n957), .B(n713), .Z(n1390)); + IV2 U1401 ( .A(pi00), .Z(n713)); + AN2 U1402 ( .A(n804), .B(n854), .Z(n957)); + AN2 U1403 ( .A(n744), .B(n1023), .Z(n854)); + IV2 U1404 ( .A(pi10), .Z(n1023)); + AN2 U1405 ( .A(n718), .B(n982), .Z(n1371)); + OR2 U1406 ( .A(n1396), .B(pi11), .Z(n982)); + AN2 U1407 ( .A(pi10), .B(n744), .Z(n1396)); + IV2 U1408 ( .A(pi08), .Z(n744)); + AN2 U1409 ( .A(pi00), .B(pi04), .Z(n718)); + AN2 U1410 ( .A(n804), .B(pi09), .Z(n939)); + IV2 U1411 ( .A(pi13), .Z(n804)); + +endmodule + +module IV2(A, Z); + input A; + output Z; + + assign Z = ~A; +endmodule + +module AN2(A, B, Z); + input A, B; + output Z; + + assign Z = A & B; +endmodule + +module OR2(A, B, Z); + input A, B; + output Z; + + assign Z = A | B; +endmodule diff --git a/examples/smtbmc/glift/alu4.ys b/examples/smtbmc/glift/alu4.ys new file mode 100644 index 00000000000..d5ab7fb3bb0 --- /dev/null +++ b/examples/smtbmc/glift/alu4.ys @@ -0,0 +1,45 @@ +read_verilog alu4.v +techmap +flatten +select alu4_lev2 +glift -optimize-precise +techmap +opt +rename alu4_lev2 uut +cd .. +delete [AIONX][NVXR]2 +read_verilog alu4.v +techmap +flatten +select alu4_lev2 +glift -create-precise +techmap +opt +rename alu4_lev2 spec +cd .. +delete [AIONX][NVXR]2 + +design -push-copy +miter -equiv spec uut miter +flatten +delete uut spec +techmap +opt +stat miter +abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter +techmap +opt +stat +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu4.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +design -pop +stat + +copy uut solved +qbfsat -specialize-from-file alu4.soln solved +opt solved +miter -equiv spec solved satmiter +flatten +sat -prove trigger 0 satmiter +delete satmiter +stat +shell diff --git a/examples/smtbmc/glift/mux2.ys b/examples/smtbmc/glift/mux2.ys new file mode 100644 index 00000000000..6b2b98c89c7 --- /dev/null +++ b/examples/smtbmc/glift/mux2.ys @@ -0,0 +1,39 @@ +logger -expect log "SAT proof finished - no model found: SUCCESS!" 1 +logger -expect log "Number of cells:.*[\t ]12" 1 +logger -expect log "Number of cells:.*[\t ]20" 1 +logger -expect log "Problem is satisfiable with \\gate.__glift_weight = 11." 1 +logger -expect log "Problem is NOT satisfiable with \\gate.__glift_weight <= 10." 1 +logger -expect log "Wire \\gate.__glift_weight is minimized at 11." 1 +logger -expect log "Specializing .* from file with .* = 1." 2 +logger -expect log "Specializing .* from file with .* = 0." 4 +read_verilog < Date: Tue, 28 Apr 2020 06:13:12 +0000 Subject: [PATCH 0009/2410] glift: Add `-create-imprecise` command, rename other commands, and re-work the help text. --- examples/smtbmc/glift/C7552.ys | 2 +- examples/smtbmc/glift/C880.ys | 2 +- examples/smtbmc/glift/alu2.ys | 2 +- examples/smtbmc/glift/alu4.ys | 2 +- examples/smtbmc/glift/mux2.ys | 9 ++-- examples/smtbmc/glift/t481.ys | 2 +- examples/smtbmc/glift/too_large.ys | 2 +- examples/smtbmc/glift/ttt2.ys | 2 +- examples/smtbmc/glift/x1.ys | 2 +- passes/cmds/glift.cc | 82 ++++++++++++++++++++---------- 10 files changed, 67 insertions(+), 40 deletions(-) diff --git a/examples/smtbmc/glift/C7552.ys b/examples/smtbmc/glift/C7552.ys index 0b39fadc7b5..139b0df4329 100644 --- a/examples/smtbmc/glift/C7552.ys +++ b/examples/smtbmc/glift/C7552.ys @@ -2,7 +2,7 @@ read_verilog C7552.v techmap flatten select C7552_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename C7552_lev2 uut diff --git a/examples/smtbmc/glift/C880.ys b/examples/smtbmc/glift/C880.ys index fe2678088b8..93f929c8957 100644 --- a/examples/smtbmc/glift/C880.ys +++ b/examples/smtbmc/glift/C880.ys @@ -2,7 +2,7 @@ read_verilog C880.v techmap flatten select C880_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename C880_lev2 uut diff --git a/examples/smtbmc/glift/alu2.ys b/examples/smtbmc/glift/alu2.ys index b0d7b3164e5..72cdaceba9f 100644 --- a/examples/smtbmc/glift/alu2.ys +++ b/examples/smtbmc/glift/alu2.ys @@ -2,7 +2,7 @@ read_verilog alu2.v techmap flatten select alu2_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename alu2_lev2 uut diff --git a/examples/smtbmc/glift/alu4.ys b/examples/smtbmc/glift/alu4.ys index d5ab7fb3bb0..b4337e69927 100644 --- a/examples/smtbmc/glift/alu4.ys +++ b/examples/smtbmc/glift/alu4.ys @@ -2,7 +2,7 @@ read_verilog alu4.v techmap flatten select alu4_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename alu4_lev2 uut diff --git a/examples/smtbmc/glift/mux2.ys b/examples/smtbmc/glift/mux2.ys index 6b2b98c89c7..c6670d74172 100644 --- a/examples/smtbmc/glift/mux2.ys +++ b/examples/smtbmc/glift/mux2.ys @@ -18,18 +18,19 @@ module mux2(a, b, s, y); endmodule EOT techmap -copy mux2 uut copy mux2 spec +copy mux2 uut +copy mux2 solved delete mux2 -glift -optimize-precise uut glift -create-precise spec +glift -create-sketch uut +glift -create-sketch -no-cost-model solved design -push-copy miter -equiv spec uut qbfmiter flatten -delete spec uut +delete spec uut solved qbfsat -assume-outputs -assume-negative-polarity -write-solution mux2.soln qbfmiter design -pop -copy uut solved qbfsat -specialize-from-file mux2.soln solved opt miter -equiv spec solved proofmiter diff --git a/examples/smtbmc/glift/t481.ys b/examples/smtbmc/glift/t481.ys index 2f54ed252cd..249a9eb7165 100644 --- a/examples/smtbmc/glift/t481.ys +++ b/examples/smtbmc/glift/t481.ys @@ -2,7 +2,7 @@ read_verilog t481.v techmap flatten select t481_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename t481_lev2 uut diff --git a/examples/smtbmc/glift/too_large.ys b/examples/smtbmc/glift/too_large.ys index e14c2b7b6fe..2bb6105ea9e 100644 --- a/examples/smtbmc/glift/too_large.ys +++ b/examples/smtbmc/glift/too_large.ys @@ -2,7 +2,7 @@ read_verilog too_large.v techmap flatten select too_large_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename too_large_lev2 uut diff --git a/examples/smtbmc/glift/ttt2.ys b/examples/smtbmc/glift/ttt2.ys index 8c649e642c8..62054a86c2b 100644 --- a/examples/smtbmc/glift/ttt2.ys +++ b/examples/smtbmc/glift/ttt2.ys @@ -2,7 +2,7 @@ read_verilog ttt2.v techmap flatten select ttt2_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename ttt2_lev2 uut diff --git a/examples/smtbmc/glift/x1.ys b/examples/smtbmc/glift/x1.ys index c5b4797d356..b010fe9ee66 100644 --- a/examples/smtbmc/glift/x1.ys +++ b/examples/smtbmc/glift/x1.ys @@ -2,7 +2,7 @@ read_verilog x1.v techmap flatten select x1_lev2 -glift -optimize-precise +glift -create-sketch techmap opt rename x1_lev2 uut diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index b35179fd155..8296e719422 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,21 +27,28 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs, opt_nomodeloptimize; + bool opt_create_precise, opt_create_imprecise, opt_create_sketch; + bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; std::vector meta_mux_selects; RTLIL::Module *module; + const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); + void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create") { - opt_create = true; + if (args[argidx] == "-create-precise") { + opt_create_precise = true; + continue; + } + if (args[argidx] == "-create-imprecise") { + opt_create_imprecise = true; continue; } - if (args[argidx] == "-sketchify") { - opt_sketchify = true; + if (args[argidx] == "-create-sketch") { + opt_create_sketch = true; continue; } if (args[argidx] == "-taint-constants") { @@ -52,14 +59,16 @@ struct GliftPass : public Pass { opt_keepoutputs = true; continue; } - if (args[argidx] == "-no-model-optimize") { - opt_nomodeloptimize = true; + if (args[argidx] == "-no-cost-model") { + opt_nocostmodel = true; continue; } break; } - if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); - if(opt_create && opt_sketchify) log_cmd_error("Only one of `-create` or `-sketchify` may be specified.\n"); + if(!opt_create_precise && !opt_create_imprecise && !opt_create_sketch) + log_cmd_error("No command provided. See help for usage.\n"); + if(static_cast(opt_create_precise) + static_cast(opt_create_imprecise) + static_cast(opt_create_sketch) != 1) + log_cmd_error("Only one command may be specified. See help for usage.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -156,9 +165,11 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (opt_create) + if (opt_create_precise) add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); - else if (opt_sketchify) { + else if (opt_create_imprecise) + add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); + else if (opt_create_sketch) { RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), @@ -210,7 +221,7 @@ struct GliftPass : public Pass { } //end foreach conn in connections //Create a rough model of area by summing the "weight" score of each meta-mux select: - if (!opt_nomodeloptimize) { + if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; for (auto &wire : meta_mux_selects) { @@ -228,7 +239,7 @@ struct GliftPass : public Pass { if (meta_mux_select_sums.size() > 0) { meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\minimize"); meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\keep"); - module->rename(meta_mux_select_sums[0].as_wire(), ID(__glift_weight)); + module->rename(meta_mux_select_sums[0].as_wire(), cost_model_wire_name); } } @@ -248,11 +259,12 @@ struct GliftPass : public Pass { } void reset() { - opt_create = false; - opt_sketchify = false; + opt_create_precise = false; + opt_create_imprecise = false; + opt_create_sketch = false; opt_taintconstants = false; opt_keepoutputs = false; - opt_nomodeloptimize = false; + opt_nocostmodel = false; module = nullptr; args.clear(); argidx = 0; @@ -262,28 +274,41 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nomodeloptimize(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise(false), opt_create_imprecise(false), opt_create_sketch(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" glift -create|-sketchify [options] [selection]\n"); + log(" glift [options] [selection]\n"); + log("\n"); + log("Augments the current or specified module with gate-level information flow tracking\n"); + log("(GLIFT) logic using the \"constructive mapping\" approach. Also can set up QBF-SAT\n"); + log("optimization problems in order to optimize GLIFT models or trade off precision and\n"); + log("complexity.\n"); log("\n"); - log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); - log("to the current or specified module.\n"); log("\n"); log("Commands:\n"); log("\n"); - log(" -create\n"); + log(" -create-precise\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -sketchify\n"); + log(" -create-imprecise\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); - log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); - log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); - log(" selected by an $anyconst cell.\n"); + log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); + log(" logic.\n"); + log("\n"); + log(" -create-sketch\n"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); + log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); + log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); + log(" option is provided, an additional wire named `__glift_weight` with the `keep` and\n"); + log(" `minimize` attributes is added to the module along with pmuxes and adders to\n"); + log(" calculate a rough estimate of the number of logic gates in the GLIFT model given\n"); + log(" an assignment for the $anyconst cells.\n"); + log("\n"); log("\n"); log("Options:\n"); log("\n"); @@ -296,9 +321,10 @@ struct GliftPass : public Pass { log(" alongside the orignal outputs.\n"); log(" (default: original module outputs are removed)\n"); log("\n"); - log(" -no-model-optimize\n"); - log(" Do not model imprecise taint tracking logic area and attempt to minimize it.\n"); - log(" (default: model area and give that signal the \"minimize\" attribute)\n"); + log(" -no-cost-model\n"); + log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); + log(" Only applicable in combination with `-create-sketch`.\n"); + log(" (default: model area and give that wire the \"keep\" and \"minimize\" attributes)\n"); log("\n"); } From bc207d5426c5c41e103ca54dbb31cab573d66df2 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Tue, 9 Jun 2020 22:56:57 +0000 Subject: [PATCH 0010/2410] glift: Change command names to better represent their functions. --- examples/smtbmc/glift/C7552.ys | 6 ++-- examples/smtbmc/glift/C880.ys | 6 ++-- examples/smtbmc/glift/alu2.ys | 6 ++-- examples/smtbmc/glift/alu4.ys | 6 ++-- examples/smtbmc/glift/mux2.ys | 6 ++-- examples/smtbmc/glift/t481.ys | 6 ++-- examples/smtbmc/glift/too_large.ys | 6 ++-- examples/smtbmc/glift/ttt2.ys | 6 ++-- examples/smtbmc/glift/x1.ys | 6 ++-- passes/cmds/glift.cc | 44 +++++++++++++++--------------- 10 files changed, 49 insertions(+), 49 deletions(-) diff --git a/examples/smtbmc/glift/C7552.ys b/examples/smtbmc/glift/C7552.ys index 139b0df4329..c1fdf244e00 100644 --- a/examples/smtbmc/glift/C7552.ys +++ b/examples/smtbmc/glift/C7552.ys @@ -2,7 +2,7 @@ read_verilog C7552.v techmap flatten select C7552_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename C7552_lev2 uut @@ -12,7 +12,7 @@ read_verilog C7552.v techmap flatten select C7552_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename C7552_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C7552.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C7552.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/C880.ys b/examples/smtbmc/glift/C880.ys index 93f929c8957..9a5e7bdcd08 100644 --- a/examples/smtbmc/glift/C880.ys +++ b/examples/smtbmc/glift/C880.ys @@ -2,7 +2,7 @@ read_verilog C880.v techmap flatten select C880_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename C880_lev2 uut @@ -12,7 +12,7 @@ read_verilog C880.v techmap flatten select C880_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename C880_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C880.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C880.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/alu2.ys b/examples/smtbmc/glift/alu2.ys index 72cdaceba9f..f79c33ca5bc 100644 --- a/examples/smtbmc/glift/alu2.ys +++ b/examples/smtbmc/glift/alu2.ys @@ -2,7 +2,7 @@ read_verilog alu2.v techmap flatten select alu2_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename alu2_lev2 uut @@ -12,7 +12,7 @@ read_verilog alu2.v techmap flatten select alu2_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename alu2_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu2.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/alu4.ys b/examples/smtbmc/glift/alu4.ys index b4337e69927..3fc2112d621 100644 --- a/examples/smtbmc/glift/alu4.ys +++ b/examples/smtbmc/glift/alu4.ys @@ -2,7 +2,7 @@ read_verilog alu4.v techmap flatten select alu4_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename alu4_lev2 uut @@ -12,7 +12,7 @@ read_verilog alu4.v techmap flatten select alu4_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename alu4_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu4.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu4.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/mux2.ys b/examples/smtbmc/glift/mux2.ys index c6670d74172..a8e99912b26 100644 --- a/examples/smtbmc/glift/mux2.ys +++ b/examples/smtbmc/glift/mux2.ys @@ -22,9 +22,9 @@ copy mux2 spec copy mux2 uut copy mux2 solved delete mux2 -glift -create-precise spec -glift -create-sketch uut -glift -create-sketch -no-cost-model solved +glift -create-precise-model spec +glift -create-instrumented-model uut +glift -create-instrumented-model -no-cost-model solved design -push-copy miter -equiv spec uut qbfmiter flatten diff --git a/examples/smtbmc/glift/t481.ys b/examples/smtbmc/glift/t481.ys index 249a9eb7165..282e723af9e 100644 --- a/examples/smtbmc/glift/t481.ys +++ b/examples/smtbmc/glift/t481.ys @@ -2,7 +2,7 @@ read_verilog t481.v techmap flatten select t481_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename t481_lev2 uut @@ -12,7 +12,7 @@ read_verilog t481.v techmap flatten select t481_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename t481_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution t481.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution t481.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/too_large.ys b/examples/smtbmc/glift/too_large.ys index 2bb6105ea9e..05b9fa5dc54 100644 --- a/examples/smtbmc/glift/too_large.ys +++ b/examples/smtbmc/glift/too_large.ys @@ -2,7 +2,7 @@ read_verilog too_large.v techmap flatten select too_large_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename too_large_lev2 uut @@ -12,7 +12,7 @@ read_verilog too_large.v techmap flatten select too_large_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename too_large_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution too_large.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution too_large.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/ttt2.ys b/examples/smtbmc/glift/ttt2.ys index 62054a86c2b..beba8b1026b 100644 --- a/examples/smtbmc/glift/ttt2.ys +++ b/examples/smtbmc/glift/ttt2.ys @@ -2,7 +2,7 @@ read_verilog ttt2.v techmap flatten select ttt2_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename ttt2_lev2 uut @@ -12,7 +12,7 @@ read_verilog ttt2.v techmap flatten select ttt2_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename ttt2_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution ttt2.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution ttt2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/examples/smtbmc/glift/x1.ys b/examples/smtbmc/glift/x1.ys index b010fe9ee66..e48a4e6ce91 100644 --- a/examples/smtbmc/glift/x1.ys +++ b/examples/smtbmc/glift/x1.ys @@ -2,7 +2,7 @@ read_verilog x1.v techmap flatten select x1_lev2 -glift -create-sketch +glift -create-instrumented-model techmap opt rename x1_lev2 uut @@ -12,7 +12,7 @@ read_verilog x1.v techmap flatten select x1_lev2 -glift -create-precise +glift -create-precise-model techmap opt rename x1_lev2 spec @@ -30,7 +30,7 @@ abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig techmap opt stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution x1.soln -show-smtbmc -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution x1.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter design -pop stat diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 8296e719422..1ed5de76a2f 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create_precise, opt_create_imprecise, opt_create_sketch; + bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; std::vector args; std::vector::size_type argidx; @@ -39,16 +39,16 @@ struct GliftPass : public Pass { void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create-precise") { - opt_create_precise = true; + if (args[argidx] == "-create-precise-model") { + opt_create_precise_model = true; continue; } - if (args[argidx] == "-create-imprecise") { - opt_create_imprecise = true; + if (args[argidx] == "-create-imprecise-model") { + opt_create_imprecise_model = true; continue; } - if (args[argidx] == "-create-sketch") { - opt_create_sketch = true; + if (args[argidx] == "-create-instrumented-model") { + opt_create_instrumented_model = true; continue; } if (args[argidx] == "-taint-constants") { @@ -65,9 +65,9 @@ struct GliftPass : public Pass { } break; } - if(!opt_create_precise && !opt_create_imprecise && !opt_create_sketch) + if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) log_cmd_error("No command provided. See help for usage.\n"); - if(static_cast(opt_create_precise) + static_cast(opt_create_imprecise) + static_cast(opt_create_sketch) != 1) + if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) log_cmd_error("Only one command may be specified. See help for usage.\n"); } @@ -165,11 +165,11 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (opt_create_precise) + if (opt_create_precise_model) add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); - else if (opt_create_imprecise) + else if (opt_create_imprecise_model) add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); - else if (opt_create_sketch) { + else if (opt_create_instrumented_model) { RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), @@ -259,9 +259,9 @@ struct GliftPass : public Pass { } void reset() { - opt_create_precise = false; - opt_create_imprecise = false; - opt_create_sketch = false; + opt_create_precise_model = false; + opt_create_imprecise_model = false; + opt_create_instrumented_model = false; opt_taintconstants = false; opt_keepoutputs = false; opt_nocostmodel = false; @@ -274,7 +274,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise(false), opt_create_imprecise(false), opt_create_sketch(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -290,17 +290,17 @@ struct GliftPass : public Pass { log("\n"); log("Commands:\n"); log("\n"); - log(" -create-precise\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-precise-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -create-imprecise\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-imprecise-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); log(" logic.\n"); log("\n"); - log(" -create-sketch\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-instrumented-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); From 26bd68625946aaac70cfe927755785b7f1a79efd Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 10 Jun 2020 00:31:46 +0000 Subject: [PATCH 0011/2410] glift: Add `-instrument-more` option to add 4 more versions of taint tracking logic. Also refactor a bit and update help text. --- passes/cmds/glift.cc | 168 +++++++++++++++++++++++++++++++------------ 1 file changed, 124 insertions(+), 44 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 1ed5de76a2f..42175859fa1 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -28,7 +28,7 @@ struct GliftPass : public Pass { private: bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; + bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel, opt_instrumentmore; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; @@ -63,6 +63,10 @@ struct GliftPass : public Pass { opt_nocostmodel = true; continue; } + if (args[argidx] == "-instrument-more") { + opt_instrumentmore = true; + continue; + } break; } if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) @@ -130,25 +134,48 @@ struct GliftPass : public Pass { module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); } + void add_imprecise_GLIFT_logic_4(RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, port_a_taint); + } + + void add_imprecise_GLIFT_logic_5(RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, port_b_taint); + } + + void add_imprecise_GLIFT_logic_6(RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, RTLIL::Const(1, 1)); + } + + void add_imprecise_GLIFT_logic_7(RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, RTLIL::Const(0, 1)); + } + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { log_assert(metamux_select.is_wire()); - log_assert(metamux_select.as_wire()->width == 2); - RTLIL::Const precise_y_cost(5); //5 AND/OR gates - RTLIL::Const imprecise_1_y_cost(2); - RTLIL::Const imprecise_2_y_cost(2); - RTLIL::Const imprecise_3_y_cost(1); + auto num_versions = opt_instrumentmore? 8 : 4; + auto select_width = log2(num_versions); + log_assert(metamux_select.as_wire()->width == select_width); - RTLIL::SigSpec meta_mux1 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux1", precise_y_cost, imprecise_1_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute()); - RTLIL::SigSpec meta_mux2 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux2", imprecise_2_y_cost, imprecise_3_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute()); - RTLIL::SigSpec ret = module->Pmux(metamux_select.as_wire()->name.str() + "_mux3", meta_mux1, meta_mux2, metamux_select[0], metamux_select.as_wire()->get_src_attribute()); + std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates - return ret; + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + for (auto i = 0; pmux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { + next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + } + if (GetSize(pmux_y_ports) % 2 == 1) + next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); + pmux_y_ports.swap(next_pmux_y_ports); + next_pmux_y_ports.clear(); + } + + log_assert(pmux_y_ports.size() == 1); + return pmux_y_ports[0]; } void create_glift_logic() { std::vector connections(module->connections()); - std::vector new_connections; for(auto &cell : module->cells().to_vector()) { if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { @@ -170,23 +197,52 @@ struct GliftPass : public Pass { else if (opt_create_imprecise_model) add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); else if (opt_create_instrumented_model) { - RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), - imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), - imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), - imprecise_3_y(module->addWire(cell->name.str() + "_y4", 1)); - - add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], precise_y); - add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_1_y); - add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_2_y); - add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], imprecise_3_y); - - RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", 2)); + std::vector taint_version; + int num_versions = opt_instrumentmore? 8 : 4; + + for (auto i = 1; i <= num_versions; ++i) + taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name.c_str(), i), 1))); + + for (auto i = 0; i < num_versions; ++i) { + switch(i) { + case 0: add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 1: add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 2: add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 3: add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], taint_version[i]); + break; + case 4: add_imprecise_GLIFT_logic_4(port_taints[A], taint_version[i]); + break; + case 5: add_imprecise_GLIFT_logic_5(port_taints[B], taint_version[i]); + break; + case 6: add_imprecise_GLIFT_logic_6(taint_version[i]); + break; + case 7: add_imprecise_GLIFT_logic_7(taint_version[i]); + break; + default: log_assert(false); + } + } + + auto select_width = log2(num_versions); + log_assert(exp2(select_width) == num_versions); + RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); meta_mux_selects.push_back(meta_mux_select); - new_connections.emplace_back(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", 2, cell->get_src_attribute())); - - RTLIL::SigSpec meta_mux1(module->Mux(cell->name.str() + "_mux1", precise_y, imprecise_1_y, meta_mux_select[1])); - RTLIL::SigSpec meta_mux2(module->Mux(cell->name.str() + "_mux2", imprecise_2_y, imprecise_3_y, meta_mux_select[1])); - module->addMux(cell->name.str() + "_mux3", meta_mux1, meta_mux2, meta_mux_select[0], port_taints[Y]); + module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); + + std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); + for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) { + next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name.c_str(), i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i])); + } + if (GetSize(meta_mux_y_ports) % 2 == 1) + next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]); + meta_mux_y_ports.swap(next_meta_mux_y_ports); + next_meta_mux_y_ports.clear(); + } + log_assert(meta_mux_y_ports.size() == 1); + module->connect(port_taints[Y], meta_mux_y_ports[0]); } else log_cmd_error("This is a bug (1).\n"); } @@ -202,7 +258,7 @@ struct GliftPass : public Pass { port_taints[i] = get_corresponding_taint_signal(ports[i]); if (cell->type == "$_NOT_") { - new_connections.emplace_back(port_taints[Y], port_taints[A]); + module->connect(port_taints[Y], port_taints[A]); } else log_cmd_error("This is a bug (2).\n"); } @@ -243,10 +299,7 @@ struct GliftPass : public Pass { } } - //Add new connections and mark new module outputs: - for (auto &conn : new_connections) - module->connect(conn); - + //Mark new module outputs: for (auto &port_name : module->ports) { RTLIL::Wire *port = module->wire(port_name); log_assert(port != nullptr); @@ -265,6 +318,7 @@ struct GliftPass : public Pass { opt_taintconstants = false; opt_keepoutputs = false; opt_nocostmodel = false; + opt_instrumentmore = false; module = nullptr; args.clear(); argidx = 0; @@ -274,7 +328,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -292,22 +346,35 @@ struct GliftPass : public Pass { log("\n"); log(" -create-precise-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); + log(" inputs, outputs, and internal nets along with precise taint tracking logic.\n"); + log(" For example, precise taint tracking logic for an AND gate is:\n"); + log("\n"); + log(" y_t = a & b_t | b & a_t | a_t & b_t\n"); + log("\n"); log("\n"); log(" -create-imprecise-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); - log(" logic.\n"); + log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint tracking\n"); + log(" logic:\n"); + log("\n"); + log(" y_t = a_t | b_t\n"); + log("\n"); log("\n"); log(" -create-instrumented-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); - log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); - log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); - log(" option is provided, an additional wire named `__glift_weight` with the `keep` and\n"); - log(" `minimize` attributes is added to the module along with pmuxes and adders to\n"); - log(" calculate a rough estimate of the number of logic gates in the GLIFT model given\n"); - log(" an assignment for the $anyconst cells.\n"); + log(" inputs, outputs, and internal nets along with 4 varying-precision versions of taint\n"); + log(" tracking logic. Which version of taint tracking logic is used for a given gate is\n"); + log(" determined by a MUX selected by an $anyconst cell. By default, unless the\n"); + log(" `-no-cost-model` option is provided, an additional wire named `__glift_weight` with\n"); + log(" the `keep` and `minimize` attributes is added to the module along with pmuxes and\n"); + log(" adders to calculate a rough estimate of the number of logic gates in the GLIFT model\n"); + log(" given an assignment for the $anyconst cells. The four versions of taint tracking logic\n"); + log(" for an AND gate are:"); + log("\n"); + log(" y_t = a & b_t | b & a_t | a_t & b_t (like `-create-precise-model`)\n"); + log(" y_t = a_t | a & b_t\n"); + log(" y_t = b_t | b & a_t\n"); + log(" y_t = a_t | b_t (like `-create-imprecise-model`)\n"); log("\n"); log("\n"); log("Options:\n"); @@ -323,9 +390,22 @@ struct GliftPass : public Pass { log("\n"); log(" -no-cost-model\n"); log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); - log(" Only applicable in combination with `-create-sketch`.\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); log(" (default: model area and give that wire the \"keep\" and \"minimize\" attributes)\n"); log("\n"); + log(" -instrument-more\n"); + log(" Allow choice from more versions of (even simpler) taint tracking logic. A total\n"); + log(" of 8 versions of taint tracking logic will be added per gate, including the 4\n"); + log(" versions from `-create-instrumented-model` and these additional versions:\n"); + log("\n"); + log(" y_t = a_t\n"); + log(" y_t = b_t\n"); + log(" y_t = 1\n"); + log(" y_t = 0\n"); + log("\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); + log(" (default: do not add more versions of taint tracking logic.\n"); + log("\n"); } void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE From c26a8d1ee051b1bb7925a58d713c452c376c1d25 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 10 Jun 2020 05:00:09 +0000 Subject: [PATCH 0012/2410] glift: Use `qbfsat -O2` instead of manually calling `abc`. --- examples/smtbmc/glift/C7552.ys | 6 +----- examples/smtbmc/glift/C880.ys | 6 +----- examples/smtbmc/glift/alu2.ys | 6 +----- examples/smtbmc/glift/alu4.ys | 6 +----- examples/smtbmc/glift/t481.ys | 6 +----- examples/smtbmc/glift/too_large.ys | 6 +----- examples/smtbmc/glift/ttt2.ys | 6 +----- examples/smtbmc/glift/x1.ys | 6 +----- 8 files changed, 8 insertions(+), 40 deletions(-) diff --git a/examples/smtbmc/glift/C7552.ys b/examples/smtbmc/glift/C7552.ys index c1fdf244e00..a9a1f5dc26c 100644 --- a/examples/smtbmc/glift/C7552.ys +++ b/examples/smtbmc/glift/C7552.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C7552.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution C7552.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/C880.ys b/examples/smtbmc/glift/C880.ys index 9a5e7bdcd08..410768f21b5 100644 --- a/examples/smtbmc/glift/C880.ys +++ b/examples/smtbmc/glift/C880.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution C880.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution C880.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/alu2.ys b/examples/smtbmc/glift/alu2.ys index f79c33ca5bc..b1671752e9b 100644 --- a/examples/smtbmc/glift/alu2.ys +++ b/examples/smtbmc/glift/alu2.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution alu2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/alu4.ys b/examples/smtbmc/glift/alu4.ys index 3fc2112d621..8e8d14225f3 100644 --- a/examples/smtbmc/glift/alu4.ys +++ b/examples/smtbmc/glift/alu4.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution alu4.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution alu4.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/t481.ys b/examples/smtbmc/glift/t481.ys index 282e723af9e..0e4afffda92 100644 --- a/examples/smtbmc/glift/t481.ys +++ b/examples/smtbmc/glift/t481.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution t481.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution t481.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/too_large.ys b/examples/smtbmc/glift/too_large.ys index 05b9fa5dc54..77be61e1703 100644 --- a/examples/smtbmc/glift/too_large.ys +++ b/examples/smtbmc/glift/too_large.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution too_large.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution too_large.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/ttt2.ys b/examples/smtbmc/glift/ttt2.ys index beba8b1026b..1314d497585 100644 --- a/examples/smtbmc/glift/ttt2.ys +++ b/examples/smtbmc/glift/ttt2.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution ttt2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution ttt2.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat diff --git a/examples/smtbmc/glift/x1.ys b/examples/smtbmc/glift/x1.ys index e48a4e6ce91..b588dea92e5 100644 --- a/examples/smtbmc/glift/x1.ys +++ b/examples/smtbmc/glift/x1.ys @@ -26,11 +26,7 @@ delete uut spec techmap opt stat miter -abc -script +print_stats;strash;print_stats;drwsat;print_stats;print_stats;fraig;print_stats;dc2,-l,-b;print_stats;irw,-l,-z;print_stats;refactor,-N,15,-z;print_stats;dch,-S,50000,-C,10000;print_stats;dc2,-l;print_stats;fraig,-C,10000;print_stats miter -techmap -opt -stat -qbfsat -dump-final-smt2 /tmp/test.smt2 -write-solution x1.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity -specialize miter +qbfsat -O2 -write-solution x1.soln -solver yices -timeout 3600 -nocleanup -assume-outputs -assume-negative-polarity miter design -pop stat From 91c20fca724b1f3ec1d0208a9e135b5abd75c0c1 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Sat, 13 Jun 2020 08:20:01 +0000 Subject: [PATCH 0013/2410] glift: Add `-simple-cost-model` option Rather than assigning specific weights to specific versions of taint tracking logic and summing the weights of all GLIFT cells, sum the following values for each GLIFT cell: - 0 if the associated hole/$anyconst cell value is non-zero, i.e. reduced-precision taint tracking logic is chosen at this cell - 1 if the associated hole/$anyconst cell value is zero, i.e. the full-precision taint tracking logic is chosen at this cell This simplified cost modeling reduces the potential for the QBF-SAT solver to minimize taint tracking logic area but significantly simplifies the QBF-SAT problem. --- passes/cmds/glift.cc | 65 ++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 42175859fa1..eee1b2c7921 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -28,7 +28,7 @@ struct GliftPass : public Pass { private: bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel, opt_instrumentmore; + bool opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; @@ -59,6 +59,10 @@ struct GliftPass : public Pass { opt_keepoutputs = true; continue; } + if (args[argidx] == "-simple-cost-model") { + opt_simplecostmodel = true; + continue; + } if (args[argidx] == "-no-cost-model") { opt_nocostmodel = true; continue; @@ -73,6 +77,10 @@ struct GliftPass : public Pass { log_cmd_error("No command provided. See help for usage.\n"); if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) log_cmd_error("Only one command may be specified. See help for usage.\n"); + if(opt_simplecostmodel && opt_nocostmodel) + log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); + if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) + log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -153,25 +161,33 @@ struct GliftPass : public Pass { RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { log_assert(metamux_select.is_wire()); - auto num_versions = opt_instrumentmore? 8 : 4; - auto select_width = log2(num_versions); - log_assert(metamux_select.as_wire()->width == select_width); - - std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates - - std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); - for (auto i = 0; pmux_y_ports.size() > 1; ++i) { - for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { - next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + if (opt_simplecostmodel) { + //The complex model is an area model, so a lower score should mean smaller. + //In this case, a nonzero hole metamux select value means less logic. + //Thus we should invert the ReduceOr over the metamux_select signal. + RTLIL::SigSpec pmux_select = module->ReduceOr(metamux_select.as_wire()->name.str() + "_nonzero", metamux_select); + return module->Pmux(NEW_ID, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->get_src_attribute()); + } else { + auto num_versions = opt_instrumentmore? 8 : 4; + auto select_width = log2(num_versions); + log_assert(metamux_select.as_wire()->width == select_width); + + std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates + + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + for (auto i = 0; pmux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { + next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + } + if (GetSize(pmux_y_ports) % 2 == 1) + next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); + pmux_y_ports.swap(next_pmux_y_ports); + next_pmux_y_ports.clear(); } - if (GetSize(pmux_y_ports) % 2 == 1) - next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); - pmux_y_ports.swap(next_pmux_y_ports); - next_pmux_y_ports.clear(); - } - log_assert(pmux_y_ports.size() == 1); - return pmux_y_ports[0]; + log_assert(pmux_y_ports.size() == 1); + return pmux_y_ports[0]; + } } void create_glift_logic() { @@ -276,7 +292,7 @@ struct GliftPass : public Pass { new_taint_outputs.push_back(first.as_wire()); } //end foreach conn in connections - //Create a rough model of area by summing the "weight" score of each meta-mux select: + //Create a rough model of area by summing the (potentially simplified) "weight" score of each meta-mux select: if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; @@ -317,6 +333,7 @@ struct GliftPass : public Pass { opt_create_instrumented_model = false; opt_taintconstants = false; opt_keepoutputs = false; + opt_simplecostmodel = false; opt_nocostmodel = false; opt_instrumentmore = false; module = nullptr; @@ -328,7 +345,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -388,6 +405,14 @@ struct GliftPass : public Pass { log(" alongside the orignal outputs.\n"); log(" (default: original module outputs are removed)\n"); log("\n"); + log(" -simple-cost-model\n"); + log(" Do not model logic area. Instead model the number of non-zero assignments to $anyconsts.\n"); + log(" Taint tracking logic versions vary in their size, but all reduced-precision versions are\n"); + log(" significantly smaller than the fully-precise version. A non-zero $anyconst assignment means\n"); + log(" that reduced-precision taint tracking logic was chosen for some gate.\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); + log(" (default: use a complex model and give that wire the \"keep\" and \"minimize\" attributes)\n"); + log("\n"); log(" -no-cost-model\n"); log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); log(" Only applicable in combination with `-create-instrumented-model`.\n"); From 8ec5929f97a0b6cf5610bd195f41a33d2104a006 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Fri, 19 Jun 2020 19:10:06 +0000 Subject: [PATCH 0014/2410] glift: Add CODEOWNERS entry. --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index a73779920c1..e3787e4294c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -34,4 +34,5 @@ backends/firrtl @ucbjrl @azidar passes/sat/qbfsat.cc @boqwxp passes/cmds/exec.cc @boqwxp +passes/cmds/glift.cc @boqwxp passes/cmds/printattrs.cc @boqwxp From 20ad37172428ae12378f87540acab55c874530fe Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Fri, 19 Jun 2020 19:57:09 +0000 Subject: [PATCH 0015/2410] glift: Replace `YS_OVERRIDE` with `override`. --- passes/cmds/glift.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index eee1b2c7921..26fdc4df7c4 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -347,7 +347,7 @@ struct GliftPass : public Pass { GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -433,7 +433,7 @@ struct GliftPass : public Pass { log("\n"); } - void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector _args, RTLIL::Design *design) override { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); From 209a123b9776fd28d73b64729eb815b2a6bfb774 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Sun, 21 Jun 2020 07:33:06 +0000 Subject: [PATCH 0016/2410] glift: Add initial hierarchy support. --- passes/cmds/glift.cc | 71 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 26fdc4df7c4..cc0e805a044 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -19,6 +19,7 @@ #include "kernel/register.h" #include "kernel/rtlil.h" +#include "kernel/utils.h" #include "kernel/log.h" USING_YOSYS_NAMESPACE @@ -36,6 +37,7 @@ struct GliftPass : public Pass { RTLIL::Module *module; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); + const RTLIL::IdString glift_attribute_name = ID(glift); void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { @@ -190,12 +192,15 @@ struct GliftPass : public Pass { } } - void create_glift_logic() { + void create_glift_logic(bool is_top_module) { + if (module->get_bool_attribute(glift_attribute_name)) + return; + std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { - log_cmd_error("Invalid cell type \"%s\" found. Module must be techmapped.\n", cell->type.c_str()); + if (!cell->type.in({"$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { const unsigned int A = 0, B = 1, Y = 2; @@ -278,13 +283,31 @@ struct GliftPass : public Pass { } else log_cmd_error("This is a bug (2).\n"); } + else if (module->design->module(cell->type) != nullptr) { + //User cell type + //This function is called on modules according to topological order, so we do not need to + //recurse to GLIFT model the child module. However, we need to augment the ports list + //with taint signals and connect the new ports to the corresponding taint signals. + RTLIL::Module *cell_module_def = module->design->module(cell->type); + dict orig_ports = cell->connections(); + log("Adding cell %s\n", cell_module_def->name.c_str()); + for (auto &it : orig_ports) { + RTLIL::SigSpec port = it.second; + RTLIL::SigSpec port_taint = get_corresponding_taint_signal(port); + + log_assert(port_taint.is_wire()); + log_assert(std::find(cell_module_def->ports.begin(), cell_module_def->ports.end(), port_taint.as_wire()->name) != cell_module_def->ports.end()); + cell->setPort(port_taint.as_wire()->name, port_taint); + } + } + else log_cmd_error("This is a bug (3).\n"); } //end foreach cell in cells for (auto &conn : connections) { RTLIL::SigSpec first = get_corresponding_taint_signal(conn.first); RTLIL::SigSpec second = get_corresponding_taint_signal(conn.second); - module->connect(get_corresponding_taint_signal(conn.first), get_corresponding_taint_signal(conn.second)); + module->connect(first, second); if(conn.second.is_wire() && conn.second.as_wire()->port_input) second.as_wire()->port_input = true; @@ -319,12 +342,13 @@ struct GliftPass : public Pass { for (auto &port_name : module->ports) { RTLIL::Wire *port = module->wire(port_name); log_assert(port != nullptr); - if (port->port_output && !opt_keepoutputs) + if (is_top_module && port->port_output && !opt_keepoutputs) port->port_output = false; } for (auto &output : new_taint_outputs) output->port_output = true; module->fixup_ports(); //we have some new taint signals in the module interface + module->set_bool_attribute(glift_attribute_name, true); } void reset() { @@ -442,15 +466,38 @@ struct GliftPass : public Pass { parse_args(); extra_args(args, argidx, design); - for (auto mod : design->selected_modules()) { - if (module) - log_cmd_error("Only one module may be selected for the glift pass! Flatten the design if necessary. (selected: %s and %s)\n", log_id(module), log_id(mod)); - module = mod; - } - if (module == nullptr) + if (GetSize(design->selected_modules()) == 0) log_cmd_error("Can't operate on an empty selection!\n"); - create_glift_logic(); + TopoSort> topo_modules; //cribbed from passes/techmap/flatten.cc + auto worklist = design->selected_modules(); + pool non_top_modules; + while (!worklist.empty()) { + RTLIL::Module *module = *(worklist.begin()); + worklist.erase(worklist.begin()); + topo_modules.node(module); + + for (auto cell : module->selected_cells()) { + RTLIL::Module *tpl = design->module(cell->type); + if (tpl != nullptr) { + if (topo_modules.database.count(tpl) == 0) + worklist.push_back(tpl); + topo_modules.edge(tpl, module); + non_top_modules.insert(cell->type); + } + } + } + + if (!topo_modules.sort()) + log_cmd_error("Cannot handle recursive module instantiations.\n"); + + for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) { + new_taint_outputs.clear(); + meta_mux_selects.clear(); + module = topo_modules.sorted[i]; + + create_glift_logic(!non_top_modules[module->name]); + } } } GliftPass; From 23defc6fe9382b2efcfc0a855655f0d235c597b5 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 00:22:12 +0000 Subject: [PATCH 0017/2410] glift: Add support for $_XOR_ and $_XNOR_ cells. --- passes/cmds/glift.cc | 94 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 15 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index cc0e805a044..f890a80bb63 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -33,7 +33,7 @@ struct GliftPass : public Pass { std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; - std::vector meta_mux_selects; + std::vector> meta_mux_selects; RTLIL::Module *module; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); @@ -140,7 +140,7 @@ struct GliftPass : public Pass { } void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { - //AKA AN2_SH5 or OR2_SH5 + //AKA AN2_SH5 or OR2_SH5 or XR2_SH2 module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); } @@ -160,7 +160,7 @@ struct GliftPass : public Pass { module->connect(port_y_taint, RTLIL::Const(0, 1)); } - RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select, const RTLIL::IdString celltype) { log_assert(metamux_select.is_wire()); if (opt_simplecostmodel) { @@ -170,13 +170,21 @@ struct GliftPass : public Pass { RTLIL::SigSpec pmux_select = module->ReduceOr(metamux_select.as_wire()->name.str() + "_nonzero", metamux_select); return module->Pmux(NEW_ID, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->get_src_attribute()); } else { - auto num_versions = opt_instrumentmore? 8 : 4; - auto select_width = log2(num_versions); - log_assert(metamux_select.as_wire()->width == select_width); - - std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates + auto select_width = metamux_select.as_wire()->width; + + std::vector costs; + if (celltype == ID(_AND_) || celltype == ID(_OR_)) { + costs = {5, 2, 2, 1, 0, 0, 0, 0}; + log_assert(select_width == 2 || select_width == 3); + log_assert(opt_instrumentmore || select_width == 2); + log_assert(!opt_instrumentmore || select_width == 3); + } + else if (celltype == ID(_XOR_) || celltype == ID(_XNOR_)) { + costs = {1, 0, 0, 0}; + log_assert(select_width == 2); + } - std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + exp2(select_width)); for (auto i = 0; pmux_y_ports.size() > 1; ++i) { for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); @@ -199,7 +207,7 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { @@ -249,7 +257,7 @@ struct GliftPass : public Pass { auto select_width = log2(num_versions); log_assert(exp2(select_width) == num_versions); RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); - meta_mux_selects.push_back(meta_mux_select); + meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); @@ -267,6 +275,62 @@ struct GliftPass : public Pass { } else log_cmd_error("This is a bug (1).\n"); } + else if (cell->type.in("$_XOR_", "$_XNOR_")) { + const unsigned int A = 0, B = 1, Y = 2; + const unsigned int NUM_PORTS = 3; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (opt_create_precise_model || opt_create_imprecise_model) + add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); + else if (opt_create_instrumented_model) { + std::vector taint_version; + int num_versions = 4; + auto select_width = log2(num_versions); + log_assert(exp2(select_width) == num_versions); + + for (auto i = 1; i <= num_versions; ++i) + taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name.c_str(), i), 1))); + + for (auto i = 0; i < num_versions; ++i) { + switch(i) { + case 0: add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], taint_version[i]); + break; + case 1: add_imprecise_GLIFT_logic_4(port_taints[A], taint_version[i]); + break; + case 2: add_imprecise_GLIFT_logic_5(port_taints[B], taint_version[i]); + break; + case 3: add_imprecise_GLIFT_logic_6(taint_version[i]); + break; + default: log_assert(false); + } + } + + RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); + meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); + module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); + + std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); + for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) { + next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name.c_str(), i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i])); + } + if (GetSize(meta_mux_y_ports) % 2 == 1) + next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]); + meta_mux_y_ports.swap(next_meta_mux_y_ports); + next_meta_mux_y_ports.clear(); + } + log_assert(meta_mux_y_ports.size() == 1); + module->connect(port_taints[Y], meta_mux_y_ports[0]); + } + else log_cmd_error("This is a bug (2).\n"); + + } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; @@ -281,7 +345,7 @@ struct GliftPass : public Pass { if (cell->type == "$_NOT_") { module->connect(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (2).\n"); + else log_cmd_error("This is a bug (3).\n"); } else if (module->design->module(cell->type) != nullptr) { //User cell type @@ -300,7 +364,7 @@ struct GliftPass : public Pass { cell->setPort(port_taint.as_wire()->name, port_taint); } } - else log_cmd_error("This is a bug (3).\n"); + else log_cmd_error("This is a bug (4).\n"); } //end foreach cell in cells for (auto &conn : connections) { @@ -319,8 +383,8 @@ struct GliftPass : public Pass { if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; - for (auto &wire : meta_mux_selects) { - meta_mux_select_sums.emplace_back(score_metamux_select(wire)); + for (auto &it : meta_mux_selects) { + meta_mux_select_sums.emplace_back(score_metamux_select(it.first, it.second)); } for (unsigned int i = 0; meta_mux_select_sums.size() > 1; ) { meta_mux_select_sums_buf.clear(); From 8cb1a86c23a8d9abbaadc1e7400018a593e2e818 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 05:54:14 +0000 Subject: [PATCH 0018/2410] glift: Add support for $_MUX_ and $_NMUX_ cells. --- passes/cmds/glift.cc | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index f890a80bb63..d6d873e0107 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -160,6 +160,26 @@ struct GliftPass : public Pass { module->connect(port_y_taint, RTLIL::Const(0, 1)); } + void add_precise_GLIFT_mux(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_s, RTLIL::SigSpec &port_s_taint, RTLIL::SigSpec &port_y_taint) { + //S&At | ~S&Bt | ~A&B&St | A&~B&St | At&St | Bt&St + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_4_1", port_a, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_4_2", port_b, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_s = module->LogicNot(cell->name.str() + "_t_4_3", port_s, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_4_4", port_s, port_a_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_4_5", n_port_s, port_b_taint, false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_4_6", n_port_a, port_b, false, cell->get_src_attribute()); + auto subexpr4 = module->And(cell->name.str() + "_t_4_7", subexpr3, port_s_taint, false, cell->get_src_attribute()); + auto subexpr5 = module->And(cell->name.str() + "_t_4_8", port_a, n_port_b, false, cell->get_src_attribute()); + auto subexpr6 = module->And(cell->name.str() + "_t_4_9", subexpr5, port_s_taint, false, cell->get_src_attribute()); + auto subexpr7 = module->And(cell->name.str() + "_t_4_10", port_a_taint, port_s_taint, false, cell->get_src_attribute()); + auto subexpr8 = module->And(cell->name.str() + "_t_4_11", port_b_taint, port_s_taint, false, cell->get_src_attribute()); + auto subexpr9 = module->Or(cell->name.str() + "_t_4_12", subexpr1, subexpr2, false, cell->get_src_attribute()); + auto subexpr10 = module->Or(cell->name.str() + "_t_4_13", subexpr4, subexpr6, false, cell->get_src_attribute()); + auto subexpr11 = module->Or(cell->name.str() + "_t_4_14", subexpr7, subexpr8, false, cell->get_src_attribute()); + auto subexpr12 = module->Or(cell->name.str() + "_t_4_15", subexpr9, subexpr10, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_4_16", subexpr11, subexpr12, port_y_taint, false, cell->get_src_attribute()); + } + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select, const RTLIL::IdString celltype) { log_assert(metamux_select.is_wire()); @@ -207,7 +227,7 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { @@ -331,6 +351,19 @@ struct GliftPass : public Pass { else log_cmd_error("This is a bug (2).\n"); } + else if (cell->type.in("$_MUX_", "$_NMUX_")) { + const unsigned int A = 0, B = 1, S = 2, Y = 3; + const unsigned int NUM_PORTS = 4; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::S), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[S].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]); + } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; From 3eb2593876b3778d158b1955aa5a2b4bf40aab5a Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 06:03:36 +0000 Subject: [PATCH 0019/2410] glift: Add support for $_NAND_ and $_NOR_ cells. --- passes/cmds/glift.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index d6d873e0107..0968da71edc 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -116,10 +116,11 @@ struct GliftPass : public Pass { void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH2 or OR2_SH2 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_1_3", (cell->type == "$_AND_")? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_1_4", (cell->type == "$_AND_")? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_1_3", is_and? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_1_4", is_and? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); auto subexpr3 = module->And(cell->name.str() + "_t_1_5", port_a_taint, port_b_taint, false, cell->get_src_attribute()); auto subexpr4 = module->Or(cell->name.str() + "_t_1_6", subexpr1, subexpr2, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_1_7", subexpr4, subexpr3, port_y_taint, false, cell->get_src_attribute()); @@ -127,16 +128,18 @@ struct GliftPass : public Pass { void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH3 or OR2_SH3 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_2_2", (cell->type == "$_AND_")? port_b : n_port_a, (cell->type == "$_AND_")? port_a_taint : port_b_taint, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_2_3", (cell->type == "$_AND_")? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_2_2", is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_2_3", is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); } void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH4 or OR2_SH4 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_3_2", (cell->type == "$_AND_")? port_a : n_port_b, (cell->type == "$_AND_")? port_b_taint : port_a_taint, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_3_3", (cell->type == "$_AND_")? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3_2", is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_3_3", is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); } void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { @@ -227,10 +230,10 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } - if (cell->type.in("$_AND_", "$_OR_")) { + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_")) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; From eda1af73c47fd24c14ac75e01bdc4e1a37194fb4 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 18:41:01 +0000 Subject: [PATCH 0020/2410] glift: Use worker pattern. --- passes/cmds/glift.cc | 155 +++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 80 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 0968da71edc..127abd7af0d 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -25,65 +25,19 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct GliftPass : public Pass { - private: - - bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore; - std::vector args; - std::vector::size_type argidx; +struct GliftWorker { +private: + bool is_top_module = false; + bool opt_create_precise_model = false, opt_create_imprecise_model = false, opt_create_instrumented_model = false; + bool opt_taintconstants = false, opt_keepoutputs = false, opt_simplecostmodel = false, opt_nocostmodel = false; + bool opt_instrumentmore = false; std::vector new_taint_outputs; std::vector> meta_mux_selects; - RTLIL::Module *module; + RTLIL::Module *module = nullptr; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); const RTLIL::IdString glift_attribute_name = ID(glift); - void parse_args() { - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create-precise-model") { - opt_create_precise_model = true; - continue; - } - if (args[argidx] == "-create-imprecise-model") { - opt_create_imprecise_model = true; - continue; - } - if (args[argidx] == "-create-instrumented-model") { - opt_create_instrumented_model = true; - continue; - } - if (args[argidx] == "-taint-constants") { - opt_taintconstants = true; - continue; - } - if (args[argidx] == "-keep-outputs") { - opt_keepoutputs = true; - continue; - } - if (args[argidx] == "-simple-cost-model") { - opt_simplecostmodel = true; - continue; - } - if (args[argidx] == "-no-cost-model") { - opt_nocostmodel = true; - continue; - } - if (args[argidx] == "-instrument-more") { - opt_instrumentmore = true; - continue; - } - break; - } - if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) - log_cmd_error("No command provided. See help for usage.\n"); - if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) - log_cmd_error("Only one command may be specified. See help for usage.\n"); - if(opt_simplecostmodel && opt_nocostmodel) - log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); - if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) - log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); - } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { RTLIL::SigSpec ret; @@ -223,7 +177,7 @@ struct GliftPass : public Pass { } } - void create_glift_logic(bool is_top_module) { + void create_glift_logic() { if (module->get_bool_attribute(glift_attribute_name)) return; @@ -451,25 +405,25 @@ struct GliftPass : public Pass { module->set_bool_attribute(glift_attribute_name, true); } - void reset() { - opt_create_precise_model = false; - opt_create_imprecise_model = false; - opt_create_instrumented_model = false; - opt_taintconstants = false; - opt_keepoutputs = false; - opt_simplecostmodel = false; - opt_nocostmodel = false; - opt_instrumentmore = false; - module = nullptr; - args.clear(); - argidx = 0; - new_taint_outputs.clear(); - meta_mux_selects.clear(); +public: + GliftWorker(RTLIL::Module *_module, bool _is_top_module, bool _opt_create_precise_model, bool _opt_create_imprecise_model, bool _opt_create_instrumented_model, bool _opt_taintconstants, bool _opt_keepoutputs, bool _opt_simplecostmodel, bool _opt_nocostmodel, bool _opt_instrumentmore) { + module = _module; + is_top_module = _is_top_module; + opt_create_precise_model = _opt_create_precise_model; + opt_create_imprecise_model = _opt_create_imprecise_model; + opt_create_instrumented_model = _opt_create_instrumented_model; + opt_taintconstants = _opt_taintconstants; + opt_keepoutputs = _opt_keepoutputs; + opt_simplecostmodel = _opt_simplecostmodel; + opt_nocostmodel = _opt_nocostmodel; + opt_instrumentmore = _opt_instrumentmore; + + create_glift_logic(); } +}; - public: - - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } +struct GliftPass : public Pass { + GliftPass() : Pass("glift", "create GLIFT models and optimization problems") {} void help() override { @@ -557,13 +511,57 @@ struct GliftPass : public Pass { log("\n"); } - void execute(std::vector _args, RTLIL::Design *design) override + void execute(std::vector args, RTLIL::Design *design) override { + bool opt_create_precise_model = false, opt_create_imprecise_model = false, opt_create_instrumented_model = false; + bool opt_taintconstants = false, opt_keepoutputs = false, opt_simplecostmodel = false, opt_nocostmodel = false; + bool opt_instrumentmore = false; log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + std::vector::size_type argidx; - reset(); - args = _args; - parse_args(); + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-create-precise-model") { + opt_create_precise_model = true; + continue; + } + if (args[argidx] == "-create-imprecise-model") { + opt_create_imprecise_model = true; + continue; + } + if (args[argidx] == "-create-instrumented-model") { + opt_create_instrumented_model = true; + continue; + } + if (args[argidx] == "-taint-constants") { + opt_taintconstants = true; + continue; + } + if (args[argidx] == "-keep-outputs") { + opt_keepoutputs = true; + continue; + } + if (args[argidx] == "-simple-cost-model") { + opt_simplecostmodel = true; + continue; + } + if (args[argidx] == "-no-cost-model") { + opt_nocostmodel = true; + continue; + } + if (args[argidx] == "-instrument-more") { + opt_instrumentmore = true; + continue; + } + break; + } + if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) + log_cmd_error("No command provided. See help for usage.\n"); + if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) + log_cmd_error("Only one command may be specified. See help for usage.\n"); + if(opt_simplecostmodel && opt_nocostmodel) + log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); + if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) + log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); extra_args(args, argidx, design); if (GetSize(design->selected_modules()) == 0) @@ -592,11 +590,8 @@ struct GliftPass : public Pass { log_cmd_error("Cannot handle recursive module instantiations.\n"); for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) { - new_taint_outputs.clear(); - meta_mux_selects.clear(); - module = topo_modules.sorted[i]; - - create_glift_logic(!non_top_modules[module->name]); + RTLIL::Module *module = topo_modules.sorted[i]; + GliftWorker(module, !non_top_modules[module->name], opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore); } } } GliftPass; From bbfa2d65fa1a89765568ac3afa7ca65b67d24bf2 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 18:50:29 +0000 Subject: [PATCH 0021/2410] glift: Use ID() rather than string literals. --- passes/cmds/glift.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 127abd7af0d..b398c3e0457 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -70,7 +70,7 @@ struct GliftWorker { void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH2 or OR2_SH2 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_1_3", is_and? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); @@ -82,7 +82,7 @@ struct GliftWorker { void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH3 or OR2_SH3 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_2_2", is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_2_3", is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); @@ -90,7 +90,7 @@ struct GliftWorker { void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH4 or OR2_SH4 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_3_2", is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_3_3", is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); @@ -150,13 +150,13 @@ struct GliftWorker { auto select_width = metamux_select.as_wire()->width; std::vector costs; - if (celltype == ID(_AND_) || celltype == ID(_OR_)) { + if (celltype == ID($_AND_) || celltype == ID($_OR_)) { costs = {5, 2, 2, 1, 0, 0, 0, 0}; log_assert(select_width == 2 || select_width == 3); log_assert(opt_instrumentmore || select_width == 2); log_assert(!opt_instrumentmore || select_width == 3); } - else if (celltype == ID(_XOR_) || celltype == ID(_XNOR_)) { + else if (celltype == ID($_XOR_) || celltype == ID($_XNOR_)) { costs = {1, 0, 0, 0}; log_assert(select_width == 2); } @@ -184,10 +184,10 @@ struct GliftWorker { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_MUX_), ID($_NMUX_), ID($_NOT_), ID($anyconst), ID($allconst), ID($assume), ID($assert)}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_")) { + if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_))) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; @@ -252,7 +252,7 @@ struct GliftWorker { } else log_cmd_error("This is a bug (1).\n"); } - else if (cell->type.in("$_XOR_", "$_XNOR_")) { + else if (cell->type.in(ID($_XOR_), ID($_XNOR_))) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; @@ -308,7 +308,7 @@ struct GliftWorker { else log_cmd_error("This is a bug (2).\n"); } - else if (cell->type.in("$_MUX_", "$_NMUX_")) { + else if (cell->type.in(ID($_MUX_), ID($_NMUX_))) { const unsigned int A = 0, B = 1, S = 2, Y = 3; const unsigned int NUM_PORTS = 4; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::S), cell->getPort(ID::Y)}; @@ -321,7 +321,7 @@ struct GliftWorker { add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]); } - else if (cell->type.in("$_NOT_")) { + else if (cell->type.in(ID($_NOT_))) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::Y)}; @@ -332,7 +332,7 @@ struct GliftWorker { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (cell->type == "$_NOT_") { + if (cell->type == ID($_NOT_)) { module->connect(port_taints[Y], port_taints[A]); } else log_cmd_error("This is a bug (3).\n"); From 2c6cc27af1e981d24342ad1b378ec0f6d93092f1 Mon Sep 17 00:00:00 2001 From: Sahand Kashani Date: Thu, 23 Jul 2020 15:17:58 +0200 Subject: [PATCH 0022/2410] Add firrtl backend support for generic parameters in blackbox components Previous blackbox components were just emitted with their interface ports, but their generic parameters were never emitted and it was therefore impossible to customize them. This commit adds support for blackbox generic parameters, though support is only provided for INTEGER and STRING parameters. Other types of parameters such as DOUBLEs, ..., would result in undefined behavior here. This allows the emission of custom extmodule instances such as the following: extmodule fourteennm_lcell_comb_: input cin: UInt<1> output combout: UInt<1> output cout: UInt<1> input dataa: UInt<1> input datab: UInt<1> input datac: UInt<1> input datad: UInt<1> input datae: UInt<1> input dataf: UInt<1> input datag: UInt<1> input datah: UInt<1> input sharein: UInt<1> output shareout: UInt<1> output sumout: UInt<1> defname = fourteennm_lcell_comb parameter extended_lut = "off" parameter lut_mask = "b0001001000010010000100100001001000010010000100100001001000010010" parameter shared_arith = "off" --- backends/firrtl/firrtl.cc | 280 ++++++++++++++++++++++++++++++-------- 1 file changed, 222 insertions(+), 58 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 9739a7a9ff5..9a201d83d31 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -102,6 +102,188 @@ const char *make_id(IdString id) return namecache.at(id).c_str(); } +std::string dump_const(const RTLIL::Const &data) +{ + std::string dataStr; + + dataStr += "\""; + + if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0) + { + // Emit binary prefix for string. + dataStr += "b"; + + // Emit bits. + int width = data.bits.size(); + for (int i = width - 1; i >= 0; i--) + { + log_assert(i < width); + switch (data.bits[i]) + { + case State::S0: dataStr += stringf("0"); break; + case State::S1: dataStr += stringf("1"); break; + case State::Sx: dataStr += stringf("x"); break; + case State::Sz: dataStr += stringf("z"); break; + case State::Sa: dataStr += stringf("-"); break; + case State::Sm: dataStr += stringf("m"); break; + } + } + } + else + { + std::string str = data.decode_string(); + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '\n') + dataStr += "\\n"; + else if (str[i] == '\t') + dataStr += "\\t"; + else if (str[i] < 32) + dataStr += stringf("\\%03o", str[i]); + else if (str[i] == '"') + dataStr += "\\\""; + else if (str[i] == '\\') + dataStr += "\\\\"; + else + dataStr += str[i]; + } + } + + dataStr += "\""; + + return dataStr; +} + +std::string extmodule_name(RTLIL::Cell *cell, RTLIL::Module *mod_instance) +{ + // Since we are creating a custom extmodule for every cell that instantiates + // this blackbox, we need to create a custom name for it. We just use the + // name of the blackbox itself followed by the name of the cell. + const std::string cell_name = std::string(make_id(cell->name)); + const std::string blackbox_name = std::string(make_id(mod_instance->name)); + const std::string extmodule_name = blackbox_name + "_" + cell_name; + return extmodule_name; +} + +/** + * Emits a parameterized extmodule. Instance parameters are obtained from + * ''cell'' as it represents the instantiation of the blackbox defined by + * ''mod_instance'' and therefore contains all its instance parameters. + */ +void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream &f) +{ + const std::string indent = " "; + + const std::string blackbox_name = std::string(make_id(mod_instance->name)); + const std::string exported_name = extmodule_name(cell, mod_instance); + + // We use the cell's fileinfo for this extmodule as its parameters come from + // the cell and not from the module itself (the module contains default + // parameters, not the instance-specific ones we're using to emit the + // extmodule). + const std::string extmoduleFileinfo = getFileinfo(cell); + + // Emit extmodule header. + f << stringf(" extmodule %s: %s\n", exported_name.c_str(), extmoduleFileinfo.c_str()); + + // Emit extmodule ports. + for (auto wire : mod_instance->wires()) + { + const auto wireName = make_id(wire->name); + const std::string wireFileinfo = getFileinfo(wire); + + if (wire->port_input && wire->port_output) + { + log_error("Module port %s.%s is inout!\n", log_id(mod_instance), log_id(wire)); + } + + const std::string portDecl = stringf("%s%s %s: UInt<%d> %s\n", + indent.c_str(), + wire->port_input ? "input" : "output", + wireName, + wire->width, + wireFileinfo.c_str() + ); + + f << portDecl; + } + + // Emit extmodule "defname" field. This is the name of the verilog blackbox + // that is used when verilog is emitted, so we use the name of mod_instance + // here. + f << stringf("%sdefname = %s\n", indent.c_str(), blackbox_name.c_str()); + + // Emit extmodule generic parameters. + for (const auto &p : cell->parameters) + { + std::string param_name(p.first.c_str()); + const std::string param_value = dump_const(p.second); + + // Remove backslashes from parameters as these come from the internal RTLIL + // naming scheme, but should not exist in the emitted firrtl blackboxes. + // When firrtl is converted to verilog and given to downstream synthesis + // tools, these tools expect to find blackbox names and parameters as they + // were originally defined, i.e. without the extra RTLIL naming conventions. + param_name.erase( + std::remove(param_name.begin(), param_name.end(), '\\'), + param_name.end() + ); + + f << stringf("%sparameter %s = %s\n", indent.c_str(), param_name.c_str(), param_value.c_str()); + } + + f << "\n"; +} + +/** + * Emits extmodules for every instantiated blackbox in the design. + * + * RTLIL stores instance parameters at the cell's instantiation location. + * However, firrtl does not support module parameterization (everything is + * already elaborated). Firrtl instead supports external modules (extmodule), + * i.e. blackboxes that are defined by verilog and which have no body in + * firrtl itself other than the declaration of the blackboxes ports and + * parameters. + * + * Furthermore, firrtl does not support parameterization (even of extmodules) + * at a module's instantiation location and users must instead declare + * different extmodules with different instance parameters in the extmodule + * definition itself. + * + * This function goes through the design to identify all RTLIL blackboxes + * and emit parameterized extmodules with a unique name for each of them. The + * name that's given to the extmodule is + * + * _ + * + * Beware that it is therefore necessary for users to replace "parameterized" + * instances in the RTLIL sense with these custom extmodules for the firrtl to + * be valid. + */ +void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f) +{ + for (auto module : design->modules()) + { + for (auto cell : module->cells()) + { + // Is this cell a module instance? + bool cellIsModuleInstance = cell->type[0] != '$'; + + if (cellIsModuleInstance) + { + // Find the module corresponding to this instance. + auto modInstance = design->module(cell->type); + bool modIsBlackbox = modInstance->get_blackbox_attribute(); + + if (modIsBlackbox) + { + emit_extmodule(cell, modInstance, f); + } + } + } + } +} + struct FirrtlWorker { Module *module; @@ -328,8 +510,16 @@ struct FirrtlWorker log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str()); return; } + + // If the instance is that of a blackbox, use the modified extmodule name + // that contains per-instance parameterizations. These instances were + // emitted earlier in the firrtl backend. + const std::string instanceName = instModule->get_blackbox_attribute() ? + extmodule_name(cell, instModule) : + instanceOf; + std::string cellFileinfo = getFileinfo(cell); - wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceOf.c_str(), cellFileinfo.c_str())); + wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceName.c_str(), cellFileinfo.c_str())); for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) { if (it->second.size() > 0) { @@ -392,33 +582,6 @@ struct FirrtlWorker return result; } - void emit_extmodule() - { - std::string moduleFileinfo = getFileinfo(module); - f << stringf(" extmodule %s: %s\n", make_id(module->name), moduleFileinfo.c_str()); - vector port_decls; - - for (auto wire : module->wires()) - { - const auto wireName = make_id(wire->name); - std::string wireFileinfo = getFileinfo(wire); - - if (wire->port_input && wire->port_output) - { - log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); - } - port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output", - wireName, wire->width, wireFileinfo.c_str())); - } - - for (auto &str : port_decls) - { - f << str; - } - - f << stringf("\n"); - } - void emit_module() { std::string moduleFileinfo = getFileinfo(module); @@ -440,12 +603,12 @@ struct FirrtlWorker { if (wire->port_input && wire->port_output) log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); - port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output", + port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent.c_str(), wire->port_input ? "input" : "output", wireName, wire->width, wireFileinfo.c_str())); } else { - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", wireName, wire->width, wireFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), wireName, wire->width, wireFileinfo.c_str())); } } @@ -476,7 +639,7 @@ struct FirrtlWorker if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor))) { string a_expr = make_expr(cell->getPort(ID::A)); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str())); if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; @@ -516,7 +679,7 @@ struct FirrtlWorker if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -528,7 +691,7 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); string b_expr = make_expr(cell->getPort(ID::B)); std::string cellFileinfo = getFileinfo(cell); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str())); if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; @@ -746,7 +909,7 @@ struct FirrtlWorker if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -759,11 +922,11 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); string b_expr = make_expr(cell->getPort(ID::B)); string s_expr = make_expr(cell->getPort(ID::S)); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), width, cellFileinfo.c_str())); string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -902,9 +1065,9 @@ struct FirrtlWorker string expr = make_expr(cell->getPort(ID::D)); string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")"; - wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s %s\n", y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str())); + wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent.c_str(), y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str())); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Q)); continue; @@ -923,7 +1086,7 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); // Get the initial bit selector string b_expr = make_expr(cell->getPort(ID::B)); - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); if (cell->getParam(ID::B_SIGNED).as_bool()) { // Use validif to constrain the selection (test the sign bit) @@ -933,7 +1096,7 @@ struct FirrtlWorker } string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -945,7 +1108,7 @@ struct FirrtlWorker string b_expr = make_expr(cell->getPort(ID::B)); auto b_string = b_expr.c_str(); string expr; - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); if (cell->getParam(ID::B_SIGNED).as_bool()) { // We generate a left or right shift based on the sign of b. @@ -959,7 +1122,7 @@ struct FirrtlWorker } else { expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string); } - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -972,8 +1135,8 @@ struct FirrtlWorker if (a_width < y_width) { a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width); } - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), a_expr.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), a_expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -986,8 +1149,8 @@ struct FirrtlWorker int y_width = GetSize(conn.first); string expr = make_expr(conn.second); - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, conn.first); } @@ -1053,13 +1216,13 @@ struct FirrtlWorker if (is_valid) { if (make_unconn_id) { - wire_decls.push_back(stringf(" wire %s: UInt<1> %s\n", unconn_id.c_str(), wireFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent.c_str(), unconn_id.c_str(), wireFileinfo.c_str())); // `invalid` is a firrtl construction for simulation so we will not // tag it with a @[fileinfo] tag as it doesn't directly correspond to // a specific line of verilog code. - wire_decls.push_back(stringf(" %s is invalid\n", unconn_id.c_str())); + wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), unconn_id.c_str())); } - wire_exprs.push_back(stringf(" %s <= %s %s\n", make_id(wire->name), expr.c_str(), wireFileinfo.c_str())); + wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), make_id(wire->name), expr.c_str(), wireFileinfo.c_str())); } else { if (make_unconn_id) { unconn_id.clear(); @@ -1067,7 +1230,7 @@ struct FirrtlWorker // `invalid` is a firrtl construction for simulation so we will not // tag it with a @[fileinfo] tag as it doesn't directly correspond to // a specific line of verilog code. - wire_decls.push_back(stringf(" %s is invalid\n", make_id(wire->name))); + wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), make_id(wire->name))); } } @@ -1112,12 +1275,7 @@ struct FirrtlWorker void run() { - // Blackboxes should be emitted as `extmodule`s in firrtl. Only ports are - // emitted in such a case. - if (module->get_blackbox_attribute()) - emit_extmodule(); - else - emit_module(); + emit_module(); } }; @@ -1180,10 +1338,16 @@ struct FirrtlBackend : public Backend { std::string circuitFileinfo = getFileinfo(top); *f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str()); + emit_elaborated_extmodules(design, *f); + + // Emit non-blackbox modules. for (auto module : design->modules()) { - FirrtlWorker worker(module, *f, design); - worker.run(); + if (!module->get_blackbox_attribute()) + { + FirrtlWorker worker(module, *f, design); + worker.run(); + } } namecache.clear(); From 5157f5623e2795c6ec2da650a7d8b5587af50c78 Mon Sep 17 00:00:00 2001 From: Sahand Kashani Date: Thu, 6 Aug 2020 00:49:55 +0200 Subject: [PATCH 0023/2410] Add support for real-valued parameters + preserve type of parameters This commit adds support for real-valued parameters in blackboxes. Additionally, parameters now retain their types are no longer all encoded as strings. There is a caveat with this implementation due to my limited knowledge of yosys, more specifically to how yosys encodes bitwidths of parameter values. The example below can motivate the implementation choice I took. Suppose a verilog component is declared with the following parameters: parameter signed [26:0] test_signed; parameter [26:0] test_unsigned; parameter signed [40:0] test_signed_large; If you instantiate it as follows: defparam .test_signed = 49; defparam .test_unsigned = 40'd35; defparam .test_signed_large = 40'd12; If you peek in the RTLIL::Const structure corresponding to these params, you realize that parameter "test_signed" is being considered as a 32-bit value since it's declared as "49" without a width specifier, even though the parameter is defined to have a maximum width of 27 bits. A similar issue occurs for parameter "test_unsigned" where it is supposed to take a maximum bit width of 27 bits, but if the user supplies a 40-bit value as above, then yosys considers the value to be 40 bits. I suppose this is due to the type being defined by the RHS rather than the definition. Regardless of this, I emit the same widths as what the user specifies on the RHS when generating firrtl IR. --- backends/firrtl/firrtl.cc | 151 ++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 38 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 9a201d83d31..5c2807ef49e 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -102,56 +102,128 @@ const char *make_id(IdString id) return namecache.at(id).c_str(); } +std::string dump_const_string(const RTLIL::Const &data) +{ + std::string res_str; + + std::string str = data.decode_string(); + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '\n') + res_str += "\\n"; + else if (str[i] == '\t') + res_str += "\\t"; + else if (str[i] < 32) + res_str += stringf("\\%03o", str[i]); + else if (str[i] == '"') + res_str += "\\\""; + else if (str[i] == '\\') + res_str += "\\\\"; + else + res_str += str[i]; + } + + return res_str; +} + std::string dump_const(const RTLIL::Const &data) { - std::string dataStr; + std::string res_str; - dataStr += "\""; + // // For debugging purposes to find out how Yosys encodes flags. + // res_str += stringf("flags_%x --> ", data.flags); - if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0) + // Real-valued parameter. + if (data.flags & RTLIL::CONST_FLAG_REAL) + { + // Yosys stores real values as strings, so we call the string dumping code. + res_str += dump_const_string(data); + } + // String parameter. + else if (data.flags & RTLIL::CONST_FLAG_STRING) + { + res_str += "\""; + res_str += dump_const_string(data); + res_str += "\""; + } + // Numeric (non-real) parameter. + else { - // Emit binary prefix for string. - dataStr += "b"; - - // Emit bits. int width = data.bits.size(); - for (int i = width - 1; i >= 0; i--) + + // If a standard 32-bit int, then emit standard int value like "56" or + // "-56". Firrtl supports negative-valued int literals. + // + // SignedInt + // : ( '+' | '-' ) PosInt + // ; + if (width <= 32) { - log_assert(i < width); - switch (data.bits[i]) + int32_t int_val = 0; + + for (int i = 0; i < width; i++) { - case State::S0: dataStr += stringf("0"); break; - case State::S1: dataStr += stringf("1"); break; - case State::Sx: dataStr += stringf("x"); break; - case State::Sz: dataStr += stringf("z"); break; - case State::Sa: dataStr += stringf("-"); break; - case State::Sm: dataStr += stringf("m"); break; + switch (data.bits[i]) + { + case State::S0: break; + case State::S1: int_val |= (1 << i); break; + default: + log_error("Unexpected int value\n"); + break; + } } + + res_str += stringf("%d", int_val); } - } - else - { - std::string str = data.decode_string(); - for (size_t i = 0; i < str.size(); i++) + else { - if (str[i] == '\n') - dataStr += "\\n"; - else if (str[i] == '\t') - dataStr += "\\t"; - else if (str[i] < 32) - dataStr += stringf("\\%03o", str[i]); - else if (str[i] == '"') - dataStr += "\\\""; - else if (str[i] == '\\') - dataStr += "\\\\"; - else - dataStr += str[i]; + // If value is larger than 32 bits, then emit a binary representation of + // the number. We have to do this as firrtl number literals don't support + // specifying their width, therefore a binary literal is the only way to + // guarantee the parameter widths match that provided on the RHS of a + // verilog parameter assignment. There is a caveat to this approach + // though: + // + // Note that parameter may be defined as having a fixed width as follows: + // + // parameter signed [26:0] test_signed; + // parameter [26:0] test_unsigned; + // parameter signed [40:0] test_signed_large; + // + // However, if you assign a value on the RHS without specifying the + // precision, then yosys considers the value you used as an int and + // assigns it a width of 32 bits regardless of the type of the parameter. + // + // defparam .test_signed = 49; (width = 32, though should be 27 based on definition) + // defparam .test_unsigned = 40'd35; (width = 40, though should be 27 based on definition) + // defparam .test_signed_large = 40'd12; (width = 40) + // + // We therefore may lose the precision of the original verilog literal if + // it was written without it's bitwidth specifier. + + // Emit binary prefix for string. + res_str += "\"b"; + + // Emit bits. + for (int i = width - 1; i >= 0; i--) + { + log_assert(i < width); + switch (data.bits[i]) + { + case State::S0: res_str += "0"; break; + case State::S1: res_str += "1"; break; + case State::Sx: res_str += "x"; break; + case State::Sz: res_str += "z"; break; + case State::Sa: res_str += "-"; break; + case State::Sm: res_str += "m"; break; + } + } + + res_str += "\""; } } - dataStr += "\""; - - return dataStr; + return res_str; } std::string extmodule_name(RTLIL::Cell *cell, RTLIL::Module *mod_instance) @@ -216,8 +288,11 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream // Emit extmodule generic parameters. for (const auto &p : cell->parameters) { - std::string param_name(p.first.c_str()); - const std::string param_value = dump_const(p.second); + const RTLIL::IdString p_id = p.first; + const RTLIL::Const p_value = p.second; + + std::string param_name(p_id.c_str()); + const std::string param_value = dump_const(p_value); // Remove backslashes from parameters as these come from the internal RTLIL // naming scheme, but should not exist in the emitted firrtl blackboxes. From 191406f930ea27c10f08fe1abcbe954fc537dcba Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 2 Nov 2020 06:33:03 +0000 Subject: [PATCH 0024/2410] check: reformat log/help text to match most other passes --- passes/cmds/check.cc | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index a8b5362b32c..54b9b340db1 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -35,30 +35,28 @@ struct CheckPass : public Pass { log("\n"); log("This pass identifies the following problems in the current design:\n"); log("\n"); - log(" - combinatorial loops\n"); - log("\n"); - log(" - two or more conflicting drivers for one wire\n"); - log("\n"); - log(" - used wires that do not have a driver\n"); + log(" - combinatorial loops\n"); + log(" - two or more conflicting drivers for one wire\n"); + log(" - used wires that do not have a driver\n"); log("\n"); log("Options:\n"); log("\n"); - log(" -noinit\n"); - log(" Also check for wires which have the 'init' attribute set.\n"); + log(" -noinit\n"); + log(" also check for wires which have the 'init' attribute set\n"); log("\n"); - log(" -initdrv\n"); - log(" Also check for wires that have the 'init' attribute set and are not\n"); - log(" driven by an FF cell type.\n"); + log(" -initdrv\n"); + log(" also check for wires that have the 'init' attribute set and are not\n"); + log(" driven by an FF cell type\n"); log("\n"); - log(" -mapped\n"); - log(" Also check for internal cells that have not been mapped to cells of the\n"); - log(" target architecture.\n"); + log(" -mapped\n"); + log(" also check for internal cells that have not been mapped to cells of the\n"); + log(" target architecture\n"); log("\n"); - log(" -allow-tbuf\n"); - log(" Modify the -mapped behavior to still allow $_TBUF_ cells.\n"); + log(" -allow-tbuf\n"); + log(" modify the -mapped behavior to still allow $_TBUF_ cells\n"); log("\n"); - log(" -assert\n"); - log(" Produce a runtime error if any problems are found in the current design.\n"); + log(" -assert\n"); + log(" produce a runtime error if any problems are found in the current design\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -103,7 +101,7 @@ struct CheckPass : public Pass { if (module->has_processes_warn()) continue; - log("checking module %s..\n", log_id(module)); + log("Checking module %s...\n", log_id(module)); SigMap sigmap(module); dict> wire_drivers; @@ -216,7 +214,7 @@ struct CheckPass : public Pass { } } - log("found and reported %d problems.\n", counter); + log("Found and reported %d problems.\n", counter); if (assert_mode && counter > 0) log_error("Found %d problems in 'check -assert'.\n", counter); From d6a93b8b903bb74b9eb10a16f8766958a83f8cf9 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 3 Nov 2020 15:36:27 +0000 Subject: [PATCH 0025/2410] check: add support for processes. --- passes/cmds/check.cc | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 54b9b340db1..36febb98ac6 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -98,9 +98,6 @@ struct CheckPass : public Pass { for (auto module : design->selected_whole_modules_warn()) { - if (module->has_processes_warn()) - continue; - log("Checking module %s...\n", log_id(module)); SigMap sigmap(module); @@ -109,6 +106,44 @@ struct CheckPass : public Pass { pool used_wires; TopoSort topo; + for (auto &proc_it : module->processes) + { + std::vector all_cases = {&proc_it.second->root_case}; + for (size_t i = 0; i < all_cases.size(); i++) { + for (auto action : all_cases[i]->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) { + wire_drivers[bit].push_back( + stringf("action %s <= %s (case rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + } + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + for (auto switch_ : all_cases[i]->switches) { + for (auto case_ : switch_->cases) { + all_cases.push_back(case_); + for (auto compare : case_->compare) + for (auto bit : sigmap(compare)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto &sync : proc_it.second->syncs) { + for (auto bit : sigmap(sync->signal)) + if (bit.wire) used_wires.insert(bit); + for (auto action : sync->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) + wire_drivers[bit].push_back( + stringf("action %s <= %s (sync rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto cell : module->cells()) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { From 84ecb321b4f9f9e6284e4c26eee81759b93f266c Mon Sep 17 00:00:00 2001 From: dalance Date: Wed, 11 Nov 2020 12:03:37 +0900 Subject: [PATCH 0026/2410] Fix begin/end in generate --- tests/simple/const_branch_finish.v | 3 --- tests/simple/generate.v | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/simple/const_branch_finish.v b/tests/simple/const_branch_finish.v index 8166688e60c..f585be87a97 100644 --- a/tests/simple/const_branch_finish.v +++ b/tests/simple/const_branch_finish.v @@ -21,9 +21,6 @@ module top; end end generate - begin : unconditional_block - initial `CONSTANT_CHECK - end if (WIDTH == 32) begin : conditional_block initial `CONSTANT_CHECK end diff --git a/tests/simple/generate.v b/tests/simple/generate.v index 12327b36eb8..667f400967e 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -167,7 +167,7 @@ module gen_test7; reg [2:0] out2; wire [2:0] out3; generate - begin : cond + if (1) begin : cond reg [2:0] sub_out1; reg [2:0] sub_out2; wire [2:0] sub_out3; @@ -215,9 +215,9 @@ module gen_test8; wire [1:0] x = 2'b11; generate - begin : A + if (1) begin : A wire [1:0] x; - begin : B + if (1) begin : B wire [1:0] x = 2'b00; `ASSERT(x == 0) `ASSERT(A.x == 2) @@ -228,7 +228,7 @@ module gen_test8; `ASSERT(gen_test8.A.C.x == 1) `ASSERT(gen_test8.A.B.x == 0) end - begin : C + if (1) begin : C wire [1:0] x = 2'b01; `ASSERT(x == 1) `ASSERT(A.x == 2) From 296a23f489b4534e581d887a08d6a0326efc8dd6 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 19 Nov 2020 13:23:54 -0500 Subject: [PATCH 0027/2410] Makefile: Add disabled-by-default ENABLE_SCCACHE config option. --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97a6370d9ec..6e4586aa5ee 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,8 @@ ENABLE_GPROF := 0 ENABLE_DEBUG := 0 ENABLE_NDEBUG := 0 ENABLE_CCACHE := 0 +# sccache is not always a drop-in replacement for ccache in practice +ENABLE_SCCACHE := 0 LINK_CURSES := 0 LINK_TERMCAP := 0 LINK_ABC := 0 @@ -530,6 +532,10 @@ endif ifeq ($(ENABLE_CCACHE),1) CXX := ccache $(CXX) +else +ifeq ($(ENABLE_SCCACHE),1) +CXX := sccache $(CXX) +endif endif define add_share_file @@ -1019,4 +1025,3 @@ echo-abc-rev: .PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator coverage vcxsrc mxebin .PHONY: config-clean config-clang config-gcc config-gcc-static config-gcc-4.8 config-afl-gcc config-gprof config-sudo - From 949eb95593aec0753010289612d018c21ae46c5e Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sat, 21 Nov 2020 00:10:06 +0000 Subject: [PATCH 0028/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97a6370d9ec..01060dedf11 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3683 +YOSYS_VER := 0.9+3686 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1034422c58f8a10390eb3538c2dbe6d52931bf8a Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sun, 22 Nov 2020 12:56:29 -0800 Subject: [PATCH 0029/2410] Adds appendix on RTLIL text format --- manual/CHAPTER_Overview.tex | 4 + manual/CHAPTER_TextRtlil.tex | 252 +++++++++++++++++++++++++++++++++++ manual/manual.tex | 4 + 3 files changed, 260 insertions(+) create mode 100644 manual/CHAPTER_TextRtlil.tex diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex index ed8b4cd4955..83db5aac7aa 100644 --- a/manual/CHAPTER_Overview.tex +++ b/manual/CHAPTER_Overview.tex @@ -230,6 +230,7 @@ \subsection{RTLIL::Design and RTLIL::Module} is generated instead of a hash string.) \subsection{RTLIL::Cell and RTLIL::Wire} +\label{sec:rtlil_cell_wire} A module contains zero to many RTLIL::Cell and RTLIL::Wire objects. Objects of these types are used to model netlists. Usually the goal of all synthesis efforts is to convert @@ -275,6 +276,7 @@ \subsection{RTLIL::Cell and RTLIL::Wire} to each cell port. The RTLIL::SigSpec data type is described in the next section. \subsection{RTLIL::SigSpec} +\label{sec:rtlil_sigspec} A ``signal'' is everything that can be applied to a cell port. I.e. @@ -295,6 +297,7 @@ \subsection{RTLIL::SigSpec} the type name RTLIL::SigSig was defined for such a pair. \subsection{RTLIL::Process} +\label{sec:rtlil_process} When a high-level HDL frontend processes behavioural code it splits it up into data path logic (e.g.~the expression {\tt a + b} is replaced by the output of an @@ -444,6 +447,7 @@ \subsection{RTLIL::Process} for most synthesis tasks. \subsection{RTLIL::Memory} +\label{sec:rtlil_memory} For every array (memory) in the HDL code an RTLIL::Memory object is created. A memory object has the following properties: diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex new file mode 100644 index 00000000000..662e5d75146 --- /dev/null +++ b/manual/CHAPTER_TextRtlil.tex @@ -0,0 +1,252 @@ +\chapter{RTLIL Text Representation} +\label{chapter:textrtlil} + +% Stolen from stackexchange: calculate indent based on given keyword, +% with some nice hrules added in. +\newlength{\myl} + +\newenvironment{indentgrammar}[1] + {\vspace{0.5cm}\hrule + \setlength{\myl}{\widthof{#1}+2em} + \grammarindent\the\myl + \begin{grammar}} + {\end{grammar} + \hrule} + +This appendix documents the text representation of RTLIL in extended Backus-Naur form (EBNF). + +The grammar is not meant to represent semantic limitations. For example, processes must contain exactly one switch statement, but the grammar allows zero or more than one. That is, the grammar is "permissive", and later stages of processing perform more rigorous checks. + +The grammar is also not meant to represent the exact grammar used in the RTLIL frontend, since that grammar is specific to processing by lex and yacc, and is somewhat less understandable than simple EBNF notation. + +\section{Lexical elements} + +\subsection{Identifiers} + +There are three types of identifiers in RTLIL: + +\begin{itemize} + \item Publically visible identifiers + \item Auto-generated identifiers + \item Dotted numeric identifiers +\end{itemize} + +\begin{indentgrammar}{} + ::= | | + + ::= "\textbackslash" $+$ + + ::= "\textdollar" $+$ + + ::= "." $+$ +\end{indentgrammar} + +\subsection{Values} + +A \textit{value} consists of a width in bits and a bit representation, most significant bit first. Bits may be any of: +\begin{itemize} + \item \texttt{0}: A logic zero value + \item \texttt{1}: A logic one value + \item \texttt{x}: An unknown logic value + \item \texttt{z}: A high-impedance value + \item \texttt{m}: ? + \item \texttt{-}: A don't care value +\end{itemize} + +An \textit{integer} is simply a signed integer value in decimal format. + +\begin{indentgrammar}{} + ::= $+$ \texttt{\textbf{'}} $*$ + + ::= "0" | "1" | "x" | "z" | "m" | "-" + + ::= "-"$?$ $+$ +\end{indentgrammar} + +\subsection{Strings} + +A string is a series of characters delimited by double-quote characters. Within a string, certain escapes can be used: + +\begin{itemize} + \item \texttt{\textbackslash n}: A newline + \item \texttt{\textbackslash t}: A tab + \item \texttt{\textbackslash \textit{ooo}}: A character specified as a one, two, or three digit octal value +\end{itemize} + +All other characters may be escaped by a backslash, and become the following character. Thus: + +\begin{itemize} + \item \texttt{\textbackslash \textbackslash}: A backslash + \item \texttt{\textbackslash \"}: A double-quote + \item \texttt{\textbackslash r}: An 'r' character +\end{itemize} + +\subsection{Comments} + +A comment starts with a \texttt{\textbf{\#}} character and proceeds to the end of the line. All comments are ignored. + +\section{File} + +A file consists of zero or more designs. A design may be a module, an attribute statement, or an autoindex statement. + +Note that in general, statements are terminated by an end of line. + +\begin{indentgrammar}{} + ::= $*$ + + ::= | | +\end{indentgrammar} + +\subsection{Modules} + +A module consists of zero or more module statements. + +\begin{indentgrammar}{} + ::= "module" $*$ + + ::= + + \alt + \alt + \alt + \alt + \alt + \alt +\end{indentgrammar} + +\subsection{Signal specifications} + +A signal is anything that can be applied to a cell port, i.e. a constant value, all bits or a selection of bits from a wire, or concatenations of those. + +See Sec.~\ref{sec:rtlil_sigspec} for an overview of signal specifications. + +\begin{indentgrammar}{} + ::= + + \alt + \alt "[" (":" )$?$ "]" + \alt "\{" $*$ "\}" +\end{indentgrammar} + +\subsection{Connection statements} + +Declares a connection between the given signals. + +\begin{indentgrammar}{} + ::= "connect" +\end{indentgrammar} + +\subsection{Attribute statements} + +Declares an attribute with the given identifier and value for the following non-attribute statement. + +\begin{indentgrammar}{} + ::= "attribute" + + ::= | | +\end{indentgrammar} + +\subsection{Autoindex statements} + +The function of this statement is currently undocumented. + +\begin{indentgrammar}{} + ::= "autoidx" +\end{indentgrammar} + +\subsection{Parameter statements} + +Declares a parameter with the given identifier for the enclosing module, optionally with the given default value. + +\begin{indentgrammar}{} + ::= "parameter" $?$ +\end{indentgrammar} + +\subsection{Wire statements} + +Declares a wire with the given identifier in the enclosing module, with options. + +See Sec.~\ref{sec:rtlil_cell_wire} for an overview of wires. + +\begin{indentgrammar}{} + ::= "wire" $*$ + + ::= + + ::= +"width" + \alt "offset" + \alt "input" + \alt "output" + \alt "inout" + \alt "upto" + \alt "signed" +\end{indentgrammar} + +\subsection{Memory statements} + +Declares a memory with the given identifier in the enclosing module, with options. + +See Sec.~\ref{sec:rtlil_memory} for an overview of memory cells, and Sec.~\ref{sec:memcells} for details about memory cell types. + +\begin{indentgrammar}{} + ::= "memory" $*$ + + ::= +"width" + \alt "size" + \alt "offset" +\end{indentgrammar} + +\subsection{Cell statements} + +Declares a cell with the given identifier in the enclosing module. + +See Chap.~\ref{chapter:celllib} for a detailed list of cell types. + +\begin{indentgrammar}{} + ::= "cell" "end" + + ::= + + ::= + + ::= +"parameter" ("signed" | "real")$?$ + \alt "connect" +\end{indentgrammar} + +\subsection{Process statements} + +Declares a process with the given identifier in the enclosing module. + +See Sec.~\ref{sec:rtlil_process} for an overview of processes. + +\begin{indentgrammar}{} + ::= "process" $*$ $*$ "end" + + ::= | | + + ::= "switch" $*$ $*$ "end" + + ::= "case" $?$ $*$ + + ::= ("," )$*$ + + ::= +"sync" $*$ + \alt "sync" "always" $*$ + \alt "sync" "global" $*$ + \alt "sync" "init" $*$ + + ::= "low" | "high" | "posedge" | "negedge" | "edge" + + ::= "assign" + + ::= "update" + + ::= + + ::= +\end{indentgrammar} + diff --git a/manual/manual.tex b/manual/manual.tex index 75f087ecae4..dac8b1000fc 100644 --- a/manual/manual.tex +++ b/manual/manual.tex @@ -75,6 +75,9 @@ \usetikzlibrary{through} \usetikzlibrary{shapes.geometric} +\usepackage{calc} +\usepackage[nounderscore]{syntax} + \lstset{basicstyle=\ttfamily} \def\B#1{{\tt\textbackslash{}#1}} @@ -214,6 +217,7 @@ \chapter{Command Reference Manual} \label{commandref} \input{command-reference-manual} +\include{CHAPTER_TextRtlil} \include{CHAPTER_Appnotes} % \include{CHAPTER_StateOfTheArt} From 5159dda826e7acfc66920a72326e5ce0f3b61f71 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sun, 22 Nov 2020 18:48:21 -0800 Subject: [PATCH 0030/2410] Update to Values section --- manual/CHAPTER_TextRtlil.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 662e5d75146..6b0572c64b4 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -48,8 +48,8 @@ \subsection{Values} \item \texttt{0}: A logic zero value \item \texttt{1}: A logic one value \item \texttt{x}: An unknown logic value - \item \texttt{z}: A high-impedance value - \item \texttt{m}: ? + \item \texttt{z}: A high-impedance value (or don't care in case patterns) + \item \texttt{m}: A marked bit (internal use only) \item \texttt{-}: A don't care value \end{itemize} From c5a2ae01cd6b7d5f59b627eae7779359737bb847 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sun, 22 Nov 2020 18:50:41 -0800 Subject: [PATCH 0031/2410] Update to Values #2 --- manual/CHAPTER_TextRtlil.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 6b0572c64b4..30ddaafd3c6 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -47,7 +47,7 @@ \subsection{Values} \begin{itemize} \item \texttt{0}: A logic zero value \item \texttt{1}: A logic one value - \item \texttt{x}: An unknown logic value + \item \texttt{x}: An unknown logic value (or don't care in case patterns) \item \texttt{z}: A high-impedance value (or don't care in case patterns) \item \texttt{m}: A marked bit (internal use only) \item \texttt{-}: A don't care value From d3d28e287f1935a25e288ecdbb50060bc4d0de84 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sun, 22 Nov 2020 21:08:58 -0800 Subject: [PATCH 0032/2410] Adds missing "end" and eol to module. --- manual/CHAPTER_TextRtlil.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 30ddaafd3c6..e8423539833 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -102,7 +102,7 @@ \subsection{Modules} A module consists of zero or more module statements. \begin{indentgrammar}{} - ::= "module" $*$ + ::= "module" $*$ "end" ::= From 930a6ae7db905a31d003db0d034177dc0067c84a Mon Sep 17 00:00:00 2001 From: Sahand Kashani Date: Mon, 23 Nov 2020 10:43:59 +0100 Subject: [PATCH 0033/2410] Formatting fixes --- backends/firrtl/firrtl.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 5c2807ef49e..44c3397da37 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -178,11 +178,8 @@ std::string dump_const(const RTLIL::Const &data) else { // If value is larger than 32 bits, then emit a binary representation of - // the number. We have to do this as firrtl number literals don't support - // specifying their width, therefore a binary literal is the only way to - // guarantee the parameter widths match that provided on the RHS of a - // verilog parameter assignment. There is a caveat to this approach - // though: + // the number as integers are not large enough to contain the result. + // There is a caveat to this approach though: // // Note that parameter may be defined as having a fixed width as follows: // @@ -194,12 +191,12 @@ std::string dump_const(const RTLIL::Const &data) // precision, then yosys considers the value you used as an int and // assigns it a width of 32 bits regardless of the type of the parameter. // - // defparam .test_signed = 49; (width = 32, though should be 27 based on definition) - // defparam .test_unsigned = 40'd35; (width = 40, though should be 27 based on definition) - // defparam .test_signed_large = 40'd12; (width = 40) + // defparam .test_signed = 49; (width = 32, though should be 27 based on definition) + // defparam .test_unsigned = 40'd35; (width = 40, though should be 27 based on definition) + // defparam .test_signed_large = 40'd12; (width = 40) // // We therefore may lose the precision of the original verilog literal if - // it was written without it's bitwidth specifier. + // it was written without its bitwidth specifier. // Emit binary prefix for string. res_str += "\"b"; @@ -329,7 +326,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream * and emit parameterized extmodules with a unique name for each of them. The * name that's given to the extmodule is * - * _ + * _ * * Beware that it is therefore necessary for users to replace "parameterized" * instances in the RTLIL sense with these custom extmodules for the firrtl to From cc0d7244b844d0565beadbd4c87f1900a079e0bd Mon Sep 17 00:00:00 2001 From: nitz Date: Mon, 23 Nov 2020 21:48:44 -0500 Subject: [PATCH 0034/2410] tcl -h message only if YOSYS_ENABLE_TCL defined. --- kernel/driver.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index 57ed7b8b452..b55f0283709 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -267,9 +267,11 @@ int main(int argc, char **argv) printf("\n"); printf(" -s scriptfile\n"); printf(" execute the commands in the script file\n"); +#ifdef YOSYS_ENABLE_TCL printf("\n"); printf(" -c tcl_scriptfile\n"); printf(" execute the commands in the tcl script file (see 'help tcl' for details)\n"); +#endif printf("\n"); printf(" -p command\n"); printf(" execute the commands\n"); From cdc802e4b77e6fecd250850c99469b81c2c7f104 Mon Sep 17 00:00:00 2001 From: Chris Dailey Date: Tue, 24 Nov 2020 15:17:16 -0500 Subject: [PATCH 0035/2410] Add rewrite_filename for sim -vcd argument. --- passes/sat/sim.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 75f922dba2e..3ba66bd33cc 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -810,7 +810,9 @@ struct SimPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-vcd" && argidx+1 < args.size()) { - worker.vcdfile.open(args[++argidx].c_str()); + std::string vcd_filename = args[++argidx]; + rewrite_filename(vcd_filename); + worker.vcdfile.open(vcd_filename.c_str()); continue; } if (args[argidx] == "-n" && argidx+1 < args.size()) { From 278b54227339099faf93301cfd4a6b566651441b Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Tue, 24 Nov 2020 15:27:30 -0800 Subject: [PATCH 0036/2410] Cleans up some descriptions and syntax Now all rules ending in "-stmt" end in eol. --- manual/CHAPTER_TextRtlil.tex | 68 +++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index e8423539833..720fe8fa123 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -87,33 +87,35 @@ \subsection{Comments} \section{File} -A file consists of zero or more designs. A design may be a module, an attribute statement, or an autoindex statement. +A file consists of zero or more modules, attribute statements, and auto-index statements. All statements terminate in an end-of-line. Because of this, statements cannot contain end-of-lines. -Note that in general, statements are terminated by an end of line. +Attributes at the file level are applied to the following module. \begin{indentgrammar}{} - ::= $*$ - - ::= | | + ::= ( | | )$*$ \end{indentgrammar} \subsection{Modules} -A module consists of zero or more module statements. +Declares a module consisting of zero or more attributes, wires, memories, cells, processes, and connections. + +\begin{indentgrammar}{} + ::= -\begin{indentgrammar}{} - ::= "module" $*$ "end" + ::= "module" - ::= - + ::= +( \alt \alt \alt - \alt - \alt - \alt + \alt + \alt + \alt )$*$ \end{indentgrammar} + ::= "end" + \subsection{Signal specifications} A signal is anything that can be applied to a cell port, i.e. a constant value, all bits or a selection of bits from a wire, or concatenations of those. @@ -138,7 +140,7 @@ \subsection{Connection statements} \subsection{Attribute statements} -Declares an attribute with the given identifier and value for the following non-attribute statement. +Declares an attribute with the given identifier and value. Attributes at the file level apply to the following module. Attributes within a module apply to the following non-attribute statement. \begin{indentgrammar}{} ::= "attribute" @@ -198,14 +200,16 @@ \subsection{Memory statements} \alt "offset" \end{indentgrammar} -\subsection{Cell statements} +\subsection{Cells} Declares a cell with the given identifier in the enclosing module. See Chap.~\ref{chapter:celllib} for a detailed list of cell types. \begin{indentgrammar}{} - ::= "cell" "end" + ::= + + ::= "cell" ::= @@ -214,6 +218,8 @@ \subsection{Cell statements} ::= "parameter" ("signed" | "real")$?$ \alt "connect" + + ::= "end" \end{indentgrammar} \subsection{Process statements} @@ -222,22 +228,34 @@ \subsection{Process statements} See Sec.~\ref{sec:rtlil_process} for an overview of processes. -\begin{indentgrammar}{} - ::= "process" $*$ $*$ "end" +\begin{indentgrammar}{} + ::= $*$ + + ::= "process" - ::= | | + ::= "end" - ::= "switch" $*$ $*$ "end" + ::= ( | | )$*$ - ::= "case" $?$ $*$ + ::= $*$ $*$ + + := "switch" + + ::= "end" + + ::= + + ::= "case" $?$ ::= ("," )$*$ + ::= $*$ + ::= -"sync" $*$ - \alt "sync" "always" $*$ - \alt "sync" "global" $*$ - \alt "sync" "init" $*$ +"sync" + \alt "sync" "always" + \alt "sync" "global" + \alt "sync" "init" ::= "low" | "high" | "posedge" | "negedge" | "edge" From 88c47a380bdd62b633b11d1e763e7bcfd54ef423 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 25 Nov 2020 00:10:05 +0000 Subject: [PATCH 0037/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 01060dedf11..0cd924f49e1 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3686 +YOSYS_VER := 0.9+3696 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 9431033921286c20af594e1dfba96be96a88eb9c Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 24 Nov 2020 21:32:27 -0500 Subject: [PATCH 0038/2410] Makefile: Update ABCREV to bring in sccache fixes. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6e4586aa5ee..fe1afd19363 100644 --- a/Makefile +++ b/Makefile @@ -138,7 +138,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 341db25 +ABCREV = 4f5f73d ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 From be938b309451c152aab6edb4e4745aa682a2bf39 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Tue, 24 Nov 2020 21:59:53 -0800 Subject: [PATCH 0039/2410] Refactors for attributes. --- manual/CHAPTER_TextRtlil.tex | 100 +++++++++++++++++------------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 720fe8fa123..f3962c4a4c7 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -19,6 +19,8 @@ \chapter{RTLIL Text Representation} The grammar is also not meant to represent the exact grammar used in the RTLIL frontend, since that grammar is specific to processing by lex and yacc, and is somewhat less understandable than simple EBNF notation. +Finally, note that all statements (rules ending in \texttt{-stmt}) terminate in an end-of-line. Because of this, statements cannot contain end-of-lines. + \section{Lexical elements} \subsection{Identifiers} @@ -87,34 +89,53 @@ \subsection{Comments} \section{File} -A file consists of zero or more modules, attribute statements, and auto-index statements. All statements terminate in an end-of-line. Because of this, statements cannot contain end-of-lines. - -Attributes at the file level are applied to the following module. +A file consists of an optional autoindex statement followed by zero or more modules. \begin{indentgrammar}{} - ::= ( | | )$*$ + ::= $?$ * +\end{indentgrammar} + +\subsection{Autoindex statements} + +The autoindex statement sets the global autoindex value used by Yosys when it needs to generate a unique name, e.g. \texttt{\textdollar{}flatten\textdollar{}N}. The N part is filled with the value of the global autoindex value, which is subsequently incremented. This global has to be dumped into RTLIL, otherwise e.g. dumping and running a pass would have different properties than just running a pass on a warm design. + +\begin{indentgrammar}{} + ::= "autoidx" \end{indentgrammar} \subsection{Modules} -Declares a module consisting of zero or more attributes, wires, memories, cells, processes, and connections. +Declares a module, with zero or more attributes, consisting of zero or more wires, memories, cells, processes, and connections. \begin{indentgrammar}{} - ::= + ::= $*$ ::= "module" ::= ( - \alt - \alt - \alt + \alt + \alt \alt \alt - \alt )$*$ -\end{indentgrammar} + \alt )$*$ + + ::= "parameter" $?$ + + ::= | | ::= "end" +\end{indentgrammar} + +\subsection{Attribute statements} + +Declares an attribute with the given identifier and value. + +\textbf{Warning:} There is currently a bug where integer constants are silently truncated to 32 bits and treated as unsigned. + +\begin{indentgrammar}{} + ::= "attribute" +\end{indentgrammar} \subsection{Signal specifications} @@ -130,47 +151,25 @@ \subsection{Signal specifications} \alt "\{" $*$ "\}" \end{indentgrammar} -\subsection{Connection statements} - -Declares a connection between the given signals. - -\begin{indentgrammar}{} - ::= "connect" -\end{indentgrammar} - -\subsection{Attribute statements} - -Declares an attribute with the given identifier and value. Attributes at the file level apply to the following module. Attributes within a module apply to the following non-attribute statement. - -\begin{indentgrammar}{} - ::= "attribute" - - ::= | | -\end{indentgrammar} - -\subsection{Autoindex statements} - -The function of this statement is currently undocumented. - -\begin{indentgrammar}{} - ::= "autoidx" -\end{indentgrammar} +\subsection{Connections} -\subsection{Parameter statements} +Declares a connection, with zero or more attributes, between the given signals. -Declares a parameter with the given identifier for the enclosing module, optionally with the given default value. +\begin{indentgrammar}{} + ::= $*$ -\begin{indentgrammar}{} - ::= "parameter" $?$ + ::= "connect" \end{indentgrammar} -\subsection{Wire statements} +\subsection{Wires} -Declares a wire with the given identifier in the enclosing module, with options. +Declares a wire, with zero or more attributes, with the given identifier and options in the enclosing module. See Sec.~\ref{sec:rtlil_cell_wire} for an overview of wires. \begin{indentgrammar}{} + ::= $*$ + ::= "wire" $*$ ::= @@ -185,13 +184,15 @@ \subsection{Wire statements} \alt "signed" \end{indentgrammar} -\subsection{Memory statements} +\subsection{Memories} -Declares a memory with the given identifier in the enclosing module, with options. +Declares a memory, with zero or more attributes, with the given identifier and options in the enclosing module. See Sec.~\ref{sec:rtlil_memory} for an overview of memory cells, and Sec.~\ref{sec:memcells} for details about memory cell types. \begin{indentgrammar}{} + ::= $*$ + ::= "memory" $*$ ::= @@ -202,12 +203,12 @@ \subsection{Memory statements} \subsection{Cells} -Declares a cell with the given identifier in the enclosing module. +Declares a cell, with zero or more attributes, with the given identifier and type in the enclosing module. See Chap.~\ref{chapter:celllib} for a detailed list of cell types. \begin{indentgrammar}{} - ::= + ::= $*$ $*$ ::= "cell" @@ -222,14 +223,14 @@ \subsection{Cells} ::= "end" \end{indentgrammar} -\subsection{Process statements} +\subsection{Processes} -Declares a process with the given identifier in the enclosing module. +Declares a process, with zero or more attributes, with the given identifier in the enclosing module. See Sec.~\ref{sec:rtlil_process} for an overview of processes. \begin{indentgrammar}{} - ::= $*$ + ::= $*$ $*$ ::= "process" @@ -267,4 +268,3 @@ \subsection{Process statements} ::= \end{indentgrammar} - From addc493e8d7f64267661af3bf7fbaf265e2b17ba Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 25 Nov 2020 17:43:28 +0100 Subject: [PATCH 0040/2410] generate only simple assignments in verilog backend --- backends/verilog/verilog_backend.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 9523f4a526c..f8b5b0e3e72 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1546,11 +1546,15 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, left); - f << stringf(" = "); - dump_sigspec(f, right); - f << stringf(";\n"); + int offset = 0; + for (auto &chunk : left.chunks()) { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, chunk); + f << stringf(" = "); + dump_sigspec(f, right.extract(offset, GetSize(chunk))); + f << stringf(";\n"); + offset += GetSize(chunk); + } } void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw); From 015b476e56b6bc05acdf9055284e633c1cce2491 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 25 Nov 2020 16:47:20 +0000 Subject: [PATCH 0041/2410] rtlil: remove dotted identifiers. No one knows where they came from and they never did anything useful. --- frontends/rtlil/rtlil_lexer.l | 1 - 1 file changed, 1 deletion(-) diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l index 295455f53e6..beef220f6f0 100644 --- a/frontends/rtlil/rtlil_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -86,7 +86,6 @@ USING_YOSYS_NAMESPACE "\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } "$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } -"."[0-9]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } [0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; } -?[0-9]+ { From 39af3e629f5ae1e6e2a70b64330460ea0096440d Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 08:59:25 -0800 Subject: [PATCH 0042/2410] Clarifies processes, corrects some attributes --- manual/CHAPTER_TextRtlil.tex | 75 ++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index f3962c4a4c7..ee77a987d7a 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -15,22 +15,21 @@ \chapter{RTLIL Text Representation} This appendix documents the text representation of RTLIL in extended Backus-Naur form (EBNF). -The grammar is not meant to represent semantic limitations. For example, processes must contain exactly one switch statement, but the grammar allows zero or more than one. That is, the grammar is "permissive", and later stages of processing perform more rigorous checks. +The grammar is not meant to represent semantic limitations. That is, the grammar is "permissive", and later stages of processing perform more rigorous checks. -The grammar is also not meant to represent the exact grammar used in the RTLIL frontend, since that grammar is specific to processing by lex and yacc, and is somewhat less understandable than simple EBNF notation. +The grammar is also not meant to represent the exact grammar used in the RTLIL frontend, since that grammar is specific to processing by lex and yacc, is even more permissive, and is somewhat less understandable than simple EBNF notation. -Finally, note that all statements (rules ending in \texttt{-stmt}) terminate in an end-of-line. Because of this, statements cannot contain end-of-lines. +Finally, note that all statements (rules ending in \texttt{-stmt}) terminate in an end-of-line. Because of this, a statement cannot be broken into multiple lines. \section{Lexical elements} \subsection{Identifiers} -There are three types of identifiers in RTLIL: +There are two types of identifiers in RTLIL: \begin{itemize} \item Publically visible identifiers \item Auto-generated identifiers - \item Dotted numeric identifiers \end{itemize} \begin{indentgrammar}{} @@ -39,8 +38,6 @@ \subsection{Identifiers} ::= "\textbackslash" $+$ ::= "\textdollar" $+$ - - ::= "." $+$ \end{indentgrammar} \subsection{Values} @@ -118,7 +115,7 @@ \subsection{Modules} \alt \alt \alt - \alt )$*$ + \alt )$*$ ::= "parameter" $?$ @@ -131,7 +128,7 @@ \subsection{Attribute statements} Declares an attribute with the given identifier and value. -\textbf{Warning:} There is currently a bug where integer constants are silently truncated to 32 bits and treated as unsigned. +\textbf{Warning:} Integer constants greater than 32 bits are silently truncated to 32 bits and treated as unsigned. \begin{indentgrammar}{} ::= "attribute" @@ -153,11 +150,9 @@ \subsection{Signal specifications} \subsection{Connections} -Declares a connection, with zero or more attributes, between the given signals. - -\begin{indentgrammar}{} - ::= $*$ +Declares a connection between the given signals. +\begin{indentgrammar}{} ::= "connect" \end{indentgrammar} @@ -203,9 +198,9 @@ \subsection{Memories} \subsection{Cells} -Declares a cell, with zero or more attributes, with the given identifier and type in the enclosing module. +Declares a cell, with zero or more attributes, with the given identifier and type in the enclosing module. -See Chap.~\ref{chapter:celllib} for a detailed list of cell types. +Cells perform functions on input signals. See Chap.~\ref{chapter:celllib} for a detailed list of cell types. \begin{indentgrammar}{} ::= $*$ $*$ @@ -225,46 +220,68 @@ \subsection{Cells} \subsection{Processes} -Declares a process, with zero or more attributes, with the given identifier in the enclosing module. +Declares a process, with zero or more attributes, with the given identifier in the enclosing module. The body of a process consists of zero or more assignments, exactly one switch, and zero or more syncs. See Sec.~\ref{sec:rtlil_process} for an overview of processes. \begin{indentgrammar}{} - ::= $*$ $*$ + ::= $*$ ::= "process" + ::= $*$ $*$ $*$ + + ::= "assign" + + ::= + + ::= + ::= "end" - ::= ( | | )$*$ +\end{indentgrammar} - ::= $*$ $*$ +\subsection{Switches} - := "switch" +Switches test a signal for equality against a list of cases. Each case specifies a comma-separated list of signals to check against. If there are no signals in the list, then the case is the default case. The body of a case consists of zero or more switches and assignments. Both switches and cases may have zero or more attributes. - ::= "end" +\begin{indentgrammar}{} + ::= $*$ - ::= + := $*$ "switch" + + ::= $*$ ::= "case" $?$ ::= ("," )$*$ + ::= ( | )$*$ + + ::= "end" +\end{indentgrammar} + +\subsection{Syncs} + +Syncs update signals with other signals when an event happens. Such an event may be: + +\begin{itemize} + \item An edge or level on a signal + \item Global clock ticks + \item Initialization + \item Always +\end{itemize} + +\begin{indentgrammar}{} ::= $*$ ::= "sync" - \alt "sync" "always" \alt "sync" "global" \alt "sync" "init" + \alt "sync" "always" ::= "low" | "high" | "posedge" | "negedge" | "edge" - ::= "assign" - ::= "update" - - ::= - - ::= \end{indentgrammar} From 7b093dca10707443d8517504fad7f5afa9eea6ca Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 25 Nov 2020 18:21:41 +0100 Subject: [PATCH 0043/2410] Add verilog backend option for simple_lhs --- backends/verilog/verilog_backend.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index f8b5b0e3e72..165ce1ea4b3 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -35,7 +35,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog; +bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs; int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter; std::map auto_name_map; std::set reg_wires; @@ -1546,14 +1546,22 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - int offset = 0; - for (auto &chunk : left.chunks()) { + if (simple_lhs) { + int offset = 0; + for (auto &chunk : left.chunks()) { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, chunk); + f << stringf(" = "); + dump_sigspec(f, right.extract(offset, GetSize(chunk))); + f << stringf(";\n"); + offset += GetSize(chunk); + } + } else { f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, chunk); + dump_sigspec(f, left); f << stringf(" = "); - dump_sigspec(f, right.extract(offset, GetSize(chunk))); + dump_sigspec(f, right); f << stringf(";\n"); - offset += GetSize(chunk); } } @@ -1865,6 +1873,9 @@ struct VerilogBackend : public Backend { log(" deactivates this feature and instead will write string constants\n"); log(" as binary numbers.\n"); log("\n"); + log(" -simple-lhs\n"); + log(" Connection assignments with simple left hand side without concatenations.\n"); + log("\n"); log(" -extmem\n"); log(" instead of initializing memories using assignments to individual\n"); log(" elements, use the '$readmemh' function to read initialization data\n"); @@ -1912,6 +1923,7 @@ struct VerilogBackend : public Backend { defparam = false; decimal = false; siminit = false; + simple_lhs = false; auto_prefix = ""; bool blackboxes = false; @@ -1984,6 +1996,10 @@ struct VerilogBackend : public Backend { selected = true; continue; } + if (arg == "-simple-lhs") { + simple_lhs = true; + continue; + } if (arg == "-v") { verbose = true; continue; From 09f6e9d6b6c45b164188c8cdcc75e9628e531bfa Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 09:53:39 -0800 Subject: [PATCH 0044/2410] Clarifies use of integers, and character set. --- manual/CHAPTER_TextRtlil.tex | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index ee77a987d7a..12b90a7f708 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -23,6 +23,10 @@ \chapter{RTLIL Text Representation} \section{Lexical elements} +\subsection{Characters} + +The characters accepted in an RTLIL file are those encodable in 8 bits. Unicode is not supported. For maximum safety, limit characters to the 7-bit ASCII range $[0,127]$. + \subsection{Identifiers} There are two types of identifiers in RTLIL: @@ -33,13 +37,15 @@ \subsection{Identifiers} \end{itemize} \begin{indentgrammar}{} - ::= | | + ::= | ::= "\textbackslash" $+$ ::= "\textdollar" $+$ \end{indentgrammar} +A \texttt{nonws} character is any character other than a space (ASCII 32), tab (ASCII 9), newline (ASCII 10), or carriage return (ASCII 13). + \subsection{Values} A \textit{value} consists of a width in bits and a bit representation, most significant bit first. Bits may be any of: @@ -52,11 +58,13 @@ \subsection{Values} \item \texttt{-}: A don't care value \end{itemize} -An \textit{integer} is simply a signed integer value in decimal format. +An \textit{integer} is simply a signed integer value in decimal format. \textbf{Warning:} Integer constants are limited to 32 bits. That is, they may only be in the range $[-2147483648, 2147483648)$. Integers outside this range will result in an error. \begin{indentgrammar}{} ::= $+$ \texttt{\textbf{'}} $*$ + ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + ::= "0" | "1" | "x" | "z" | "m" | "-" ::= "-"$?$ $+$ @@ -128,8 +136,6 @@ \subsection{Attribute statements} Declares an attribute with the given identifier and value. -\textbf{Warning:} Integer constants greater than 32 bits are silently truncated to 32 bits and treated as unsigned. - \begin{indentgrammar}{} ::= "attribute" \end{indentgrammar} @@ -138,6 +144,8 @@ \subsection{Signal specifications} A signal is anything that can be applied to a cell port, i.e. a constant value, all bits or a selection of bits from a wire, or concatenations of those. +\textbf{Warning:} When an integer constant is a sigspec, it is always 32 bits wide, 2's complement. For example, a constant of $-1$ is the same as \texttt{32'11111111111111111111111111111111}, while a constant of $1$ is the same as \texttt{32'1}. + See Sec.~\ref{sec:rtlil_sigspec} for an overview of signal specifications. \begin{indentgrammar}{} From 5615c4190758c2df6ab55f8332a478296b6fd0af Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 09:58:36 -0800 Subject: [PATCH 0045/2410] Cleans up doublequotes --- manual/CHAPTER_TextRtlil.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 12b90a7f708..6bcb325fc6b 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -15,7 +15,7 @@ \chapter{RTLIL Text Representation} This appendix documents the text representation of RTLIL in extended Backus-Naur form (EBNF). -The grammar is not meant to represent semantic limitations. That is, the grammar is "permissive", and later stages of processing perform more rigorous checks. +The grammar is not meant to represent semantic limitations. That is, the grammar is ``permissive'', and later stages of processing perform more rigorous checks. The grammar is also not meant to represent the exact grammar used in the RTLIL frontend, since that grammar is specific to processing by lex and yacc, is even more permissive, and is somewhat less understandable than simple EBNF notation. @@ -84,7 +84,7 @@ \subsection{Strings} \begin{itemize} \item \texttt{\textbackslash \textbackslash}: A backslash - \item \texttt{\textbackslash \"}: A double-quote + \item \texttt{\textbackslash ''}: A double-quote \item \texttt{\textbackslash r}: An 'r' character \end{itemize} From 1faf0e6dcc734355ff8eb45d6ac63a6e8ae08f7b Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 10:06:22 -0800 Subject: [PATCH 0046/2410] Clarifies whitespace and eol. --- manual/CHAPTER_TextRtlil.tex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 6bcb325fc6b..1454bc26e58 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -27,6 +27,12 @@ \subsection{Characters} The characters accepted in an RTLIL file are those encodable in 8 bits. Unicode is not supported. For maximum safety, limit characters to the 7-bit ASCII range $[0,127]$. +Between lexer tokens outside of strings, spaces (ASCII 32) and tabs (ASCII 9) are ignored. + +A \texttt{nonws} character is any character other than a space (ASCII 32), tab (ASCII 9), newline (ASCII 10), or carriage return (ASCII 13). + +An \texttt{eol} is any number of consecutive newlines (ASCII 10) and carriage returns (ASCII 13). + \subsection{Identifiers} There are two types of identifiers in RTLIL: @@ -44,8 +50,6 @@ \subsection{Identifiers} ::= "\textdollar" $+$ \end{indentgrammar} -A \texttt{nonws} character is any character other than a space (ASCII 32), tab (ASCII 9), newline (ASCII 10), or carriage return (ASCII 13). - \subsection{Values} A \textit{value} consists of a width in bits and a bit representation, most significant bit first. Bits may be any of: From 5d1bb79895545772703f305180e73053aec747c2 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 11:57:17 -0800 Subject: [PATCH 0047/2410] Clarifies how character encodings work. --- manual/CHAPTER_TextRtlil.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 1454bc26e58..7e7dc19ca02 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -25,13 +25,13 @@ \section{Lexical elements} \subsection{Characters} -The characters accepted in an RTLIL file are those encodable in 8 bits. Unicode is not supported. For maximum safety, limit characters to the 7-bit ASCII range $[0,127]$. +The characters accepted in an RTLIL file are those encodable in 8 bits. UTF-8 is safe to use. Byte order marks at the beginning of the file will cause an error. -Between lexer tokens outside of strings, spaces (ASCII 32) and tabs (ASCII 9) are ignored. +ASCII spaces (32) and tabs (9) separate lexer tokens. -A \texttt{nonws} character is any character other than a space (ASCII 32), tab (ASCII 9), newline (ASCII 10), or carriage return (ASCII 13). +A \texttt{nonws} character, used in identifiers, is any character whose encoding consists solely of bytes above ASCII space (32). -An \texttt{eol} is any number of consecutive newlines (ASCII 10) and carriage returns (ASCII 13). +An \texttt{eol} is one or more consecutive ASCII newlines (10) and carriage returns (13). \subsection{Identifiers} @@ -76,7 +76,7 @@ \subsection{Values} \subsection{Strings} -A string is a series of characters delimited by double-quote characters. Within a string, certain escapes can be used: +A string is a series of characters delimited by double-quote characters. Within a string, any character except ASCII NUL (0) may be used. In addition, certain escapes can be used: \begin{itemize} \item \texttt{\textbackslash n}: A newline From 2bb3fc654a812dd2d82c6b3250a46dcede035de8 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Wed, 25 Nov 2020 12:02:35 -0800 Subject: [PATCH 0048/2410] Further juggles the wording of "character". --- manual/CHAPTER_TextRtlil.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 7e7dc19ca02..243b56a87a4 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -25,7 +25,7 @@ \section{Lexical elements} \subsection{Characters} -The characters accepted in an RTLIL file are those encodable in 8 bits. UTF-8 is safe to use. Byte order marks at the beginning of the file will cause an error. +An RTLIL file is a stream of bytes. Strictly speaking, a ``character'' in an RTLIL file is a single byte. The lexer treats multi-byte encoded characters as consecutive single-byte characters. While other encodings \textit{may} work, UTF-8 is known to be safe to use. Byte order marks at the beginning of the file will cause an error. ASCII spaces (32) and tabs (9) separate lexer tokens. From 2116c585810cddb73777b46ea9aad0d6d511d82b Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 26 Nov 2020 00:10:09 +0000 Subject: [PATCH 0049/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 43c3a7af4d9..d352358a0e0 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3696 +YOSYS_VER := 0.9+3710 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 150b729b6f1c06b94a5f1189289c8e094cda2f6e Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Wed, 25 Nov 2020 08:46:26 -0500 Subject: [PATCH 0050/2410] Add #include needed to build with gcc-11 Suggested by Jeff Law --- passes/sat/freduce.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 762edfdfbf0..f87b85da913 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -27,6 +27,7 @@ #include #include #include +#include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN From 6a328e7032024e8abd3dda561733cac3a033ae60 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Wed, 25 Nov 2020 12:29:59 -0500 Subject: [PATCH 0051/2410] fixup over commit 829b5cca to re-enable ABCEXTERNAL support --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index d352358a0e0..02592df98ff 100644 --- a/Makefile +++ b/Makefile @@ -608,6 +608,11 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.cc)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o +ifeq ($(ENABLE_ABC),1) +ifneq ($(ABCEXTERNAL),) +kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' +endif +endif OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/mem.o kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' From 2e23dfd96bee8df01912ffae71b95aaf35567aa7 Mon Sep 17 00:00:00 2001 From: Julius Roob Date: Thu, 26 Nov 2020 13:28:28 +0100 Subject: [PATCH 0052/2410] Return correct modname when found in cache. --- frontends/ast/ast.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index c8183580bca..1c0a8b34df4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1511,6 +1511,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict Date: Mon, 30 Nov 2020 11:43:12 +0100 Subject: [PATCH 0053/2410] add -noalu and -json option for apicula --- techlibs/gowin/synth_gowin.cc | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 4d1e968ae6e..5bf0894da12 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -44,6 +44,11 @@ struct SynthGowinPass : public ScriptPass log(" write the design to the specified Verilog netlist file. writing of an\n"); log(" output file is omitted if this parameter is not specified.\n"); log("\n"); + log(" -json \n"); + log(" write the design to the specified JSON netlist file. writing of an\n"); + log(" output file is omitted if this parameter is not specified.\n"); + log(" This disables features not yet supported by nexpnr-gowin.\n"); + log("\n"); log(" -run :\n"); log(" only run the commands between the labels (see below). an empty\n"); log(" from label is synonymous to 'begin', and empty to label is\n"); @@ -70,6 +75,9 @@ struct SynthGowinPass : public ScriptPass log(" -noiopads\n"); log(" do not emit IOB at top level ports\n"); log("\n"); + log(" -noalu\n"); + log(" do not use ALU cells\n"); + log("\n"); log(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); @@ -79,13 +87,14 @@ struct SynthGowinPass : public ScriptPass log("\n"); } - string top_opt, vout_file; - bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads; + string top_opt, vout_file, json_file; + bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu; void clear_flags() override { top_opt = "-auto-top"; vout_file = ""; + json_file = ""; retime = false; flatten = true; nobram = false; @@ -94,6 +103,7 @@ struct SynthGowinPass : public ScriptPass nowidelut = false; abc9 = false; noiopads = false; + noalu = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -112,6 +122,14 @@ struct SynthGowinPass : public ScriptPass vout_file = args[++argidx]; continue; } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + nobram = true; + nolutram = true; + nowidelut = true; + noalu = true; + continue; + } if (args[argidx] == "-run" && argidx+1 < args.size()) { size_t pos = args[argidx+1].find(':'); if (pos == std::string::npos) @@ -144,6 +162,10 @@ struct SynthGowinPass : public ScriptPass nowidelut = true; continue; } + if (args[argidx] == "-noalu") { + noalu = true; + continue; + } if (args[argidx] == "-abc9") { abc9 = true; continue; @@ -210,7 +232,11 @@ struct SynthGowinPass : public ScriptPass if (check_label("map_gates")) { - run("techmap -map +/techmap.v -map +/gowin/arith_map.v"); + if (noalu) { + run("techmap -map +/techmap.v"); + } else { + run("techmap -map +/techmap.v -map +/gowin/arith_map.v"); + } run("opt -fast"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); @@ -270,6 +296,9 @@ struct SynthGowinPass : public ScriptPass if (!vout_file.empty() || help_mode) run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s", help_mode ? "" : vout_file.c_str())); + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", + help_mode ? "" : json_file.c_str())); } } } SynthGowinPass; From c1f6ce8b33b1c06a4e38b621e27876d5715eb26d Mon Sep 17 00:00:00 2001 From: georgerennie Date: Tue, 1 Dec 2020 01:37:19 +0000 Subject: [PATCH 0054/2410] Fix SYNTHESIS always being defined in Verilog frontend --- frontends/verilog/preproc.cc | 1 - frontends/verilog/verilog_frontend.cc | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index ea23139e23a..752f7a7a8c0 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -321,7 +321,6 @@ struct define_body_t define_map_t::define_map_t() { add("YOSYS", "1"); - add(formal_mode ? "FORMAL" : "SYNTHESIS", "1"); } // We must define this destructor here (rather than relying on the default), because we need to diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 2e9c9b2e2e9..5319a45ad16 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -446,6 +446,9 @@ struct VerilogFrontend : public Frontend { } break; } + + defines_map.add(formal_mode ? "FORMAL" : "SYNTHESIS", "1"); + extra_args(f, filename, args, argidx); log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str()); From d021f4b4003bb7a374038134c65edd3f67473a92 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 2 Dec 2020 00:10:06 +0000 Subject: [PATCH 0055/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d352358a0e0..c561b0c722e 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3710 +YOSYS_VER := 0.9+3715 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 5beab5bc17f9fa1f2340b491e073cfb973ad2e2b Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 2 Dec 2020 08:25:27 +0000 Subject: [PATCH 0056/2410] cxxrtl: provide a way to perform unobtrusive power-on reset. Although it is always possible to destroy and recreate the design to simulate a power-on reset, this has two drawbacks: * Black boxes are also destroyed and recreated, which causes them to reacquire their resources, which might be costly and/or erase important state. * Pointers into the design are invalidated and have to be acquired again, which is costly and might be very inconvenient if they are captured elsewhere (especially through the C API). --- backends/cxxrtl/cxxrtl.h | 29 +++++++++++++++++++--- backends/cxxrtl/cxxrtl_backend.cc | 40 +++++++++++++++++++++++++++++++ backends/cxxrtl/cxxrtl_capi.cc | 4 ++++ backends/cxxrtl/cxxrtl_capi.h | 8 +++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 41089a153d5..4528a7d8fbe 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -96,9 +96,11 @@ struct value : public expr_base> { explicit constexpr value(Init ...init) : data{init...} {} value(const value &) = default; - value(value &&) = default; value &operator=(const value &) = default; + value(value &&) = default; + value &operator=(value &&) = default; + // A (no-op) helper that forces the cast to value<>. CXXRTL_ALWAYS_INLINE const value &val() const { @@ -647,10 +649,16 @@ struct wire { template explicit constexpr wire(Init ...init) : curr{init...}, next{init...} {} + // Copying and copy-assigning values is natural. If, however, a value is replaced with a wire, + // e.g. because a module is built with a different optimization level, then existing code could + // unintentionally copy a wire instead, which would create a subtle but serious bug. To make sure + // this doesn't happen, prohibit copying and copy-assigning wires. wire(const wire &) = delete; - wire(wire &&) = default; wire &operator=(const wire &) = delete; + wire(wire &&) = default; + wire &operator=(wire &&) = default; + template CXXRTL_ALWAYS_INLINE IntegerT get() const { @@ -692,6 +700,9 @@ struct memory { memory(const memory &) = delete; memory &operator=(const memory &) = delete; + memory(memory &&) = default; + memory &operator=(memory &&) = default; + // The only way to get the compiler to put the initializer in .rodata and do not copy it on stack is to stuff it // into a plain array. You'd think an std::initializer_list would work here, but it doesn't, because you can't // construct an initializer_list in a constexpr (or something) and so if you try to do that the whole thing is @@ -815,7 +826,7 @@ struct metadata { typedef std::map metadata_map; -// Helper class to disambiguate values/wires and their aliases. +// Tag class to disambiguate values/wires and their aliases. struct debug_alias {}; // This structure is intended for consumption via foreign function interfaces, like Python's ctypes. @@ -965,13 +976,25 @@ struct debug_items { } }; +// Tag class to disambiguate module move constructor and module constructor that takes black boxes +// out of another instance of the module. +struct adopt {}; + struct module { module() {} virtual ~module() {} + // Modules with black boxes cannot be copied. Although not all designs include black boxes, + // delete the copy constructor and copy assignment operator to make sure that any downstream + // code that manipulates modules doesn't accidentally depend on their availability. module(const module &) = delete; module &operator=(const module &) = delete; + module(module &&) = default; + module &operator=(module &&) = default; + + virtual void reset() = 0; + virtual bool eval() = 0; virtual bool commit() = 0; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index a48ea5b23a8..aab415720ee 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1869,6 +1869,46 @@ struct CxxrtlWorker { } if (has_cells) f << "\n"; + f << indent << mangle(module) << "() {}\n"; + if (has_cells) { + f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) :\n"; + bool first = true; + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + if (first) { + first = false; + } else { + f << ",\n"; + } + RTLIL::Module *cell_module = module->design->module(cell->type); + if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) { + f << indent << " " << mangle(cell) << "(std::move(other." << mangle(cell) << "))"; + } else { + f << indent << " " << mangle(cell) << "(adopt {}, std::move(other." << mangle(cell) << "))"; + } + } + f << " {\n"; + inc_indent(); + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + RTLIL::Module *cell_module = module->design->module(cell->type); + if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) + f << indent << mangle(cell) << "->reset();\n"; + } + dec_indent(); + f << indent << "}\n"; + } else { + f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) {}\n"; + } + f << "\n"; + f << indent << "void reset() override {\n"; + inc_indent(); + f << indent << "*this = " << mangle(module) << "(adopt {}, std::move(*this));\n"; + dec_indent(); + f << indent << "}\n"; + f << "\n"; f << indent << "bool eval() override;\n"; f << indent << "bool commit() override;\n"; if (debug_info) diff --git a/backends/cxxrtl/cxxrtl_capi.cc b/backends/cxxrtl/cxxrtl_capi.cc index b77e4c49141..1c3c63e3e54 100644 --- a/backends/cxxrtl/cxxrtl_capi.cc +++ b/backends/cxxrtl/cxxrtl_capi.cc @@ -43,6 +43,10 @@ void cxxrtl_destroy(cxxrtl_handle handle) { delete handle; } +void cxxrtl_reset(cxxrtl_handle handle) { + handle->module->reset(); +} + int cxxrtl_eval(cxxrtl_handle handle) { return handle->module->eval(); } diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index 385d6dcf386..662bf2c20e0 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -55,6 +55,14 @@ cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design); // Release all resources used by a design and its handle. void cxxrtl_destroy(cxxrtl_handle handle); +// Reinitialize the design, replacing the internal state with the reset values while preserving +// black boxes. +// +// This operation is essentially equivalent to a power-on reset. Values, wires, and memories are +// returned to their reset state while preserving the state of black boxes and keeping all of +// the interior pointers obtained with e.g. `cxxrtl_get` valid. +void cxxrtl_reset(cxxrtl_handle handle); + // Evaluate the design, propagating changes on inputs to the `next` value of internal state and // output wires. // From 1c4a18f66fb0d589e1798090a7b584ab1988407a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 2 Dec 2020 15:18:04 +0100 Subject: [PATCH 0057/2410] Bump required Verific version --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 31c77d39c4d..cf3bf10704d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,7 +55,7 @@ USING_YOSYS_NAMESPACE # error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific." #endif -#if SYMBIOTIC_VERIFIC_API_VERSION < 20201001 +#if SYMBIOTIC_VERIFIC_API_VERSION < 20201101 # error "Please update your version of Symbiotic EDA flavored Verific." #endif From 264e924abb85424a70daf50662700e3aceada689 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 2 Dec 2020 17:08:39 +0000 Subject: [PATCH 0058/2410] nexus: More efficient CO mapping Signed-off-by: David Shah --- techlibs/nexus/arith_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index fd9d61be352..ce14a15eaa1 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -88,9 +88,9 @@ module _80_nexus_alu (A, B, CI, BI, X, Y, CO); .COUT(FCO[i+2]) ); - assign CO[i] = (AA[i] && BB[i]) || (((i == 0) ? CI : CO[i-1]) && (AA[i] || BB[i])); + assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); if (i+1 < Y_WIDTH) begin - assign CO[i+1] = (AA[i+1] && BB[i+1]) || (CO[i] && (AA[i+1] || BB[i+1])); + assign CO[i + 1] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); assign Y[i+1] = Y1[i]; end end endgenerate From aa0a15a42cf7513697b3d93457a69ecf2d8b9e05 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 2 Dec 2020 19:41:00 +0000 Subject: [PATCH 0059/2410] cxxrtl: use CXXRTL_ASSERT for RTL contract violations instead of assert. RTL contract violations and C++ contract violations are different: the former depend on the netlist and will never violate memory safety whereas the latter may. When loading a CXXRTL simulation into another process, RTL contract violations should generally not crash it, while C++ contract violations should. --- backends/cxxrtl/cxxrtl.h | 14 ++++++++++++++ backends/cxxrtl/cxxrtl_backend.cc | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 41089a153d5..7d3a8485c56 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -53,6 +53,20 @@ #define CXXRTL_ALWAYS_INLINE inline #endif +// CXXRTL uses assert() to check for C++ contract violations (which may result in e.g. undefined behavior +// of the simulation code itself), and CXXRTL_ASSERT to check for RTL contract violations (which may at +// most result in undefined simulation results). +// +// Though by default, CXXRTL_ASSERT() expands to assert(), it may be overridden e.g. when integrating +// the simulation into another process that should survive violating RTL contracts. +#ifndef CXXRTL_ASSERT +#ifndef CXXRTL_NDEBUG +#define CXXRTL_ASSERT(x) assert(x) +#else +#define CXXRTL_ASSERT(x) +#endif +#endif + namespace cxxrtl { // All arbitrary-width values in CXXRTL are backed by arrays of unsigned integers called chunks. The chunk size diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index a48ea5b23a8..23ea57b5ab5 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1154,7 +1154,7 @@ struct CxxrtlWorker { // larger program) will never crash the code that calls into it. // // If assertions are disabled, out of bounds reads are defined to return zero. - f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds read\");\n"; + f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds read\");\n"; f << indent << "if(" << valid_index_temp << ".valid) {\n"; inc_indent(); if (writable_memories[memory]) { @@ -1211,7 +1211,7 @@ struct CxxrtlWorker { // See above for rationale of having both the assert and the condition. // // If assertions are disabled, out of bounds writes are defined to do nothing. - f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds write\");\n"; + f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds write\");\n"; f << indent << "if (" << valid_index_temp << ".valid) {\n"; inc_indent(); f << indent << mangle(memory) << ".update(" << valid_index_temp << ".index, "; From 7067f0d7885b57cd00ad62ee0ff776b554592ac0 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 2 Dec 2020 21:39:25 +0000 Subject: [PATCH 0060/2410] cxxrtl: fix crashes caused by a floating or constant clock input. E.g. in: module test; wire clk = 0; reg data; always @(posedge clk) data <= 0; endmodule --- backends/cxxrtl/cxxrtl_backend.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index a48ea5b23a8..38d2efb8430 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1036,8 +1036,12 @@ struct CxxrtlWorker { // Edge-sensitive logic RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); - f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") - << mangle(clk_bit) << ") {\n"; + if (clk_bit.wire) { + f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } inc_indent(); if (cell->hasPort(ID::EN)) { f << indent << "if ("; @@ -1130,8 +1134,12 @@ struct CxxrtlWorker { if (cell->getParam(ID::CLK_ENABLE).as_bool()) { RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); - f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") - << mangle(clk_bit) << ") {\n"; + if (clk_bit.wire) { + f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } inc_indent(); } RTLIL::Memory *memory = cell->module->memories[cell->getParam(ID::MEMID).decode_string()]; @@ -2105,14 +2113,14 @@ struct CxxrtlWorker { // Various DFF cells are treated like posedge/negedge processes, see above for details. if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { - if (cell->getPort(ID::CLK).is_wire()) + if (sigmap(cell->getPort(ID::CLK)).is_wire()) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } // Similar for memory port cells. if (cell->type.in(ID($memrd), ID($memwr))) { if (cell->getParam(ID::CLK_ENABLE).as_bool()) { - if (cell->getPort(ID::CLK).is_wire()) + if (sigmap(cell->getPort(ID::CLK)).is_wire()) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } From 5a15307926a5984737615a9767c55a11dfb53562 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 3 Dec 2020 00:10:09 +0000 Subject: [PATCH 0061/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 355b2a25e6d..4d15c79b726 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3715 +YOSYS_VER := 0.9+3743 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From e89f6ae819e31103f9cd03163cd52672ec0ac472 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 3 Dec 2020 01:58:02 +0000 Subject: [PATCH 0062/2410] cxxrtl: allow customizing the root module path in the C API. --- backends/cxxrtl/cxxrtl_capi.cc | 15 ++++++++++++++- backends/cxxrtl/cxxrtl_capi.h | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_capi.cc b/backends/cxxrtl/cxxrtl_capi.cc index 1c3c63e3e54..f92709b4696 100644 --- a/backends/cxxrtl/cxxrtl_capi.cc +++ b/backends/cxxrtl/cxxrtl_capi.cc @@ -32,9 +32,22 @@ const cxxrtl::debug_items &cxxrtl_debug_items_from_handle(cxxrtl_handle handle) } cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design) { + return cxxrtl_create_at(design, ""); +} + +cxxrtl_handle cxxrtl_create_at(cxxrtl_toplevel design, const char *root) { + std::string path = root; + if (!path.empty()) { + // module::debug_info() accepts either an empty path, or a path ending in space to simplify + // the logic in generated code. While this is sketchy at best to expose in the C++ API, this + // would be a lot worse in the C API, so don't expose it here. + assert(path.back() != ' '); + path += ' '; + } + cxxrtl_handle handle = new _cxxrtl_handle; handle->module = std::move(design->module); - handle->module->debug_info(handle->objects); + handle->module->debug_info(handle->objects, path); delete design; return handle; } diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index 662bf2c20e0..d67c58f94d1 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -52,6 +52,12 @@ typedef struct _cxxrtl_handle *cxxrtl_handle; // The `design` is consumed by this operation and cannot be used afterwards. cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design); +// Create a design handle at a given hierarchy position from a design toplevel. +// +// This operation is similar to `cxxrtl_create`, except the full hierarchical name of every object +// is prepended with `root`. +cxxrtl_handle cxxrtl_create_at(cxxrtl_toplevel design, const char *root); + // Release all resources used by a design and its handle. void cxxrtl_destroy(cxxrtl_handle handle); From 95c60866813e520da48c628d4f98a2fe2cb4db25 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 4 Dec 2020 00:10:06 +0000 Subject: [PATCH 0063/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d15c79b726..45fd2fd7e70 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3743 +YOSYS_VER := 0.9+3746 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 75f9e9cb452013c8a07333d486a59c238e1b446f Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 7 Dec 2020 08:42:45 +0000 Subject: [PATCH 0064/2410] bugpoint: add -command option. --- passes/cmds/bugpoint.cc | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 81d7a34bbe6..d32d33560d0 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -30,7 +30,7 @@ struct BugpointPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" bugpoint [options] -script \n"); + log(" bugpoint [options] [-script | -command \"\"]\n"); log("\n"); log("This command minimizes the current design that is known to crash Yosys with the\n"); log("given script into a smaller testcase. It does this by removing an arbitrary part\n"); @@ -39,8 +39,8 @@ struct BugpointPass : public Pass { log("still causes a crash. Once this command finishes, it replaces the current design\n"); log("with the smallest testcase it was able to produce.\n"); log("\n"); - log(" -script \n"); - log(" use this script to crash Yosys. required.\n"); + log(" -script | -command \"\"\n"); + log(" use this script file or command to crash Yosys. required.\n"); log("\n"); log(" -yosys \n"); log(" use this Yosys binary. if not specified, `yosys` is used.\n"); @@ -85,7 +85,7 @@ struct BugpointPass : public Pass { log("\n"); } - bool run_yosys(RTLIL::Design *design, string yosys_cmd, string script) + bool run_yosys(RTLIL::Design *design, string yosys_cmd, string yosys_arg) { design->sort(); @@ -93,7 +93,7 @@ struct BugpointPass : public Pass { RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); - string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log -s %s bugpoint-case.il", yosys_cmd.c_str(), script.c_str()); + string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log %s bugpoint-case.il", yosys_cmd.c_str(), yosys_arg.c_str()); return run_command(yosys_cmdline) == 0; } @@ -315,7 +315,7 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", script, grep; + string yosys_cmd = "yosys", yosys_arg, grep; bool fast = false, clean = false; bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false; @@ -330,7 +330,15 @@ struct BugpointPass : public Pass { continue; } if (args[argidx] == "-script" && argidx + 1 < args.size()) { - script = args[++argidx]; + if (!yosys_arg.empty()) + log_cmd_error("A -script or -command option can be only provided once!\n"); + yosys_arg = stringf("-s %s", args[++argidx].c_str()); + continue; + } + if (args[argidx] == "-command" && argidx + 1 < args.size()) { + if (!yosys_arg.empty()) + log_cmd_error("A -script or -command option can be only provided once!\n"); + yosys_arg = stringf("-p %s", args[++argidx].c_str()); continue; } if (args[argidx] == "-grep" && argidx + 1 < args.size()) { @@ -379,8 +387,8 @@ struct BugpointPass : public Pass { } extra_args(args, argidx, design); - if (script.empty()) - log_cmd_error("Missing -script option.\n"); + if (yosys_arg.empty()) + log_cmd_error("Missing -script or -command option.\n"); if (!has_part) { @@ -396,8 +404,8 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - if (run_yosys(crashing_design, yosys_cmd, script)) - log_cmd_error("The provided script file and Yosys binary do not crash on this design!\n"); + if (run_yosys(crashing_design, yosys_cmd, yosys_arg)) + log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -413,12 +421,12 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - crashes = !run_yosys(testcase, yosys_cmd, script); + crashes = !run_yosys(testcase, yosys_cmd, yosys_arg); delete testcase; } else { - crashes = !run_yosys(simplified, yosys_cmd, script); + crashes = !run_yosys(simplified, yosys_cmd, yosys_arg); } if (crashes && check_logfile(grep)) From b1135a88dd24b294c41f8964cfc425d938e3dbee Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 7 Dec 2020 08:23:32 +0000 Subject: [PATCH 0065/2410] bugpoint: accept quoted strings in -grep. --- passes/cmds/bugpoint.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index d32d33560d0..8197b21f716 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -45,7 +45,7 @@ struct BugpointPass : public Pass { log(" -yosys \n"); log(" use this Yosys binary. if not specified, `yosys` is used.\n"); log("\n"); - log(" -grep \n"); + log(" -grep \"\"\n"); log(" only consider crashes that place this string in the log file.\n"); log("\n"); log(" -fast\n"); @@ -102,6 +102,9 @@ struct BugpointPass : public Pass { if (grep.empty()) return true; + if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') + grep = grep.substr(1, grep.size() - 2); + std::ifstream f("bugpoint-case.log"); while (!f.eof()) { From 2b474a01e11342d7ed3e8d67b0c4561fa8628429 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 7 Dec 2020 08:27:25 +0000 Subject: [PATCH 0066/2410] bugpoint: try to remove whole processes first. --- passes/cmds/bugpoint.cc | 44 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 8197b21f716..f2d70a3d172 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -77,6 +77,10 @@ struct BugpointPass : public Pass { log(" -connections\n"); log(" try to reconnect ports to 'x.\n"); log("\n"); + log(" -processes\n"); + log(" try to remove processes. processes with a (* bugpoint_keep *) attribute\n"); + log(" will be skipped.\n"); + log("\n"); log(" -assigns\n"); log(" try to remove process assigns from cases.\n"); log("\n"); @@ -132,7 +136,7 @@ struct BugpointPass : public Pass { return design_copy; } - RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates) + RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool processes, bool assigns, bool updates) { RTLIL::Design *design_copy = new RTLIL::Design; for (auto module : design->modules()) @@ -197,7 +201,6 @@ struct BugpointPass : public Pass { if (mod->get_blackbox_attribute()) continue; - Cell *removed_cell = nullptr; for (auto cell : mod->cells()) { @@ -260,6 +263,33 @@ struct BugpointPass : public Pass { } } } + if (processes) + { + for (auto mod : design_copy->modules()) + { + if (mod->get_blackbox_attribute()) + continue; + + RTLIL::IdString removed_process; + for (auto process : mod->processes) + { + if (process.second->get_bool_attribute(ID::bugpoint_keep)) + continue; + + if (index++ == seed) + { + log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); + removed_process = process.first; + break; + } + } + if (!removed_process.empty()) { + delete mod->processes[removed_process]; + mod->processes.erase(removed_process); + return design_copy; + } + } + } if (assigns) { for (auto mod : design_copy->modules()) @@ -320,7 +350,7 @@ struct BugpointPass : public Pass { { string yosys_cmd = "yosys", yosys_arg, grep; bool fast = false, clean = false; - bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false; + bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, has_part = false; log_header(design, "Executing BUGPOINT pass (minimize testcases).\n"); log_push(); @@ -376,6 +406,11 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-processes") { + processes = true; + has_part = true; + continue; + } if (args[argidx] == "-assigns") { assigns = true; has_part = true; @@ -399,6 +434,7 @@ struct BugpointPass : public Pass { ports = true; cells = true; connections = true; + processes = true; assigns = true; updates = true; } @@ -416,7 +452,7 @@ struct BugpointPass : public Pass { bool found_something = false, stage2 = false; while (true) { - if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, assigns, updates)) + if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, processes, assigns, updates)) { simplified = clean_design(simplified, fast, /*do_delete=*/true); From 1838edf35cbd558d3a9a9c4a1ea10e080e8d56ab Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 7 Dec 2020 09:24:35 +0000 Subject: [PATCH 0067/2410] bugpoint: add -wires option. --- kernel/rtlil.cc | 2 +- passes/cmds/bugpoint.cc | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a9f5856160f..1faf376e7fd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1826,7 +1826,7 @@ void RTLIL::Module::remove(const pool &wires) sig.pack(); for (auto &c : sig.chunks_) if (c.wire != NULL && wires_p->count(c.wire)) { - c.wire = module->addWire(NEW_ID, c.width); + c.wire = module->addWire(stringf("$delete_wire$%d", autoidx++), c.width); c.offset = 0; } } diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index f2d70a3d172..da81e7f0915 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -136,7 +136,7 @@ struct BugpointPass : public Pass { return design_copy; } - RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool processes, bool assigns, bool updates) + RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool processes, bool assigns, bool updates, bool wires) { RTLIL::Design *design_copy = new RTLIL::Design; for (auto module : design->modules()) @@ -343,6 +343,35 @@ struct BugpointPass : public Pass { } } } + if (wires) + { + for (auto mod : design_copy->modules()) + { + if (mod->get_blackbox_attribute()) + continue; + + Wire *removed_wire = nullptr; + for (auto wire : mod->wires()) + { + if (wire->get_bool_attribute(ID::bugpoint_keep)) + continue; + + if (wire->name.begins_with("$delete_wire")) + continue; + + if (index++ == seed) + { + log_header(design, "Trying to remove wire %s.%s.\n", log_id(mod), log_id(wire)); + removed_wire = wire; + break; + } + } + if (removed_wire) { + mod->remove({removed_wire}); + return design_copy; + } + } + } return nullptr; } @@ -350,7 +379,7 @@ struct BugpointPass : public Pass { { string yosys_cmd = "yosys", yosys_arg, grep; bool fast = false, clean = false; - bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, has_part = false; + bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; log_header(design, "Executing BUGPOINT pass (minimize testcases).\n"); log_push(); @@ -421,6 +450,11 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-wires") { + wires = true; + has_part = true; + continue; + } break; } extra_args(args, argidx, design); @@ -437,6 +471,7 @@ struct BugpointPass : public Pass { processes = true; assigns = true; updates = true; + wires = true; } if (!design->full_selection()) @@ -452,7 +487,7 @@ struct BugpointPass : public Pass { bool found_something = false, stage2 = false; while (true) { - if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, processes, assigns, updates)) + if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, processes, assigns, updates, wires)) { simplified = clean_design(simplified, fast, /*do_delete=*/true); From 17812a1560b52b997889d606115266528cdc871f Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 7 Dec 2020 13:27:17 +0000 Subject: [PATCH 0068/2410] nexus: Add LRAM inference Signed-off-by: David Shah --- techlibs/nexus/Makefile.inc | 3 + techlibs/nexus/lrams.txt | 22 ++++++ techlibs/nexus/lrams_init.vh | 128 ++++++++++++++++++++++++++++++++++ techlibs/nexus/lrams_map.v | 56 +++++++++++++++ techlibs/nexus/synth_nexus.cc | 19 ++++- 5 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 techlibs/nexus/lrams.txt create mode 100644 techlibs/nexus/lrams_init.vh create mode 100644 techlibs/nexus/lrams_map.v diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc index c9a9ad4fff4..9828d32c163 100644 --- a/techlibs/nexus/Makefile.inc +++ b/techlibs/nexus/Makefile.inc @@ -9,6 +9,9 @@ $(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams.txt)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_init.vh)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams.txt)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_init.vh)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams.txt)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/arith_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/latches_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/dsp_map.v)) diff --git a/techlibs/nexus/lrams.txt b/techlibs/nexus/lrams.txt new file mode 100644 index 00000000000..481629b985f --- /dev/null +++ b/techlibs/nexus/lrams.txt @@ -0,0 +1,22 @@ +bram $__NX_PDPSC512K + init 1 + + abits 14 + dbits 32 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 4 1 + transp 0 0 + clocks 2 2 + clkpol 2 2 +endbram + +match $__NX_PDPSC512K + # explicitly requested LRAM only, due to limited availability and + # slower Fmax + attribute lram + shuffle_enable A + make_transp +endmatch diff --git a/techlibs/nexus/lrams_init.vh b/techlibs/nexus/lrams_init.vh new file mode 100644 index 00000000000..31a7ba4a81e --- /dev/null +++ b/techlibs/nexus/lrams_init.vh @@ -0,0 +1,128 @@ +.INITVAL_00($sformatf("0x%05120x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_01($sformatf("0x%05120x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_02($sformatf("0x%05120x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_03($sformatf("0x%05120x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_04($sformatf("0x%05120x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_05($sformatf("0x%05120x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_06($sformatf("0x%05120x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_07($sformatf("0x%05120x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_08($sformatf("0x%05120x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_09($sformatf("0x%05120x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0A($sformatf("0x%05120x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0B($sformatf("0x%05120x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0C($sformatf("0x%05120x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0D($sformatf("0x%05120x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0E($sformatf("0x%05120x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0F($sformatf("0x%05120x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_10($sformatf("0x%05120x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_11($sformatf("0x%05120x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_12($sformatf("0x%05120x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_13($sformatf("0x%05120x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_14($sformatf("0x%05120x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_15($sformatf("0x%05120x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_16($sformatf("0x%05120x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_17($sformatf("0x%05120x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_18($sformatf("0x%05120x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_19($sformatf("0x%05120x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1A($sformatf("0x%05120x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1B($sformatf("0x%05120x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1C($sformatf("0x%05120x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1D($sformatf("0x%05120x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1E($sformatf("0x%05120x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1F($sformatf("0x%05120x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_20($sformatf("0x%05120x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_21($sformatf("0x%05120x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_22($sformatf("0x%05120x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_23($sformatf("0x%05120x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_24($sformatf("0x%05120x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_25($sformatf("0x%05120x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_26($sformatf("0x%05120x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_27($sformatf("0x%05120x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_28($sformatf("0x%05120x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_29($sformatf("0x%05120x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2A($sformatf("0x%05120x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2B($sformatf("0x%05120x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2C($sformatf("0x%05120x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2D($sformatf("0x%05120x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2E($sformatf("0x%05120x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2F($sformatf("0x%05120x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_30($sformatf("0x%05120x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_31($sformatf("0x%05120x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_32($sformatf("0x%05120x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_33($sformatf("0x%05120x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_34($sformatf("0x%05120x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_35($sformatf("0x%05120x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_36($sformatf("0x%05120x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_37($sformatf("0x%05120x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_38($sformatf("0x%05120x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_39($sformatf("0x%05120x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3A($sformatf("0x%05120x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3B($sformatf("0x%05120x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3C($sformatf("0x%05120x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3D($sformatf("0x%05120x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3E($sformatf("0x%05120x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3F($sformatf("0x%05120x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_40($sformatf("0x%05120x", permute_init(INIT[64 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_41($sformatf("0x%05120x", permute_init(INIT[65 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_42($sformatf("0x%05120x", permute_init(INIT[66 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_43($sformatf("0x%05120x", permute_init(INIT[67 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_44($sformatf("0x%05120x", permute_init(INIT[68 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_45($sformatf("0x%05120x", permute_init(INIT[69 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_46($sformatf("0x%05120x", permute_init(INIT[70 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_47($sformatf("0x%05120x", permute_init(INIT[71 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_48($sformatf("0x%05120x", permute_init(INIT[72 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_49($sformatf("0x%05120x", permute_init(INIT[73 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4A($sformatf("0x%05120x", permute_init(INIT[74 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4B($sformatf("0x%05120x", permute_init(INIT[75 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4C($sformatf("0x%05120x", permute_init(INIT[76 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4D($sformatf("0x%05120x", permute_init(INIT[77 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4E($sformatf("0x%05120x", permute_init(INIT[78 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4F($sformatf("0x%05120x", permute_init(INIT[79 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_50($sformatf("0x%05120x", permute_init(INIT[80 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_51($sformatf("0x%05120x", permute_init(INIT[81 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_52($sformatf("0x%05120x", permute_init(INIT[82 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_53($sformatf("0x%05120x", permute_init(INIT[83 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_54($sformatf("0x%05120x", permute_init(INIT[84 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_55($sformatf("0x%05120x", permute_init(INIT[85 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_56($sformatf("0x%05120x", permute_init(INIT[86 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_57($sformatf("0x%05120x", permute_init(INIT[87 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_58($sformatf("0x%05120x", permute_init(INIT[88 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_59($sformatf("0x%05120x", permute_init(INIT[89 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5A($sformatf("0x%05120x", permute_init(INIT[90 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5B($sformatf("0x%05120x", permute_init(INIT[91 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5C($sformatf("0x%05120x", permute_init(INIT[92 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5D($sformatf("0x%05120x", permute_init(INIT[93 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5E($sformatf("0x%05120x", permute_init(INIT[94 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5F($sformatf("0x%05120x", permute_init(INIT[95 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_60($sformatf("0x%05120x", permute_init(INIT[96 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_61($sformatf("0x%05120x", permute_init(INIT[97 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_62($sformatf("0x%05120x", permute_init(INIT[98 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_63($sformatf("0x%05120x", permute_init(INIT[99 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_64($sformatf("0x%05120x", permute_init(INIT[100 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_65($sformatf("0x%05120x", permute_init(INIT[101 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_66($sformatf("0x%05120x", permute_init(INIT[102 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_67($sformatf("0x%05120x", permute_init(INIT[103 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_68($sformatf("0x%05120x", permute_init(INIT[104 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_69($sformatf("0x%05120x", permute_init(INIT[105 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6A($sformatf("0x%05120x", permute_init(INIT[106 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6B($sformatf("0x%05120x", permute_init(INIT[107 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6C($sformatf("0x%05120x", permute_init(INIT[108 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6D($sformatf("0x%05120x", permute_init(INIT[109 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6E($sformatf("0x%05120x", permute_init(INIT[110 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6F($sformatf("0x%05120x", permute_init(INIT[111 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_70($sformatf("0x%05120x", permute_init(INIT[112 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_71($sformatf("0x%05120x", permute_init(INIT[113 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_72($sformatf("0x%05120x", permute_init(INIT[114 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_73($sformatf("0x%05120x", permute_init(INIT[115 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_74($sformatf("0x%05120x", permute_init(INIT[116 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_75($sformatf("0x%05120x", permute_init(INIT[117 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_76($sformatf("0x%05120x", permute_init(INIT[118 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_77($sformatf("0x%05120x", permute_init(INIT[119 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_78($sformatf("0x%05120x", permute_init(INIT[120 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_79($sformatf("0x%05120x", permute_init(INIT[121 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7A($sformatf("0x%05120x", permute_init(INIT[122 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7B($sformatf("0x%05120x", permute_init(INIT[123 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7C($sformatf("0x%05120x", permute_init(INIT[124 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7D($sformatf("0x%05120x", permute_init(INIT[125 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7E($sformatf("0x%05120x", permute_init(INIT[126 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7F($sformatf("0x%05120x", permute_init(INIT[127 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), diff --git a/techlibs/nexus/lrams_map.v b/techlibs/nexus/lrams_map.v new file mode 100644 index 00000000000..938a0e84345 --- /dev/null +++ b/techlibs/nexus/lrams_map.v @@ -0,0 +1,56 @@ +module \$__NX_PDPSC512K (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 14; + parameter CFG_DBITS = 32; + parameter CFG_ENABLE_A = 4; + + parameter CLKPOL2 = 1; + parameter [524287:0] INIT = 524287'b0; + + input CLK2; + + input [CFG_ABITS-1:0] A1ADDR; + input [CFG_DBITS-1:0] A1DATA; + input [CFG_ENABLE_A-1:0] A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + output [CFG_DBITS-1:0] B1DATA; + input B1EN; + + wire clk; + wire [31:0] rd; + assign B1DATA = rd[CFG_DBITS-1:0]; + + generate + if (CLKPOL2) + assign clk = CLK2; + else + INV clk_inv_i (.A(CLK2), .Z(clk)); + endgenerate + + wire we = |A1EN; + + localparam INIT_CHUNK_SIZE = 4096; + + function [5119:0] permute_init; + input [INIT_CHUNK_SIZE-1:0] chunk; + integer i; + begin + for (i = 0; i < 128; i = i + 1'b1) + permute_init[i * 40 +: 40] = {8'b0, chunk[i * 32 +: 32]}; + end + endfunction + + generate + PDPSC512K #( + .OUTREG("NO_REG"), + .ECC_BYTE_SEL("BYTE_EN"), +`include "lrams_init.vh" + .GSR("DISABLED") + ) _TECHMAP_REPLACE_ ( + .CLK(clk), .RSTR(1'b0), + .DI(A1DATA), .ADW(A1ADDR), .CEW(we), .WE(we), .CSW(1'b1), + .ADR(B1ADDR), .DO(rd), .CER(B1EN), .CSR(1'b1), + ); + endgenerate + +endmodule diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 9eabbace724..7f36eb2827e 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -77,6 +77,11 @@ struct SynthNexusPass : public ScriptPass log(" -nodffe\n"); log(" do not use flipflops with CE in output netlist\n"); log("\n"); + log(" -nolram\n"); + log(" do not use large RAM cells in output netlist\n"); + log(" note that large RAM must be explicitly requested with a (* lram *)\n"); + log(" attribute on the memory.\n"); + log("\n"); log(" -nobram\n"); log(" do not use block RAM cells in output netlist\n"); log("\n"); @@ -101,7 +106,7 @@ struct SynthNexusPass : public ScriptPass } string top_opt, json_file, vm_file, family; - bool noccu2, nodffe, nobram, nolutram, nowidelut, noiopad, nodsp, flatten, dff, retime, abc9; + bool noccu2, nodffe, nolram, nobram, nolutram, nowidelut, noiopad, nodsp, flatten, dff, retime, abc9; void clear_flags() override { @@ -111,6 +116,7 @@ struct SynthNexusPass : public ScriptPass vm_file = ""; noccu2 = false; nodffe = false; + nolram = false; nobram = false; nolutram = false; nowidelut = false; @@ -181,6 +187,10 @@ struct SynthNexusPass : public ScriptPass nodffe = true; continue; } + if (args[argidx] == "-nolram") { + nolram = true; + continue; + } if (args[argidx] == "-nobram") { nobram = true; continue; @@ -286,6 +296,13 @@ struct SynthNexusPass : public ScriptPass run("opt_clean"); } + if (!nolram && check_label("map_lram", "(skip if -nolram)")) + { + run("memory_bram -rules +/nexus/lrams.txt"); + run("setundef -zero -params t:$__NX_PDPSC512K"); + run("techmap -map +/nexus/lrams_map.v"); + } + if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run("memory_bram -rules +/nexus/brams.txt"); From 186d6df4c3e612667b1eb945ce3e27a92e2cb485 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 7 Dec 2020 13:52:44 -0700 Subject: [PATCH 0069/2410] Allow constant function calls in constant function arguments --- frontends/ast/simplify.cc | 5 +++++ tests/various/const_arg_loop.v | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index fb6623f0238..8e205cb7682 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1205,6 +1205,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_block = this; current_block_child = children[i]; } + if (!in_param_here && type == AST_FCALL) { + bool recommend_const_eval = false; + bool require_const_eval = has_const_only_constructs(recommend_const_eval); + in_param_here = recommend_const_eval || require_const_eval; + } if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK) current_top_block = children[i]; if (i == 0 && child_0_is_self_determined) diff --git a/tests/various/const_arg_loop.v b/tests/various/const_arg_loop.v index 3bfff4acd8d..76cc67abb78 100644 --- a/tests/various/const_arg_loop.v +++ b/tests/various/const_arg_loop.v @@ -14,6 +14,11 @@ module top; end endfunction + function automatic [31:0] pass_through; + input [31:0] inp; + pass_through = inp; + endfunction + function automatic [31:0] operation2; input [4:0] var; input integer num; @@ -47,6 +52,9 @@ module top; wire [31:0] x1; assign x1 = operation1(A, a); + wire [31:0] x1b; + assign x1b = operation1(pass_through(A), a); + wire [31:0] x2; assign x2 = operation2(A, a); @@ -58,6 +66,7 @@ module top; assert property (a == 2); assert property (A == 3); assert property (x1 == 16); + assert property (x1b == 16); assert property (x2 == 4); assert property (x3 == 16); `endif From f5cc1224f9be332c055fe31d6b7db8969e060ad5 Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 8 Dec 2020 15:49:20 +0000 Subject: [PATCH 0070/2410] nexus: Add MULTADDSUB9X9WIDE sim model Signed-off-by: David Shah --- techlibs/nexus/cells_sim.v | 115 +++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v index b5938e08fe0..1e876a210d6 100644 --- a/techlibs/nexus/cells_sim.v +++ b/techlibs/nexus/cells_sim.v @@ -941,3 +941,118 @@ module MULTADDSUB36X36 #( .Z(Z) ); endmodule + +module MULTADDSUB9X9WIDE #( + parameter REGINPUTAB0 = "REGISTER", + parameter REGINPUTAB1 = "REGISTER", + parameter REGINPUTAB2 = "REGISTER", + parameter REGINPUTAB3 = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGADDSUB = "REGISTER", + parameter REGLOADC = "REGISTER", + parameter REGLOADC2 = "REGISTER", + parameter REGPIPELINE = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [8:0] A0, B0, A1, B1, A2, B2, A3, B3, + input [53:0] C, + input CLK, + input CEA0A1, CEA2A3, + input RSTA0A1, RSTA2A3, + input CEB0B1, CEB2B3, + input RSTB0B1, RSTB2B3, + input CEC, RSTC, + input CECTRL, RSTCTRL, + input SIGNED, + input RSTPIPE, CEPIPE, + input RSTOUT, CEOUT, + input LOADC, + input [3:0] ADDSUB, + output [53:0] Z +); + wire [17:0] m0, m1, m2, m3; + + localparam M_WIDTH = 18; + localparam Z_WIDTH = 54; + + MULT9X9 #( + .REGINPUTA(REGINPUTAB0), .REGINPUTB(REGINPUTAB0), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE) + ) m9_0 ( + .A(A0), .B(B0), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), + .CLK(CLK), + .CEA(CEA0A1), .RSTA(RSTA0A1), + .CEB(CEB0B1), .RSTB(RSTB0B1), + .CEOUT(CEPIPE), .RSTOUT(RSTPIPE), + .Z(m0) + ); + MULT9X9 #( + .REGINPUTA(REGINPUTAB1), .REGINPUTB(REGINPUTAB1), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE) + ) m9_1 ( + .A(A1), .B(B1), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), + .CLK(CLK), + .CEA(CEA0A1), .RSTA(RSTA0A1), + .CEB(CEB0B1), .RSTB(RSTB0B1), + .CEOUT(CEPIPE), .RSTOUT(RSTPIPE), + .Z(m1) + ); + MULT9X9 #( + .REGINPUTA(REGINPUTAB2), .REGINPUTB(REGINPUTAB2), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE) + ) m9_2 ( + .A(A2), .B(B2), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), + .CLK(CLK), + .CEA(CEA2A3), .RSTA(RSTA2A3), + .CEB(CEB2B3), .RSTB(RSTB2B3), + .CEOUT(CEPIPE), .RSTOUT(RSTPIPE), + .Z(m2) + ); + MULT9X9 #( + .REGINPUTA(REGINPUTAB3), .REGINPUTB(REGINPUTAB3), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE) + ) m9_3 ( + .A(A3), .B(B3), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), + .CLK(CLK), + .CEA(CEA2A3), .RSTA(RSTA2A3), + .CEB(CEB2B3), .RSTB(RSTB2B3), + .CEOUT(CEPIPE), .RSTOUT(RSTPIPE), + .Z(m3) + ); + + wire [53:0] c_r, c_r2; + wire [3:0] addsub_r, addsub_r2; + wire sgd_r, sgd_r2, csgd_r, csgd_r2; + wire loadc_r, loadc_r2; + + OXIDE_DSP_REG #(5, REGADDSUB, RESETMODE) addsub_reg(CLK, CECTRL, RSTCTRL, {SIGNED, ADDSUB}, {sgd_r, addsub_r}); + OXIDE_DSP_REG #(5, REGADDSUB, RESETMODE) addsub2_reg(CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2}); + + OXIDE_DSP_REG #(1, REGLOADC, RESETMODE) loadc_reg(CLK, CECTRL, RSTCTRL, LOADC, loadc_r); + OXIDE_DSP_REG #(1, REGLOADC2, RESETMODE) loadc2_reg(CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2); + + OXIDE_DSP_REG #(55, REGINPUTC, RESETMODE) c_reg(CLK, CEC, RSTC, {SIGNED, C}, {csgd_r, c_r}); + OXIDE_DSP_REG #(55, REGPIPELINE, RESETMODE) c2_reg(CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2}); + + + wire [18:0] m0_ext, m1_ext, m2_ext, m3_ext; + + assign m0_ext = {sgd_r2 ? m0[M_WIDTH-1] : 1'b0, m0}; + assign m1_ext = {sgd_r2 ? m1[M_WIDTH-1] : 1'b0, m1}; + assign m2_ext = {sgd_r2 ? m2[M_WIDTH-1] : 1'b0, m2}; + assign m3_ext = {sgd_r2 ? m3[M_WIDTH-1] : 1'b0, m3}; + + wire [18:0] s0 = addsub_r2[2] ? (m0_ext - m1_ext) : (m0_ext + m1_ext); + wire [18:0] s1 = addsub_r2[3] ? (m2_ext - m3_ext) : (m2_ext + m3_ext); + + wire [53:0] s0_ext = {{(54-19){sgd_r2 ? s0[18] : 1'b0}}, s0}; + wire [53:0] s1_ext = {{(54-19){sgd_r2 ? s1[18] : 1'b0}}, s1}; + + wire [53:0] c_op = loadc_r2 ? c_r2 : Z; + + // The diagram in the docs is wrong! It is not two cascaded 2-input add/subs as shown, + // but a three-input unit with negation controls on two inputs (i.e. addsub_r2[0] + // negates s1 not (s1 +/- s0)) + wire [53:0] z_d = c_op + (addsub_r2[0] ? -s1_ext : s1_ext) + (addsub_r2[1] ? -s0_ext : s0_ext); + + OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg(CLK, CEOUT, RSTOUT, z_d, Z); + +endmodule From c46452221ef1164fc1681e2f21d06e104e376a04 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 9 Dec 2020 00:10:04 +0000 Subject: [PATCH 0071/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 45fd2fd7e70..4a9417962ce 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3746 +YOSYS_VER := 0.9+3752 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 82dcf78cd9e90106653bcdd82a8a9cbf391f0afd Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 9 Dec 2020 11:06:22 +0100 Subject: [PATCH 0072/2410] Return nice error in pmgen generated code, fixes #2482 --- passes/pmgen/pmgen.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 592a26fa67f..db827ee8272 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -451,7 +451,9 @@ def process_pmgfile(f, filename): current_pattern = None print(" SigSpec port(Cell *cell, IdString portname) {", file=f) - print(" return sigmap(cell->getPort(portname));", file=f) + print(" try {", file=f) + print(" return sigmap(cell->getPort(portname));", file=f) + print(" } catch(std::out_of_range) { log_error(\"Accessing non existing port %s\\n\",portname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" SigSpec port(Cell *cell, IdString portname, const SigSpec& defval) {", file=f) @@ -460,7 +462,9 @@ def process_pmgfile(f, filename): print("", file=f) print(" Const param(Cell *cell, IdString paramname) {", file=f) - print(" return cell->getParam(paramname);", file=f) + print(" try {", file=f) + print(" return cell->getParam(paramname);", file=f) + print(" } catch(std::out_of_range) { log_error(\"Accessing non existing parameter %s\\n\",paramname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" Const param(Cell *cell, IdString paramname, const Const& defval) {", file=f) From 442d19f6478180cb4c49cc4e67e93ae391da9e65 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 10 Dec 2020 00:10:10 +0000 Subject: [PATCH 0073/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4a9417962ce..24129fc4347 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3752 +YOSYS_VER := 0.9+3755 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From e4aa8bc96b1650ef17d70a0ba7cd88b21b7e38dc Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 11 Dec 2020 23:30:32 +0000 Subject: [PATCH 0074/2410] cxxrtl: don't overwrite buffered inputs. Before this commit, a cell's input was always assigned like: p_cell.p_input = (value...); If `p_input` is buffered (e.g. if the design is built at -O0), this is not correct. (In practice, this breaks clocking.) Unfortunately, the incorrect design was compiled without diagnostics because wire<> was move-assignable and also implicitly constructible from value<>. After this commit, cell inputs are no longer incorrectly assumed to always be unbuffered, and wires are not assignable from values. --- backends/cxxrtl/cxxrtl.h | 2 +- backends/cxxrtl/cxxrtl_backend.cc | 56 ++++++++++++++++++------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index eb7d7eaeb30..d850fdba40b 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -659,7 +659,7 @@ struct wire { value next; wire() = default; - constexpr wire(const value &init) : curr(init), next(init) {} + explicit constexpr wire(const value &init) : curr(init), next(init) {} template explicit constexpr wire(Init ...init) : curr{init...}, next{init...} {} diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 7efb0aeaf39..c193d78e915 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1240,10 +1240,19 @@ struct CxxrtlWorker { // User cells } else { log_assert(cell->known()); + bool buffered_inputs = false; const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; for (auto conn : cell->connections()) - if (cell->input(conn.first) && !cell->output(conn.first)) { - f << indent << mangle(cell) << access << mangle_wire_name(conn.first) << " = "; + if (cell->input(conn.first)) { + RTLIL::Module *cell_module = cell->module->design->module(cell->type); + log_assert(cell_module != nullptr && cell_module->wire(conn.first) && conn.second.is_wire()); + RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first); + f << indent << mangle(cell) << access << mangle_wire_name(conn.first); + if (!is_cxxrtl_blackbox_cell(cell) && !unbuffered_wires[cell_module_wire]) { + buffered_inputs = true; + f << ".next"; + } + f << " = "; dump_sigspec_rhs(conn.second); f << ";\n"; if (getenv("CXXRTL_VOID_MY_WARRANTY")) { @@ -1255,19 +1264,11 @@ struct CxxrtlWorker { // with: // top.prev_p_clk = value<1>{0u}; top.p_clk = value<1>{1u}; top.step(); // Don't rely on this; it will be removed without warning. - RTLIL::Module *cell_module = cell->module->design->module(cell->type); - if (cell_module != nullptr && cell_module->wire(conn.first) && conn.second.is_wire()) { - RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first); - if (edge_wires[conn.second.as_wire()] && edge_wires[cell_module_wire]) { - f << indent << mangle(cell) << access << "prev_" << mangle(cell_module_wire) << " = "; - f << "prev_" << mangle(conn.second.as_wire()) << ";\n"; - } + if (edge_wires[conn.second.as_wire()] && edge_wires[cell_module_wire]) { + f << indent << mangle(cell) << access << "prev_" << mangle(cell_module_wire) << " = "; + f << "prev_" << mangle(conn.second.as_wire()) << ";\n"; } } - } else if (cell->input(conn.first)) { - f << indent << mangle(cell) << access << mangle_wire_name(conn.first) << ".next = "; - dump_sigspec_rhs(conn.second); - f << ";\n"; } auto assign_from_outputs = [&](bool cell_converged) { for (auto conn : cell->connections()) { @@ -1285,9 +1286,9 @@ struct CxxrtlWorker { // have any buffered wires if they were not output ports. Imagine inlining the cell's eval() function, // and consider the fate of the localized wires that used to be output ports.) // - // Unlike cell inputs (which are never buffered), it is not possible to know apriori whether the cell - // (which may be late bound) will converge immediately. Because of this, the choice between using .curr - // (appropriate for buffered outputs) and .next (appropriate for unbuffered outputs) is made at runtime. + // It is not possible to know apriori whether the cell (which may be late bound) will converge immediately. + // Because of this, the choice between using .curr (appropriate for buffered outputs) and .next (appropriate + // for unbuffered outputs) is made at runtime. if (cell_converged && is_cxxrtl_comb_port(cell, conn.first)) f << ".next;\n"; else @@ -1295,16 +1296,23 @@ struct CxxrtlWorker { } } }; - f << indent << "if (" << mangle(cell) << access << "eval()) {\n"; - inc_indent(); - assign_from_outputs(/*cell_converged=*/true); - dec_indent(); - f << indent << "} else {\n"; - inc_indent(); + if (buffered_inputs) { + // If we have any buffered inputs, there's no chance of converging immediately. + f << indent << mangle(cell) << access << "eval();\n"; f << indent << "converged = false;\n"; assign_from_outputs(/*cell_converged=*/false); - dec_indent(); - f << indent << "}\n"; + } else { + f << indent << "if (" << mangle(cell) << access << "eval()) {\n"; + inc_indent(); + assign_from_outputs(/*cell_converged=*/true); + dec_indent(); + f << indent << "} else {\n"; + inc_indent(); + f << indent << "converged = false;\n"; + assign_from_outputs(/*cell_converged=*/false); + dec_indent(); + f << indent << "}\n"; + } } } From 080f311040a0c1bb5fd877e4ad06fc613fdc3314 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 12 Dec 2020 20:50:37 +0000 Subject: [PATCH 0075/2410] kernel: make IdString::isPublic() const. --- kernel/rtlil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a03e8933c59..cd966b81522 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -376,7 +376,7 @@ namespace RTLIL bool in(const std::string &rhs) const { return *this == rhs; } bool in(const pool &rhs) const { return rhs.count(*this) != 0; } - bool isPublic() { return begins_with("\\"); } + bool isPublic() const { return begins_with("\\"); } }; namespace ID { From 5a881497e12a100438a51a2f0c1b133a8cc389ff Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sun, 13 Dec 2020 00:10:07 +0000 Subject: [PATCH 0076/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 24129fc4347..0de22cfc032 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3755 +YOSYS_VER := 0.9+3758 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From ac1a78923af80cec3760cfbd0f6f4a96d180cce8 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 00:54:12 +0000 Subject: [PATCH 0077/2410] cxxrtl: use IdString::isPublic(). NFC. --- backends/cxxrtl/cxxrtl_backend.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index c193d78e915..f1ed475414d 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -211,7 +211,7 @@ bool is_ff_cell(RTLIL::IdString type) bool is_internal_cell(RTLIL::IdString type) { - return type[0] == '$' && !type.begins_with("$paramod"); + return !type.isPublic() && !type.begins_with("$paramod"); } bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) @@ -1665,7 +1665,7 @@ struct CxxrtlWorker { inc_indent(); f << indent << "assert(path.empty() || path[path.size() - 1] == ' ');\n"; for (auto wire : module->wires()) { - if (wire->name[0] != '\\') + if (!wire->name.isPublic()) continue; if (module->get_bool_attribute(ID(cxxrtl_blackbox)) && (wire->port_id == 0)) continue; @@ -1743,7 +1743,7 @@ struct CxxrtlWorker { } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto &memory_it : module->memories) { - if (memory_it.first[0] != '\\') + if (!memory_it.first.isPublic()) continue; f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(memory_it.second)); f << ", debug_item(" << mangle(memory_it.second) << ", "; @@ -2338,7 +2338,7 @@ struct CxxrtlWorker { // Note that the information collected here can't be used for optimizing the netlist: debug information queries // are pure and run on a design in a stable state, which allows assumptions that do not otherwise hold. for (auto wire : module->wires()) { - if (wire->name[0] != '\\') + if (!wire->name.isPublic()) continue; if (!unbuffered_wires[wire]) continue; From 57759c3d1fa573c99552533758a0c198c0641b51 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 12 Dec 2020 20:24:53 +0000 Subject: [PATCH 0078/2410] cxxrtl: fix outdated comment. NFC. --- backends/cxxrtl/cxxrtl_backend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index f1ed475414d..8e51f30431c 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1157,8 +1157,8 @@ struct CxxrtlWorker { } // The generated code has two bounds checks; one in an assertion, and another that guards the read. // This is done so that the code does not invoke undefined behavior under any conditions, but nevertheless - // loudly crashes if an illegal condition is encountered. The assert may be turned off with -DNDEBUG not - // just for release builds, but also to make sure the simulator (which is presumably embedded in some + // loudly crashes if an illegal condition is encountered. The assert may be turned off with -DCXXRTL_NDEBUG + // not only for release builds, but also to make sure the simulator (which is presumably embedded in some // larger program) will never crash the code that calls into it. // // If assertions are disabled, out of bounds reads are defined to return zero. From 3b5a1314cd02d093cb1328d7c2f7abced876a514 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 00:34:32 +0000 Subject: [PATCH 0079/2410] cxxrtl: rename "elision" to "inlining". NFC. "Elision" in this context is an unusual and not very descriptive term whereas "inlining" is common and straightforward. Also, introducing "inlining" makes it easier to introduce its dual under the obvious name "outlining". --- backends/cxxrtl/cxxrtl_backend.cc | 154 +++++++++++++++--------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8e51f30431c..ca7f3a3cc81 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -195,7 +195,7 @@ bool is_extending_cell(RTLIL::IdString type) ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)); } -bool is_elidable_cell(RTLIL::IdString type) +bool is_inlinable_cell(RTLIL::IdString type) { return is_unary_cell(type) || is_binary_cell(type) || type.in( ID($mux), ID($concat), ID($slice), ID($pmux)); @@ -273,7 +273,7 @@ struct FlowGraph { std::vector nodes; dict> wire_comb_defs, wire_sync_defs, wire_uses; - dict wire_def_elidable, wire_use_elidable; + dict wire_def_inlinable, wire_use_inlinable; dict bit_has_state; ~FlowGraph() @@ -282,7 +282,7 @@ struct FlowGraph { delete node; } - void add_defs(Node *node, const RTLIL::SigSpec &sig, bool is_ff, bool elidable) + void add_defs(Node *node, const RTLIL::SigSpec &sig, bool is_ff, bool inlinable) { for (auto chunk : sig.chunks()) if (chunk.wire) { @@ -298,9 +298,9 @@ struct FlowGraph { } for (auto bit : sig.bits()) bit_has_state[bit] |= is_ff; - // Only comb defs of an entire wire in the right order can be elided. + // Only comb defs of an entire wire in the right order can be inlined. if (!is_ff && sig.is_wire()) - wire_def_elidable[sig.as_wire()] = elidable; + wire_def_inlinable[sig.as_wire()] = inlinable; } void add_uses(Node *node, const RTLIL::SigSpec &sig) @@ -308,26 +308,26 @@ struct FlowGraph { for (auto chunk : sig.chunks()) if (chunk.wire) { wire_uses[chunk.wire].insert(node); - // Only a single use of an entire wire in the right order can be elided. + // Only a single use of an entire wire in the right order can be inlined. // (But the use can include other chunks.) - if (!wire_use_elidable.count(chunk.wire)) - wire_use_elidable[chunk.wire] = true; + if (!wire_use_inlinable.count(chunk.wire)) + wire_use_inlinable[chunk.wire] = true; else - wire_use_elidable[chunk.wire] = false; + wire_use_inlinable[chunk.wire] = false; } } - bool is_elidable(const RTLIL::Wire *wire) const + bool is_inlinable(const RTLIL::Wire *wire) const { - if (wire_def_elidable.count(wire) && wire_use_elidable.count(wire)) - return wire_def_elidable.at(wire) && wire_use_elidable.at(wire); + if (wire_def_inlinable.count(wire) && wire_use_inlinable.count(wire)) + return wire_def_inlinable.at(wire) && wire_use_inlinable.at(wire); return false; } // Connections void add_connect_defs_uses(Node *node, const RTLIL::SigSig &conn) { - add_defs(node, conn.first, /*is_ff=*/false, /*elidable=*/true); + add_defs(node, conn.first, /*is_ff=*/false, /*inlinable=*/true); add_uses(node, conn.second); } @@ -373,8 +373,8 @@ struct FlowGraph { for (auto conn : cell->connections()) if (cell->output(conn.first)) if (is_cxxrtl_sync_port(cell, conn.first)) { - // See note regarding elidability below. - add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); + // See note regarding inlinability below. + add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/false); } } @@ -382,19 +382,19 @@ struct FlowGraph { { for (auto conn : cell->connections()) { if (cell->output(conn.first)) { - if (is_elidable_cell(cell->type)) - add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/true); + if (is_inlinable_cell(cell->type)) + add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/true); else if (is_ff_cell(cell->type) || (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool())) - add_defs(node, conn.second, /*is_ff=*/true, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/true, /*inlinable=*/false); else if (is_internal_cell(cell->type)) - add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/false); else if (!is_cxxrtl_sync_port(cell, conn.first)) { - // Although at first it looks like outputs of user-defined cells may always be elided, the reality is - // more complex. Fully sync outputs produce no defs and so don't participate in elision. Fully comb + // Although at first it looks like outputs of user-defined cells may always be inlined, the reality is + // more complex. Fully sync outputs produce no defs and so don't participate in inlining. Fully comb // outputs are assigned in a different way depending on whether the cell's eval() immediately converged. - // Unknown/mixed outputs could be elided, but should be rare in practical designs and don't justify - // the infrastructure required to elide outputs of cells with many of them. - add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); + // Unknown/mixed outputs could be inlined, but should be rare in practical designs and don't justify + // the infrastructure required to inline outputs of cells with many of them. + add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/false); } } if (cell->input(conn.first)) @@ -432,7 +432,7 @@ struct FlowGraph { void add_case_defs_uses(Node *node, const RTLIL::CaseRule *case_) { for (auto &action : case_->actions) { - add_defs(node, action.first, /*is_ff=*/false, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/false, /*inlinable=*/false); add_uses(node, action.second); } for (auto sub_switch : case_->switches) { @@ -451,9 +451,9 @@ struct FlowGraph { for (auto sync : process->syncs) for (auto action : sync->actions) { if (sync->type == RTLIL::STp || sync->type == RTLIL::STn || sync->type == RTLIL::STe) - add_defs(node, action.first, /*is_ff=*/true, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/true, /*inlinable=*/false); else - add_defs(node, action.first, /*is_ff=*/false, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/false, /*inlinable=*/false); add_uses(node, action.second); } } @@ -535,8 +535,8 @@ struct CxxrtlWorker { bool unbuffer_public = false; bool localize_internal = false; bool localize_public = false; - bool elide_internal = false; - bool elide_public = false; + bool inline_internal = false; + bool inline_public = false; bool debug_info = false; @@ -549,10 +549,10 @@ struct CxxrtlWorker { dict edge_types; pool writable_memories; dict> transparent_for; - dict elided_wires; dict> schedule; pool unbuffered_wires; pool localized_wires; + dict inlined_wires; dict debug_alias_wires; dict debug_const_wires; dict bit_has_state; @@ -792,16 +792,16 @@ struct CxxrtlWorker { dump_const(chunk.data, chunk.width, chunk.offset); return false; } else { - if (elided_wires.count(chunk.wire)) { + if (inlined_wires.count(chunk.wire)) { log_assert(!is_lhs); - const FlowGraph::Node &node = elided_wires[chunk.wire]; + const FlowGraph::Node &node = inlined_wires[chunk.wire]; switch (node.type) { case FlowGraph::Node::Type::CONNECT: - dump_connect_elided(node.connect); + dump_connect_expr(node.connect); break; case FlowGraph::Node::Type::CELL_EVAL: - log_assert(is_elidable_cell(node.cell->type)); - dump_cell_elided(node.cell); + log_assert(is_inlinable_cell(node.cell->type)); + dump_cell_expr(node.cell); break; default: log_assert(false); @@ -858,10 +858,10 @@ struct CxxrtlWorker { void collect_sigspec_rhs(const RTLIL::SigSpec &sig, std::vector &cells) { for (auto chunk : sig.chunks()) { - if (!chunk.wire || !elided_wires.count(chunk.wire)) + if (!chunk.wire || !inlined_wires.count(chunk.wire)) continue; - const FlowGraph::Node &node = elided_wires[chunk.wire]; + const FlowGraph::Node &node = inlined_wires[chunk.wire]; switch (node.type) { case FlowGraph::Node::Type::CONNECT: collect_connect(node.connect, cells); @@ -875,19 +875,19 @@ struct CxxrtlWorker { } } - void dump_connect_elided(const RTLIL::SigSig &conn) + void dump_connect_expr(const RTLIL::SigSig &conn) { dump_sigspec_rhs(conn.second); } - bool is_connect_elided(const RTLIL::SigSig &conn) + bool is_connect_inlined(const RTLIL::SigSig &conn) { - return conn.first.is_wire() && elided_wires.count(conn.first.as_wire()); + return conn.first.is_wire() && inlined_wires.count(conn.first.as_wire()); } void collect_connect(const RTLIL::SigSig &conn, std::vector &cells) { - if (!is_connect_elided(conn)) + if (!is_connect_inlined(conn)) return; collect_sigspec_rhs(conn.second, cells); @@ -895,14 +895,14 @@ struct CxxrtlWorker { void dump_connect(const RTLIL::SigSig &conn) { - if (is_connect_elided(conn)) + if (is_connect_inlined(conn)) return; f << indent << "// connection\n"; f << indent; dump_sigspec_lhs(conn.first); f << " = "; - dump_connect_elided(conn); + dump_connect_expr(conn); f << ";\n"; } @@ -919,7 +919,7 @@ struct CxxrtlWorker { } } - void dump_cell_elided(const RTLIL::Cell *cell) + void dump_cell_expr(const RTLIL::Cell *cell) { // Unary cells if (is_unary_cell(cell->type)) { @@ -983,15 +983,15 @@ struct CxxrtlWorker { } } - bool is_cell_elided(const RTLIL::Cell *cell) + bool is_cell_inlined(const RTLIL::Cell *cell) { - return is_elidable_cell(cell->type) && cell->hasPort(ID::Y) && cell->getPort(ID::Y).is_wire() && - elided_wires.count(cell->getPort(ID::Y).as_wire()); + return is_inlinable_cell(cell->type) && cell->hasPort(ID::Y) && cell->getPort(ID::Y).is_wire() && + inlined_wires.count(cell->getPort(ID::Y).as_wire()); } void collect_cell_eval(const RTLIL::Cell *cell, std::vector &cells) { - if (!is_cell_elided(cell)) + if (!is_cell_inlined(cell)) return; cells.push_back(cell->name); @@ -1002,33 +1002,33 @@ struct CxxrtlWorker { void dump_cell_eval(const RTLIL::Cell *cell) { - if (is_cell_elided(cell)) + if (is_cell_inlined(cell)) return; if (cell->type == ID($meminit)) return; // Handled elsewhere. - std::vector elided_cells; - if (is_elidable_cell(cell->type)) { + std::vector inlined_cells; + if (is_inlinable_cell(cell->type)) { for (auto port : cell->connections()) if (port.first != ID::Y) - collect_sigspec_rhs(port.second, elided_cells); + collect_sigspec_rhs(port.second, inlined_cells); } - if (elided_cells.empty()) { + if (inlined_cells.empty()) { dump_attrs(cell); f << indent << "// cell " << cell->name.str() << "\n"; } else { f << indent << "// cells"; - for (auto elided_cell : elided_cells) - f << " " << elided_cell.str(); + for (auto inlined_cell : inlined_cells) + f << " " << inlined_cell.str(); f << "\n"; } // Elidable cells - if (is_elidable_cell(cell->type)) { + if (is_inlinable_cell(cell->type)) { f << indent; dump_sigspec_lhs(cell->getPort(ID::Y)); f << " = "; - dump_cell_elided(cell); + dump_cell_expr(cell); f << ";\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { @@ -1458,16 +1458,16 @@ struct CxxrtlWorker { } } - void dump_wire(const RTLIL::Wire *wire, bool is_local_context) + void dump_wire(const RTLIL::Wire *wire, bool is_local) { - if (elided_wires.count(wire)) + if (inlined_wires.count(wire)) return; - if (localized_wires[wire] && is_local_context) { + if (localized_wires[wire] && is_local) { dump_attrs(wire); f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; } - if (!localized_wires[wire] && !is_local_context) { + if (!localized_wires[wire] && !is_local) { std::string width; if (wire->module->has_attribute(ID(cxxrtl_blackbox)) && wire->has_attribute(ID(cxxrtl_width))) { width = wire->get_string_attribute(ID(cxxrtl_width)); @@ -1597,7 +1597,7 @@ struct CxxrtlWorker { } } for (auto wire : module->wires()) - dump_wire(wire, /*is_local_context=*/true); + dump_wire(wire, /*is_local=*/true); for (auto node : schedule[module]) { switch (node.type) { case FlowGraph::Node::Type::CONNECT: @@ -1624,7 +1624,7 @@ struct CxxrtlWorker { inc_indent(); f << indent << "bool changed = false;\n"; for (auto wire : module->wires()) { - if (elided_wires.count(wire)) + if (inlined_wires.count(wire)) continue; if (unbuffered_wires[wire]) { if (edge_wires[wire]) @@ -1808,7 +1808,7 @@ struct CxxrtlWorker { inc_indent(); for (auto wire : module->wires()) { if (wire->port_id != 0) - dump_wire(wire, /*is_local_context=*/false); + dump_wire(wire, /*is_local=*/false); } f << "\n"; f << indent << "bool eval() override {\n"; @@ -1854,7 +1854,7 @@ struct CxxrtlWorker { f << indent << "struct " << mangle(module) << " : public module {\n"; inc_indent(); for (auto wire : module->wires()) - dump_wire(wire, /*is_local_context=*/false); + dump_wire(wire, /*is_local=*/false); f << "\n"; bool has_memories = false; for (auto memory : module->memories) { @@ -2234,16 +2234,16 @@ struct CxxrtlWorker { } for (auto wire : module->wires()) { - if (!flow.is_elidable(wire)) continue; + if (!flow.is_inlinable(wire)) continue; if (wire->port_id != 0) continue; if (wire->get_bool_attribute(ID::keep)) continue; - if (wire->name.begins_with("$") && !elide_internal) continue; - if (wire->name.begins_with("\\") && !elide_public) continue; + if (wire->name.begins_with("$") && !inline_internal) continue; + if (wire->name.begins_with("\\") && !inline_public) continue; if (edge_wires[wire]) continue; if (flow.wire_comb_defs[wire].size() > 1) log_cmd_error("Wire %s.%s has multiple drivers.\n", log_id(module), log_id(wire)); log_assert(flow.wire_comb_defs[wire].size() == 1); - elided_wires[wire] = **flow.wire_comb_defs[wire].begin(); + inlined_wires[wire] = **flow.wire_comb_defs[wire].begin(); } dict, hash_ptr_ops> node_defs; @@ -2280,9 +2280,9 @@ struct CxxrtlWorker { for (auto succ_node : flow.wire_uses[wire]) if (evaluated[succ_node]) { feedback_wires.insert(wire); - // Feedback wires may never be elided because feedback requires state, but the point of elision - // (and localization) is to eliminate state. - elided_wires.erase(wire); + // Feedback wires may never be inlined because feedback requires state, but the point of + // inlining (and localization) is to eliminate state. + inlined_wires.erase(wire); } } @@ -2344,7 +2344,7 @@ struct CxxrtlWorker { continue; const RTLIL::Wire *wire_it = wire; while (1) { - if (!(flow.wire_def_elidable.count(wire_it) && flow.wire_def_elidable[wire_it])) + if (!(flow.wire_def_inlinable.count(wire_it) && flow.wire_def_inlinable[wire_it])) break; // not an alias: complex def log_assert(flow.wire_comb_defs[wire_it].size() == 1); FlowGraph::Node *node = *flow.wire_comb_defs[wire_it].begin(); @@ -2660,7 +2660,7 @@ struct CxxrtlBackend : public Backend { log(" like -O1, and unbuffer internal wires if possible.\n"); log("\n"); log(" -O3\n"); - log(" like -O2, and elide internal wires if possible.\n"); + log(" like -O2, and inline internal wires if possible.\n"); log("\n"); log(" -O4\n"); log(" like -O3, and unbuffer public wires not marked (*keep*) if possible.\n"); @@ -2669,7 +2669,7 @@ struct CxxrtlBackend : public Backend { log(" like -O4, and localize public wires not marked (*keep*) if possible.\n"); log("\n"); log(" -O6\n"); - log(" like -O5, and elide public wires not marked (*keep*) if possible.\n"); + log(" like -O5, and inline public wires not marked (*keep*) if possible.\n"); log("\n"); log(" -Og\n"); log(" highest optimization level that provides debug information for all\n"); @@ -2757,7 +2757,7 @@ struct CxxrtlBackend : public Backend { switch (opt_level) { // the highest level here must match DEFAULT_OPT_LEVEL case 6: - worker.elide_public = true; + worker.inline_public = true; YS_FALLTHROUGH case 5: worker.localize_public = true; @@ -2766,7 +2766,7 @@ struct CxxrtlBackend : public Backend { worker.unbuffer_public = true; YS_FALLTHROUGH case 3: - worker.elide_internal = true; + worker.inline_internal = true; YS_FALLTHROUGH case 2: worker.localize_internal = true; From ece25a45d4b12f0436be238a13e622b58282036e Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 07:03:16 +0000 Subject: [PATCH 0080/2410] cxxrtl: implement debug information outlining. Aggressive wire localization and inlining is necessary for CXXRTL to achieve high performance. However, that comes with a cost: reduced debug information coverage. Previously, as a workaround, the `-Og` option could have been used to guarantee complete coverage, at a cost of a significant performance penalty. This commit introduces debug information outlining. The main eval() function is compiled with the user-specified optimization settings. In tandem, an auxiliary debug_eval() function, compiled from the same netlist, can be used to reconstruct the values of localized/inlined signals on demand. To the extent that it is possible, debug_eval() reuses the results of computations performed by eval(), only filling in the missing values. Benchmarking a representative design (Minerva SoC SRAM) shows that: * Switching from `-O4`/`-Og` to `-O6` reduces runtime by ~40%. * Switching from `-g1` to `-g2`, both used with `-O6`, increases compile time by ~25%. * Although `-g2` increases the resident size of generated modules, this has no effect on runtime. Because the impact of `-g2` is minimal and the benefits of having unconditional 100% debug information coverage (and the performance improvement as well) are major, this commit removes `-Og` and changes the defaults to `-O6 -g2`. We'll have our cake and eat it too! --- backends/cxxrtl/cxxrtl.h | 41 +++++- backends/cxxrtl/cxxrtl_backend.cc | 232 +++++++++++++++++++++++------- backends/cxxrtl/cxxrtl_capi.cc | 4 + backends/cxxrtl/cxxrtl_capi.h | 40 +++++- backends/cxxrtl/cxxrtl_vcd.h | 32 ++++- 5 files changed, 278 insertions(+), 71 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index d850fdba40b..59393e415cf 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -843,6 +844,9 @@ typedef std::map metadata_map; // Tag class to disambiguate values/wires and their aliases. struct debug_alias {}; +// Tag declaration to disambiguate values and debug outlines. +using debug_outline = ::_cxxrtl_outline; + // This structure is intended for consumption via foreign function interfaces, like Python's ctypes. // Because of this it uses a C-style layout that is easy to parse rather than more idiomatic C++. // @@ -851,10 +855,11 @@ struct debug_alias {}; struct debug_item : ::cxxrtl_object { // Object types. enum : uint32_t { - VALUE = CXXRTL_VALUE, - WIRE = CXXRTL_WIRE, - MEMORY = CXXRTL_MEMORY, - ALIAS = CXXRTL_ALIAS, + VALUE = CXXRTL_VALUE, + WIRE = CXXRTL_WIRE, + MEMORY = CXXRTL_MEMORY, + ALIAS = CXXRTL_ALIAS, + OUTLINE = CXXRTL_OUTLINE, }; // Object flags. @@ -881,6 +886,7 @@ struct debug_item : ::cxxrtl_object { zero_at = 0; curr = item.data; next = item.data; + outline = nullptr; } template @@ -895,6 +901,7 @@ struct debug_item : ::cxxrtl_object { zero_at = 0; curr = const_cast(item.data); next = nullptr; + outline = nullptr; } template @@ -910,6 +917,7 @@ struct debug_item : ::cxxrtl_object { zero_at = 0; curr = item.curr.data; next = item.next.data; + outline = nullptr; } template @@ -924,6 +932,7 @@ struct debug_item : ::cxxrtl_object { zero_at = zero_offset; curr = item.data.empty() ? nullptr : item.data[0].data; next = nullptr; + outline = nullptr; } template @@ -938,6 +947,7 @@ struct debug_item : ::cxxrtl_object { zero_at = 0; curr = const_cast(item.data); next = nullptr; + outline = nullptr; } template @@ -953,6 +963,22 @@ struct debug_item : ::cxxrtl_object { zero_at = 0; curr = const_cast(item.curr.data); next = nullptr; + outline = nullptr; + } + + template + debug_item(debug_outline &group, const value &item, size_t lsb_offset = 0) { + static_assert(sizeof(item) == value::chunks * sizeof(chunk_t), + "value is not compatible with C layout"); + type = OUTLINE; + flags = DRIVEN_COMB; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = const_cast(item.data); + next = nullptr; + outline = &group; } }; static_assert(std::is_standard_layout::value, "debug_item is not compatible with C layout"); @@ -1029,11 +1055,16 @@ struct module { } // namespace cxxrtl -// Internal structure used to communicate with the implementation of the C interface. +// Internal structures used to communicate with the implementation of the C interface. + typedef struct _cxxrtl_toplevel { std::unique_ptr module; } *cxxrtl_toplevel; +typedef struct _cxxrtl_outline { + std::function eval; +} *cxxrtl_outline; + // Definitions of internal Yosys cells. Other than the functions in this namespace, CXXRTL is fully generic // and indepenent of Yosys implementation details. // diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index ca7f3a3cc81..5e2f4f31a5c 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -539,6 +539,7 @@ struct CxxrtlWorker { bool inline_public = false; bool debug_info = false; + bool debug_eval = false; std::ostringstream f; std::string indent; @@ -553,8 +554,9 @@ struct CxxrtlWorker { pool unbuffered_wires; pool localized_wires; dict inlined_wires; - dict debug_alias_wires; dict debug_const_wires; + dict debug_alias_wires; + pool debug_outlined_wires; dict bit_has_state; dict> blackbox_specializations; dict eval_converges; @@ -786,22 +788,22 @@ struct CxxrtlWorker { dump_const(data, data.size()); } - bool dump_sigchunk(const RTLIL::SigChunk &chunk, bool is_lhs) + bool dump_sigchunk(const RTLIL::SigChunk &chunk, bool is_lhs, bool for_debug = false) { if (chunk.wire == NULL) { dump_const(chunk.data, chunk.width, chunk.offset); return false; } else { - if (inlined_wires.count(chunk.wire)) { + if (inlined_wires.count(chunk.wire) && (!for_debug || !debug_outlined_wires[chunk.wire])) { log_assert(!is_lhs); const FlowGraph::Node &node = inlined_wires[chunk.wire]; switch (node.type) { case FlowGraph::Node::Type::CONNECT: - dump_connect_expr(node.connect); + dump_connect_expr(node.connect, for_debug); break; case FlowGraph::Node::Type::CELL_EVAL: log_assert(is_inlinable_cell(node.cell->type)); - dump_cell_expr(node.cell); + dump_cell_expr(node.cell, for_debug); break; default: log_assert(false); @@ -821,36 +823,36 @@ struct CxxrtlWorker { } } - bool dump_sigspec(const RTLIL::SigSpec &sig, bool is_lhs) + bool dump_sigspec(const RTLIL::SigSpec &sig, bool is_lhs, bool for_debug = false) { if (sig.empty()) { f << "value<0>()"; return false; } else if (sig.is_chunk()) { - return dump_sigchunk(sig.as_chunk(), is_lhs); + return dump_sigchunk(sig.as_chunk(), is_lhs, for_debug); } else { - dump_sigchunk(*sig.chunks().rbegin(), is_lhs); + dump_sigchunk(*sig.chunks().rbegin(), is_lhs, for_debug); for (auto it = sig.chunks().rbegin() + 1; it != sig.chunks().rend(); ++it) { f << ".concat("; - dump_sigchunk(*it, is_lhs); + dump_sigchunk(*it, is_lhs, for_debug); f << ")"; } return true; } } - void dump_sigspec_lhs(const RTLIL::SigSpec &sig) + void dump_sigspec_lhs(const RTLIL::SigSpec &sig, bool for_debug = false) { - dump_sigspec(sig, /*is_lhs=*/true); + dump_sigspec(sig, /*is_lhs=*/true, for_debug); } - void dump_sigspec_rhs(const RTLIL::SigSpec &sig) + void dump_sigspec_rhs(const RTLIL::SigSpec &sig, bool for_debug = false) { // In the contexts where we want template argument deduction to occur for `template ... value`, // it is necessary to have the argument to already be a `value`, since template argument deduction and implicit // type conversion are mutually exclusive. In these contexts, we use dump_sigspec_rhs() to emit an explicit // type conversion, but only if the expression needs it. - bool is_complex = dump_sigspec(sig, /*is_lhs=*/false); + bool is_complex = dump_sigspec(sig, /*is_lhs=*/false, for_debug); if (is_complex) f << ".val()"; } @@ -875,9 +877,9 @@ struct CxxrtlWorker { } } - void dump_connect_expr(const RTLIL::SigSig &conn) + void dump_connect_expr(const RTLIL::SigSig &conn, bool for_debug = false) { - dump_sigspec_rhs(conn.second); + dump_sigspec_rhs(conn.second, for_debug); } bool is_connect_inlined(const RTLIL::SigSig &conn) @@ -885,6 +887,14 @@ struct CxxrtlWorker { return conn.first.is_wire() && inlined_wires.count(conn.first.as_wire()); } + bool is_connect_outlined(const RTLIL::SigSig &conn) + { + for (auto chunk : conn.first.chunks()) + if (debug_outlined_wires.count(chunk.wire)) + return true; + return false; + } + void collect_connect(const RTLIL::SigSig &conn, std::vector &cells) { if (!is_connect_inlined(conn)) @@ -893,16 +903,18 @@ struct CxxrtlWorker { collect_sigspec_rhs(conn.second, cells); } - void dump_connect(const RTLIL::SigSig &conn) + void dump_connect(const RTLIL::SigSig &conn, bool for_debug = false) { - if (is_connect_inlined(conn)) + if (!for_debug && is_connect_inlined(conn)) + return; + if (for_debug && !is_connect_outlined(conn)) return; f << indent << "// connection\n"; f << indent; - dump_sigspec_lhs(conn.first); + dump_sigspec_lhs(conn.first, for_debug); f << " = "; - dump_connect_expr(conn); + dump_connect_expr(conn, for_debug); f << ";\n"; } @@ -919,7 +931,7 @@ struct CxxrtlWorker { } } - void dump_cell_expr(const RTLIL::Cell *cell) + void dump_cell_expr(const RTLIL::Cell *cell, bool for_debug = false) { // Unary cells if (is_unary_cell(cell->type)) { @@ -927,7 +939,7 @@ struct CxxrtlWorker { if (is_extending_cell(cell->type)) f << '_' << (cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u'); f << "<" << cell->getParam(ID::Y_WIDTH).as_int() << ">("; - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); f << ")"; // Binary cells } else if (is_binary_cell(cell->type)) { @@ -936,18 +948,18 @@ struct CxxrtlWorker { f << '_' << (cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u') << (cell->getParam(ID::B_SIGNED).as_bool() ? 's' : 'u'); f << "<" << cell->getParam(ID::Y_WIDTH).as_int() << ">("; - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); f << ", "; - dump_sigspec_rhs(cell->getPort(ID::B)); + dump_sigspec_rhs(cell->getPort(ID::B), for_debug); f << ")"; // Muxes } else if (cell->type == ID($mux)) { f << "("; - dump_sigspec_rhs(cell->getPort(ID::S)); + dump_sigspec_rhs(cell->getPort(ID::S), for_debug); f << " ? "; - dump_sigspec_rhs(cell->getPort(ID::B)); + dump_sigspec_rhs(cell->getPort(ID::B), for_debug); f << " : "; - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); f << ")"; // Parallel (one-hot) muxes } else if (cell->type == ID($pmux)) { @@ -955,24 +967,24 @@ struct CxxrtlWorker { int s_width = cell->getParam(ID::S_WIDTH).as_int(); for (int part = 0; part < s_width; part++) { f << "("; - dump_sigspec_rhs(cell->getPort(ID::S).extract(part)); + dump_sigspec_rhs(cell->getPort(ID::S).extract(part), for_debug); f << " ? "; - dump_sigspec_rhs(cell->getPort(ID::B).extract(part * width, width)); + dump_sigspec_rhs(cell->getPort(ID::B).extract(part * width, width), for_debug); f << " : "; } - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); for (int part = 0; part < s_width; part++) { f << ")"; } // Concats } else if (cell->type == ID($concat)) { - dump_sigspec_rhs(cell->getPort(ID::B)); + dump_sigspec_rhs(cell->getPort(ID::B), for_debug); f << ".concat("; - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); f << ").val()"; // Slices } else if (cell->type == ID($slice)) { - dump_sigspec_rhs(cell->getPort(ID::A)); + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); f << ".slice<"; f << cell->getParam(ID::OFFSET).as_int() + cell->getParam(ID::Y_WIDTH).as_int() - 1; f << ","; @@ -989,6 +1001,17 @@ struct CxxrtlWorker { inlined_wires.count(cell->getPort(ID::Y).as_wire()); } + bool is_cell_outlined(const RTLIL::Cell *cell) + { + if (is_internal_cell(cell->type)) + for (auto conn : cell->connections()) + if (cell->output(conn.first)) + for (auto chunk : conn.second.chunks()) + if (debug_outlined_wires.count(chunk.wire)) + return true; + return false; + } + void collect_cell_eval(const RTLIL::Cell *cell, std::vector &cells) { if (!is_cell_inlined(cell)) @@ -1000,9 +1023,11 @@ struct CxxrtlWorker { collect_sigspec_rhs(port.second, cells); } - void dump_cell_eval(const RTLIL::Cell *cell) + void dump_cell_eval(const RTLIL::Cell *cell, bool for_debug = false) { - if (is_cell_inlined(cell)) + if (!for_debug && is_cell_inlined(cell)) + return; + if (for_debug && !is_cell_outlined(cell)) return; if (cell->type == ID($meminit)) return; // Handled elsewhere. @@ -1026,9 +1051,9 @@ struct CxxrtlWorker { // Elidable cells if (is_inlinable_cell(cell->type)) { f << indent; - dump_sigspec_lhs(cell->getPort(ID::Y)); + dump_sigspec_lhs(cell->getPort(ID::Y), for_debug); f << " = "; - dump_cell_expr(cell); + dump_cell_expr(cell, for_debug); f << ";\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { @@ -1460,14 +1485,11 @@ struct CxxrtlWorker { void dump_wire(const RTLIL::Wire *wire, bool is_local) { - if (inlined_wires.count(wire)) - return; - - if (localized_wires[wire] && is_local) { + if (is_local && localized_wires[wire] && !inlined_wires.count(wire)) { dump_attrs(wire); f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; } - if (!localized_wires[wire] && !is_local) { + if (!is_local && !localized_wires[wire]) { std::string width; if (wire->module->has_attribute(ID(cxxrtl_blackbox)) && wire->has_attribute(ID(cxxrtl_width))) { width = wire->get_string_attribute(ID(cxxrtl_width)); @@ -1530,6 +1552,23 @@ struct CxxrtlWorker { } } + void dump_debug_wire(const RTLIL::Wire *wire, bool is_local) + { + if (!debug_outlined_wires[wire]) + return; + + bool is_outlined_member = wire->name.isPublic() && + !(debug_const_wires.count(wire) || debug_alias_wires.count(wire)); + if (is_local && !is_outlined_member) { + dump_attrs(wire); + f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; + } + if (!is_local && is_outlined_member) { + dump_attrs(wire); + f << indent << "/*outline*/ value<" << wire->width << "> " << mangle(wire) << ";\n"; + } + } + void dump_memory(RTLIL::Module *module, const RTLIL::Memory *memory) { vector init_cells; @@ -1619,6 +1658,27 @@ struct CxxrtlWorker { dec_indent(); } + void dump_debug_eval_method(RTLIL::Module *module) + { + inc_indent(); + for (auto wire : module->wires()) + dump_debug_wire(wire, /*is_local=*/true); + for (auto node : schedule[module]) { + switch (node.type) { + case FlowGraph::Node::Type::CONNECT: + dump_connect(node.connect, /*for_debug=*/true); + break; + case FlowGraph::Node::Type::CELL_EVAL: + dump_cell_eval(node.cell, /*for_debug=*/true); + break; + case FlowGraph::Node::Type::CELL_SYNC: + case FlowGraph::Node::Type::PROCESS: + break; + } + } + dec_indent(); + } + void dump_commit_method(RTLIL::Module *module) { inc_indent(); @@ -1656,6 +1716,7 @@ struct CxxrtlWorker { size_t count_public_wires = 0; size_t count_const_wires = 0; size_t count_alias_wires = 0; + size_t count_inline_wires = 0; size_t count_member_wires = 0; size_t count_skipped_wires = 0; size_t count_driven_sync = 0; @@ -1685,6 +1746,12 @@ struct CxxrtlWorker { f << ", debug_item(debug_alias(), " << mangle(debug_alias_wires[wire]) << ", "; f << wire->start_offset << "));\n"; count_alias_wires++; + } else if (debug_outlined_wires.count(wire)) { + // Inlined but rematerializable wire + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(debug_eval_outline, " << mangle(wire) << ", "; + f << wire->start_offset << "));\n"; + count_inline_wires++; } else if (!localized_wires.count(wire)) { // Member wire std::vector flags; @@ -1738,6 +1805,7 @@ struct CxxrtlWorker { f << "));\n"; count_member_wires++; } else { + // Localized or inlined wire with no debug information count_skipped_wires++; } } @@ -1761,14 +1829,16 @@ struct CxxrtlWorker { log_debug("Debug information statistics for module `%s':\n", log_id(module)); log_debug(" Public wires: %zu, of which:\n", count_public_wires); - log_debug(" Const wires: %zu\n", count_const_wires); - log_debug(" Alias wires: %zu\n", count_alias_wires); log_debug(" Member wires: %zu, of which:\n", count_member_wires); log_debug(" Driven sync: %zu\n", count_driven_sync); log_debug(" Driven comb: %zu\n", count_driven_comb); - log_debug(" Undriven: %zu\n", count_undriven); log_debug(" Mixed driver: %zu\n", count_mixed_driver); - log_debug(" Other wires: %zu (no debug information)\n", count_skipped_wires); + log_debug(" Undriven: %zu\n", count_undriven); + log_debug(" Inline wires: %zu\n", count_inline_wires); + log_debug(" Alias wires: %zu\n", count_alias_wires); + log_debug(" Const wires: %zu\n", count_const_wires); + log_debug(" Other wires: %zu%s\n", count_skipped_wires, + count_skipped_wires > 0 ? " (debug information unavailable)" : ""); } void dump_metadata_map(const dict &metadata_map) @@ -1855,7 +1925,8 @@ struct CxxrtlWorker { inc_indent(); for (auto wire : module->wires()) dump_wire(wire, /*is_local=*/false); - f << "\n"; + for (auto wire : module->wires()) + dump_debug_wire(wire, /*is_local=*/false); bool has_memories = false; for (auto memory : module->memories) { dump_memory(module, memory.second); @@ -1927,8 +1998,20 @@ struct CxxrtlWorker { f << "\n"; f << indent << "bool eval() override;\n"; f << indent << "bool commit() override;\n"; - if (debug_info) + if (debug_info) { + if (debug_eval) { + f << "\n"; + f << indent << "void debug_eval();\n"; + for (auto wire : module->wires()) + if (debug_outlined_wires.count(wire)) { + f << indent << "debug_outline debug_eval_outline { std::bind(&" + << mangle(module) << "::debug_eval, this) };\n"; + break; + } + } + f << "\n"; f << indent << "void debug_info(debug_items &items, std::string path = \"\") override;\n"; + } dec_indent(); f << indent << "}; // struct " << mangle(module) << "\n"; f << "\n"; @@ -1948,6 +2031,12 @@ struct CxxrtlWorker { f << indent << "}\n"; f << "\n"; if (debug_info) { + if (debug_eval) { + f << indent << "void " << mangle(module) << "::debug_eval() {\n"; + dump_debug_eval_method(module); + f << indent << "}\n"; + f << "\n"; + } f << indent << "void " << mangle(module) << "::debug_info(debug_items &items, std::string path) {\n"; dump_debug_info_method(module); f << indent << "}\n"; @@ -2251,6 +2340,11 @@ struct CxxrtlWorker { for (auto node : wire_comb_def.second) node_defs[node].insert(wire_comb_def.first); + dict, hash_ptr_ops> node_uses; + for (auto wire_use : flow.wire_uses) + for (auto node : wire_use.second) + node_uses[node].insert(wire_use.first); + Scheduler scheduler; dict::Vertex*, hash_ptr_ops> node_map; for (auto node : flow.nodes) @@ -2368,6 +2462,30 @@ struct CxxrtlWorker { } } } + if (debug_info && debug_eval) { + // Find wires that can be be outlined, i.e. whose values can be always recovered from + // the values of other wires. (This is the inverse of inlining--any wire that can be + // inlined can also be outlined.) Although this may seem strictly less efficient, since + // such values are computed at least twice, second-order effects make outlining useful. + pool worklist, visited; + for (auto wire : module->wires()) { + if (!wire->name.isPublic()) + continue; // only outline public wires + worklist.insert(wire); + } + while (!worklist.empty()) { + const RTLIL::Wire *wire = worklist.pop(); + visited.insert(wire); + if (!localized_wires.count(wire) && !inlined_wires.count(wire)) + continue; // member wire, doesn't need outlining + if (wire->name.isPublic() || !inlined_wires.count(wire)) + debug_outlined_wires.insert(wire); // allow outlining of internal wires only + for (auto node : flow.wire_comb_defs[wire]) + for (auto node_use : node_uses[node]) + if (!visited.count(node_use)) + worklist.insert(node_use); + } + } } if (has_feedback_arcs || has_buffered_comb_wires) { // Although both non-feedback buffered combinatorial wires and apparent feedback wires may be eliminated @@ -2457,8 +2575,7 @@ struct CxxrtlWorker { struct CxxrtlBackend : public Backend { static const int DEFAULT_OPT_LEVEL = 6; - static const int OPT_LEVEL_DEBUG = 4; - static const int DEFAULT_DEBUG_LEVEL = 1; + static const int DEFAULT_DEBUG_LEVEL = 2; CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { } void help() override @@ -2671,10 +2788,6 @@ struct CxxrtlBackend : public Backend { log(" -O6\n"); log(" like -O5, and inline public wires not marked (*keep*) if possible.\n"); log("\n"); - log(" -Og\n"); - log(" highest optimization level that provides debug information for all\n"); - log(" public wires. currently, alias for -O%d.\n", OPT_LEVEL_DEBUG); - log("\n"); log(" -g \n"); log(" set the debug level. the default is -g%d. higher debug levels provide\n", DEFAULT_DEBUG_LEVEL); log(" more visibility and generate more code, but do not pessimize evaluation.\n"); @@ -2686,6 +2799,10 @@ struct CxxrtlBackend : public Backend { log(" debug information for non-optimized public wires. this also makes it\n"); log(" possible to use the C API.\n"); log("\n"); + log(" -g2\n"); + log(" like -g1, and compute debug information on demand for all public wires\n"); + log(" that were optimized out.\n"); + log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override @@ -2715,12 +2832,14 @@ struct CxxrtlBackend : public Backend { continue; } if (args[argidx] == "-Og") { - opt_level = OPT_LEVEL_DEBUG; + log_warning("The `-Og` option has been removed. Use `-g2` instead for complete " + "design coverage regardless of optimization level.\n"); continue; } if (args[argidx] == "-O" && argidx+1 < args.size() && args[argidx+1] == "g") { argidx++; - opt_level = OPT_LEVEL_DEBUG; + log_warning("The `-Og` option has been removed. Use `-g2` instead for complete " + "design coverage regardless of optimization level.\n"); continue; } if (args[argidx] == "-O" && argidx+1 < args.size()) { @@ -2781,6 +2900,9 @@ struct CxxrtlBackend : public Backend { } switch (debug_level) { // the highest level here must match DEFAULT_DEBUG_LEVEL + case 2: + worker.debug_eval = true; + YS_FALLTHROUGH case 1: worker.debug_info = true; YS_FALLTHROUGH diff --git a/backends/cxxrtl/cxxrtl_capi.cc b/backends/cxxrtl/cxxrtl_capi.cc index f92709b4696..227173ba87f 100644 --- a/backends/cxxrtl/cxxrtl_capi.cc +++ b/backends/cxxrtl/cxxrtl_capi.cc @@ -86,3 +86,7 @@ void cxxrtl_enum(cxxrtl_handle handle, void *data, for (auto &it : handle->objects.table) callback(data, it.first.c_str(), static_cast(&it.second[0]), it.second.size()); } + +void cxxrtl_outline_eval(cxxrtl_outline outline) { + outline->eval(); +} diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index d67c58f94d1..7d9c60ac590 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -128,6 +128,18 @@ enum cxxrtl_type { // pointer is always NULL. CXXRTL_ALIAS = 3, + // Outlines correspond to netlist nodes that were optimized in a way that makes them inaccessible + // outside of a module's `eval()` function. At the highest debug information level, every inlined + // node has a corresponding outline object. + // + // Outlines can be inspected via the `curr` pointer and can never be modified; the `next` pointer + // is always NULL. Unlike all other objects, the bits of an outline object are meaningful only + // after a call to `cxxrtl_outline_eval` and until any subsequent modification to the netlist. + // Observing this requirement is the responsibility of the caller; it is not enforced. + // + // Outlines always correspond to combinatorial netlist nodes that are not ports. + CXXRTL_OUTLINE = 4, + // More object types may be added in the future, but the existing ones will never change. }; @@ -171,8 +183,8 @@ enum cxxrtl_flag { // Node has bits that are driven by a combinatorial cell or another node. // - // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined - // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags. + // This flag can be set on objects of type `CXXRTL_VALUE`, `CXXRTL_WIRE`, and `CXXRTL_OUTLINE`. + // It may be combined with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags. // // This flag is set on objects that have bits connected to the output of a combinatorial cell, // or directly to another node. For designs without combinatorial loops, writing to such bits @@ -193,8 +205,8 @@ enum cxxrtl_flag { // Description of a simulated object. // -// The `data` array can be accessed directly to inspect and, if applicable, modify the bits -// stored in the object. +// The `curr` and `next` arrays can be accessed directly to inspect and, if applicable, modify +// the bits stored in the object. struct cxxrtl_object { // Type of the object. // @@ -231,6 +243,12 @@ struct cxxrtl_object { uint32_t *curr; uint32_t *next; + // Opaque reference to an outline. Only meaningful for outline objects. + // + // See the documentation of `cxxrtl_outline` for details. When creating a `cxxrtl_object`, set + // this field to NULL. + struct _cxxrtl_outline *outline; + // More description fields may be added in the future, but the existing ones will never change. }; @@ -272,6 +290,20 @@ void cxxrtl_enum(cxxrtl_handle handle, void *data, void (*callback)(void *data, const char *name, struct cxxrtl_object *object, size_t parts)); +// Opaque reference to an outline. +// +// An outline is a group of outline objects that are evaluated simultaneously. The identity of +// an outline can be compared to determine whether any two objects belong to the same outline. +typedef struct _cxxrtl_outline *cxxrtl_outline; + +// Evaluate an outline. +// +// After evaluating an outline, the bits of every outline object contained in it are consistent +// with the current state of the netlist. In general, any further modification to the netlist +// causes every outline object to become stale, after which the corresponding outline must be +// re-evaluated, otherwise the bits read from that object are meaningless. +void cxxrtl_outline_eval(cxxrtl_outline outline); + #ifdef __cplusplus } #endif diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index dbeabbaf2d8..6ee98b4284d 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -28,10 +28,13 @@ class vcd_writer { size_t ident; size_t width; chunk_t *curr; - size_t prev_off; + size_t cache_offset; + debug_outline *outline; + bool *outline_warm; }; std::vector current_scope; + std::map outlines; std::vector variables; std::vector cache; std::map aliases; @@ -112,16 +115,22 @@ class vcd_writer { buffer += '\n'; } - const variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false) { + void reset_outlines() { + for (auto &outline_it : outlines) + outline_it.second = /*warm=*/(outline_it.first == nullptr); + } + + variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false, debug_outline *outline = nullptr) { if (aliases.count(curr)) { return variables[aliases[curr]]; } else { + auto outline_it = outlines.emplace(outline, /*warm=*/(outline == nullptr)).first; const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); aliases[curr] = variables.size(); if (constant) { - variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1 }); + variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1, outline_it->first, &outline_it->second }); } else { - variables.emplace_back(variable { variables.size(), width, curr, cache.size() }); + variables.emplace_back(variable { variables.size(), width, curr, cache.size(), outline_it->first, &outline_it->second }); cache.insert(cache.end(), &curr[0], &curr[chunks]); } return variables.back(); @@ -129,13 +138,17 @@ class vcd_writer { } bool test_variable(const variable &var) { - if (var.prev_off == (size_t)-1) + if (var.cache_offset == (size_t)-1) return false; // constant + if (!*var.outline_warm) { + var.outline->eval(); + *var.outline_warm = true; + } const size_t chunks = (var.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); - if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.prev_off])) { + if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset])) { return false; } else { - std::copy(&var.curr[0], &var.curr[chunks], &cache[var.prev_off]); + std::copy(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset]); return true; } } @@ -197,6 +210,10 @@ class vcd_writer { emit_var(register_variable(item.width, item.curr), "wire", name, item.lsb_at, multipart); break; + case debug_item::OUTLINE: + emit_var(register_variable(item.width, item.curr, /*constant=*/false, item.outline), + "wire", name, item.lsb_at, multipart); + break; } } @@ -228,6 +245,7 @@ class vcd_writer { emit_scope({}); emit_enddefinitions(); } + reset_outlines(); emit_time(timestamp); for (auto var : variables) if (test_variable(var) || first_sample) { From dd6a761db04ca67205ad25d7f5dbb63daa8d9e9d Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 07:44:27 +0000 Subject: [PATCH 0081/2410] cxxrtl: add a "bare minimum" debug information level. Useful to reduce overhead when no debug capabilities are necessary except for access to design state. --- backends/cxxrtl/cxxrtl_backend.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 5e2f4f31a5c..588cca12e0e 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -539,6 +539,7 @@ struct CxxrtlWorker { bool inline_public = false; bool debug_info = false; + bool debug_alias = false; bool debug_eval = false; std::ostringstream f; @@ -2425,7 +2426,7 @@ struct CxxrtlWorker { for (auto item : flow.bit_has_state) bit_has_state.insert(item); - if (debug_info) { + if (debug_info && debug_alias) { // Find wires that alias other wires or are tied to a constant; debug information can be enriched with these // at essentially zero additional cost. // @@ -2575,7 +2576,7 @@ struct CxxrtlWorker { struct CxxrtlBackend : public Backend { static const int DEFAULT_OPT_LEVEL = 6; - static const int DEFAULT_DEBUG_LEVEL = 2; + static const int DEFAULT_DEBUG_LEVEL = 3; CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { } void help() override @@ -2793,14 +2794,18 @@ struct CxxrtlBackend : public Backend { log(" more visibility and generate more code, but do not pessimize evaluation.\n"); log("\n"); log(" -g0\n"); - log(" no debug information.\n"); + log(" no debug information. the C API is unavailable.\n"); log("\n"); log(" -g1\n"); - log(" debug information for non-optimized public wires. this also makes it\n"); - log(" possible to use the C API.\n"); + log(" debug information for member public wires only. this is the bare minimum\n"); + log(" necessary to access all design state. enables the C API.\n"); log("\n"); log(" -g2\n"); - log(" like -g1, and compute debug information on demand for all public wires\n"); + log(" like -g1, and include debug information for public wires that are tied\n"); + log(" to a constant or another public wire.\n"); + log("\n"); + log(" -g3\n"); + log(" like -g2, and compute debug information on demand for all public wires\n"); log(" that were optimized out.\n"); log("\n"); } @@ -2832,13 +2837,13 @@ struct CxxrtlBackend : public Backend { continue; } if (args[argidx] == "-Og") { - log_warning("The `-Og` option has been removed. Use `-g2` instead for complete " + log_warning("The `-Og` option has been removed. Use `-g3` instead for complete " "design coverage regardless of optimization level.\n"); continue; } if (args[argidx] == "-O" && argidx+1 < args.size() && args[argidx+1] == "g") { argidx++; - log_warning("The `-Og` option has been removed. Use `-g2` instead for complete " + log_warning("The `-Og` option has been removed. Use `-g3` instead for complete " "design coverage regardless of optimization level.\n"); continue; } @@ -2900,9 +2905,12 @@ struct CxxrtlBackend : public Backend { } switch (debug_level) { // the highest level here must match DEFAULT_DEBUG_LEVEL - case 2: + case 3: worker.debug_eval = true; YS_FALLTHROUGH + case 2: + worker.debug_alias = true; + YS_FALLTHROUGH case 1: worker.debug_info = true; YS_FALLTHROUGH From de991977385330dfd628f15440e90a607842fbc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 14 Dec 2020 18:14:42 +0100 Subject: [PATCH 0082/2410] timinginfo: Error instead of segfault on const signals. Reported by @Ravenslofty --- kernel/timinginfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h index d818e580b96..eba3386d6f2 100644 --- a/kernel/timinginfo.h +++ b/kernel/timinginfo.h @@ -88,10 +88,10 @@ struct TimingInfo auto src = cell->getPort(ID::SRC); auto dst = cell->getPort(ID::DST); for (const auto &c : src.chunks()) - if (!c.wire->port_input) + if (!c.wire || !c.wire->port_input) log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); for (const auto &c : dst.chunks()) - if (!c.wire->port_output) + if (!c.wire || !c.wire->port_output) log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst)); int rise_max = cell->getParam(ID::T_RISE_MAX).as_int(); int fall_max = cell->getParam(ID::T_FALL_MAX).as_int(); From 40e35993af6ecb6207f15cc176455ff8d66bcc69 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 15 Dec 2020 00:10:06 +0000 Subject: [PATCH 0083/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0de22cfc032..923e0605767 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3758 +YOSYS_VER := 0.9+3760 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4d40595d644cfe58425a3de023c712641c429010 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 15:33:47 +0000 Subject: [PATCH 0084/2410] cxxrtl: make alias analysis outlining-aware. Before this commit, if a sequence of wires assigned in a chain would terminate on a cell, none of the wires would get marked as aliases, and typically all of the public wires would get outlined. The reason for this behavior is that alias analysis predates outlining and in fact runs before it. After this commit, alias analysis runs after outlining and considers outlined wires valid aliasees. More importantly, if the chained wires contain any valid aliasees, then all of the wires are aliased to the one that is topologically deepest. Aliased wires incur virtually no overhead for the VCD writer, unlike outlined wires that would otherwise take their place. On Minerva SoC SRAM, size of the full VCD dump is reduced by ~65%, and throughput is increased by ~55%. --- backends/cxxrtl/cxxrtl_backend.cc | 86 +++++++++++++++++-------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 588cca12e0e..fa19a8dd612 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2426,43 +2426,6 @@ struct CxxrtlWorker { for (auto item : flow.bit_has_state) bit_has_state.insert(item); - if (debug_info && debug_alias) { - // Find wires that alias other wires or are tied to a constant; debug information can be enriched with these - // at essentially zero additional cost. - // - // Note that the information collected here can't be used for optimizing the netlist: debug information queries - // are pure and run on a design in a stable state, which allows assumptions that do not otherwise hold. - for (auto wire : module->wires()) { - if (!wire->name.isPublic()) - continue; - if (!unbuffered_wires[wire]) - continue; - const RTLIL::Wire *wire_it = wire; - while (1) { - if (!(flow.wire_def_inlinable.count(wire_it) && flow.wire_def_inlinable[wire_it])) - break; // not an alias: complex def - log_assert(flow.wire_comb_defs[wire_it].size() == 1); - FlowGraph::Node *node = *flow.wire_comb_defs[wire_it].begin(); - if (node->type != FlowGraph::Node::Type::CONNECT) - break; // not an alias: def by cell - RTLIL::SigSpec rhs_sig = node->connect.second; - if (rhs_sig.is_wire()) { - RTLIL::Wire *rhs_wire = rhs_sig.as_wire(); - if (unbuffered_wires[rhs_wire]) { - wire_it = rhs_wire; // maybe an alias - } else { - debug_alias_wires[wire] = rhs_wire; // is an alias - break; - } - } else if (rhs_sig.is_fully_const()) { - debug_const_wires[wire] = rhs_sig.as_const(); // is a const - break; - } else { - break; // not an alias: complex rhs - } - } - } - } if (debug_info && debug_eval) { // Find wires that can be be outlined, i.e. whose values can be always recovered from // the values of other wires. (This is the inverse of inlining--any wire that can be @@ -2471,7 +2434,7 @@ struct CxxrtlWorker { pool worklist, visited; for (auto wire : module->wires()) { if (!wire->name.isPublic()) - continue; // only outline public wires + continue; worklist.insert(wire); } while (!worklist.empty()) { @@ -2487,6 +2450,53 @@ struct CxxrtlWorker { worklist.insert(node_use); } } + if (debug_info && debug_alias) { + // Find wires that alias other wires or are tied to a constant. Both of these cases are + // directly expressible in the debug information, improving coverage at zero cost. + for (auto wire : module->wires()) { + if (!wire->name.isPublic()) + continue; + const RTLIL::Wire *cursor = wire; + RTLIL::SigSpec alias_of; + while (1) { + if (!(flow.wire_def_inlinable.count(cursor) && flow.wire_def_inlinable[cursor])) + break; // not an alias: complex def + log_assert(flow.wire_comb_defs[cursor].size() == 1); + FlowGraph::Node *node = *flow.wire_comb_defs[cursor].begin(); + if (node->type != FlowGraph::Node::Type::CONNECT) + break; // not an alias: def by cell + RTLIL::SigSpec rhs_sig = node->connect.second; + if (rhs_sig.is_fully_const()) { + alias_of = rhs_sig; // alias of const + break; + } else if (rhs_sig.is_wire()) { + RTLIL::Wire *rhs_wire = rhs_sig.as_wire(); // possible alias of wire + if (rhs_wire->port_input && !rhs_wire->port_output) { + alias_of = rhs_wire; // alias of input + break; + } else if (!localized_wires.count(rhs_wire) && !inlined_wires.count(rhs_wire)) { + alias_of = rhs_wire; // alias of member + break; + } else { + if (rhs_wire->name.isPublic() && debug_outlined_wires.count(rhs_wire)) + alias_of = rhs_wire; // alias of either outline or another alias + cursor = rhs_wire; // keep looking + } + } else { + break; // not an alias: complex rhs + } + } + if (alias_of.empty()) { + continue; + } else if (alias_of.is_fully_const()) { + debug_const_wires[wire] = alias_of.as_const(); + } else if (alias_of.is_wire()) { + debug_alias_wires[wire] = alias_of.as_wire(); + } else log_abort(); + if (inlined_wires.count(wire)) + debug_outlined_wires.erase(wire); + } + } } if (has_feedback_arcs || has_buffered_comb_wires) { // Although both non-feedback buffered combinatorial wires and apparent feedback wires may be eliminated From f75bc6c7aac92c7c1c8954ec7fe5325a94e6e491 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 13 Dec 2020 18:16:55 +0000 Subject: [PATCH 0085/2410] cxxrtl: disable optimization of debug_items(). Implementing outlining has greatly increased the amount of debug information in a typical build, and consequently exposed performance issues in C++ compilers, which are similar for both GCC and Clang; the compile time of Minerva SoC SRAM increased almost twofold. Although one would expect the slowdown to be caused by the increased use of templates in `debug_eval()`, it is actually almost entirely attributable to optimizations and codegen for `debug_items()`. Fortunately, it is neither possible nor desirable to optimize `debug_items()`: in most cases it is called exactly once, and its body is a linear sequence of calls with unique arguments. This commit turns off optimizations for `debug_items()` on GCC and Clang, improving -Os compile time of Minerva SoC SRAM by ~40% (!) --- backends/cxxrtl/cxxrtl.h | 17 ++++++++++++++--- backends/cxxrtl/cxxrtl_backend.cc | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 59393e415cf..3c315c7dffd 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -41,18 +41,29 @@ #include +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + // CXXRTL essentially uses the C++ compiler as a hygienic macro engine that feeds an instruction selector. // It generates a lot of specialized template functions with relatively large bodies that, when inlined // into the caller and (for those with loops) unrolled, often expose many new optimization opportunities. // Because of this, most of the CXXRTL runtime must be always inlined for best performance. -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif #if __has_attribute(always_inline) #define CXXRTL_ALWAYS_INLINE inline __attribute__((__always_inline__)) #else #define CXXRTL_ALWAYS_INLINE inline #endif +// Conversely, some functions in the generated code are extremely large yet very cold, with both of these +// properties being extreme enough to confuse C++ compilers into spending pathological amounts of time +// on a futile (the code becomes worse) attempt to optimize the least important parts of code. +#if __has_attribute(optnone) +#define CXXRTL_EXTREMELY_COLD __attribute__((__optnone__)) +#elif __has_attribute(optimize) +#define CXXRTL_EXTREMELY_COLD __attribute__((__optimize__(0))) +#else +#define CXXRTL_EXTREMELY_COLD +#endif // CXXRTL uses assert() to check for C++ contract violations (which may result in e.g. undefined behavior // of the simulation code itself), and CXXRTL_ASSERT to check for RTL contract violations (which may at diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index fa19a8dd612..7bf44626aa9 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2038,6 +2038,7 @@ struct CxxrtlWorker { f << indent << "}\n"; f << "\n"; } + f << indent << "CXXRTL_EXTREMELY_COLD\n"; f << indent << "void " << mangle(module) << "::debug_info(debug_items &items, std::string path) {\n"; dump_debug_info_method(module); f << indent << "}\n"; From d889a3df35e539b6dcfbee9c6a98461eca1a0b0e Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 15 Dec 2020 03:46:06 +0000 Subject: [PATCH 0086/2410] cxxrtl: print names of cells inlined in connections. --- backends/cxxrtl/cxxrtl_backend.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 7bf44626aa9..9875aba60a3 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -911,7 +911,16 @@ struct CxxrtlWorker { if (for_debug && !is_connect_outlined(conn)) return; - f << indent << "// connection\n"; + std::vector inlined_cells; + collect_sigspec_rhs(conn.second, inlined_cells); + if (for_debug || inlined_cells.empty()) { + f << indent << "// connection\n"; + } else { + f << indent << "// cells"; + for (auto inlined_cell : inlined_cells) + f << " " << inlined_cell.str(); + f << "\n"; + } f << indent; dump_sigspec_lhs(conn.first, for_debug); f << " = "; From 871fc34ad43dac0ff924b8f72a0524d937040190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 17 Dec 2020 00:24:48 +0100 Subject: [PATCH 0087/2410] xilinx: Add FDDRCPE and FDDRRSE blackbox cells. These are necessary primitives for proper DDR support on Virtex 2 and Spartan 3. --- techlibs/xilinx/cells_xtra.py | 5 +++++ techlibs/xilinx/cells_xtra.v | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index f086291ab2d..4eb8ddb1921 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -188,6 +188,11 @@ def __init__(self, name, keep=False, port_attrs={}): # I/O logic. # Virtex 2, Spartan 3. + # Note: these two are not officially listed in the HDL library guide, but + # they are more fundamental than OFDDR* and are necessary to construct + # differential DDR outputs (OFDDR* can only do single-ended). + Cell('FDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}), + Cell('FDDRRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}), Cell('IFDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}), Cell('IFDDRRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}), Cell('OFDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'Q': ['iopad_external_pin']}), diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 3021f6b5a0a..9a246c30887 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -5301,6 +5301,34 @@ module DSP48E2 (...); input RSTP; endmodule +module FDDRCPE (...); + parameter INIT = 1'b0; + (* clkbuf_sink *) + input C0; + (* clkbuf_sink *) + input C1; + input CE; + input D0; + input D1; + input CLR; + input PRE; + output Q; +endmodule + +module FDDRRSE (...); + parameter INIT = 1'b0; + output Q; + (* clkbuf_sink *) + input C0; + (* clkbuf_sink *) + input C1; + input CE; + input D0; + input D1; + input R; + input S; +endmodule + module IFDDRCPE (...); output Q0; output Q1; From eaf6b551b68f44bc31c2d4274c91944451b01649 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 18 Dec 2020 00:10:05 +0000 Subject: [PATCH 0088/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 923e0605767..0235775a423 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3760 +YOSYS_VER := 0.9+3762 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 0d8e5d965f2585e6ed151a9e92d83ee63df6172a Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 18 Dec 2020 12:59:08 -0700 Subject: [PATCH 0089/2410] Sign extend port connections where necessary - Signed cell outputs are sign extended when bound to larger wires - Signed connections are sign extended when bound to larger cell inputs - Sign extension is performed in hierarchy and flatten phases - genrtlil indirects signed constants through signed wires - Other phases producing RTLIL may need to be updated to preserve signedness information - Resolves #1418 - Resolves #2265 --- frontends/ast/genrtlil.cc | 26 ++++++++++- passes/hierarchy/hierarchy.cc | 8 +++- passes/techmap/flatten.cc | 5 +- tests/various/port_sign_extend.v | 76 +++++++++++++++++++++++++++++++ tests/various/port_sign_extend.ys | 22 +++++++++ 5 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 tests/various/port_sign_extend.v create mode 100644 tests/various/port_sign_extend.ys diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e878d0dd2ba..500ccf8c001 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -106,6 +106,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + wire->is_signed = that->is_signed; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -1721,8 +1722,29 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } if (child->type == AST_ARGUMENT) { RTLIL::SigSpec sig; - if (child->children.size() > 0) - sig = child->children[0]->genRTLIL(); + if (child->children.size() > 0) { + AstNode *arg = child->children[0]; + int local_width_hint = -1; + bool local_sign_hint = false; + // don't inadvertently attempt to detect the width of interfaces + if (arg->type != AST_IDENTIFIER || !arg->id2ast || arg->id2ast->type != AST_CELL) + arg->detectSignWidth(local_width_hint, local_sign_hint); + sig = arg->genRTLIL(local_width_hint, local_sign_hint); + log_assert(local_sign_hint == arg->is_signed); + if (sig.is_wire()) { + // if the resulting SigSpec is a wire, its + // signedness should match that of the AstNode + log_assert(arg->is_signed == sig.as_wire()->is_signed); + } else if (arg->is_signed) { + // non-trivial signed nodes are indirected through + // signed wires to enable sign extension + RTLIL::IdString wire_name = NEW_ID; + RTLIL::Wire *wire = current_module->addWire(wire_name, arg->bits.size()); + wire->is_signed = true; + current_module->connect(wire, sig); + sig = wire; + } + } if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 225e1feaeab..3372687e187 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1233,14 +1233,18 @@ struct HierarchyPass : public Pass { { int n = GetSize(conn.second) - GetSize(w); if (!w->port_input && w->port_output) - module->connect(sig.extract(GetSize(w), n), Const(0, n)); + { + RTLIL::SigSpec out = sig.extract(0, GetSize(w)); + out.extend_u0(GetSize(sig), w->is_signed); + module->connect(sig.extract(GetSize(w), n), out.extract(GetSize(w), n)); + } sig.remove(GetSize(w), n); } else { int n = GetSize(w) - GetSize(conn.second); if (w->port_input && !w->port_output) - sig.append(Const(0, n)); + sig.extend_u0(GetSize(w), sig.is_wire() && sig.as_wire()->is_signed); else sig.append(module->addWire(NEW_ID, n)); } diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 08978f44692..ec5f83fb03f 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -180,12 +180,15 @@ struct FlattenWorker RTLIL::Wire *tpl_wire = tpl->wire(port_name); RTLIL::SigSig new_conn; + bool is_signed = false; if (tpl_wire->port_output && !tpl_wire->port_input) { new_conn.first = port_it.second; new_conn.second = tpl_wire; + is_signed = tpl_wire->is_signed; } else if (!tpl_wire->port_output && tpl_wire->port_input) { new_conn.first = tpl_wire; new_conn.second = port_it.second; + is_signed = new_conn.second.is_wire() && new_conn.second.as_wire()->is_signed; } else { SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second; for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { @@ -204,7 +207,7 @@ struct FlattenWorker if (new_conn.second.size() > new_conn.first.size()) new_conn.second.remove(new_conn.first.size(), new_conn.second.size() - new_conn.first.size()); if (new_conn.second.size() < new_conn.first.size()) - new_conn.second.append(RTLIL::SigSpec(RTLIL::State::S0, new_conn.first.size() - new_conn.second.size())); + new_conn.second.extend_u0(new_conn.first.size(), is_signed); log_assert(new_conn.first.size() == new_conn.second.size()); if (sigmap(new_conn.first).has_const()) diff --git a/tests/various/port_sign_extend.v b/tests/various/port_sign_extend.v new file mode 100644 index 00000000000..055f20ad8a0 --- /dev/null +++ b/tests/various/port_sign_extend.v @@ -0,0 +1,76 @@ +module GeneratorSigned1(out); + output wire signed out; + assign out = 1; +endmodule + +module GeneratorUnsigned1(out); + output wire out; + assign out = 1; +endmodule + +module GeneratorSigned2(out); + output wire signed [1:0] out; + assign out = 2; +endmodule + +module GeneratorUnsigned2(out); + output wire [1:0] out; + assign out = 2; +endmodule + +module PassThrough(a, b); + input wire [3:0] a; + output wire [3:0] b; + assign b = a; +endmodule + +module act(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5; + + // unsigned constant + PassThrough pt1(1'b1, o1); + + // unsigned wire + wire tmp2; + assign tmp2 = 1'sb1; + PassThrough pt2(tmp2, o2); + + // signed constant + PassThrough pt3(1'sb1, o3); + + // signed wire + wire signed tmp4; + assign tmp4 = 1'sb1; + PassThrough pt4(tmp4, o4); + + // signed expressions + wire signed [1:0] tmp5a = 2'b11; + wire signed [1:0] tmp5b = 2'b01; + PassThrough pt5(tmp5a ^ tmp5b, o5); + + output wire [2:0] yay1, nay1; + GeneratorSigned1 os1(yay1); + GeneratorUnsigned1 ou1(nay1); + + output wire [2:0] yay2, nay2; + GeneratorSigned2 os2(yay2); + GeneratorUnsigned2 ou2(nay2); +endmodule + +module ref(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5; + + assign o1 = 4'b0001; + assign o2 = 4'b0001; + assign o3 = 4'b1111; + assign o4 = 4'b1111; + assign o5 = 4'b1110; + + output wire [2:0] yay1, nay1; + assign yay1 = 3'b111; + assign nay1 = 3'b001; + + output wire [2:0] yay2, nay2; + assign yay2 = 3'b110; + assign nay2 = 3'b010; +endmodule diff --git a/tests/various/port_sign_extend.ys b/tests/various/port_sign_extend.ys new file mode 100644 index 00000000000..0a6a9381038 --- /dev/null +++ b/tests/various/port_sign_extend.ys @@ -0,0 +1,22 @@ +read_verilog port_sign_extend.v +hierarchy +flatten +equiv_make ref act equiv +equiv_simple +equiv_status -assert + +delete + +read_verilog port_sign_extend.v +flatten +equiv_make ref act equiv +equiv_simple +equiv_status -assert + +delete + +read_verilog port_sign_extend.v +hierarchy +equiv_make ref act equiv +prep -flatten -top equiv +equiv_status -assert From b90d51e35ddcb4b25814acac9bf6e09b4478b6ef Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sun, 20 Dec 2020 00:10:10 +0000 Subject: [PATCH 0090/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0235775a423..c1c112ec9d6 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3762 +YOSYS_VER := 0.9+3773 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 3d3ea5099d50a3de7b76ea47189b5700956b2703 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 20 Dec 2020 14:48:16 +0000 Subject: [PATCH 0091/2410] cxxrtl: use `static inline` instead of `inline` in the C API. In C, non-static inline functions require an implementation elsewhere (even though the body is right there in the header). It is basically never desirable to use those as opposed to static inline ones. --- backends/cxxrtl/cxxrtl_capi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index 7d9c60ac590..2df2b7287f4 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -272,7 +272,7 @@ struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, s // This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that, // if the object exists, it consists of a single part. If assertions are disabled, it returns NULL // for multi-part objects. -inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) { +static inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) { size_t parts = 0; struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts); assert(object == NULL || parts == 1); From 40ca9d038b1e657b9b9ac17e7e5a2969c9922e00 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 00:22:50 +0000 Subject: [PATCH 0092/2410] cxxrtl: speed up commits on clang. On Minerva SoC SRAM compiled with clang-11, this change cuts commit time in half (!) and overall time by 20%. When compiled with gcc-10, there is no difference. --- backends/cxxrtl/cxxrtl_backend.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 9875aba60a3..3b2fb498562 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1702,19 +1702,19 @@ struct CxxrtlWorker { continue; } if (!module->get_bool_attribute(ID(cxxrtl_blackbox)) || wire->port_id != 0) - f << indent << "changed |= " << mangle(wire) << ".commit();\n"; + f << indent << "if (" << mangle(wire) << ".commit()) changed = true;\n"; } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto memory : module->memories) { if (!writable_memories[memory.second]) continue; - f << indent << "changed |= " << mangle(memory.second) << ".commit();\n"; + f << indent << "if (" << mangle(memory.second) << ".commit()) changed = true;\n"; } for (auto cell : module->cells()) { if (is_internal_cell(cell->type)) continue; const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; - f << indent << "changed |= " << mangle(cell) << access << "commit();\n"; + f << indent << "if (" << mangle(cell) << access << "commit()) changed = true;\n"; } } f << indent << "return changed;\n"; From b9721bedf01ca1f536bbf13ba761333c6867bd29 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 02:15:55 +0000 Subject: [PATCH 0093/2410] cxxrtl: speed up bit repeats (sign extends, etc). On Minerva SoC SRAM, depending on the compiler, this change improves overall time by 4-7%. --- backends/cxxrtl/cxxrtl.h | 8 ++++++++ backends/cxxrtl/cxxrtl_backend.cc | 25 ++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 3c315c7dffd..0a6bcb84940 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -317,6 +317,14 @@ struct value : public expr_base> { return sext_cast()(*this); } + // Bit replication is far more efficient than the equivalent concatenation. + template + CXXRTL_ALWAYS_INLINE + value repeat() const { + static_assert(Bits == 1, "repeat() is implemented only for 1-bit values"); + return *this ? value().bit_not() : value(); + } + // Operations with run-time parameters (offsets, amounts, etc). // // These operations are used for computations. diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 3b2fb498562..916303bfe49 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -832,11 +832,26 @@ struct CxxrtlWorker { } else if (sig.is_chunk()) { return dump_sigchunk(sig.as_chunk(), is_lhs, for_debug); } else { - dump_sigchunk(*sig.chunks().rbegin(), is_lhs, for_debug); - for (auto it = sig.chunks().rbegin() + 1; it != sig.chunks().rend(); ++it) { - f << ".concat("; - dump_sigchunk(*it, is_lhs, for_debug); - f << ")"; + bool first = true; + auto chunks = sig.chunks(); + for (auto it = chunks.rbegin(); it != chunks.rend(); it++) { + if (!first) + f << ".concat("; + bool is_complex = dump_sigchunk(*it, is_lhs, for_debug); + if (!is_lhs && it->width == 1) { + size_t repeat = 1; + while ((it + repeat) != chunks.rend() && *(it + repeat) == *it) + repeat++; + if (repeat > 1) { + if (is_complex) + f << ".val()"; + f << ".repeat<" << repeat << ">()"; + } + it += repeat - 1; + } + if (!first) + f << ")"; + first = false; } return true; } From 5ffb676fa9505f6be846cb5bcf99bfeb628337f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 18 Dec 2020 20:51:26 +0100 Subject: [PATCH 0094/2410] xilinx: Regenerate cells_xtra.v using Vivado 2020.2 --- techlibs/xilinx/cells_xtra.py | 1 + techlibs/xilinx/cells_xtra.v | 90 +++++++++++++++++++---------------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index 4eb8ddb1921..c7ffb94cf6d 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -664,6 +664,7 @@ def xtract_cell_decl(cell, dirs, outf): dirs = [ os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'), + os.path.join(args.vivado_dir, 'data/verilog/src/unisims'), os.path.join(args.vivado_dir, 'data/verilog/src/retarget'), os.path.join(args.ise_dir, 'ISE_DS/ISE/verilog/xeclib/unisims'), ] diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 9a246c30887..1fb340fc01d 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -6252,6 +6252,7 @@ module ODDRE1 (...); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D1_INVERTED = 1'b0; parameter [0:0] IS_D2_INVERTED = 1'b0; + parameter SIM_DEVICE = "ULTRASCALE"; parameter [0:0] SRVAL = 1'b0; output Q; (* clkbuf_sink *) @@ -7284,6 +7285,8 @@ module BUFGCE (...); parameter CE_TYPE = "SYNC"; parameter [0:0] IS_CE_INVERTED = 1'b0; parameter [0:0] IS_I_INVERTED = 1'b0; + parameter SIM_DEVICE = "ULTRASCALE"; + parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) output O; (* invertible_pin = "IS_CE_INVERTED" *) @@ -7334,6 +7337,8 @@ module BUFGMUX_VIRTEX4 (...); endmodule module BUFG_GT (...); + parameter SIM_DEVICE = "ULTRASCALE"; + parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) output O; input CE; @@ -7353,6 +7358,8 @@ module BUFG_GT_SYNC (...); endmodule module BUFG_PS (...); + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) output O; input I; @@ -7360,9 +7367,13 @@ endmodule module BUFGCE_DIV (...); parameter integer BUFGCE_DIVIDE = 1; + parameter CE_TYPE = "SYNC"; + parameter HARDSYNC_CLR = "FALSE"; parameter [0:0] IS_CE_INVERTED = 1'b0; parameter [0:0] IS_CLR_INVERTED = 1'b0; parameter [0:0] IS_I_INVERTED = 1'b0; + parameter SIM_DEVICE = "ULTRASCALE"; + parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) output O; (* invertible_pin = "IS_CE_INVERTED" *) @@ -7959,14 +7970,18 @@ module MMCM_BASE (...); endmodule module MMCME2_ADV (...); + parameter real CLKIN_FREQ_MAX = 1066.000; + parameter real CLKIN_FREQ_MIN = 10.000; + parameter real CLKPFD_FREQ_MAX = 550.000; + parameter real CLKPFD_FREQ_MIN = 10.000; + parameter real VCOCLK_FREQ_MAX = 1600.000; + parameter real VCOCLK_FREQ_MIN = 600.000; parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; parameter CLKFBOUT_USE_FINE_PS = "FALSE"; parameter real CLKIN1_PERIOD = 0.000; parameter real CLKIN2_PERIOD = 0.000; - parameter real CLKIN_FREQ_MAX = 1066.000; - parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKOUT0_DIVIDE_F = 1.000; parameter real CLKOUT0_DUTY_CYCLE = 0.500; parameter real CLKOUT0_PHASE = 0.000; @@ -7996,8 +8011,6 @@ module MMCME2_ADV (...); parameter real CLKOUT6_DUTY_CYCLE = 0.500; parameter real CLKOUT6_PHASE = 0.000; parameter CLKOUT6_USE_FINE_PS = "FALSE"; - parameter real CLKPFD_FREQ_MAX = 550.000; - parameter real CLKPFD_FREQ_MIN = 10.000; parameter COMPENSATION = "ZHOLD"; parameter integer DIVCLK_DIVIDE = 1; parameter [0:0] IS_CLKINSEL_INVERTED = 1'b0; @@ -8011,9 +8024,6 @@ module MMCME2_ADV (...); parameter SS_MODE = "CENTER_HIGH"; parameter integer SS_MOD_PERIOD = 10000; parameter STARTUP_WAIT = "FALSE"; - parameter real VCOCLK_FREQ_MAX = 1600.000; - parameter real VCOCLK_FREQ_MIN = 600.000; - parameter STARTUP_WAIT = "FALSE"; output CLKFBOUT; output CLKFBOUTB; output CLKFBSTOPPED; @@ -8209,14 +8219,18 @@ module PLLE2_BASE (...); endmodule module MMCME3_ADV (...); + parameter real CLKIN_FREQ_MAX = 1066.000; + parameter real CLKIN_FREQ_MIN = 10.000; + parameter real CLKPFD_FREQ_MAX = 550.000; + parameter real CLKPFD_FREQ_MIN = 10.000; + parameter real VCOCLK_FREQ_MAX = 1600.000; + parameter real VCOCLK_FREQ_MIN = 600.000; parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; parameter CLKFBOUT_USE_FINE_PS = "FALSE"; parameter real CLKIN1_PERIOD = 0.000; parameter real CLKIN2_PERIOD = 0.000; - parameter real CLKIN_FREQ_MAX = 1066.000; - parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKOUT0_DIVIDE_F = 1.000; parameter real CLKOUT0_DUTY_CYCLE = 0.500; parameter real CLKOUT0_PHASE = 0.000; @@ -8246,8 +8260,6 @@ module MMCME3_ADV (...); parameter real CLKOUT6_DUTY_CYCLE = 0.500; parameter real CLKOUT6_PHASE = 0.000; parameter CLKOUT6_USE_FINE_PS = "FALSE"; - parameter real CLKPFD_FREQ_MAX = 550.000; - parameter real CLKPFD_FREQ_MIN = 10.000; parameter COMPENSATION = "AUTO"; parameter integer DIVCLK_DIVIDE = 1; parameter [0:0] IS_CLKFBIN_INVERTED = 1'b0; @@ -8264,9 +8276,6 @@ module MMCME3_ADV (...); parameter SS_MODE = "CENTER_HIGH"; parameter integer SS_MOD_PERIOD = 10000; parameter STARTUP_WAIT = "FALSE"; - parameter real VCOCLK_FREQ_MAX = 1600.000; - parameter real VCOCLK_FREQ_MIN = 600.000; - parameter STARTUP_WAIT = "FALSE"; output CDDCDONE; output CLKFBOUT; output CLKFBOUTB; @@ -8371,10 +8380,14 @@ module MMCME3_BASE (...); endmodule module PLLE3_ADV (...); - parameter integer CLKFBOUT_MULT = 5; - parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 70.000; + parameter real CLKPFD_FREQ_MAX = 667.500; + parameter real CLKPFD_FREQ_MIN = 70.000; + parameter real VCOCLK_FREQ_MAX = 1335.000; + parameter real VCOCLK_FREQ_MIN = 600.000; + parameter integer CLKFBOUT_MULT = 5; + parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_PERIOD = 0.000; parameter integer CLKOUT0_DIVIDE = 1; parameter real CLKOUT0_DUTY_CYCLE = 0.500; @@ -8383,8 +8396,6 @@ module PLLE3_ADV (...); parameter real CLKOUT1_DUTY_CYCLE = 0.500; parameter real CLKOUT1_PHASE = 0.000; parameter CLKOUTPHY_MODE = "VCO_2X"; - parameter real CLKPFD_FREQ_MAX = 667.500; - parameter real CLKPFD_FREQ_MIN = 70.000; parameter COMPENSATION = "AUTO"; parameter integer DIVCLK_DIVIDE = 1; parameter [0:0] IS_CLKFBIN_INVERTED = 1'b0; @@ -8393,9 +8404,6 @@ module PLLE3_ADV (...); parameter [0:0] IS_RST_INVERTED = 1'b0; parameter real REF_JITTER = 0.010; parameter STARTUP_WAIT = "FALSE"; - parameter real VCOCLK_FREQ_MAX = 1335.000; - parameter real VCOCLK_FREQ_MIN = 600.000; - parameter STARTUP_WAIT = "FALSE"; output CLKFBOUT; output CLKOUT0; output CLKOUT0B; @@ -8458,14 +8466,18 @@ module PLLE3_BASE (...); endmodule module MMCME4_ADV (...); + parameter real CLKIN_FREQ_MAX = 1066.000; + parameter real CLKIN_FREQ_MIN = 10.000; + parameter real CLKPFD_FREQ_MAX = 550.000; + parameter real CLKPFD_FREQ_MIN = 10.000; + parameter real VCOCLK_FREQ_MAX = 1600.000; + parameter real VCOCLK_FREQ_MIN = 800.000; parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; parameter CLKFBOUT_USE_FINE_PS = "FALSE"; parameter real CLKIN1_PERIOD = 0.000; parameter real CLKIN2_PERIOD = 0.000; - parameter real CLKIN_FREQ_MAX = 1066.000; - parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKOUT0_DIVIDE_F = 1.000; parameter real CLKOUT0_DUTY_CYCLE = 0.500; parameter real CLKOUT0_PHASE = 0.000; @@ -8495,8 +8507,6 @@ module MMCME4_ADV (...); parameter real CLKOUT6_DUTY_CYCLE = 0.500; parameter real CLKOUT6_PHASE = 0.000; parameter CLKOUT6_USE_FINE_PS = "FALSE"; - parameter real CLKPFD_FREQ_MAX = 550.000; - parameter real CLKPFD_FREQ_MIN = 10.000; parameter COMPENSATION = "AUTO"; parameter integer DIVCLK_DIVIDE = 1; parameter [0:0] IS_CLKFBIN_INVERTED = 1'b0; @@ -8513,9 +8523,6 @@ module MMCME4_ADV (...); parameter SS_MODE = "CENTER_HIGH"; parameter integer SS_MOD_PERIOD = 10000; parameter STARTUP_WAIT = "FALSE"; - parameter real VCOCLK_FREQ_MAX = 1600.000; - parameter real VCOCLK_FREQ_MIN = 800.000; - parameter STARTUP_WAIT = "FALSE"; output CDDCDONE; output CLKFBOUT; output CLKFBOUTB; @@ -8620,10 +8627,14 @@ module MMCME4_BASE (...); endmodule module PLLE4_ADV (...); - parameter integer CLKFBOUT_MULT = 5; - parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 70.000; + parameter real CLKPFD_FREQ_MAX = 667.500; + parameter real CLKPFD_FREQ_MIN = 70.000; + parameter real VCOCLK_FREQ_MAX = 1500.000; + parameter real VCOCLK_FREQ_MIN = 750.000; + parameter integer CLKFBOUT_MULT = 5; + parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_PERIOD = 0.000; parameter integer CLKOUT0_DIVIDE = 1; parameter real CLKOUT0_DUTY_CYCLE = 0.500; @@ -8632,8 +8643,6 @@ module PLLE4_ADV (...); parameter real CLKOUT1_DUTY_CYCLE = 0.500; parameter real CLKOUT1_PHASE = 0.000; parameter CLKOUTPHY_MODE = "VCO_2X"; - parameter real CLKPFD_FREQ_MAX = 667.500; - parameter real CLKPFD_FREQ_MIN = 70.000; parameter COMPENSATION = "AUTO"; parameter integer DIVCLK_DIVIDE = 1; parameter [0:0] IS_CLKFBIN_INVERTED = 1'b0; @@ -8642,9 +8651,6 @@ module PLLE4_ADV (...); parameter [0:0] IS_RST_INVERTED = 1'b0; parameter real REF_JITTER = 0.010; parameter STARTUP_WAIT = "FALSE"; - parameter real VCOCLK_FREQ_MAX = 1500.000; - parameter real VCOCLK_FREQ_MIN = 750.000; - parameter STARTUP_WAIT = "FALSE"; output CLKFBOUT; output CLKOUT0; output CLKOUT0B; @@ -17385,7 +17391,7 @@ module GTYE4_CHANNEL (...); parameter [15:0] RXDFE_KH_CFG0 = 16'h0000; parameter [15:0] RXDFE_KH_CFG1 = 16'h0000; parameter [15:0] RXDFE_KH_CFG2 = 16'h0000; - parameter [15:0] RXDFE_KH_CFG3 = 16'h0000; + parameter [15:0] RXDFE_KH_CFG3 = 16'h2000; parameter [15:0] RXDFE_OS_CFG0 = 16'h0000; parameter [15:0] RXDFE_OS_CFG1 = 16'h0000; parameter [15:0] RXDFE_UT_CFG0 = 16'h0000; @@ -17436,7 +17442,7 @@ module GTYE4_CHANNEL (...); parameter [4:0] RX_CLK_SLIP_OVRD = 5'b00000; parameter [3:0] RX_CM_BUF_CFG = 4'b1010; parameter [0:0] RX_CM_BUF_PD = 1'b0; - parameter integer RX_CM_SEL = 3; + parameter integer RX_CM_SEL = 2; parameter integer RX_CM_TRIM = 12; parameter [0:0] RX_CTLE_PWR_SAVING = 1'b0; parameter [3:0] RX_CTLE_RES_CTRL = 4'b0000; @@ -17444,12 +17450,12 @@ module GTYE4_CHANNEL (...); parameter [5:0] RX_DDI_SEL = 6'b000000; parameter RX_DEFER_RESET_BUF_EN = "TRUE"; parameter [2:0] RX_DEGEN_CTRL = 3'b100; - parameter integer RX_DFELPM_CFG0 = 0; + parameter integer RX_DFELPM_CFG0 = 10; parameter [0:0] RX_DFELPM_CFG1 = 1'b1; parameter [0:0] RX_DFELPM_KLKH_AGC_STUP_EN = 1'b1; parameter integer RX_DFE_AGC_CFG1 = 4; parameter integer RX_DFE_KL_LPM_KH_CFG0 = 1; - parameter integer RX_DFE_KL_LPM_KH_CFG1 = 4; + parameter integer RX_DFE_KL_LPM_KH_CFG1 = 2; parameter [1:0] RX_DFE_KL_LPM_KL_CFG0 = 2'b01; parameter integer RX_DFE_KL_LPM_KL_CFG1 = 4; parameter [0:0] RX_DFE_LPM_HOLD_DURING_EIDLE = 1'b0; @@ -17465,7 +17471,7 @@ module GTYE4_CHANNEL (...); parameter [0:0] RX_I2V_FILTER_EN = 1'b1; parameter integer RX_INT_DATAWIDTH = 1; parameter [0:0] RX_PMA_POWER_SAVE = 1'b0; - parameter [15:0] RX_PMA_RSV0 = 16'h000F; + parameter [15:0] RX_PMA_RSV0 = 16'h002F; parameter real RX_PROGDIV_CFG = 0.0; parameter [15:0] RX_PROGDIV_RATE = 16'h0001; parameter [3:0] RX_RESLOAD_CTRL = 4'b0000; @@ -17496,11 +17502,11 @@ module GTYE4_CHANNEL (...); parameter SATA_CPLL_CFG = "VCO_3000MHZ"; parameter [2:0] SATA_EIDLE_VAL = 3'b100; parameter SHOW_REALIGN_COMMA = "TRUE"; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RECEIVER_DETECT_PASS = "TRUE"; parameter SIM_RESET_SPEEDUP = "TRUE"; parameter SIM_TX_EIDLE_DRIVE_LEVEL = "Z"; - parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter [0:0] SRSTMODE = 1'b0; parameter [1:0] TAPDLY_SET_TX = 2'h0; parameter [14:0] TERM_RCAL_CFG = 15'b100001000010000; @@ -18032,9 +18038,9 @@ module GTYE4_COMMON (...); parameter [8:0] SDM0INITSEED0_1 = 9'b000000000; parameter [15:0] SDM1INITSEED0_0 = 16'b0000000000000000; parameter [8:0] SDM1INITSEED0_1 = 9'b000000000; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RESET_SPEEDUP = "TRUE"; - parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter [15:0] UB_CFG0 = 16'h0000; parameter [15:0] UB_CFG1 = 16'h0000; parameter [15:0] UB_CFG2 = 16'h0000; From f2932628fcb68584cec181ca7bc572fd78eb7223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 19 Dec 2020 18:14:06 +0100 Subject: [PATCH 0095/2410] xilinx: Add some missing blackbox cells. --- techlibs/xilinx/cells_sim.v | 99 + techlibs/xilinx/cells_xtra.py | 253 +- techlibs/xilinx/cells_xtra.v | 10372 ++++++++++++++++++++++++-------- 3 files changed, 8101 insertions(+), 2623 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 4162160bbe2..adaf7aee1e8 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -2023,6 +2023,105 @@ module RAM64M8 ( end endmodule +module RAM32X16DR8 ( + output DOA, + output DOB, + output DOC, + output DOD, + output DOE, + output DOF, + output DOG, + output [1:0] DOH, + input [5:0] ADDRA, ADDRB, ADDRC, ADDRD, ADDRE, ADDRF, ADDRG, + input [4:0] ADDRH, + input [1:0] DIA, + input [1:0] DIB, + input [1:0] DIC, + input [1:0] DID, + input [1:0] DIE, + input [1:0] DIF, + input [1:0] DIG, + input [1:0] DIH, + (* clkbuf_sink *) + (* invertible_pin = "IS_WCLK_INVERTED" *) + input WCLK, + input WE +); + parameter [0:0] IS_WCLK_INVERTED = 1'b0; + reg [63:0] mem_a, mem_b, mem_c, mem_d, mem_e, mem_f, mem_g, mem_h; + assign DOA = mem_a[ADDRA]; + assign DOB = mem_b[ADDRB]; + assign DOC = mem_c[ADDRC]; + assign DOD = mem_d[ADDRD]; + assign DOE = mem_e[ADDRE]; + assign DOF = mem_f[ADDRF]; + assign DOG = mem_g[ADDRG]; + assign DOH = mem_h[2*ADDRH+:2]; + wire clk = WCLK ^ IS_WCLK_INVERTED; + always @(posedge clk) + if (WE) begin + mem_a[2*ADDRH+:2] <= DIA; + mem_b[2*ADDRH+:2] <= DIB; + mem_c[2*ADDRH+:2] <= DIC; + mem_d[2*ADDRH+:2] <= DID; + mem_e[2*ADDRH+:2] <= DIE; + mem_f[2*ADDRH+:2] <= DIF; + mem_g[2*ADDRH+:2] <= DIG; + mem_h[2*ADDRH+:2] <= DIH; + end +endmodule + +module RAM64X8SW ( + output [7:0] O, + input [5:0] A, + input D, + (* clkbuf_sink *) + (* invertible_pin = "IS_WCLK_INVERTED" *) + input WCLK, + input WE, + input [2:0] WSEL +); + parameter [63:0] INIT_A = 64'h0000000000000000; + parameter [63:0] INIT_B = 64'h0000000000000000; + parameter [63:0] INIT_C = 64'h0000000000000000; + parameter [63:0] INIT_D = 64'h0000000000000000; + parameter [63:0] INIT_E = 64'h0000000000000000; + parameter [63:0] INIT_F = 64'h0000000000000000; + parameter [63:0] INIT_G = 64'h0000000000000000; + parameter [63:0] INIT_H = 64'h0000000000000000; + parameter [0:0] IS_WCLK_INVERTED = 1'b0; + reg [63:0] mem_a = INIT_A; + reg [63:0] mem_b = INIT_B; + reg [63:0] mem_c = INIT_C; + reg [63:0] mem_d = INIT_D; + reg [63:0] mem_e = INIT_E; + reg [63:0] mem_f = INIT_F; + reg [63:0] mem_g = INIT_G; + reg [63:0] mem_h = INIT_H; + assign O[7] = mem_a[A]; + assign O[6] = mem_b[A]; + assign O[5] = mem_c[A]; + assign O[4] = mem_d[A]; + assign O[3] = mem_e[A]; + assign O[2] = mem_f[A]; + assign O[1] = mem_g[A]; + assign O[0] = mem_h[A]; + wire clk = WCLK ^ IS_WCLK_INVERTED; + always @(posedge clk) + if (WE) begin + case (WSEL) + 3'b111: mem_a[A] <= D; + 3'b110: mem_b[A] <= D; + 3'b101: mem_c[A] <= D; + 3'b100: mem_d[A] <= D; + 3'b011: mem_e[A] <= D; + 3'b010: mem_f[A] <= D; + 3'b001: mem_g[A] <= D; + 3'b000: mem_h[A] <= D; + endcase + end +endmodule + // ROM. module ROM16X1 ( diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index c7ffb94cf6d..cb23b97872e 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -57,6 +57,8 @@ def __init__(self, name, keep=False, port_attrs={}): # Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}), # Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), # Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}), + # Cell('RAM32X16DR8', port_attrs={'WCLK': ['clkbuf_sink']}), + # Cell('RAM64X8SW', port_attrs={'WCLK': ['clkbuf_sink']}), # Cell('ROM16X1'), # Cell('ROM32X1'), # Cell('ROM64X1'), @@ -243,12 +245,12 @@ def __init__(self, name, keep=False, port_attrs={}): 'CLKDIVP': ['clkbuf_sink'], }), Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}), - Cell('PHASER_IN'), - Cell('PHASER_IN_PHY'), - Cell('PHASER_OUT'), - Cell('PHASER_OUT_PHY'), - Cell('PHASER_REF'), - Cell('PHY_CONTROL'), + Cell('PHASER_IN', keep=True), + Cell('PHASER_IN_PHY', keep=True), + Cell('PHASER_OUT', keep=True), + Cell('PHASER_OUT_PHY', keep=True), + Cell('PHASER_REF', keep=True), + Cell('PHY_CONTROL', keep=True), # Ultrascale. Cell('IDDRE1', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}), Cell('ODDRE1', port_attrs={'C': ['clkbuf_sink']}), @@ -262,7 +264,7 @@ def __init__(self, name, keep=False, port_attrs={}): }), Cell('OSERDESE3', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}), Cell('BITSLICE_CONTROL', keep=True), - Cell('RIU_OR'), + Cell('RIU_OR', keep=True), Cell('RX_BITSLICE'), Cell('RXTX_BITSLICE'), Cell('TX_BITSLICE'), @@ -327,7 +329,7 @@ def __init__(self, name, keep=False, port_attrs={}): Cell('PULLUP'), # Misc. Cell('DCIRESET', keep=True), - Cell('HPIO_VREF'), # Ultrascale + Cell('HPIO_VREF', keep=True), # Ultrascale # Clock buffers (global). # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}), @@ -456,6 +458,7 @@ def __init__(self, name, keep=False, port_attrs={}): Cell('FRAME_ECC_VIRTEX6'), Cell('FRAME_ECCE2'), # Series 7 Cell('FRAME_ECCE3'), # Ultrascale + Cell('FRAME_ECCE4'), # Ultrascale+ # AXSS command access. Cell('USR_ACCESS_VIRTEX4'), Cell('USR_ACCESS_VIRTEX5'), @@ -470,10 +473,10 @@ def __init__(self, name, keep=False, port_attrs={}): Cell('EFUSE_USR'), # ADC. - Cell('SYSMON'), # Virtex 5/6 - Cell('XADC'), # Series 7 - Cell('SYSMONE1'), # Ultrascale - Cell('SYSMONE4'), # Ultrascale+ + Cell('SYSMON', keep=True), # Virtex 5/6 + Cell('XADC', keep=True), # Series 7 + Cell('SYSMONE1', keep=True), # Ultrascale + Cell('SYSMONE4', keep=True), # Ultrascale+ # Gigabit transceivers. # Spartan 6. @@ -507,18 +510,30 @@ def __init__(self, name, keep=False, port_attrs={}): # Ultrascale. Cell('GTHE3_CHANNEL'), Cell('GTHE3_COMMON'), - Cell('GTHE4_CHANNEL'), - Cell('GTHE4_COMMON'), Cell('GTYE3_CHANNEL'), Cell('GTYE3_COMMON'), - Cell('GTYE4_CHANNEL'), - Cell('GTYE4_COMMON'), Cell('IBUFDS_GTE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), - Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), Cell('OBUFDS_GTE3', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), Cell('OBUFDS_GTE3_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), + # Ultrascale+. + Cell('GTHE4_CHANNEL'), + Cell('GTHE4_COMMON'), + Cell('GTYE4_CHANNEL'), + Cell('GTYE4_COMMON'), + Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), Cell('OBUFDS_GTE4', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), Cell('OBUFDS_GTE4_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), + # Ultrascale+ GTM. + Cell('GTM_DUAL'), # not in the libraries guide + Cell('IBUFDS_GTM', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), + Cell('OBUFDS_GTM', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), + Cell('OBUFDS_GTM_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), + + # High-speed ADC/DAC. + Cell('HSDAC'), # not in libraries guide + Cell('HSADC'), # not in libraries guide + Cell('RFDAC'), # not in libraries guide + Cell('RFADC'), # not in libraries guide # PCIE IP. Cell('PCIE_A1'), # Spartan 6 @@ -528,6 +543,7 @@ def __init__(self, name, keep=False, port_attrs={}): Cell('PCIE_3_0'), # Series 7 Cell('PCIE_3_1'), # Ultrascale Cell('PCIE40E4'), # Ultrascale+ + Cell('PCIE4CE4'), # Ultrascale+ v2 (not in the libraries guide) # Ethernet IP. Cell('EMAC'), # Virtex 4 @@ -536,17 +552,29 @@ def __init__(self, name, keep=False, port_attrs={}): Cell('CMAC'), # Ultrascale Cell('CMACE4'), # Ultrsacale+ + # Hard memory controllers. + Cell('MCB'), # Spartan 6 Memory Controller Block + Cell('HBM_REF_CLK', keep=True), # not in liraries guide + # not sure how the following relate to the hw + Cell('HBM_SNGLBLI_INTF_APB', keep=True), # not in liraries guide + Cell('HBM_SNGLBLI_INTF_AXI', keep=True), # not in liraries guide + Cell('HBM_ONE_STACK_INTF', keep=True), # not in liraries guide + Cell('HBM_TWO_STACK_INTF', keep=True), # not in liraries guide + # PowerPC. # TODO PPC405 (Virtex 2) Cell('PPC405_ADV'), # Virtex 4 Cell('PPC440'), # Virtex 5 + # ARM. + Cell('PS7', keep=True), # The Zynq 7000 ARM Processor System (not in libraries guide). + Cell('PS8', keep=True), # The Zynq Ultrascale+ ARM Processor System (not in libraries guide). + # Misc hard IP. - Cell('MCB'), # Spartan 6 Memory Controller Block - Cell('PS7', keep=True), # The Zynq 7000 ARM Processor System. - Cell('PS8', keep=True), # The Zynq Ultrascale+ ARM Processor System. Cell('ILKN'), # Ultrascale Interlaken Cell('ILKNE4'), # Ultrascale+ Interlaken + Cell('VCU', keep=True), # Zynq MPSoC Video Codec Unit (not in libraries guide). + Cell('FE'), # Zynq RFSoC Forward Error Correction (not in libraries guide). ] @@ -559,100 +587,101 @@ class State(Enum): def xtract_cell_decl(cell, dirs, outf): for dir in dirs: - fname = os.path.join(dir, cell.name + '.v') - try: - with open(fname) as f: - state = State.OUTSIDE - found = False - # Probably the most horrible Verilog "parser" ever written. - module_ports = [] - invertible_ports = set() - for l in f: - l = l.partition('//')[0] - l = l.strip() - if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)): - if found: - print('Multiple modules in {}.'.format(fname)) - sys.exit(1) - elif state != State.OUTSIDE: - print('Nested modules in {}.'.format(fname)) - sys.exit(1) - found = True - state = State.IN_MODULE - if cell.keep: - outf.write('(* keep *)\n') - outf.write('module {} (...);\n'.format(cell.name)) - elif l.startswith('module '): - if state != State.OUTSIDE: - print('Nested modules in {}.'.format(fname)) - sys.exit(1) - state = State.IN_OTHER_MODULE - elif l.startswith('task '): - if state == State.IN_MODULE: - state = State.IN_TASK - elif l.startswith('function '): - if state == State.IN_MODULE: - state = State.IN_FUNCTION - elif l == 'endtask': - if state == State.IN_TASK: - state = State.IN_MODULE - elif l == 'endfunction': - if state == State.IN_FUNCTION: + for ext in ['.v', '.sv']: + fname = os.path.join(dir, cell.name + ext) + try: + with open(fname) as f: + state = State.OUTSIDE + found = False + # Probably the most horrible Verilog "parser" ever written. + module_ports = [] + invertible_ports = set() + for l in f: + l = l.partition('//')[0] + l = l.strip() + if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)): + if found: + print('Multiple modules in {}.'.format(fname)) + sys.exit(1) + elif state != State.OUTSIDE: + print('Nested modules in {}.'.format(fname)) + sys.exit(1) + found = True state = State.IN_MODULE - elif l == 'endmodule': - if state == State.IN_MODULE: - for kind, rng, port in module_ports: - for attr in cell.port_attrs.get(port, []): - outf.write(' (* {} *)\n'.format(attr)) - if port in invertible_ports: - outf.write(' (* invertible_pin = "IS_{}_INVERTED" *)\n'.format(port)) - if rng is None: - outf.write(' {} {};\n'.format(kind, port)) + if cell.keep: + outf.write('(* keep *)\n') + outf.write('module {} (...);\n'.format(cell.name)) + elif l.startswith('module '): + if state != State.OUTSIDE: + print('Nested modules in {}.'.format(fname)) + sys.exit(1) + state = State.IN_OTHER_MODULE + elif l.startswith('task '): + if state == State.IN_MODULE: + state = State.IN_TASK + elif l.startswith('function '): + if state == State.IN_MODULE: + state = State.IN_FUNCTION + elif l == 'endtask': + if state == State.IN_TASK: + state = State.IN_MODULE + elif l == 'endfunction': + if state == State.IN_FUNCTION: + state = State.IN_MODULE + elif l == 'endmodule': + if state == State.IN_MODULE: + for kind, rng, port in module_ports: + for attr in cell.port_attrs.get(port, []): + outf.write(' (* {} *)\n'.format(attr)) + if port in invertible_ports: + outf.write(' (* invertible_pin = "IS_{}_INVERTED" *)\n'.format(port)) + if rng is None: + outf.write(' {} {};\n'.format(kind, port)) + else: + outf.write(' {} {} {};\n'.format(kind, rng, port)) + outf.write(l + '\n') + outf.write('\n') + elif state != State.IN_OTHER_MODULE: + print('endmodule in weird place in {}.'.format(cell.name, fname)) + sys.exit(1) + state = State.OUTSIDE + elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: + if l.endswith((';', ',')): + l = l[:-1] + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + kind, _, ports = l.partition(' ') + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() else: - outf.write(' {} {} {};\n'.format(kind, rng, port)) - outf.write(l + '\n') - outf.write('\n') - elif state != State.IN_OTHER_MODULE: - print('endmodule in weird place in {}.'.format(cell.name, fname)) - sys.exit(1) - state = State.OUTSIDE - elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: - if l.endswith((';', ',')): - l = l[:-1] - if ';' in l: - print('Weird port line in {} [{}].'.format(fname, l)) - sys.exit(1) - kind, _, ports = l.partition(' ') - for port in ports.split(','): - port = port.strip() - if port.startswith('['): - rng, port = port.split() - else: - rng = None - module_ports.append((kind, rng, port)) - elif l.startswith('parameter ') and state == State.IN_MODULE: - if 'UNPLACED' in l: - continue - if l.endswith((';', ',')): - l = l[:-1] - while ' ' in l: - l = l.replace(' ', ' ') - if ';' in l: - print('Weird parameter line in {} [{}].'.format(fname, l)) - sys.exit(1) - outf.write(' {};\n'.format(l)) - match = re.search('IS_([a-zA-Z0-9_]+)_INVERTED', l) - if match: - invertible_ports.add(match[1]) - if state != State.OUTSIDE: - print('endmodule not found in {}.'.format(fname)) - sys.exit(1) - if not found: - print('Cannot find module {} in {}.'.format(cell.name, fname)) - sys.exit(1) - return - except FileNotFoundError: - continue + rng = None + module_ports.append((kind, rng, port)) + elif l.startswith('parameter ') and state == State.IN_MODULE: + if 'UNPLACED' in l: + continue + if l.endswith((';', ',')): + l = l[:-1] + while ' ' in l: + l = l.replace(' ', ' ') + if ';' in l: + print('Weird parameter line in {} [{}].'.format(fname, l)) + sys.exit(1) + outf.write(' {};\n'.format(l)) + match = re.search('IS_([a-zA-Z0-9_]+)_INVERTED', l) + if match: + invertible_ports.add(match[1]) + if state != State.OUTSIDE: + print('endmodule not found in {}.'.format(fname)) + sys.exit(1) + if not found: + print('Cannot find module {} in {}.'.format(cell.name, fname)) + sys.exit(1) + return + except FileNotFoundError: + continue print('Cannot find {}.'.format(cell.name)) sys.exit(1) diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 1fb340fc01d..1187101fda9 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -5994,6 +5994,7 @@ module OSERDESE2 (...); input TCE; endmodule +(* keep *) module PHASER_IN (...); parameter integer CLKOUT_DIV = 4; parameter DQS_BIAS_MODE = "FALSE"; @@ -6030,6 +6031,7 @@ module PHASER_IN (...); input [5:0] COUNTERLOADVAL; endmodule +(* keep *) module PHASER_IN_PHY (...); parameter BURST_MODE = "FALSE"; parameter integer CLKOUT_DIV = 4; @@ -6074,6 +6076,7 @@ module PHASER_IN_PHY (...); input [5:0] COUNTERLOADVAL; endmodule +(* keep *) module PHASER_OUT (...); parameter integer CLKOUT_DIV = 4; parameter COARSE_BYPASS = "FALSE"; @@ -6115,6 +6118,7 @@ module PHASER_OUT (...); input [8:0] COUNTERLOADVAL; endmodule +(* keep *) module PHASER_OUT_PHY (...); parameter integer CLKOUT_DIV = 4; parameter COARSE_BYPASS = "FALSE"; @@ -6161,6 +6165,7 @@ module PHASER_OUT_PHY (...); input [8:0] COUNTERLOADVAL; endmodule +(* keep *) module PHASER_REF (...); parameter [0:0] IS_RST_INVERTED = 1'b0; parameter [0:0] IS_PWRDWN_INVERTED = 1'b0; @@ -6172,6 +6177,7 @@ module PHASER_REF (...); input RST; endmodule +(* keep *) module PHY_CONTROL (...); parameter integer AO_TOGGLE = 0; parameter [3:0] AO_WRLVL_EN = 4'b0000; @@ -6466,6 +6472,7 @@ module BITSLICE_CONTROL (...); input [39:0] TX_BIT_CTRL_IN_TRI; endmodule +(* keep *) module RIU_OR (...); parameter SIM_DEVICE = "ULTRASCALE"; parameter real SIM_VERSION = 2.0; @@ -7275,6 +7282,7 @@ module DCIRESET (...); input RST; endmodule +(* keep *) module HPIO_VREF (...); parameter VREF_CNTR = "OFF"; output VREF; @@ -9232,6 +9240,18 @@ module FRAME_ECCE3 (...); input ICAPTOPCLK; endmodule +module FRAME_ECCE4 (...); + output CRCERROR; + output ECCERRORNOTSINGLE; + output ECCERRORSINGLE; + output ENDOFFRAME; + output ENDOFSCAN; + output [26:0] FAR; + input [1:0] FARSEL; + input ICAPBOTCLK; + input ICAPTOPCLK; +endmodule + module USR_ACCESS_VIRTEX4 (...); output [31:0] DATA; output DATAVALID; @@ -9297,6 +9317,7 @@ module EFUSE_USR (...); output [31:0] EFUSEUSR; endmodule +(* keep *) module SYSMON (...); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; @@ -9349,6 +9370,7 @@ module SYSMON (...); input [6:0] DADDR; endmodule +(* keep *) module XADC (...); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; @@ -9414,6 +9436,7 @@ module XADC (...); input [6:0] DADDR; endmodule +(* keep *) module SYSMONE1 (...); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; @@ -9522,6 +9545,7 @@ module SYSMONE1 (...); input VP; endmodule +(* keep *) module SYSMONE4 (...); parameter [15:0] COMMON_N_SOURCE = 16'hFFFF; parameter [15:0] INIT_40 = 16'h0000; @@ -15163,13 +15187,13 @@ module GTHE3_COMMON (...); input RCALENB; endmodule -module GTHE4_CHANNEL (...); +module GTYE3_CHANNEL (...); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; parameter [15:0] ADAPT_CFG0 = 16'h9200; parameter [15:0] ADAPT_CFG1 = 16'h801C; - parameter [15:0] ADAPT_CFG2 = 16'h0000; + parameter [15:0] ADAPT_CFG2 = 16'b0000000000000000; parameter ALIGN_COMMA_DOUBLE = "FALSE"; parameter [9:0] ALIGN_COMMA_ENABLE = 10'b0001111111; parameter integer ALIGN_COMMA_WORD = 1; @@ -15177,15 +15201,14 @@ module GTHE4_CHANNEL (...); parameter [9:0] ALIGN_MCOMMA_VALUE = 10'b1010000011; parameter ALIGN_PCOMMA_DET = "TRUE"; parameter [9:0] ALIGN_PCOMMA_VALUE = 10'b0101111100; + parameter [0:0] AUTO_BW_SEL_BYPASS = 1'b0; parameter [0:0] A_RXOSCALRESET = 1'b0; parameter [0:0] A_RXPROGDIVRESET = 1'b0; - parameter [0:0] A_RXTERMINATION = 1'b1; parameter [4:0] A_TXDIFFCTRL = 5'b01100; parameter [0:0] A_TXPROGDIVRESET = 1'b0; parameter [0:0] CAPBYPASS_FORCE = 1'b0; parameter CBCC_DATA_SOURCE_SEL = "DECODED"; parameter [0:0] CDR_SWAP_MODE_EN = 1'b0; - parameter [0:0] CFOK_PWRSVE_EN = 1'b1; parameter CHAN_BOND_KEEP_ALIGN = "FALSE"; parameter integer CHAN_BOND_MAX_SKEW = 7; parameter [9:0] CHAN_BOND_SEQ_1_1 = 10'b0101111100; @@ -15200,7 +15223,7 @@ module GTHE4_CHANNEL (...); parameter [3:0] CHAN_BOND_SEQ_2_ENABLE = 4'b1111; parameter CHAN_BOND_SEQ_2_USE = "FALSE"; parameter integer CHAN_BOND_SEQ_LEN = 2; - parameter [15:0] CH_HSPMUX = 16'h2424; + parameter [15:0] CH_HSPMUX = 16'h0000; parameter [15:0] CKCAL1_CFG_0 = 16'b0000000000000000; parameter [15:0] CKCAL1_CFG_1 = 16'b0000000000000000; parameter [15:0] CKCAL1_CFG_2 = 16'b0000000000000000; @@ -15210,7 +15233,7 @@ module GTHE4_CHANNEL (...); parameter [15:0] CKCAL2_CFG_2 = 16'b0000000000000000; parameter [15:0] CKCAL2_CFG_3 = 16'b0000000000000000; parameter [15:0] CKCAL2_CFG_4 = 16'b0000000000000000; - parameter [15:0] CKCAL_RSVD0 = 16'h4000; + parameter [15:0] CKCAL_RSVD0 = 16'h0000; parameter [15:0] CKCAL_RSVD1 = 16'h0000; parameter CLK_CORRECT_USE = "TRUE"; parameter CLK_COR_KEEP_IDLE = "FALSE"; @@ -15230,13 +15253,14 @@ module GTHE4_CHANNEL (...); parameter [3:0] CLK_COR_SEQ_2_ENABLE = 4'b1111; parameter CLK_COR_SEQ_2_USE = "FALSE"; parameter integer CLK_COR_SEQ_LEN = 2; - parameter [15:0] CPLL_CFG0 = 16'h01FA; - parameter [15:0] CPLL_CFG1 = 16'h24A9; - parameter [15:0] CPLL_CFG2 = 16'h6807; - parameter [15:0] CPLL_CFG3 = 16'h0000; + parameter [15:0] CPLL_CFG0 = 16'h20F8; + parameter [15:0] CPLL_CFG1 = 16'hA494; + parameter [15:0] CPLL_CFG2 = 16'hF001; + parameter [5:0] CPLL_CFG3 = 6'h00; parameter integer CPLL_FBDIV = 4; parameter integer CPLL_FBDIV_45 = 4; parameter [15:0] CPLL_INIT_CFG0 = 16'h001E; + parameter [7:0] CPLL_INIT_CFG1 = 8'h00; parameter [15:0] CPLL_LOCK_CFG = 16'h01E8; parameter integer CPLL_REFCLK_DIV = 1; parameter [2:0] CTLE3_OCAP_EXT_CTRL = 3'b000; @@ -15246,14 +15270,16 @@ module GTHE4_CHANNEL (...); parameter DEC_MCOMMA_DETECT = "TRUE"; parameter DEC_PCOMMA_DETECT = "TRUE"; parameter DEC_VALID_COMMA_ONLY = "TRUE"; - parameter [0:0] DELAY_ELEC = 1'b0; + parameter [0:0] DFE_D_X_REL_POS = 1'b0; + parameter [0:0] DFE_VCM_COMP_EN = 1'b0; parameter [9:0] DMONITOR_CFG0 = 10'h000; parameter [7:0] DMONITOR_CFG1 = 8'h00; parameter [0:0] ES_CLK_PHASE_SEL = 1'b0; parameter [5:0] ES_CONTROL = 6'b000000; parameter ES_ERRDET_EN = "FALSE"; parameter ES_EYE_SCAN_EN = "FALSE"; - parameter [11:0] ES_HORZ_OFFSET = 12'h800; + parameter [11:0] ES_HORZ_OFFSET = 12'h000; + parameter [9:0] ES_PMA_CFG = 10'b0000000000; parameter [4:0] ES_PRESCALE = 5'b00000; parameter [15:0] ES_QUALIFIER0 = 16'h0000; parameter [15:0] ES_QUALIFIER1 = 16'h0000; @@ -15285,19 +15311,32 @@ module GTHE4_CHANNEL (...); parameter [15:0] ES_SDATA_MASK7 = 16'h0000; parameter [15:0] ES_SDATA_MASK8 = 16'h0000; parameter [15:0] ES_SDATA_MASK9 = 16'h0000; + parameter [10:0] EVODD_PHI_CFG = 11'b00000000000; parameter [0:0] EYE_SCAN_SWAP_EN = 1'b0; parameter [3:0] FTS_DESKEW_SEQ_ENABLE = 4'b1111; parameter [3:0] FTS_LANE_DESKEW_CFG = 4'b1111; parameter FTS_LANE_DESKEW_EN = "FALSE"; parameter [4:0] GEARBOX_MODE = 5'b00000; + parameter [0:0] GM_BIAS_SELECT = 1'b0; parameter [0:0] ISCAN_CK_PH_SEL2 = 1'b0; parameter [0:0] LOCAL_MASTER = 1'b0; + parameter [15:0] LOOP0_CFG = 16'h0000; + parameter [15:0] LOOP10_CFG = 16'h0000; + parameter [15:0] LOOP11_CFG = 16'h0000; + parameter [15:0] LOOP12_CFG = 16'h0000; + parameter [15:0] LOOP13_CFG = 16'h0000; + parameter [15:0] LOOP1_CFG = 16'h0000; + parameter [15:0] LOOP2_CFG = 16'h0000; + parameter [15:0] LOOP3_CFG = 16'h0000; + parameter [15:0] LOOP4_CFG = 16'h0000; + parameter [15:0] LOOP5_CFG = 16'h0000; + parameter [15:0] LOOP6_CFG = 16'h0000; + parameter [15:0] LOOP7_CFG = 16'h0000; + parameter [15:0] LOOP8_CFG = 16'h0000; + parameter [15:0] LOOP9_CFG = 16'h0000; parameter [2:0] LPBK_BIAS_CTRL = 3'b000; parameter [0:0] LPBK_EN_RCAL_B = 1'b0; parameter [3:0] LPBK_EXT_RCAL = 4'b0000; - parameter [2:0] LPBK_IND_CTRL0 = 3'b000; - parameter [2:0] LPBK_IND_CTRL1 = 3'b000; - parameter [2:0] LPBK_IND_CTRL2 = 3'b000; parameter [3:0] LPBK_RG_CTRL = 4'b0000; parameter [1:0] OOBDIVCTL = 2'b00; parameter [0:0] OOB_PWRUP = 1'b0; @@ -15310,32 +15349,25 @@ module GTHE4_CHANNEL (...); parameter [5:0] PCI3_RX_ELECIDLE_HI_COUNT = 6'b000000; parameter [0:0] PCI3_RX_ELECIDLE_LP4_DISABLE = 1'b0; parameter [0:0] PCI3_RX_FIFO_DISABLE = 1'b0; - parameter [4:0] PCIE3_CLK_COR_EMPTY_THRSH = 5'b00000; - parameter [5:0] PCIE3_CLK_COR_FULL_THRSH = 6'b010000; - parameter [4:0] PCIE3_CLK_COR_MAX_LAT = 5'b01000; - parameter [4:0] PCIE3_CLK_COR_MIN_LAT = 5'b00100; - parameter [5:0] PCIE3_CLK_COR_THRSH_TIMER = 6'b001000; parameter [15:0] PCIE_BUFG_DIV_CTRL = 16'h0000; - parameter [1:0] PCIE_PLL_SEL_MODE_GEN12 = 2'h0; - parameter [1:0] PCIE_PLL_SEL_MODE_GEN3 = 2'h0; - parameter [1:0] PCIE_PLL_SEL_MODE_GEN4 = 2'h0; parameter [15:0] PCIE_RXPCS_CFG_GEN3 = 16'h0000; parameter [15:0] PCIE_RXPMA_CFG = 16'h0000; parameter [15:0] PCIE_TXPCS_CFG_GEN3 = 16'h0000; parameter [15:0] PCIE_TXPMA_CFG = 16'h0000; parameter PCS_PCIE_EN = "FALSE"; parameter [15:0] PCS_RSVD0 = 16'b0000000000000000; + parameter [2:0] PCS_RSVD1 = 3'b000; parameter [11:0] PD_TRANS_TIME_FROM_P2 = 12'h03C; parameter [7:0] PD_TRANS_TIME_NONE_P2 = 8'h19; parameter [7:0] PD_TRANS_TIME_TO_P2 = 8'h64; + parameter [1:0] PLL_SEL_MODE_GEN12 = 2'h0; + parameter [1:0] PLL_SEL_MODE_GEN3 = 2'h0; + parameter [15:0] PMA_RSV0 = 16'h0000; + parameter [15:0] PMA_RSV1 = 16'h0000; parameter integer PREIQ_FREQ_BST = 0; parameter [2:0] PROCESS_PAR = 3'b010; parameter [0:0] RATE_SW_USE_DRP = 1'b0; - parameter [0:0] RCLK_SIPO_DLY_ENB = 1'b0; - parameter [0:0] RCLK_SIPO_INV_EN = 1'b0; parameter [0:0] RESET_POWERSAVE_DISABLE = 1'b0; - parameter [2:0] RTX_BUF_CML_CTRL = 3'b010; - parameter [1:0] RTX_BUF_TERM_CTRL = 2'b00; parameter [4:0] RXBUFRESET_TIME = 5'b00001; parameter RXBUF_ADDR_MODE = "FULL"; parameter [3:0] RXBUF_EIDLE_HI_CNT = 4'b1000; @@ -15350,48 +15382,37 @@ module GTHE4_CHANNEL (...); parameter integer RXBUF_THRESH_UNDFLW = 4; parameter [4:0] RXCDRFREQRESET_TIME = 5'b00001; parameter [4:0] RXCDRPHRESET_TIME = 5'b00001; - parameter [15:0] RXCDR_CFG0 = 16'h0003; - parameter [15:0] RXCDR_CFG0_GEN3 = 16'h0003; - parameter [15:0] RXCDR_CFG1 = 16'h0000; - parameter [15:0] RXCDR_CFG1_GEN3 = 16'h0000; - parameter [15:0] RXCDR_CFG2 = 16'h0164; - parameter [9:0] RXCDR_CFG2_GEN2 = 10'h164; - parameter [15:0] RXCDR_CFG2_GEN3 = 16'h0034; - parameter [15:0] RXCDR_CFG2_GEN4 = 16'h0034; - parameter [15:0] RXCDR_CFG3 = 16'h0024; - parameter [5:0] RXCDR_CFG3_GEN2 = 6'h24; - parameter [15:0] RXCDR_CFG3_GEN3 = 16'h0024; - parameter [15:0] RXCDR_CFG3_GEN4 = 16'h0024; - parameter [15:0] RXCDR_CFG4 = 16'h5CF6; - parameter [15:0] RXCDR_CFG4_GEN3 = 16'h5CF6; - parameter [15:0] RXCDR_CFG5 = 16'hB46B; - parameter [15:0] RXCDR_CFG5_GEN3 = 16'h146B; + parameter [15:0] RXCDR_CFG0 = 16'h0000; + parameter [15:0] RXCDR_CFG0_GEN3 = 16'h0000; + parameter [15:0] RXCDR_CFG1 = 16'h0300; + parameter [15:0] RXCDR_CFG1_GEN3 = 16'h0300; + parameter [15:0] RXCDR_CFG2 = 16'h0060; + parameter [15:0] RXCDR_CFG2_GEN3 = 16'h0060; + parameter [15:0] RXCDR_CFG3 = 16'h0000; + parameter [15:0] RXCDR_CFG3_GEN3 = 16'h0000; + parameter [15:0] RXCDR_CFG4 = 16'h0002; + parameter [15:0] RXCDR_CFG4_GEN3 = 16'h0002; + parameter [15:0] RXCDR_CFG5 = 16'h0000; + parameter [15:0] RXCDR_CFG5_GEN3 = 16'h0000; parameter [0:0] RXCDR_FR_RESET_ON_EIDLE = 1'b0; parameter [0:0] RXCDR_HOLD_DURING_EIDLE = 1'b0; - parameter [15:0] RXCDR_LOCK_CFG0 = 16'h0040; - parameter [15:0] RXCDR_LOCK_CFG1 = 16'h8000; + parameter [15:0] RXCDR_LOCK_CFG0 = 16'h0001; + parameter [15:0] RXCDR_LOCK_CFG1 = 16'h0000; parameter [15:0] RXCDR_LOCK_CFG2 = 16'h0000; parameter [15:0] RXCDR_LOCK_CFG3 = 16'h0000; - parameter [15:0] RXCDR_LOCK_CFG4 = 16'h0000; parameter [0:0] RXCDR_PH_RESET_ON_EIDLE = 1'b0; - parameter [15:0] RXCFOK_CFG0 = 16'h0000; - parameter [15:0] RXCFOK_CFG1 = 16'h0002; + parameter [1:0] RXCFOKDONE_SRC = 2'b00; + parameter [15:0] RXCFOK_CFG0 = 16'h3E00; + parameter [15:0] RXCFOK_CFG1 = 16'h0042; parameter [15:0] RXCFOK_CFG2 = 16'h002D; - parameter [15:0] RXCKCAL1_IQ_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL1_I_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL1_Q_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL2_DX_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL2_D_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL2_S_LOOP_RST_CFG = 16'h0000; - parameter [15:0] RXCKCAL2_X_LOOP_RST_CFG = 16'h0000; parameter [6:0] RXDFELPMRESET_TIME = 7'b0001111; parameter [15:0] RXDFELPM_KL_CFG0 = 16'h0000; parameter [15:0] RXDFELPM_KL_CFG1 = 16'h0022; parameter [15:0] RXDFELPM_KL_CFG2 = 16'h0100; - parameter [15:0] RXDFE_CFG0 = 16'h4000; + parameter [15:0] RXDFE_CFG0 = 16'h4C00; parameter [15:0] RXDFE_CFG1 = 16'h0000; - parameter [15:0] RXDFE_GC_CFG0 = 16'h0000; - parameter [15:0] RXDFE_GC_CFG1 = 16'h0000; + parameter [15:0] RXDFE_GC_CFG0 = 16'h1E00; + parameter [15:0] RXDFE_GC_CFG1 = 16'h1900; parameter [15:0] RXDFE_GC_CFG2 = 16'h0000; parameter [15:0] RXDFE_H2_CFG0 = 16'h0000; parameter [15:0] RXDFE_H2_CFG1 = 16'h0002; @@ -15421,31 +15442,26 @@ module GTHE4_CHANNEL (...); parameter [15:0] RXDFE_HE_CFG1 = 16'h0002; parameter [15:0] RXDFE_HF_CFG0 = 16'h0000; parameter [15:0] RXDFE_HF_CFG1 = 16'h0002; - parameter [15:0] RXDFE_KH_CFG0 = 16'h0000; - parameter [15:0] RXDFE_KH_CFG1 = 16'h0000; - parameter [15:0] RXDFE_KH_CFG2 = 16'h0000; - parameter [15:0] RXDFE_KH_CFG3 = 16'h0000; parameter [15:0] RXDFE_OS_CFG0 = 16'h0000; - parameter [15:0] RXDFE_OS_CFG1 = 16'h0002; + parameter [15:0] RXDFE_OS_CFG1 = 16'h0200; parameter [0:0] RXDFE_PWR_SAVING = 1'b0; parameter [15:0] RXDFE_UT_CFG0 = 16'h0000; parameter [15:0] RXDFE_UT_CFG1 = 16'h0002; - parameter [15:0] RXDFE_UT_CFG2 = 16'h0000; parameter [15:0] RXDFE_VP_CFG0 = 16'h0000; parameter [15:0] RXDFE_VP_CFG1 = 16'h0022; - parameter [15:0] RXDLY_CFG = 16'h0010; + parameter [15:0] RXDLY_CFG = 16'h001F; parameter [15:0] RXDLY_LCFG = 16'h0030; parameter RXELECIDLE_CFG = "SIGCFG_4"; parameter integer RXGBOX_FIFO_INIT_RD_ADDR = 4; parameter RXGEARBOX_EN = "FALSE"; parameter [4:0] RXISCANRESET_TIME = 5'b00001; parameter [15:0] RXLPM_CFG = 16'h0000; - parameter [15:0] RXLPM_GC_CFG = 16'h1000; + parameter [15:0] RXLPM_GC_CFG = 16'h0200; parameter [15:0] RXLPM_KH_CFG0 = 16'h0000; parameter [15:0] RXLPM_KH_CFG1 = 16'h0002; - parameter [15:0] RXLPM_OS_CFG0 = 16'h0000; + parameter [15:0] RXLPM_OS_CFG0 = 16'h0400; parameter [15:0] RXLPM_OS_CFG1 = 16'h0000; - parameter [8:0] RXOOB_CFG = 9'b000110000; + parameter [8:0] RXOOB_CFG = 9'b000000110; parameter RXOOB_CLK_CFG = "PMA"; parameter [4:0] RXOSCALRESET_TIME = 5'b00011; parameter integer RXOUT_DIV = 4; @@ -15456,9 +15472,9 @@ module GTHE4_CHANNEL (...); parameter [15:0] RXPHSLIP_CFG = 16'h9933; parameter [4:0] RXPH_MONITOR_SEL = 5'b00000; parameter [0:0] RXPI_AUTO_BW_SEL_BYPASS = 1'b0; - parameter [15:0] RXPI_CFG0 = 16'h0002; - parameter [15:0] RXPI_CFG1 = 16'b0000000000000000; + parameter [15:0] RXPI_CFG = 16'h0100; parameter [0:0] RXPI_LPM = 1'b0; + parameter [15:0] RXPI_RSV0 = 16'h0000; parameter [1:0] RXPI_SEL_LC = 2'b00; parameter [1:0] RXPI_STARTCODE = 2'b00; parameter [0:0] RXPI_VREFSEL = 1'b0; @@ -15466,14 +15482,13 @@ module GTHE4_CHANNEL (...); parameter [4:0] RXPMARESET_TIME = 5'b00001; parameter [0:0] RXPRBS_ERR_LOOPBACK = 1'b0; parameter integer RXPRBS_LINKACQ_CNT = 15; - parameter [0:0] RXREFCLKDIV2_SEL = 1'b0; parameter integer RXSLIDE_AUTO_WAIT = 7; parameter RXSLIDE_MODE = "OFF"; parameter [0:0] RXSYNC_MULTILANE = 1'b0; parameter [0:0] RXSYNC_OVRD = 1'b0; parameter [0:0] RXSYNC_SKIP_DA = 1'b0; parameter [0:0] RX_AFE_CM_EN = 1'b0; - parameter [15:0] RX_BIAS_CFG0 = 16'h12B0; + parameter [15:0] RX_BIAS_CFG0 = 16'h1534; parameter [5:0] RX_BUFFER_CFG = 6'b000000; parameter [0:0] RX_CAPFF_SARC_ENB = 1'b0; parameter integer RX_CLK25_DIV = 8; @@ -15482,27 +15497,29 @@ module GTHE4_CHANNEL (...); parameter [3:0] RX_CM_BUF_CFG = 4'b1010; parameter [0:0] RX_CM_BUF_PD = 1'b0; parameter integer RX_CM_SEL = 3; - parameter integer RX_CM_TRIM = 12; - parameter [7:0] RX_CTLE3_LPF = 8'b00000000; + parameter integer RX_CM_TRIM = 10; + parameter [0:0] RX_CTLE1_KHKL = 1'b0; + parameter [0:0] RX_CTLE2_KHKL = 1'b0; + parameter [0:0] RX_CTLE3_AGC = 1'b0; parameter integer RX_DATA_WIDTH = 20; parameter [5:0] RX_DDI_SEL = 6'b000000; parameter RX_DEFER_RESET_BUF_EN = "TRUE"; - parameter [2:0] RX_DEGEN_CTRL = 3'b011; - parameter integer RX_DFELPM_CFG0 = 0; - parameter [0:0] RX_DFELPM_CFG1 = 1'b1; + parameter [2:0] RX_DEGEN_CTRL = 3'b010; + parameter integer RX_DFELPM_CFG0 = 6; + parameter [0:0] RX_DFELPM_CFG1 = 1'b0; parameter [0:0] RX_DFELPM_KLKH_AGC_STUP_EN = 1'b1; parameter [1:0] RX_DFE_AGC_CFG0 = 2'b00; parameter integer RX_DFE_AGC_CFG1 = 4; parameter integer RX_DFE_KL_LPM_KH_CFG0 = 1; - parameter integer RX_DFE_KL_LPM_KH_CFG1 = 4; + parameter integer RX_DFE_KL_LPM_KH_CFG1 = 2; parameter [1:0] RX_DFE_KL_LPM_KL_CFG0 = 2'b01; - parameter integer RX_DFE_KL_LPM_KL_CFG1 = 4; + parameter [2:0] RX_DFE_KL_LPM_KL_CFG1 = 3'b010; parameter [0:0] RX_DFE_LPM_HOLD_DURING_EIDLE = 1'b0; parameter RX_DISPERR_SEQ_MATCH = "TRUE"; parameter [0:0] RX_DIV2_MODE_B = 1'b0; parameter [4:0] RX_DIVRESET_TIME = 5'b00001; parameter [0:0] RX_EN_CTLE_RCAL_B = 1'b0; - parameter [0:0] RX_EN_HI_LR = 1'b1; + parameter [0:0] RX_EN_HI_LR = 1'b0; parameter [8:0] RX_EXT_RL_CTRL = 9'b000000000; parameter [6:0] RX_EYESCAN_VS_CODE = 7'b0000000; parameter [0:0] RX_EYESCAN_VS_NEG_DIR = 1'b0; @@ -15511,7 +15528,6 @@ module GTHE4_CHANNEL (...); parameter [0:0] RX_FABINT_USRCLK_FLOP = 1'b0; parameter integer RX_INT_DATAWIDTH = 1; parameter [0:0] RX_PMA_POWER_SAVE = 1'b0; - parameter [15:0] RX_PMA_RSV0 = 16'h0000; parameter real RX_PROGDIV_CFG = 0.0; parameter [15:0] RX_PROGDIV_RATE = 16'h0001; parameter [3:0] RX_RESLOAD_CTRL = 4'b0000; @@ -15519,32 +15535,34 @@ module GTHE4_CHANNEL (...); parameter [2:0] RX_SAMPLE_PERIOD = 3'b101; parameter integer RX_SIG_VALID_DLY = 11; parameter [0:0] RX_SUM_DFETAPREP_EN = 1'b0; - parameter [3:0] RX_SUM_IREF_TUNE = 4'b1001; - parameter [3:0] RX_SUM_RESLOAD_CTRL = 4'b0000; - parameter [3:0] RX_SUM_VCMTUNE = 4'b1010; + parameter [3:0] RX_SUM_IREF_TUNE = 4'b0000; + parameter [3:0] RX_SUM_VCMTUNE = 4'b1000; parameter [0:0] RX_SUM_VCM_OVWR = 1'b0; parameter [2:0] RX_SUM_VREF_TUNE = 3'b100; parameter [1:0] RX_TUNE_AFE_OS = 2'b00; parameter [2:0] RX_VREG_CTRL = 3'b101; parameter [0:0] RX_VREG_PDB = 1'b1; parameter [1:0] RX_WIDEMODE_CDR = 2'b01; - parameter [1:0] RX_WIDEMODE_CDR_GEN3 = 2'b01; - parameter [1:0] RX_WIDEMODE_CDR_GEN4 = 2'b01; parameter RX_XCLK_SEL = "RXDES"; parameter [0:0] RX_XMODE_SEL = 1'b0; - parameter [0:0] SAMPLE_CLK_PHASE = 1'b0; - parameter [0:0] SAS_12G_MODE = 1'b0; + parameter integer SAS_MAX_COM = 64; + parameter integer SAS_MIN_COM = 36; parameter [3:0] SATA_BURST_SEQ_LEN = 4'b1111; parameter [2:0] SATA_BURST_VAL = 3'b100; parameter SATA_CPLL_CFG = "VCO_3000MHZ"; parameter [2:0] SATA_EIDLE_VAL = 3'b100; + parameter integer SATA_MAX_BURST = 8; + parameter integer SATA_MAX_INIT = 21; + parameter integer SATA_MAX_WAKE = 7; + parameter integer SATA_MIN_BURST = 4; + parameter integer SATA_MIN_INIT = 12; + parameter integer SATA_MIN_WAKE = 4; parameter SHOW_REALIGN_COMMA = "TRUE"; - parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RECEIVER_DETECT_PASS = "TRUE"; parameter SIM_RESET_SPEEDUP = "TRUE"; - parameter SIM_TX_EIDLE_DRIVE_LEVEL = "Z"; - parameter [0:0] SRSTMODE = 1'b0; + parameter [0:0] SIM_TX_EIDLE_DRIVE_LEVEL = 1'b0; + parameter integer SIM_VERSION = 2; parameter [1:0] TAPDLY_SET_TX = 2'h0; parameter [3:0] TEMPERATURE_PAR = 4'b0010; parameter [14:0] TERM_RCAL_CFG = 15'b100001000010000; @@ -15554,20 +15572,18 @@ module GTHE4_CHANNEL (...); parameter [7:0] TST_RSV1 = 8'h00; parameter TXBUF_EN = "TRUE"; parameter TXBUF_RESET_ON_RATE_CHANGE = "FALSE"; - parameter [15:0] TXDLY_CFG = 16'h0010; + parameter [15:0] TXDLY_CFG = 16'h001F; parameter [15:0] TXDLY_LCFG = 16'h0030; - parameter [3:0] TXDRVBIAS_N = 4'b1010; parameter TXFIFO_ADDR_CFG = "LOW"; parameter integer TXGBOX_FIFO_INIT_RD_ADDR = 4; parameter TXGEARBOX_EN = "FALSE"; parameter integer TXOUT_DIV = 4; parameter [4:0] TXPCSRESET_TIME = 5'b00001; - parameter [15:0] TXPHDLY_CFG0 = 16'h6020; - parameter [15:0] TXPHDLY_CFG1 = 16'h0002; + parameter [15:0] TXPHDLY_CFG0 = 16'h2020; + parameter [15:0] TXPHDLY_CFG1 = 16'h0001; parameter [15:0] TXPH_CFG = 16'h0123; parameter [15:0] TXPH_CFG2 = 16'h0000; parameter [4:0] TXPH_MONITOR_SEL = 5'b00000; - parameter [15:0] TXPI_CFG = 16'h0000; parameter [1:0] TXPI_CFG0 = 2'b00; parameter [1:0] TXPI_CFG1 = 2'b00; parameter [1:0] TXPI_CFG2 = 2'b00; @@ -15577,29 +15593,30 @@ module GTHE4_CHANNEL (...); parameter [0:0] TXPI_GRAY_SEL = 1'b0; parameter [0:0] TXPI_INVSTROBE_SEL = 1'b0; parameter [0:0] TXPI_LPM = 1'b0; - parameter [0:0] TXPI_PPM = 1'b0; parameter TXPI_PPMCLK_SEL = "TXUSRCLK2"; parameter [7:0] TXPI_PPM_CFG = 8'b00000000; + parameter [15:0] TXPI_RSV0 = 16'h0000; parameter [2:0] TXPI_SYNFREQ_PPM = 3'b000; parameter [0:0] TXPI_VREFSEL = 1'b0; parameter [4:0] TXPMARESET_TIME = 5'b00001; - parameter [0:0] TXREFCLKDIV2_SEL = 1'b0; parameter [0:0] TXSYNC_MULTILANE = 1'b0; parameter [0:0] TXSYNC_OVRD = 1'b0; parameter [0:0] TXSYNC_SKIP_DA = 1'b0; parameter integer TX_CLK25_DIV = 8; parameter [0:0] TX_CLKMUX_EN = 1'b1; + parameter [0:0] TX_CLKREG_PDB = 1'b0; + parameter [2:0] TX_CLKREG_SET = 3'b000; parameter integer TX_DATA_WIDTH = 20; - parameter [15:0] TX_DCC_LOOP_RST_CFG = 16'h0000; + parameter [5:0] TX_DCD_CFG = 6'b000010; + parameter [0:0] TX_DCD_EN = 1'b0; parameter [5:0] TX_DEEMPH0 = 6'b000000; parameter [5:0] TX_DEEMPH1 = 6'b000000; - parameter [5:0] TX_DEEMPH2 = 6'b000000; - parameter [5:0] TX_DEEMPH3 = 6'b000000; parameter [4:0] TX_DIVRESET_TIME = 5'b00001; parameter TX_DRIVE_MODE = "DIRECT"; parameter integer TX_DRVMUX_CTRL = 2; parameter [2:0] TX_EIDLE_ASSERT_DELAY = 3'b110; parameter [2:0] TX_EIDLE_DEASSERT_DELAY = 3'b100; + parameter [0:0] TX_EML_PHI_TUNE = 1'b0; parameter [0:0] TX_FABINT_USRCLK_FLOP = 1'b0; parameter [0:0] TX_FIFO_BYP_EN = 1'b0; parameter [0:0] TX_IDLE_DATA_ZERO = 1'b0; @@ -15616,75 +15633,44 @@ module GTHE4_CHANNEL (...); parameter [6:0] TX_MARGIN_LOW_2 = 7'b1000010; parameter [6:0] TX_MARGIN_LOW_3 = 7'b1000000; parameter [6:0] TX_MARGIN_LOW_4 = 7'b1000000; + parameter [2:0] TX_MODE_SEL = 3'b000; parameter [15:0] TX_PHICAL_CFG0 = 16'h0000; - parameter [15:0] TX_PHICAL_CFG1 = 16'h003F; + parameter [15:0] TX_PHICAL_CFG1 = 16'h7E00; parameter [15:0] TX_PHICAL_CFG2 = 16'h0000; parameter integer TX_PI_BIASSET = 0; - parameter [1:0] TX_PI_IBIAS_MID = 2'b00; + parameter [15:0] TX_PI_CFG0 = 16'h0000; + parameter [15:0] TX_PI_CFG1 = 16'h0000; + parameter [0:0] TX_PI_DIV2_MODE_B = 1'b0; + parameter [0:0] TX_PI_SEL_QPLL0 = 1'b0; + parameter [0:0] TX_PI_SEL_QPLL1 = 1'b0; parameter [0:0] TX_PMADATA_OPT = 1'b0; parameter [0:0] TX_PMA_POWER_SAVE = 1'b0; - parameter [15:0] TX_PMA_RSV0 = 16'h0008; parameter integer TX_PREDRV_CTRL = 2; parameter TX_PROGCLK_SEL = "POSTPI"; parameter real TX_PROGDIV_CFG = 0.0; parameter [15:0] TX_PROGDIV_RATE = 16'h0001; - parameter [0:0] TX_QPI_STATUS_EN = 1'b0; parameter [13:0] TX_RXDETECT_CFG = 14'h0032; - parameter integer TX_RXDETECT_REF = 3; + parameter integer TX_RXDETECT_REF = 4; parameter [2:0] TX_SAMPLE_PERIOD = 3'b101; parameter [0:0] TX_SARC_LPBK_ENB = 1'b0; - parameter [1:0] TX_SW_MEAS = 2'b00; - parameter [2:0] TX_VREG_CTRL = 3'b000; - parameter [0:0] TX_VREG_PDB = 1'b0; - parameter [1:0] TX_VREG_VREFSEL = 2'b00; parameter TX_XCLK_SEL = "TXOUT"; - parameter [0:0] USB_BOTH_BURST_IDLE = 1'b0; - parameter [6:0] USB_BURSTMAX_U3WAKE = 7'b1111111; - parameter [6:0] USB_BURSTMIN_U3WAKE = 7'b1100011; - parameter [0:0] USB_CLK_COR_EQ_EN = 1'b0; - parameter [0:0] USB_EXT_CNTL = 1'b1; - parameter [9:0] USB_IDLEMAX_POLLING = 10'b1010111011; - parameter [9:0] USB_IDLEMIN_POLLING = 10'b0100101011; - parameter [8:0] USB_LFPSPING_BURST = 9'b000000101; - parameter [8:0] USB_LFPSPOLLING_BURST = 9'b000110001; - parameter [8:0] USB_LFPSPOLLING_IDLE_MS = 9'b000000100; - parameter [8:0] USB_LFPSU1EXIT_BURST = 9'b000011101; - parameter [8:0] USB_LFPSU2LPEXIT_BURST_MS = 9'b001100011; - parameter [8:0] USB_LFPSU3WAKE_BURST_MS = 9'b111110011; - parameter [3:0] USB_LFPS_TPERIOD = 4'b0011; - parameter [0:0] USB_LFPS_TPERIOD_ACCURATE = 1'b1; - parameter [0:0] USB_MODE = 1'b0; - parameter [0:0] USB_PCIE_ERR_REP_DIS = 1'b0; - parameter integer USB_PING_SATA_MAX_INIT = 21; - parameter integer USB_PING_SATA_MIN_INIT = 12; - parameter integer USB_POLL_SATA_MAX_BURST = 8; - parameter integer USB_POLL_SATA_MIN_BURST = 4; - parameter [0:0] USB_RAW_ELEC = 1'b0; - parameter [0:0] USB_RXIDLE_P0_CTRL = 1'b1; - parameter [0:0] USB_TXIDLE_TUNE_ENABLE = 1'b1; - parameter integer USB_U1_SATA_MAX_WAKE = 7; - parameter integer USB_U1_SATA_MIN_WAKE = 4; - parameter integer USB_U2_SAS_MAX_COM = 64; - parameter integer USB_U2_SAS_MIN_COM = 36; parameter [0:0] USE_PCS_CLK_PHASE_SEL = 1'b0; - parameter [0:0] Y_ALL_MODE = 1'b0; - output BUFGTCE; + output [2:0] BUFGTCE; output [2:0] BUFGTCEMASK; output [8:0] BUFGTDIV; - output BUFGTRESET; + output [2:0] BUFGTRESET; output [2:0] BUFGTRSTMASK; output CPLLFBCLKLOST; output CPLLLOCK; output CPLLREFCLKLOST; - output [15:0] DMONITOROUT; - output DMONITOROUTCLK; + output [16:0] DMONITOROUT; output [15:0] DRPDO; output DRPRDY; output EYESCANDATAERROR; - output GTHTXN; - output GTHTXP; output GTPOWERGOOD; output GTREFCLKMONITOR; + output GTYTXN; + output GTYTXP; output PCIERATEGEN3; output PCIERATEIDLE; output [1:0] PCIERATEQPLLPD; @@ -15695,8 +15681,7 @@ module GTHE4_CHANNEL (...); output PCIEUSERRATESTART; output [15:0] PCSRSVDOUT; output PHYSTATUS; - output [15:0] PINRSRVDAS; - output POWERPRESENT; + output [7:0] PINRSRVDAS; output RESETEXCEPTION; output [2:0] RXBUFSTATUS; output RXBYTEISALIGNED; @@ -15724,10 +15709,7 @@ module GTHE4_CHANNEL (...); output RXELECIDLE; output [5:0] RXHEADER; output [1:0] RXHEADERVALID; - output RXLFPSTRESETDET; - output RXLFPSU2LPEXITDET; - output RXLFPSU3WAKEDET; - output [7:0] RXMONITOROUT; + output [6:0] RXMONITOROUT; output RXOSINTDONE; output RXOSINTSTARTED; output RXOSINTSTROBEDONE; @@ -15741,8 +15723,6 @@ module GTHE4_CHANNEL (...); output RXPRBSERR; output RXPRBSLOCKED; output RXPRGDIVRESETDONE; - output RXQPISENN; - output RXQPISENP; output RXRATEDONE; output RXRECCLKOUT; output RXRESETDONE; @@ -15766,8 +15746,6 @@ module GTHE4_CHANNEL (...); output TXPHINITDONE; output TXPMARESETDONE; output TXPRGDIVRESETDONE; - output TXQPISENN; - output TXQPISENP; output TXRATEDONE; output TXRESETDONE; output TXSYNCDONE; @@ -15778,7 +15756,6 @@ module GTHE4_CHANNEL (...); input CFGRESET; input CLKRSVD0; input CLKRSVD1; - input CPLLFREQLOCK; input CPLLLOCKDETCLK; input CPLLLOCKEN; input CPLLPD; @@ -15790,64 +15767,65 @@ module GTHE4_CHANNEL (...); input DRPCLK; input [15:0] DRPDI; input DRPEN; - input DRPRST; input DRPWE; + input ELPCALDVORWREN; + input ELPCALPAORWREN; + input EVODDPHICALDONE; + input EVODDPHICALSTART; + input EVODDPHIDRDEN; + input EVODDPHIDWREN; + input EVODDPHIXRDEN; + input EVODDPHIXWREN; + input EYESCANMODE; input EYESCANRESET; input EYESCANTRIGGER; - input FREQOS; input GTGREFCLK; - input GTHRXN; - input GTHRXP; input GTNORTHREFCLK0; input GTNORTHREFCLK1; input GTREFCLK0; input GTREFCLK1; + input GTRESETSEL; input [15:0] GTRSVD; input GTRXRESET; - input GTRXRESETSEL; input GTSOUTHREFCLK0; input GTSOUTHREFCLK1; input GTTXRESET; - input GTTXRESETSEL; - input INCPCTRL; + input GTYRXN; + input GTYRXP; input [2:0] LOOPBACK; + input [15:0] LOOPRSVD; + input LPBKRXTXSEREN; + input LPBKTXRXSEREN; input PCIEEQRXEQADAPTDONE; input PCIERSTIDLE; input PCIERSTTXSYNCSTART; input PCIEUSERRATEDONE; input [15:0] PCSRSVDIN; + input [4:0] PCSRSVDIN2; + input [4:0] PMARSVDIN; input QPLL0CLK; - input QPLL0FREQLOCK; input QPLL0REFCLK; input QPLL1CLK; - input QPLL1FREQLOCK; input QPLL1REFCLK; input RESETOVRD; + input RSTCLKENTX; input RX8B10BEN; - input RXAFECFOKEN; input RXBUFRESET; input RXCDRFREQRESET; input RXCDRHOLD; input RXCDROVRDEN; input RXCDRRESET; + input RXCDRRESETRSV; input RXCHBONDEN; input [4:0] RXCHBONDI; input [2:0] RXCHBONDLEVEL; input RXCHBONDMASTER; input RXCHBONDSLAVE; input RXCKCALRESET; - input [6:0] RXCKCALSTART; input RXCOMMADETEN; - input [1:0] RXDFEAGCCTRL; + input RXDCCFORCESTART; input RXDFEAGCHOLD; input RXDFEAGCOVRDEN; - input [3:0] RXDFECFOKFCNUM; - input RXDFECFOKFEN; - input RXDFECFOKFPULSE; - input RXDFECFOKHOLD; - input RXDFECFOKOVREN; - input RXDFEKHHOLD; - input RXDFEKHOVRDEN; input RXDFELFHOLD; input RXDFELFOVRDEN; input RXDFELPMRESET; @@ -15883,13 +15861,13 @@ module GTHE4_CHANNEL (...); input RXDFEUTOVRDEN; input RXDFEVPHOLD; input RXDFEVPOVRDEN; + input RXDFEVSEN; input RXDFEXYDEN; input RXDLYBYPASS; input RXDLYEN; input RXDLYOVRDEN; input RXDLYSRESET; input [1:0] RXELECIDLEMODE; - input RXEQTRAINING; input RXGEARBOXSLIP; input RXLATCLK; input RXLPMEN; @@ -15906,6 +15884,12 @@ module GTHE4_CHANNEL (...); input RXOOBRESET; input RXOSCALRESET; input RXOSHOLD; + input [3:0] RXOSINTCFG; + input RXOSINTEN; + input RXOSINTHOLD; + input RXOSINTOVRDEN; + input RXOSINTSTROBE; + input RXOSINTTESTOVRDEN; input RXOSOVRDEN; input [2:0] RXOUTCLKSEL; input RXPCOMMAALIGNEN; @@ -15922,7 +15906,6 @@ module GTHE4_CHANNEL (...); input RXPRBSCNTRESET; input [3:0] RXPRBSSEL; input RXPROGDIVRESET; - input RXQPIEN; input [2:0] RXRATE; input RXRATEMODE; input RXSLIDE; @@ -15932,7 +15915,6 @@ module GTHE4_CHANNEL (...); input RXSYNCIN; input RXSYNCMODE; input [1:0] RXSYSCLKSEL; - input RXTERMINATION; input RXUSERRDY; input RXUSRCLK; input RXUSRCLK2; @@ -15940,6 +15922,7 @@ module GTHE4_CHANNEL (...); input [19:0] TSTIN; input [7:0] TX8B10BBYPASS; input TX8B10BEN; + input [2:0] TXBUFDIFFCTRL; input TXCOMINIT; input TXCOMSAS; input TXCOMWAKE; @@ -15950,9 +15933,10 @@ module GTHE4_CHANNEL (...); input [7:0] TXDATAEXTENDRSVD; input TXDCCFORCESTART; input TXDCCRESET; - input [1:0] TXDEEMPH; + input TXDEEMPH; input TXDETECTRX; input [4:0] TXDIFFCTRL; + input TXDIFFPD; input TXDLYBYPASS; input TXDLYEN; input TXDLYHOLD; @@ -15960,17 +15944,12 @@ module GTHE4_CHANNEL (...); input TXDLYSRESET; input TXDLYUPDOWN; input TXELECIDLE; + input TXELFORCESTART; input [5:0] TXHEADER; input TXINHIBIT; input TXLATCLK; - input TXLFPSTRESET; - input TXLFPSU2LPEXIT; - input TXLFPSU3WAKE; input [6:0] TXMAINCURSOR; input [2:0] TXMARGIN; - input TXMUXDCDEXHOLD; - input TXMUXDCDORWREN; - input TXONESZEROS; input [2:0] TXOUTCLKSEL; input TXPCSRESET; input [1:0] TXPD; @@ -15996,8 +15975,6 @@ module GTHE4_CHANNEL (...); input [3:0] TXPRBSSEL; input [4:0] TXPRECURSOR; input TXPROGDIVRESET; - input TXQPIBIASEN; - input TXQPIWEAKPUP; input [2:0] TXRATE; input TXRATEMODE; input [6:0] TXSEQUENCE; @@ -16011,34 +15988,28 @@ module GTHE4_CHANNEL (...); input TXUSRCLK2; endmodule -module GTHE4_COMMON (...); - parameter [0:0] AEN_QPLL0_FBDIV = 1'b1; - parameter [0:0] AEN_QPLL1_FBDIV = 1'b1; - parameter [0:0] AEN_SDM0TOGGLE = 1'b0; - parameter [0:0] AEN_SDM1TOGGLE = 1'b0; - parameter [0:0] A_SDM0TOGGLE = 1'b0; - parameter [8:0] A_SDM1DATA_HIGH = 9'b000000000; - parameter [15:0] A_SDM1DATA_LOW = 16'b0000000000000000; - parameter [0:0] A_SDM1TOGGLE = 1'b0; +module GTYE3_COMMON (...); + parameter [15:0] A_SDM1DATA1_0 = 16'b0000000000000000; + parameter [8:0] A_SDM1DATA1_1 = 9'b000000000; parameter [15:0] BIAS_CFG0 = 16'h0000; parameter [15:0] BIAS_CFG1 = 16'h0000; parameter [15:0] BIAS_CFG2 = 16'h0000; parameter [15:0] BIAS_CFG3 = 16'h0000; parameter [15:0] BIAS_CFG4 = 16'h0000; - parameter [15:0] BIAS_CFG_RSVD = 16'h0000; + parameter [9:0] BIAS_CFG_RSVD = 10'b0000000000; parameter [15:0] COMMON_CFG0 = 16'h0000; parameter [15:0] COMMON_CFG1 = 16'h0000; - parameter [15:0] POR_CFG = 16'h0000; - parameter [15:0] PPF0_CFG = 16'h0F00; - parameter [15:0] PPF1_CFG = 16'h0F00; + parameter [15:0] POR_CFG = 16'h0004; + parameter [15:0] PPF0_CFG = 16'h0FFF; + parameter [15:0] PPF1_CFG = 16'h0FFF; parameter QPLL0CLKOUT_RATE = "FULL"; - parameter [15:0] QPLL0_CFG0 = 16'h391C; + parameter [15:0] QPLL0_CFG0 = 16'h301C; parameter [15:0] QPLL0_CFG1 = 16'h0000; parameter [15:0] QPLL0_CFG1_G3 = 16'h0020; - parameter [15:0] QPLL0_CFG2 = 16'h0F80; - parameter [15:0] QPLL0_CFG2_G3 = 16'h0F80; + parameter [15:0] QPLL0_CFG2 = 16'h0780; + parameter [15:0] QPLL0_CFG2_G3 = 16'h0780; parameter [15:0] QPLL0_CFG3 = 16'h0120; - parameter [15:0] QPLL0_CFG4 = 16'h0002; + parameter [15:0] QPLL0_CFG4 = 16'h0021; parameter [9:0] QPLL0_CP = 10'b0000011111; parameter [9:0] QPLL0_CP_G3 = 10'b0000011111; parameter integer QPLL0_FBDIV = 66; @@ -16047,22 +16018,20 @@ module GTHE4_COMMON (...); parameter [7:0] QPLL0_INIT_CFG1 = 8'h00; parameter [15:0] QPLL0_LOCK_CFG = 16'h01E8; parameter [15:0] QPLL0_LOCK_CFG_G3 = 16'h21E8; - parameter [9:0] QPLL0_LPF = 10'b1011111111; + parameter [9:0] QPLL0_LPF = 10'b1111111111; parameter [9:0] QPLL0_LPF_G3 = 10'b1111111111; - parameter [0:0] QPLL0_PCI_EN = 1'b0; - parameter [0:0] QPLL0_RATE_SW_USE_DRP = 1'b0; - parameter integer QPLL0_REFCLK_DIV = 1; + parameter integer QPLL0_REFCLK_DIV = 2; parameter [15:0] QPLL0_SDM_CFG0 = 16'h0040; parameter [15:0] QPLL0_SDM_CFG1 = 16'h0000; parameter [15:0] QPLL0_SDM_CFG2 = 16'h0000; parameter QPLL1CLKOUT_RATE = "FULL"; - parameter [15:0] QPLL1_CFG0 = 16'h691C; - parameter [15:0] QPLL1_CFG1 = 16'h0020; + parameter [15:0] QPLL1_CFG0 = 16'h301C; + parameter [15:0] QPLL1_CFG1 = 16'h0000; parameter [15:0] QPLL1_CFG1_G3 = 16'h0020; - parameter [15:0] QPLL1_CFG2 = 16'h0F80; - parameter [15:0] QPLL1_CFG2_G3 = 16'h0F80; + parameter [15:0] QPLL1_CFG2 = 16'h0780; + parameter [15:0] QPLL1_CFG2_G3 = 16'h0780; parameter [15:0] QPLL1_CFG3 = 16'h0120; - parameter [15:0] QPLL1_CFG4 = 16'h0002; + parameter [15:0] QPLL1_CFG4 = 16'h0021; parameter [9:0] QPLL1_CP = 10'b0000011111; parameter [9:0] QPLL1_CP_G3 = 10'b0000011111; parameter integer QPLL1_FBDIV = 66; @@ -16071,12 +16040,10 @@ module GTHE4_COMMON (...); parameter [7:0] QPLL1_INIT_CFG1 = 8'h00; parameter [15:0] QPLL1_LOCK_CFG = 16'h01E8; parameter [15:0] QPLL1_LOCK_CFG_G3 = 16'h21E8; - parameter [9:0] QPLL1_LPF = 10'b1011111111; + parameter [9:0] QPLL1_LPF = 10'b1111111111; parameter [9:0] QPLL1_LPF_G3 = 10'b1111111111; - parameter [0:0] QPLL1_PCI_EN = 1'b0; - parameter [0:0] QPLL1_RATE_SW_USE_DRP = 1'b0; - parameter integer QPLL1_REFCLK_DIV = 1; - parameter [15:0] QPLL1_SDM_CFG0 = 16'h0000; + parameter integer QPLL1_REFCLK_DIV = 2; + parameter [15:0] QPLL1_SDM_CFG0 = 16'h0040; parameter [15:0] QPLL1_SDM_CFG1 = 16'h0000; parameter [15:0] QPLL1_SDM_CFG2 = 16'h0000; parameter [15:0] RSVD_ATTR0 = 16'h0000; @@ -16085,15 +16052,15 @@ module GTHE4_COMMON (...); parameter [15:0] RSVD_ATTR3 = 16'h0000; parameter [1:0] RXRECCLKOUT0_SEL = 2'b00; parameter [1:0] RXRECCLKOUT1_SEL = 2'b00; - parameter [0:0] SARC_ENB = 1'b0; + parameter [0:0] SARC_EN = 1'b1; parameter [0:0] SARC_SEL = 1'b0; parameter [15:0] SDM0INITSEED0_0 = 16'b0000000000000000; parameter [8:0] SDM0INITSEED0_1 = 9'b000000000; parameter [15:0] SDM1INITSEED0_0 = 16'b0000000000000000; parameter [8:0] SDM1INITSEED0_1 = 9'b000000000; - parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RESET_SPEEDUP = "TRUE"; + parameter integer SIM_VERSION = 2; output [15:0] DRPDO; output DRPRDY; output [7:0] PMARSVDOUT0; @@ -16112,20 +16079,18 @@ module GTHE4_COMMON (...); output [7:0] QPLLDMONITOR1; output REFCLKOUTMONITOR0; output REFCLKOUTMONITOR1; - output [1:0] RXRECCLK0SEL; - output [1:0] RXRECCLK1SEL; + output [1:0] RXRECCLK0_SEL; + output [1:0] RXRECCLK1_SEL; output [3:0] SDM0FINALOUT; output [14:0] SDM0TESTDATA; output [3:0] SDM1FINALOUT; output [14:0] SDM1TESTDATA; - output [9:0] TCONGPO; - output TCONRSVDOUT0; input BGBYPASSB; input BGMONITORENB; input BGPDB; input [4:0] BGRCALOVRD; input BGRCALOVRDENB; - input [15:0] DRPADDR; + input [9:0] DRPADDR; input DRPCLK; input [15:0] DRPDI; input DRPEN; @@ -16144,21 +16109,15 @@ module GTHE4_COMMON (...); input GTSOUTHREFCLK01; input GTSOUTHREFCLK10; input GTSOUTHREFCLK11; - input [2:0] PCIERATEQPLL0; - input [2:0] PCIERATEQPLL1; input [7:0] PMARSVD0; input [7:0] PMARSVD1; input QPLL0CLKRSVD0; - input QPLL0CLKRSVD1; - input [7:0] QPLL0FBDIV; input QPLL0LOCKDETCLK; input QPLL0LOCKEN; input QPLL0PD; input [2:0] QPLL0REFCLKSEL; input QPLL0RESET; input QPLL1CLKRSVD0; - input QPLL1CLKRSVD1; - input [7:0] QPLL1FBDIV; input QPLL1LOCKDETCLK; input QPLL1LOCKEN; input QPLL1PD; @@ -16171,25 +16130,55 @@ module GTHE4_COMMON (...); input RCALENB; input [24:0] SDM0DATA; input SDM0RESET; - input SDM0TOGGLE; input [1:0] SDM0WIDTH; input [24:0] SDM1DATA; input SDM1RESET; - input SDM1TOGGLE; input [1:0] SDM1WIDTH; - input [9:0] TCONGPI; - input TCONPOWERUP; - input [1:0] TCONRESET; - input [1:0] TCONRSVDIN1; endmodule -module GTYE3_CHANNEL (...); +module IBUFDS_GTE3 (...); + parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; + parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00; + parameter [1:0] REFCLK_ICNTL_RX = 2'b00; + output O; + output ODIV2; + input CEB; + (* iopad_external_pin *) + input I; + (* iopad_external_pin *) + input IB; +endmodule + +module OBUFDS_GTE3 (...); + parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; + parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; + (* iopad_external_pin *) + output O; + (* iopad_external_pin *) + output OB; + input CEB; + input I; +endmodule + +module OBUFDS_GTE3_ADV (...); + parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; + parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; + (* iopad_external_pin *) + output O; + (* iopad_external_pin *) + output OB; + input CEB; + input [3:0] I; + input [1:0] RXRECCLK_SEL; +endmodule + +module GTHE4_CHANNEL (...); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; parameter [15:0] ADAPT_CFG0 = 16'h9200; parameter [15:0] ADAPT_CFG1 = 16'h801C; - parameter [15:0] ADAPT_CFG2 = 16'b0000000000000000; + parameter [15:0] ADAPT_CFG2 = 16'h0000; parameter ALIGN_COMMA_DOUBLE = "FALSE"; parameter [9:0] ALIGN_COMMA_ENABLE = 10'b0001111111; parameter integer ALIGN_COMMA_WORD = 1; @@ -16197,14 +16186,15 @@ module GTYE3_CHANNEL (...); parameter [9:0] ALIGN_MCOMMA_VALUE = 10'b1010000011; parameter ALIGN_PCOMMA_DET = "TRUE"; parameter [9:0] ALIGN_PCOMMA_VALUE = 10'b0101111100; - parameter [0:0] AUTO_BW_SEL_BYPASS = 1'b0; parameter [0:0] A_RXOSCALRESET = 1'b0; parameter [0:0] A_RXPROGDIVRESET = 1'b0; + parameter [0:0] A_RXTERMINATION = 1'b1; parameter [4:0] A_TXDIFFCTRL = 5'b01100; parameter [0:0] A_TXPROGDIVRESET = 1'b0; parameter [0:0] CAPBYPASS_FORCE = 1'b0; parameter CBCC_DATA_SOURCE_SEL = "DECODED"; parameter [0:0] CDR_SWAP_MODE_EN = 1'b0; + parameter [0:0] CFOK_PWRSVE_EN = 1'b1; parameter CHAN_BOND_KEEP_ALIGN = "FALSE"; parameter integer CHAN_BOND_MAX_SKEW = 7; parameter [9:0] CHAN_BOND_SEQ_1_1 = 10'b0101111100; @@ -16219,7 +16209,7 @@ module GTYE3_CHANNEL (...); parameter [3:0] CHAN_BOND_SEQ_2_ENABLE = 4'b1111; parameter CHAN_BOND_SEQ_2_USE = "FALSE"; parameter integer CHAN_BOND_SEQ_LEN = 2; - parameter [15:0] CH_HSPMUX = 16'h0000; + parameter [15:0] CH_HSPMUX = 16'h2424; parameter [15:0] CKCAL1_CFG_0 = 16'b0000000000000000; parameter [15:0] CKCAL1_CFG_1 = 16'b0000000000000000; parameter [15:0] CKCAL1_CFG_2 = 16'b0000000000000000; @@ -16229,7 +16219,7 @@ module GTYE3_CHANNEL (...); parameter [15:0] CKCAL2_CFG_2 = 16'b0000000000000000; parameter [15:0] CKCAL2_CFG_3 = 16'b0000000000000000; parameter [15:0] CKCAL2_CFG_4 = 16'b0000000000000000; - parameter [15:0] CKCAL_RSVD0 = 16'h0000; + parameter [15:0] CKCAL_RSVD0 = 16'h4000; parameter [15:0] CKCAL_RSVD1 = 16'h0000; parameter CLK_CORRECT_USE = "TRUE"; parameter CLK_COR_KEEP_IDLE = "FALSE"; @@ -16249,14 +16239,13 @@ module GTYE3_CHANNEL (...); parameter [3:0] CLK_COR_SEQ_2_ENABLE = 4'b1111; parameter CLK_COR_SEQ_2_USE = "FALSE"; parameter integer CLK_COR_SEQ_LEN = 2; - parameter [15:0] CPLL_CFG0 = 16'h20F8; - parameter [15:0] CPLL_CFG1 = 16'hA494; - parameter [15:0] CPLL_CFG2 = 16'hF001; - parameter [5:0] CPLL_CFG3 = 6'h00; + parameter [15:0] CPLL_CFG0 = 16'h01FA; + parameter [15:0] CPLL_CFG1 = 16'h24A9; + parameter [15:0] CPLL_CFG2 = 16'h6807; + parameter [15:0] CPLL_CFG3 = 16'h0000; parameter integer CPLL_FBDIV = 4; parameter integer CPLL_FBDIV_45 = 4; parameter [15:0] CPLL_INIT_CFG0 = 16'h001E; - parameter [7:0] CPLL_INIT_CFG1 = 8'h00; parameter [15:0] CPLL_LOCK_CFG = 16'h01E8; parameter integer CPLL_REFCLK_DIV = 1; parameter [2:0] CTLE3_OCAP_EXT_CTRL = 3'b000; @@ -16266,16 +16255,14 @@ module GTYE3_CHANNEL (...); parameter DEC_MCOMMA_DETECT = "TRUE"; parameter DEC_PCOMMA_DETECT = "TRUE"; parameter DEC_VALID_COMMA_ONLY = "TRUE"; - parameter [0:0] DFE_D_X_REL_POS = 1'b0; - parameter [0:0] DFE_VCM_COMP_EN = 1'b0; + parameter [0:0] DELAY_ELEC = 1'b0; parameter [9:0] DMONITOR_CFG0 = 10'h000; parameter [7:0] DMONITOR_CFG1 = 8'h00; parameter [0:0] ES_CLK_PHASE_SEL = 1'b0; parameter [5:0] ES_CONTROL = 6'b000000; parameter ES_ERRDET_EN = "FALSE"; parameter ES_EYE_SCAN_EN = "FALSE"; - parameter [11:0] ES_HORZ_OFFSET = 12'h000; - parameter [9:0] ES_PMA_CFG = 10'b0000000000; + parameter [11:0] ES_HORZ_OFFSET = 12'h800; parameter [4:0] ES_PRESCALE = 5'b00000; parameter [15:0] ES_QUALIFIER0 = 16'h0000; parameter [15:0] ES_QUALIFIER1 = 16'h0000; @@ -16307,32 +16294,19 @@ module GTYE3_CHANNEL (...); parameter [15:0] ES_SDATA_MASK7 = 16'h0000; parameter [15:0] ES_SDATA_MASK8 = 16'h0000; parameter [15:0] ES_SDATA_MASK9 = 16'h0000; - parameter [10:0] EVODD_PHI_CFG = 11'b00000000000; parameter [0:0] EYE_SCAN_SWAP_EN = 1'b0; parameter [3:0] FTS_DESKEW_SEQ_ENABLE = 4'b1111; parameter [3:0] FTS_LANE_DESKEW_CFG = 4'b1111; parameter FTS_LANE_DESKEW_EN = "FALSE"; parameter [4:0] GEARBOX_MODE = 5'b00000; - parameter [0:0] GM_BIAS_SELECT = 1'b0; parameter [0:0] ISCAN_CK_PH_SEL2 = 1'b0; parameter [0:0] LOCAL_MASTER = 1'b0; - parameter [15:0] LOOP0_CFG = 16'h0000; - parameter [15:0] LOOP10_CFG = 16'h0000; - parameter [15:0] LOOP11_CFG = 16'h0000; - parameter [15:0] LOOP12_CFG = 16'h0000; - parameter [15:0] LOOP13_CFG = 16'h0000; - parameter [15:0] LOOP1_CFG = 16'h0000; - parameter [15:0] LOOP2_CFG = 16'h0000; - parameter [15:0] LOOP3_CFG = 16'h0000; - parameter [15:0] LOOP4_CFG = 16'h0000; - parameter [15:0] LOOP5_CFG = 16'h0000; - parameter [15:0] LOOP6_CFG = 16'h0000; - parameter [15:0] LOOP7_CFG = 16'h0000; - parameter [15:0] LOOP8_CFG = 16'h0000; - parameter [15:0] LOOP9_CFG = 16'h0000; parameter [2:0] LPBK_BIAS_CTRL = 3'b000; parameter [0:0] LPBK_EN_RCAL_B = 1'b0; parameter [3:0] LPBK_EXT_RCAL = 4'b0000; + parameter [2:0] LPBK_IND_CTRL0 = 3'b000; + parameter [2:0] LPBK_IND_CTRL1 = 3'b000; + parameter [2:0] LPBK_IND_CTRL2 = 3'b000; parameter [3:0] LPBK_RG_CTRL = 4'b0000; parameter [1:0] OOBDIVCTL = 2'b00; parameter [0:0] OOB_PWRUP = 1'b0; @@ -16345,25 +16319,32 @@ module GTYE3_CHANNEL (...); parameter [5:0] PCI3_RX_ELECIDLE_HI_COUNT = 6'b000000; parameter [0:0] PCI3_RX_ELECIDLE_LP4_DISABLE = 1'b0; parameter [0:0] PCI3_RX_FIFO_DISABLE = 1'b0; + parameter [4:0] PCIE3_CLK_COR_EMPTY_THRSH = 5'b00000; + parameter [5:0] PCIE3_CLK_COR_FULL_THRSH = 6'b010000; + parameter [4:0] PCIE3_CLK_COR_MAX_LAT = 5'b01000; + parameter [4:0] PCIE3_CLK_COR_MIN_LAT = 5'b00100; + parameter [5:0] PCIE3_CLK_COR_THRSH_TIMER = 6'b001000; parameter [15:0] PCIE_BUFG_DIV_CTRL = 16'h0000; - parameter [15:0] PCIE_RXPCS_CFG_GEN3 = 16'h0000; + parameter [1:0] PCIE_PLL_SEL_MODE_GEN12 = 2'h0; + parameter [1:0] PCIE_PLL_SEL_MODE_GEN3 = 2'h0; + parameter [1:0] PCIE_PLL_SEL_MODE_GEN4 = 2'h0; + parameter [15:0] PCIE_RXPCS_CFG_GEN3 = 16'h0000; parameter [15:0] PCIE_RXPMA_CFG = 16'h0000; parameter [15:0] PCIE_TXPCS_CFG_GEN3 = 16'h0000; parameter [15:0] PCIE_TXPMA_CFG = 16'h0000; parameter PCS_PCIE_EN = "FALSE"; parameter [15:0] PCS_RSVD0 = 16'b0000000000000000; - parameter [2:0] PCS_RSVD1 = 3'b000; parameter [11:0] PD_TRANS_TIME_FROM_P2 = 12'h03C; parameter [7:0] PD_TRANS_TIME_NONE_P2 = 8'h19; parameter [7:0] PD_TRANS_TIME_TO_P2 = 8'h64; - parameter [1:0] PLL_SEL_MODE_GEN12 = 2'h0; - parameter [1:0] PLL_SEL_MODE_GEN3 = 2'h0; - parameter [15:0] PMA_RSV0 = 16'h0000; - parameter [15:0] PMA_RSV1 = 16'h0000; parameter integer PREIQ_FREQ_BST = 0; parameter [2:0] PROCESS_PAR = 3'b010; parameter [0:0] RATE_SW_USE_DRP = 1'b0; + parameter [0:0] RCLK_SIPO_DLY_ENB = 1'b0; + parameter [0:0] RCLK_SIPO_INV_EN = 1'b0; parameter [0:0] RESET_POWERSAVE_DISABLE = 1'b0; + parameter [2:0] RTX_BUF_CML_CTRL = 3'b010; + parameter [1:0] RTX_BUF_TERM_CTRL = 2'b00; parameter [4:0] RXBUFRESET_TIME = 5'b00001; parameter RXBUF_ADDR_MODE = "FULL"; parameter [3:0] RXBUF_EIDLE_HI_CNT = 4'b1000; @@ -16378,37 +16359,48 @@ module GTYE3_CHANNEL (...); parameter integer RXBUF_THRESH_UNDFLW = 4; parameter [4:0] RXCDRFREQRESET_TIME = 5'b00001; parameter [4:0] RXCDRPHRESET_TIME = 5'b00001; - parameter [15:0] RXCDR_CFG0 = 16'h0000; - parameter [15:0] RXCDR_CFG0_GEN3 = 16'h0000; - parameter [15:0] RXCDR_CFG1 = 16'h0300; - parameter [15:0] RXCDR_CFG1_GEN3 = 16'h0300; - parameter [15:0] RXCDR_CFG2 = 16'h0060; - parameter [15:0] RXCDR_CFG2_GEN3 = 16'h0060; - parameter [15:0] RXCDR_CFG3 = 16'h0000; - parameter [15:0] RXCDR_CFG3_GEN3 = 16'h0000; - parameter [15:0] RXCDR_CFG4 = 16'h0002; - parameter [15:0] RXCDR_CFG4_GEN3 = 16'h0002; - parameter [15:0] RXCDR_CFG5 = 16'h0000; - parameter [15:0] RXCDR_CFG5_GEN3 = 16'h0000; + parameter [15:0] RXCDR_CFG0 = 16'h0003; + parameter [15:0] RXCDR_CFG0_GEN3 = 16'h0003; + parameter [15:0] RXCDR_CFG1 = 16'h0000; + parameter [15:0] RXCDR_CFG1_GEN3 = 16'h0000; + parameter [15:0] RXCDR_CFG2 = 16'h0164; + parameter [9:0] RXCDR_CFG2_GEN2 = 10'h164; + parameter [15:0] RXCDR_CFG2_GEN3 = 16'h0034; + parameter [15:0] RXCDR_CFG2_GEN4 = 16'h0034; + parameter [15:0] RXCDR_CFG3 = 16'h0024; + parameter [5:0] RXCDR_CFG3_GEN2 = 6'h24; + parameter [15:0] RXCDR_CFG3_GEN3 = 16'h0024; + parameter [15:0] RXCDR_CFG3_GEN4 = 16'h0024; + parameter [15:0] RXCDR_CFG4 = 16'h5CF6; + parameter [15:0] RXCDR_CFG4_GEN3 = 16'h5CF6; + parameter [15:0] RXCDR_CFG5 = 16'hB46B; + parameter [15:0] RXCDR_CFG5_GEN3 = 16'h146B; parameter [0:0] RXCDR_FR_RESET_ON_EIDLE = 1'b0; parameter [0:0] RXCDR_HOLD_DURING_EIDLE = 1'b0; - parameter [15:0] RXCDR_LOCK_CFG0 = 16'h0001; - parameter [15:0] RXCDR_LOCK_CFG1 = 16'h0000; + parameter [15:0] RXCDR_LOCK_CFG0 = 16'h0040; + parameter [15:0] RXCDR_LOCK_CFG1 = 16'h8000; parameter [15:0] RXCDR_LOCK_CFG2 = 16'h0000; parameter [15:0] RXCDR_LOCK_CFG3 = 16'h0000; + parameter [15:0] RXCDR_LOCK_CFG4 = 16'h0000; parameter [0:0] RXCDR_PH_RESET_ON_EIDLE = 1'b0; - parameter [1:0] RXCFOKDONE_SRC = 2'b00; - parameter [15:0] RXCFOK_CFG0 = 16'h3E00; - parameter [15:0] RXCFOK_CFG1 = 16'h0042; + parameter [15:0] RXCFOK_CFG0 = 16'h0000; + parameter [15:0] RXCFOK_CFG1 = 16'h0002; parameter [15:0] RXCFOK_CFG2 = 16'h002D; + parameter [15:0] RXCKCAL1_IQ_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL1_I_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL1_Q_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL2_DX_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL2_D_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL2_S_LOOP_RST_CFG = 16'h0000; + parameter [15:0] RXCKCAL2_X_LOOP_RST_CFG = 16'h0000; parameter [6:0] RXDFELPMRESET_TIME = 7'b0001111; parameter [15:0] RXDFELPM_KL_CFG0 = 16'h0000; parameter [15:0] RXDFELPM_KL_CFG1 = 16'h0022; parameter [15:0] RXDFELPM_KL_CFG2 = 16'h0100; - parameter [15:0] RXDFE_CFG0 = 16'h4C00; + parameter [15:0] RXDFE_CFG0 = 16'h4000; parameter [15:0] RXDFE_CFG1 = 16'h0000; - parameter [15:0] RXDFE_GC_CFG0 = 16'h1E00; - parameter [15:0] RXDFE_GC_CFG1 = 16'h1900; + parameter [15:0] RXDFE_GC_CFG0 = 16'h0000; + parameter [15:0] RXDFE_GC_CFG1 = 16'h0000; parameter [15:0] RXDFE_GC_CFG2 = 16'h0000; parameter [15:0] RXDFE_H2_CFG0 = 16'h0000; parameter [15:0] RXDFE_H2_CFG1 = 16'h0002; @@ -16438,26 +16430,31 @@ module GTYE3_CHANNEL (...); parameter [15:0] RXDFE_HE_CFG1 = 16'h0002; parameter [15:0] RXDFE_HF_CFG0 = 16'h0000; parameter [15:0] RXDFE_HF_CFG1 = 16'h0002; + parameter [15:0] RXDFE_KH_CFG0 = 16'h0000; + parameter [15:0] RXDFE_KH_CFG1 = 16'h0000; + parameter [15:0] RXDFE_KH_CFG2 = 16'h0000; + parameter [15:0] RXDFE_KH_CFG3 = 16'h0000; parameter [15:0] RXDFE_OS_CFG0 = 16'h0000; - parameter [15:0] RXDFE_OS_CFG1 = 16'h0200; + parameter [15:0] RXDFE_OS_CFG1 = 16'h0002; parameter [0:0] RXDFE_PWR_SAVING = 1'b0; parameter [15:0] RXDFE_UT_CFG0 = 16'h0000; parameter [15:0] RXDFE_UT_CFG1 = 16'h0002; + parameter [15:0] RXDFE_UT_CFG2 = 16'h0000; parameter [15:0] RXDFE_VP_CFG0 = 16'h0000; parameter [15:0] RXDFE_VP_CFG1 = 16'h0022; - parameter [15:0] RXDLY_CFG = 16'h001F; + parameter [15:0] RXDLY_CFG = 16'h0010; parameter [15:0] RXDLY_LCFG = 16'h0030; parameter RXELECIDLE_CFG = "SIGCFG_4"; parameter integer RXGBOX_FIFO_INIT_RD_ADDR = 4; parameter RXGEARBOX_EN = "FALSE"; parameter [4:0] RXISCANRESET_TIME = 5'b00001; parameter [15:0] RXLPM_CFG = 16'h0000; - parameter [15:0] RXLPM_GC_CFG = 16'h0200; + parameter [15:0] RXLPM_GC_CFG = 16'h1000; parameter [15:0] RXLPM_KH_CFG0 = 16'h0000; parameter [15:0] RXLPM_KH_CFG1 = 16'h0002; - parameter [15:0] RXLPM_OS_CFG0 = 16'h0400; + parameter [15:0] RXLPM_OS_CFG0 = 16'h0000; parameter [15:0] RXLPM_OS_CFG1 = 16'h0000; - parameter [8:0] RXOOB_CFG = 9'b000000110; + parameter [8:0] RXOOB_CFG = 9'b000110000; parameter RXOOB_CLK_CFG = "PMA"; parameter [4:0] RXOSCALRESET_TIME = 5'b00011; parameter integer RXOUT_DIV = 4; @@ -16468,9 +16465,9 @@ module GTYE3_CHANNEL (...); parameter [15:0] RXPHSLIP_CFG = 16'h9933; parameter [4:0] RXPH_MONITOR_SEL = 5'b00000; parameter [0:0] RXPI_AUTO_BW_SEL_BYPASS = 1'b0; - parameter [15:0] RXPI_CFG = 16'h0100; + parameter [15:0] RXPI_CFG0 = 16'h0002; + parameter [15:0] RXPI_CFG1 = 16'b0000000000000000; parameter [0:0] RXPI_LPM = 1'b0; - parameter [15:0] RXPI_RSV0 = 16'h0000; parameter [1:0] RXPI_SEL_LC = 2'b00; parameter [1:0] RXPI_STARTCODE = 2'b00; parameter [0:0] RXPI_VREFSEL = 1'b0; @@ -16478,13 +16475,14 @@ module GTYE3_CHANNEL (...); parameter [4:0] RXPMARESET_TIME = 5'b00001; parameter [0:0] RXPRBS_ERR_LOOPBACK = 1'b0; parameter integer RXPRBS_LINKACQ_CNT = 15; + parameter [0:0] RXREFCLKDIV2_SEL = 1'b0; parameter integer RXSLIDE_AUTO_WAIT = 7; parameter RXSLIDE_MODE = "OFF"; parameter [0:0] RXSYNC_MULTILANE = 1'b0; parameter [0:0] RXSYNC_OVRD = 1'b0; parameter [0:0] RXSYNC_SKIP_DA = 1'b0; parameter [0:0] RX_AFE_CM_EN = 1'b0; - parameter [15:0] RX_BIAS_CFG0 = 16'h1534; + parameter [15:0] RX_BIAS_CFG0 = 16'h12B0; parameter [5:0] RX_BUFFER_CFG = 6'b000000; parameter [0:0] RX_CAPFF_SARC_ENB = 1'b0; parameter integer RX_CLK25_DIV = 8; @@ -16493,29 +16491,27 @@ module GTYE3_CHANNEL (...); parameter [3:0] RX_CM_BUF_CFG = 4'b1010; parameter [0:0] RX_CM_BUF_PD = 1'b0; parameter integer RX_CM_SEL = 3; - parameter integer RX_CM_TRIM = 10; - parameter [0:0] RX_CTLE1_KHKL = 1'b0; - parameter [0:0] RX_CTLE2_KHKL = 1'b0; - parameter [0:0] RX_CTLE3_AGC = 1'b0; + parameter integer RX_CM_TRIM = 12; + parameter [7:0] RX_CTLE3_LPF = 8'b00000000; parameter integer RX_DATA_WIDTH = 20; parameter [5:0] RX_DDI_SEL = 6'b000000; parameter RX_DEFER_RESET_BUF_EN = "TRUE"; - parameter [2:0] RX_DEGEN_CTRL = 3'b010; - parameter integer RX_DFELPM_CFG0 = 6; - parameter [0:0] RX_DFELPM_CFG1 = 1'b0; + parameter [2:0] RX_DEGEN_CTRL = 3'b011; + parameter integer RX_DFELPM_CFG0 = 0; + parameter [0:0] RX_DFELPM_CFG1 = 1'b1; parameter [0:0] RX_DFELPM_KLKH_AGC_STUP_EN = 1'b1; parameter [1:0] RX_DFE_AGC_CFG0 = 2'b00; parameter integer RX_DFE_AGC_CFG1 = 4; parameter integer RX_DFE_KL_LPM_KH_CFG0 = 1; - parameter integer RX_DFE_KL_LPM_KH_CFG1 = 2; + parameter integer RX_DFE_KL_LPM_KH_CFG1 = 4; parameter [1:0] RX_DFE_KL_LPM_KL_CFG0 = 2'b01; - parameter [2:0] RX_DFE_KL_LPM_KL_CFG1 = 3'b010; + parameter integer RX_DFE_KL_LPM_KL_CFG1 = 4; parameter [0:0] RX_DFE_LPM_HOLD_DURING_EIDLE = 1'b0; parameter RX_DISPERR_SEQ_MATCH = "TRUE"; parameter [0:0] RX_DIV2_MODE_B = 1'b0; parameter [4:0] RX_DIVRESET_TIME = 5'b00001; parameter [0:0] RX_EN_CTLE_RCAL_B = 1'b0; - parameter [0:0] RX_EN_HI_LR = 1'b0; + parameter [0:0] RX_EN_HI_LR = 1'b1; parameter [8:0] RX_EXT_RL_CTRL = 9'b000000000; parameter [6:0] RX_EYESCAN_VS_CODE = 7'b0000000; parameter [0:0] RX_EYESCAN_VS_NEG_DIR = 1'b0; @@ -16524,6 +16520,7 @@ module GTYE3_CHANNEL (...); parameter [0:0] RX_FABINT_USRCLK_FLOP = 1'b0; parameter integer RX_INT_DATAWIDTH = 1; parameter [0:0] RX_PMA_POWER_SAVE = 1'b0; + parameter [15:0] RX_PMA_RSV0 = 16'h0000; parameter real RX_PROGDIV_CFG = 0.0; parameter [15:0] RX_PROGDIV_RATE = 16'h0001; parameter [3:0] RX_RESLOAD_CTRL = 4'b0000; @@ -16531,34 +16528,32 @@ module GTYE3_CHANNEL (...); parameter [2:0] RX_SAMPLE_PERIOD = 3'b101; parameter integer RX_SIG_VALID_DLY = 11; parameter [0:0] RX_SUM_DFETAPREP_EN = 1'b0; - parameter [3:0] RX_SUM_IREF_TUNE = 4'b0000; - parameter [3:0] RX_SUM_VCMTUNE = 4'b1000; + parameter [3:0] RX_SUM_IREF_TUNE = 4'b1001; + parameter [3:0] RX_SUM_RESLOAD_CTRL = 4'b0000; + parameter [3:0] RX_SUM_VCMTUNE = 4'b1010; parameter [0:0] RX_SUM_VCM_OVWR = 1'b0; parameter [2:0] RX_SUM_VREF_TUNE = 3'b100; parameter [1:0] RX_TUNE_AFE_OS = 2'b00; parameter [2:0] RX_VREG_CTRL = 3'b101; parameter [0:0] RX_VREG_PDB = 1'b1; parameter [1:0] RX_WIDEMODE_CDR = 2'b01; + parameter [1:0] RX_WIDEMODE_CDR_GEN3 = 2'b01; + parameter [1:0] RX_WIDEMODE_CDR_GEN4 = 2'b01; parameter RX_XCLK_SEL = "RXDES"; parameter [0:0] RX_XMODE_SEL = 1'b0; - parameter integer SAS_MAX_COM = 64; - parameter integer SAS_MIN_COM = 36; + parameter [0:0] SAMPLE_CLK_PHASE = 1'b0; + parameter [0:0] SAS_12G_MODE = 1'b0; parameter [3:0] SATA_BURST_SEQ_LEN = 4'b1111; parameter [2:0] SATA_BURST_VAL = 3'b100; parameter SATA_CPLL_CFG = "VCO_3000MHZ"; parameter [2:0] SATA_EIDLE_VAL = 3'b100; - parameter integer SATA_MAX_BURST = 8; - parameter integer SATA_MAX_INIT = 21; - parameter integer SATA_MAX_WAKE = 7; - parameter integer SATA_MIN_BURST = 4; - parameter integer SATA_MIN_INIT = 12; - parameter integer SATA_MIN_WAKE = 4; parameter SHOW_REALIGN_COMMA = "TRUE"; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RECEIVER_DETECT_PASS = "TRUE"; parameter SIM_RESET_SPEEDUP = "TRUE"; - parameter [0:0] SIM_TX_EIDLE_DRIVE_LEVEL = 1'b0; - parameter integer SIM_VERSION = 2; + parameter SIM_TX_EIDLE_DRIVE_LEVEL = "Z"; + parameter [0:0] SRSTMODE = 1'b0; parameter [1:0] TAPDLY_SET_TX = 2'h0; parameter [3:0] TEMPERATURE_PAR = 4'b0010; parameter [14:0] TERM_RCAL_CFG = 15'b100001000010000; @@ -16568,18 +16563,20 @@ module GTYE3_CHANNEL (...); parameter [7:0] TST_RSV1 = 8'h00; parameter TXBUF_EN = "TRUE"; parameter TXBUF_RESET_ON_RATE_CHANGE = "FALSE"; - parameter [15:0] TXDLY_CFG = 16'h001F; + parameter [15:0] TXDLY_CFG = 16'h0010; parameter [15:0] TXDLY_LCFG = 16'h0030; + parameter [3:0] TXDRVBIAS_N = 4'b1010; parameter TXFIFO_ADDR_CFG = "LOW"; parameter integer TXGBOX_FIFO_INIT_RD_ADDR = 4; parameter TXGEARBOX_EN = "FALSE"; parameter integer TXOUT_DIV = 4; parameter [4:0] TXPCSRESET_TIME = 5'b00001; - parameter [15:0] TXPHDLY_CFG0 = 16'h2020; - parameter [15:0] TXPHDLY_CFG1 = 16'h0001; + parameter [15:0] TXPHDLY_CFG0 = 16'h6020; + parameter [15:0] TXPHDLY_CFG1 = 16'h0002; parameter [15:0] TXPH_CFG = 16'h0123; parameter [15:0] TXPH_CFG2 = 16'h0000; parameter [4:0] TXPH_MONITOR_SEL = 5'b00000; + parameter [15:0] TXPI_CFG = 16'h0000; parameter [1:0] TXPI_CFG0 = 2'b00; parameter [1:0] TXPI_CFG1 = 2'b00; parameter [1:0] TXPI_CFG2 = 2'b00; @@ -16589,30 +16586,29 @@ module GTYE3_CHANNEL (...); parameter [0:0] TXPI_GRAY_SEL = 1'b0; parameter [0:0] TXPI_INVSTROBE_SEL = 1'b0; parameter [0:0] TXPI_LPM = 1'b0; + parameter [0:0] TXPI_PPM = 1'b0; parameter TXPI_PPMCLK_SEL = "TXUSRCLK2"; parameter [7:0] TXPI_PPM_CFG = 8'b00000000; - parameter [15:0] TXPI_RSV0 = 16'h0000; parameter [2:0] TXPI_SYNFREQ_PPM = 3'b000; parameter [0:0] TXPI_VREFSEL = 1'b0; parameter [4:0] TXPMARESET_TIME = 5'b00001; + parameter [0:0] TXREFCLKDIV2_SEL = 1'b0; parameter [0:0] TXSYNC_MULTILANE = 1'b0; parameter [0:0] TXSYNC_OVRD = 1'b0; parameter [0:0] TXSYNC_SKIP_DA = 1'b0; parameter integer TX_CLK25_DIV = 8; parameter [0:0] TX_CLKMUX_EN = 1'b1; - parameter [0:0] TX_CLKREG_PDB = 1'b0; - parameter [2:0] TX_CLKREG_SET = 3'b000; parameter integer TX_DATA_WIDTH = 20; - parameter [5:0] TX_DCD_CFG = 6'b000010; - parameter [0:0] TX_DCD_EN = 1'b0; + parameter [15:0] TX_DCC_LOOP_RST_CFG = 16'h0000; parameter [5:0] TX_DEEMPH0 = 6'b000000; parameter [5:0] TX_DEEMPH1 = 6'b000000; + parameter [5:0] TX_DEEMPH2 = 6'b000000; + parameter [5:0] TX_DEEMPH3 = 6'b000000; parameter [4:0] TX_DIVRESET_TIME = 5'b00001; parameter TX_DRIVE_MODE = "DIRECT"; parameter integer TX_DRVMUX_CTRL = 2; parameter [2:0] TX_EIDLE_ASSERT_DELAY = 3'b110; parameter [2:0] TX_EIDLE_DEASSERT_DELAY = 3'b100; - parameter [0:0] TX_EML_PHI_TUNE = 1'b0; parameter [0:0] TX_FABINT_USRCLK_FLOP = 1'b0; parameter [0:0] TX_FIFO_BYP_EN = 1'b0; parameter [0:0] TX_IDLE_DATA_ZERO = 1'b0; @@ -16629,44 +16625,75 @@ module GTYE3_CHANNEL (...); parameter [6:0] TX_MARGIN_LOW_2 = 7'b1000010; parameter [6:0] TX_MARGIN_LOW_3 = 7'b1000000; parameter [6:0] TX_MARGIN_LOW_4 = 7'b1000000; - parameter [2:0] TX_MODE_SEL = 3'b000; parameter [15:0] TX_PHICAL_CFG0 = 16'h0000; - parameter [15:0] TX_PHICAL_CFG1 = 16'h7E00; + parameter [15:0] TX_PHICAL_CFG1 = 16'h003F; parameter [15:0] TX_PHICAL_CFG2 = 16'h0000; parameter integer TX_PI_BIASSET = 0; - parameter [15:0] TX_PI_CFG0 = 16'h0000; - parameter [15:0] TX_PI_CFG1 = 16'h0000; - parameter [0:0] TX_PI_DIV2_MODE_B = 1'b0; - parameter [0:0] TX_PI_SEL_QPLL0 = 1'b0; - parameter [0:0] TX_PI_SEL_QPLL1 = 1'b0; + parameter [1:0] TX_PI_IBIAS_MID = 2'b00; parameter [0:0] TX_PMADATA_OPT = 1'b0; parameter [0:0] TX_PMA_POWER_SAVE = 1'b0; + parameter [15:0] TX_PMA_RSV0 = 16'h0008; parameter integer TX_PREDRV_CTRL = 2; parameter TX_PROGCLK_SEL = "POSTPI"; parameter real TX_PROGDIV_CFG = 0.0; parameter [15:0] TX_PROGDIV_RATE = 16'h0001; + parameter [0:0] TX_QPI_STATUS_EN = 1'b0; parameter [13:0] TX_RXDETECT_CFG = 14'h0032; - parameter integer TX_RXDETECT_REF = 4; + parameter integer TX_RXDETECT_REF = 3; parameter [2:0] TX_SAMPLE_PERIOD = 3'b101; parameter [0:0] TX_SARC_LPBK_ENB = 1'b0; + parameter [1:0] TX_SW_MEAS = 2'b00; + parameter [2:0] TX_VREG_CTRL = 3'b000; + parameter [0:0] TX_VREG_PDB = 1'b0; + parameter [1:0] TX_VREG_VREFSEL = 2'b00; parameter TX_XCLK_SEL = "TXOUT"; + parameter [0:0] USB_BOTH_BURST_IDLE = 1'b0; + parameter [6:0] USB_BURSTMAX_U3WAKE = 7'b1111111; + parameter [6:0] USB_BURSTMIN_U3WAKE = 7'b1100011; + parameter [0:0] USB_CLK_COR_EQ_EN = 1'b0; + parameter [0:0] USB_EXT_CNTL = 1'b1; + parameter [9:0] USB_IDLEMAX_POLLING = 10'b1010111011; + parameter [9:0] USB_IDLEMIN_POLLING = 10'b0100101011; + parameter [8:0] USB_LFPSPING_BURST = 9'b000000101; + parameter [8:0] USB_LFPSPOLLING_BURST = 9'b000110001; + parameter [8:0] USB_LFPSPOLLING_IDLE_MS = 9'b000000100; + parameter [8:0] USB_LFPSU1EXIT_BURST = 9'b000011101; + parameter [8:0] USB_LFPSU2LPEXIT_BURST_MS = 9'b001100011; + parameter [8:0] USB_LFPSU3WAKE_BURST_MS = 9'b111110011; + parameter [3:0] USB_LFPS_TPERIOD = 4'b0011; + parameter [0:0] USB_LFPS_TPERIOD_ACCURATE = 1'b1; + parameter [0:0] USB_MODE = 1'b0; + parameter [0:0] USB_PCIE_ERR_REP_DIS = 1'b0; + parameter integer USB_PING_SATA_MAX_INIT = 21; + parameter integer USB_PING_SATA_MIN_INIT = 12; + parameter integer USB_POLL_SATA_MAX_BURST = 8; + parameter integer USB_POLL_SATA_MIN_BURST = 4; + parameter [0:0] USB_RAW_ELEC = 1'b0; + parameter [0:0] USB_RXIDLE_P0_CTRL = 1'b1; + parameter [0:0] USB_TXIDLE_TUNE_ENABLE = 1'b1; + parameter integer USB_U1_SATA_MAX_WAKE = 7; + parameter integer USB_U1_SATA_MIN_WAKE = 4; + parameter integer USB_U2_SAS_MAX_COM = 64; + parameter integer USB_U2_SAS_MIN_COM = 36; parameter [0:0] USE_PCS_CLK_PHASE_SEL = 1'b0; - output [2:0] BUFGTCE; + parameter [0:0] Y_ALL_MODE = 1'b0; + output BUFGTCE; output [2:0] BUFGTCEMASK; output [8:0] BUFGTDIV; - output [2:0] BUFGTRESET; + output BUFGTRESET; output [2:0] BUFGTRSTMASK; output CPLLFBCLKLOST; output CPLLLOCK; output CPLLREFCLKLOST; - output [16:0] DMONITOROUT; + output [15:0] DMONITOROUT; + output DMONITOROUTCLK; output [15:0] DRPDO; output DRPRDY; output EYESCANDATAERROR; + output GTHTXN; + output GTHTXP; output GTPOWERGOOD; output GTREFCLKMONITOR; - output GTYTXN; - output GTYTXP; output PCIERATEGEN3; output PCIERATEIDLE; output [1:0] PCIERATEQPLLPD; @@ -16677,7 +16704,8 @@ module GTYE3_CHANNEL (...); output PCIEUSERRATESTART; output [15:0] PCSRSVDOUT; output PHYSTATUS; - output [7:0] PINRSRVDAS; + output [15:0] PINRSRVDAS; + output POWERPRESENT; output RESETEXCEPTION; output [2:0] RXBUFSTATUS; output RXBYTEISALIGNED; @@ -16705,7 +16733,10 @@ module GTYE3_CHANNEL (...); output RXELECIDLE; output [5:0] RXHEADER; output [1:0] RXHEADERVALID; - output [6:0] RXMONITOROUT; + output RXLFPSTRESETDET; + output RXLFPSU2LPEXITDET; + output RXLFPSU3WAKEDET; + output [7:0] RXMONITOROUT; output RXOSINTDONE; output RXOSINTSTARTED; output RXOSINTSTROBEDONE; @@ -16719,6 +16750,8 @@ module GTYE3_CHANNEL (...); output RXPRBSERR; output RXPRBSLOCKED; output RXPRGDIVRESETDONE; + output RXQPISENN; + output RXQPISENP; output RXRATEDONE; output RXRECCLKOUT; output RXRESETDONE; @@ -16742,6 +16775,8 @@ module GTYE3_CHANNEL (...); output TXPHINITDONE; output TXPMARESETDONE; output TXPRGDIVRESETDONE; + output TXQPISENN; + output TXQPISENP; output TXRATEDONE; output TXRESETDONE; output TXSYNCDONE; @@ -16752,6 +16787,7 @@ module GTYE3_CHANNEL (...); input CFGRESET; input CLKRSVD0; input CLKRSVD1; + input CPLLFREQLOCK; input CPLLLOCKDETCLK; input CPLLLOCKEN; input CPLLPD; @@ -16763,65 +16799,64 @@ module GTYE3_CHANNEL (...); input DRPCLK; input [15:0] DRPDI; input DRPEN; + input DRPRST; input DRPWE; - input ELPCALDVORWREN; - input ELPCALPAORWREN; - input EVODDPHICALDONE; - input EVODDPHICALSTART; - input EVODDPHIDRDEN; - input EVODDPHIDWREN; - input EVODDPHIXRDEN; - input EVODDPHIXWREN; - input EYESCANMODE; input EYESCANRESET; input EYESCANTRIGGER; + input FREQOS; input GTGREFCLK; + input GTHRXN; + input GTHRXP; input GTNORTHREFCLK0; input GTNORTHREFCLK1; input GTREFCLK0; input GTREFCLK1; - input GTRESETSEL; input [15:0] GTRSVD; input GTRXRESET; + input GTRXRESETSEL; input GTSOUTHREFCLK0; input GTSOUTHREFCLK1; input GTTXRESET; - input GTYRXN; - input GTYRXP; + input GTTXRESETSEL; + input INCPCTRL; input [2:0] LOOPBACK; - input [15:0] LOOPRSVD; - input LPBKRXTXSEREN; - input LPBKTXRXSEREN; input PCIEEQRXEQADAPTDONE; input PCIERSTIDLE; input PCIERSTTXSYNCSTART; input PCIEUSERRATEDONE; input [15:0] PCSRSVDIN; - input [4:0] PCSRSVDIN2; - input [4:0] PMARSVDIN; input QPLL0CLK; + input QPLL0FREQLOCK; input QPLL0REFCLK; input QPLL1CLK; + input QPLL1FREQLOCK; input QPLL1REFCLK; input RESETOVRD; - input RSTCLKENTX; input RX8B10BEN; + input RXAFECFOKEN; input RXBUFRESET; input RXCDRFREQRESET; input RXCDRHOLD; input RXCDROVRDEN; input RXCDRRESET; - input RXCDRRESETRSV; input RXCHBONDEN; input [4:0] RXCHBONDI; input [2:0] RXCHBONDLEVEL; input RXCHBONDMASTER; input RXCHBONDSLAVE; input RXCKCALRESET; + input [6:0] RXCKCALSTART; input RXCOMMADETEN; - input RXDCCFORCESTART; + input [1:0] RXDFEAGCCTRL; input RXDFEAGCHOLD; input RXDFEAGCOVRDEN; + input [3:0] RXDFECFOKFCNUM; + input RXDFECFOKFEN; + input RXDFECFOKFPULSE; + input RXDFECFOKHOLD; + input RXDFECFOKOVREN; + input RXDFEKHHOLD; + input RXDFEKHOVRDEN; input RXDFELFHOLD; input RXDFELFOVRDEN; input RXDFELPMRESET; @@ -16857,13 +16892,13 @@ module GTYE3_CHANNEL (...); input RXDFEUTOVRDEN; input RXDFEVPHOLD; input RXDFEVPOVRDEN; - input RXDFEVSEN; input RXDFEXYDEN; input RXDLYBYPASS; input RXDLYEN; input RXDLYOVRDEN; input RXDLYSRESET; input [1:0] RXELECIDLEMODE; + input RXEQTRAINING; input RXGEARBOXSLIP; input RXLATCLK; input RXLPMEN; @@ -16880,12 +16915,6 @@ module GTYE3_CHANNEL (...); input RXOOBRESET; input RXOSCALRESET; input RXOSHOLD; - input [3:0] RXOSINTCFG; - input RXOSINTEN; - input RXOSINTHOLD; - input RXOSINTOVRDEN; - input RXOSINTSTROBE; - input RXOSINTTESTOVRDEN; input RXOSOVRDEN; input [2:0] RXOUTCLKSEL; input RXPCOMMAALIGNEN; @@ -16902,6 +16931,7 @@ module GTYE3_CHANNEL (...); input RXPRBSCNTRESET; input [3:0] RXPRBSSEL; input RXPROGDIVRESET; + input RXQPIEN; input [2:0] RXRATE; input RXRATEMODE; input RXSLIDE; @@ -16911,6 +16941,7 @@ module GTYE3_CHANNEL (...); input RXSYNCIN; input RXSYNCMODE; input [1:0] RXSYSCLKSEL; + input RXTERMINATION; input RXUSERRDY; input RXUSRCLK; input RXUSRCLK2; @@ -16918,7 +16949,6 @@ module GTYE3_CHANNEL (...); input [19:0] TSTIN; input [7:0] TX8B10BBYPASS; input TX8B10BEN; - input [2:0] TXBUFDIFFCTRL; input TXCOMINIT; input TXCOMSAS; input TXCOMWAKE; @@ -16929,10 +16959,9 @@ module GTYE3_CHANNEL (...); input [7:0] TXDATAEXTENDRSVD; input TXDCCFORCESTART; input TXDCCRESET; - input TXDEEMPH; + input [1:0] TXDEEMPH; input TXDETECTRX; input [4:0] TXDIFFCTRL; - input TXDIFFPD; input TXDLYBYPASS; input TXDLYEN; input TXDLYHOLD; @@ -16940,12 +16969,17 @@ module GTYE3_CHANNEL (...); input TXDLYSRESET; input TXDLYUPDOWN; input TXELECIDLE; - input TXELFORCESTART; input [5:0] TXHEADER; input TXINHIBIT; input TXLATCLK; + input TXLFPSTRESET; + input TXLFPSU2LPEXIT; + input TXLFPSU3WAKE; input [6:0] TXMAINCURSOR; input [2:0] TXMARGIN; + input TXMUXDCDEXHOLD; + input TXMUXDCDORWREN; + input TXONESZEROS; input [2:0] TXOUTCLKSEL; input TXPCSRESET; input [1:0] TXPD; @@ -16971,6 +17005,8 @@ module GTYE3_CHANNEL (...); input [3:0] TXPRBSSEL; input [4:0] TXPRECURSOR; input TXPROGDIVRESET; + input TXQPIBIASEN; + input TXQPIWEAKPUP; input [2:0] TXRATE; input TXRATEMODE; input [6:0] TXSEQUENCE; @@ -16984,28 +17020,34 @@ module GTYE3_CHANNEL (...); input TXUSRCLK2; endmodule -module GTYE3_COMMON (...); - parameter [15:0] A_SDM1DATA1_0 = 16'b0000000000000000; - parameter [8:0] A_SDM1DATA1_1 = 9'b000000000; +module GTHE4_COMMON (...); + parameter [0:0] AEN_QPLL0_FBDIV = 1'b1; + parameter [0:0] AEN_QPLL1_FBDIV = 1'b1; + parameter [0:0] AEN_SDM0TOGGLE = 1'b0; + parameter [0:0] AEN_SDM1TOGGLE = 1'b0; + parameter [0:0] A_SDM0TOGGLE = 1'b0; + parameter [8:0] A_SDM1DATA_HIGH = 9'b000000000; + parameter [15:0] A_SDM1DATA_LOW = 16'b0000000000000000; + parameter [0:0] A_SDM1TOGGLE = 1'b0; parameter [15:0] BIAS_CFG0 = 16'h0000; parameter [15:0] BIAS_CFG1 = 16'h0000; parameter [15:0] BIAS_CFG2 = 16'h0000; parameter [15:0] BIAS_CFG3 = 16'h0000; parameter [15:0] BIAS_CFG4 = 16'h0000; - parameter [9:0] BIAS_CFG_RSVD = 10'b0000000000; + parameter [15:0] BIAS_CFG_RSVD = 16'h0000; parameter [15:0] COMMON_CFG0 = 16'h0000; parameter [15:0] COMMON_CFG1 = 16'h0000; - parameter [15:0] POR_CFG = 16'h0004; - parameter [15:0] PPF0_CFG = 16'h0FFF; - parameter [15:0] PPF1_CFG = 16'h0FFF; + parameter [15:0] POR_CFG = 16'h0000; + parameter [15:0] PPF0_CFG = 16'h0F00; + parameter [15:0] PPF1_CFG = 16'h0F00; parameter QPLL0CLKOUT_RATE = "FULL"; - parameter [15:0] QPLL0_CFG0 = 16'h301C; + parameter [15:0] QPLL0_CFG0 = 16'h391C; parameter [15:0] QPLL0_CFG1 = 16'h0000; parameter [15:0] QPLL0_CFG1_G3 = 16'h0020; - parameter [15:0] QPLL0_CFG2 = 16'h0780; - parameter [15:0] QPLL0_CFG2_G3 = 16'h0780; + parameter [15:0] QPLL0_CFG2 = 16'h0F80; + parameter [15:0] QPLL0_CFG2_G3 = 16'h0F80; parameter [15:0] QPLL0_CFG3 = 16'h0120; - parameter [15:0] QPLL0_CFG4 = 16'h0021; + parameter [15:0] QPLL0_CFG4 = 16'h0002; parameter [9:0] QPLL0_CP = 10'b0000011111; parameter [9:0] QPLL0_CP_G3 = 10'b0000011111; parameter integer QPLL0_FBDIV = 66; @@ -17014,20 +17056,22 @@ module GTYE3_COMMON (...); parameter [7:0] QPLL0_INIT_CFG1 = 8'h00; parameter [15:0] QPLL0_LOCK_CFG = 16'h01E8; parameter [15:0] QPLL0_LOCK_CFG_G3 = 16'h21E8; - parameter [9:0] QPLL0_LPF = 10'b1111111111; + parameter [9:0] QPLL0_LPF = 10'b1011111111; parameter [9:0] QPLL0_LPF_G3 = 10'b1111111111; - parameter integer QPLL0_REFCLK_DIV = 2; + parameter [0:0] QPLL0_PCI_EN = 1'b0; + parameter [0:0] QPLL0_RATE_SW_USE_DRP = 1'b0; + parameter integer QPLL0_REFCLK_DIV = 1; parameter [15:0] QPLL0_SDM_CFG0 = 16'h0040; parameter [15:0] QPLL0_SDM_CFG1 = 16'h0000; parameter [15:0] QPLL0_SDM_CFG2 = 16'h0000; parameter QPLL1CLKOUT_RATE = "FULL"; - parameter [15:0] QPLL1_CFG0 = 16'h301C; - parameter [15:0] QPLL1_CFG1 = 16'h0000; + parameter [15:0] QPLL1_CFG0 = 16'h691C; + parameter [15:0] QPLL1_CFG1 = 16'h0020; parameter [15:0] QPLL1_CFG1_G3 = 16'h0020; - parameter [15:0] QPLL1_CFG2 = 16'h0780; - parameter [15:0] QPLL1_CFG2_G3 = 16'h0780; + parameter [15:0] QPLL1_CFG2 = 16'h0F80; + parameter [15:0] QPLL1_CFG2_G3 = 16'h0F80; parameter [15:0] QPLL1_CFG3 = 16'h0120; - parameter [15:0] QPLL1_CFG4 = 16'h0021; + parameter [15:0] QPLL1_CFG4 = 16'h0002; parameter [9:0] QPLL1_CP = 10'b0000011111; parameter [9:0] QPLL1_CP_G3 = 10'b0000011111; parameter integer QPLL1_FBDIV = 66; @@ -17036,10 +17080,12 @@ module GTYE3_COMMON (...); parameter [7:0] QPLL1_INIT_CFG1 = 8'h00; parameter [15:0] QPLL1_LOCK_CFG = 16'h01E8; parameter [15:0] QPLL1_LOCK_CFG_G3 = 16'h21E8; - parameter [9:0] QPLL1_LPF = 10'b1111111111; + parameter [9:0] QPLL1_LPF = 10'b1011111111; parameter [9:0] QPLL1_LPF_G3 = 10'b1111111111; - parameter integer QPLL1_REFCLK_DIV = 2; - parameter [15:0] QPLL1_SDM_CFG0 = 16'h0040; + parameter [0:0] QPLL1_PCI_EN = 1'b0; + parameter [0:0] QPLL1_RATE_SW_USE_DRP = 1'b0; + parameter integer QPLL1_REFCLK_DIV = 1; + parameter [15:0] QPLL1_SDM_CFG0 = 16'h0000; parameter [15:0] QPLL1_SDM_CFG1 = 16'h0000; parameter [15:0] QPLL1_SDM_CFG2 = 16'h0000; parameter [15:0] RSVD_ATTR0 = 16'h0000; @@ -17048,15 +17094,15 @@ module GTYE3_COMMON (...); parameter [15:0] RSVD_ATTR3 = 16'h0000; parameter [1:0] RXRECCLKOUT0_SEL = 2'b00; parameter [1:0] RXRECCLKOUT1_SEL = 2'b00; - parameter [0:0] SARC_EN = 1'b1; + parameter [0:0] SARC_ENB = 1'b0; parameter [0:0] SARC_SEL = 1'b0; parameter [15:0] SDM0INITSEED0_0 = 16'b0000000000000000; parameter [8:0] SDM0INITSEED0_1 = 9'b000000000; parameter [15:0] SDM1INITSEED0_0 = 16'b0000000000000000; parameter [8:0] SDM1INITSEED0_1 = 9'b000000000; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter SIM_MODE = "FAST"; parameter SIM_RESET_SPEEDUP = "TRUE"; - parameter integer SIM_VERSION = 2; output [15:0] DRPDO; output DRPRDY; output [7:0] PMARSVDOUT0; @@ -17075,18 +17121,20 @@ module GTYE3_COMMON (...); output [7:0] QPLLDMONITOR1; output REFCLKOUTMONITOR0; output REFCLKOUTMONITOR1; - output [1:0] RXRECCLK0_SEL; - output [1:0] RXRECCLK1_SEL; + output [1:0] RXRECCLK0SEL; + output [1:0] RXRECCLK1SEL; output [3:0] SDM0FINALOUT; output [14:0] SDM0TESTDATA; output [3:0] SDM1FINALOUT; output [14:0] SDM1TESTDATA; + output [9:0] TCONGPO; + output TCONRSVDOUT0; input BGBYPASSB; input BGMONITORENB; input BGPDB; input [4:0] BGRCALOVRD; input BGRCALOVRDENB; - input [9:0] DRPADDR; + input [15:0] DRPADDR; input DRPCLK; input [15:0] DRPDI; input DRPEN; @@ -17105,15 +17153,21 @@ module GTYE3_COMMON (...); input GTSOUTHREFCLK01; input GTSOUTHREFCLK10; input GTSOUTHREFCLK11; + input [2:0] PCIERATEQPLL0; + input [2:0] PCIERATEQPLL1; input [7:0] PMARSVD0; input [7:0] PMARSVD1; input QPLL0CLKRSVD0; + input QPLL0CLKRSVD1; + input [7:0] QPLL0FBDIV; input QPLL0LOCKDETCLK; input QPLL0LOCKEN; input QPLL0PD; input [2:0] QPLL0REFCLKSEL; input QPLL0RESET; input QPLL1CLKRSVD0; + input QPLL1CLKRSVD1; + input [7:0] QPLL1FBDIV; input QPLL1LOCKDETCLK; input QPLL1LOCKEN; input QPLL1PD; @@ -17126,10 +17180,16 @@ module GTYE3_COMMON (...); input RCALENB; input [24:0] SDM0DATA; input SDM0RESET; + input SDM0TOGGLE; input [1:0] SDM0WIDTH; input [24:0] SDM1DATA; input SDM1RESET; + input SDM1TOGGLE; input [1:0] SDM1WIDTH; + input [9:0] TCONGPI; + input TCONPOWERUP; + input [1:0] TCONRESET; + input [1:0] TCONRSVDIN1; endmodule module GTYE4_CHANNEL (...); @@ -18154,19 +18214,6 @@ module GTYE4_COMMON (...); input UBMDMTDI; endmodule -module IBUFDS_GTE3 (...); - parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; - parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00; - parameter [1:0] REFCLK_ICNTL_RX = 2'b00; - output O; - output ODIV2; - input CEB; - (* iopad_external_pin *) - input I; - (* iopad_external_pin *) - input IB; -endmodule - module IBUFDS_GTE4 (...); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00; @@ -18180,7 +18227,7 @@ module IBUFDS_GTE4 (...); input IB; endmodule -module OBUFDS_GTE3 (...); +module OBUFDS_GTE4 (...); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -18191,7 +18238,7 @@ module OBUFDS_GTE3 (...); input I; endmodule -module OBUFDS_GTE3_ADV (...); +module OBUFDS_GTE4_ADV (...); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -18203,9 +18250,669 @@ module OBUFDS_GTE3_ADV (...); input [1:0] RXRECCLK_SEL; endmodule -module OBUFDS_GTE4 (...); +module GTM_DUAL (...); + parameter [15:0] A_CFG = 16'b0000100001000000; + parameter [15:0] A_SDM_DATA_CFG0 = 16'b0000000011010000; + parameter [15:0] A_SDM_DATA_CFG1 = 16'b0000000011010000; + parameter [15:0] BIAS_CFG0 = 16'b0000000000000000; + parameter [15:0] BIAS_CFG1 = 16'b0000000000000000; + parameter [15:0] BIAS_CFG2 = 16'b0001000000000000; + parameter [15:0] BIAS_CFG3 = 16'b0000000000000001; + parameter [15:0] BIAS_CFG4 = 16'b0000000000000000; + parameter [15:0] BIAS_CFG5 = 16'b0000000000000000; + parameter [15:0] BIAS_CFG6 = 16'b0000000010000000; + parameter [15:0] BIAS_CFG7 = 16'b0000000000000000; + parameter [15:0] CH0_A_CH_CFG0 = 16'b0000000000000011; + parameter [15:0] CH0_A_CH_CFG1 = 16'b0000000000000000; + parameter [15:0] CH0_A_CH_CFG2 = 16'b0111101111110000; + parameter [15:0] CH0_A_CH_CFG3 = 16'b0000000000000000; + parameter [15:0] CH0_A_CH_CFG4 = 16'b0000000000000000; + parameter [15:0] CH0_A_CH_CFG5 = 16'b0000000000000000; + parameter [15:0] CH0_A_CH_CFG6 = 16'b0000000000000000; + parameter [15:0] CH0_RST_LP_CFG0 = 16'b0001000000010000; + parameter [15:0] CH0_RST_LP_CFG1 = 16'b0011001000010000; + parameter [15:0] CH0_RST_LP_CFG2 = 16'b0110010100000100; + parameter [15:0] CH0_RST_LP_CFG3 = 16'b0011001000010000; + parameter [15:0] CH0_RST_LP_CFG4 = 16'b0000000001000100; + parameter [15:0] CH0_RST_LP_ID_CFG0 = 16'b0011000001110000; + parameter [15:0] CH0_RST_LP_ID_CFG1 = 16'b0001000000010000; + parameter [15:0] CH0_RST_TIME_CFG0 = 16'b0000010000100001; + parameter [15:0] CH0_RST_TIME_CFG1 = 16'b0000010000100001; + parameter [15:0] CH0_RST_TIME_CFG2 = 16'b0000010000100001; + parameter [15:0] CH0_RST_TIME_CFG3 = 16'b0000010000100000; + parameter [15:0] CH0_RST_TIME_CFG4 = 16'b0000010000100001; + parameter [15:0] CH0_RST_TIME_CFG5 = 16'b0000000000000001; + parameter [15:0] CH0_RST_TIME_CFG6 = 16'b0000000000100001; + parameter [15:0] CH0_RX_ADC_CFG0 = 16'b0011010010001111; + parameter [15:0] CH0_RX_ADC_CFG1 = 16'b0011111001010101; + parameter [15:0] CH0_RX_ANA_CFG0 = 16'b1000000000011101; + parameter [15:0] CH0_RX_ANA_CFG1 = 16'b1110100010000000; + parameter [15:0] CH0_RX_ANA_CFG2 = 16'b0000000010001010; + parameter [15:0] CH0_RX_APT_CFG0A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG0B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG10A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG10B = 16'b0000000001010000; + parameter [15:0] CH0_RX_APT_CFG11A = 16'b0000000001000000; + parameter [15:0] CH0_RX_APT_CFG11B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG12A = 16'b0000000001010000; + parameter [15:0] CH0_RX_APT_CFG12B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG13A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG13B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG14A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG14B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG15A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG15B = 16'b0000100000000000; + parameter [15:0] CH0_RX_APT_CFG16A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG16B = 16'b0010000000000000; + parameter [15:0] CH0_RX_APT_CFG17A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG17B = 16'b0001000001000000; + parameter [15:0] CH0_RX_APT_CFG18A = 16'b0000100000100000; + parameter [15:0] CH0_RX_APT_CFG18B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG19A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG19B = 16'b0000100000000000; + parameter [15:0] CH0_RX_APT_CFG1A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG1B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG20A = 16'b1110000000100000; + parameter [15:0] CH0_RX_APT_CFG20B = 16'b0000000001000000; + parameter [15:0] CH0_RX_APT_CFG21A = 16'b0001000000000100; + parameter [15:0] CH0_RX_APT_CFG21B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG22A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG22B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG23A = 16'b0000100000000000; + parameter [15:0] CH0_RX_APT_CFG23B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG24A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG24B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG25A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG25B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG26A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG26B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG27A = 16'b0100000000000000; + parameter [15:0] CH0_RX_APT_CFG27B = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG28A = 16'b0000000000000000; + parameter [15:0] CH0_RX_APT_CFG28B = 16'b1000000000000000; + parameter [15:0] CH0_RX_APT_CFG2A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG2B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG3A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG3B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG4A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG4B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG5A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG5B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG6A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG6B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG7A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG7B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG8A = 16'b0000100000000000; + parameter [15:0] CH0_RX_APT_CFG8B = 16'b0000100000000000; + parameter [15:0] CH0_RX_APT_CFG9A = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CFG9B = 16'b0000000001110000; + parameter [15:0] CH0_RX_APT_CTRL_CFG2 = 16'b0000000000000100; + parameter [15:0] CH0_RX_APT_CTRL_CFG3 = 16'b0000000000000000; + parameter [15:0] CH0_RX_CAL_CFG0A = 16'b0000000000000000; + parameter [15:0] CH0_RX_CAL_CFG0B = 16'b0011001100110000; + parameter [15:0] CH0_RX_CAL_CFG1A = 16'b1110111011100001; + parameter [15:0] CH0_RX_CAL_CFG1B = 16'b1111111100000100; + parameter [15:0] CH0_RX_CAL_CFG2A = 16'b0000000000000000; + parameter [15:0] CH0_RX_CAL_CFG2B = 16'b0011000000000000; + parameter [15:0] CH0_RX_CDR_CFG0A = 16'b0000000000000011; + parameter [15:0] CH0_RX_CDR_CFG0B = 16'b0000000000000000; + parameter [15:0] CH0_RX_CDR_CFG1A = 16'b0000000000000000; + parameter [15:0] CH0_RX_CDR_CFG1B = 16'b0000000000000000; + parameter [15:0] CH0_RX_CDR_CFG2A = 16'b1001000101100100; + parameter [15:0] CH0_RX_CDR_CFG2B = 16'b0000000100100100; + parameter [15:0] CH0_RX_CDR_CFG3A = 16'b0101110011110110; + parameter [15:0] CH0_RX_CDR_CFG3B = 16'b0000000000001011; + parameter [15:0] CH0_RX_CDR_CFG4A = 16'b0000000000000110; + parameter [15:0] CH0_RX_CDR_CFG4B = 16'b0000000000000000; + parameter [15:0] CH0_RX_CLKGN_CFG0 = 16'b1100000000000000; + parameter [15:0] CH0_RX_CLKGN_CFG1 = 16'b0000000110000000; + parameter [15:0] CH0_RX_CTLE_CFG0 = 16'b0011010010001000; + parameter [15:0] CH0_RX_CTLE_CFG1 = 16'b0010000000100010; + parameter [15:0] CH0_RX_CTLE_CFG2 = 16'b0000101000000000; + parameter [15:0] CH0_RX_CTLE_CFG3 = 16'b1111001001000000; + parameter [15:0] CH0_RX_DSP_CFG = 16'b0000000000000000; + parameter [15:0] CH0_RX_MON_CFG = 16'b0000000000000000; + parameter [15:0] CH0_RX_PAD_CFG0 = 16'b0001111000000000; + parameter [15:0] CH0_RX_PAD_CFG1 = 16'b0001100000001010; + parameter [15:0] CH0_RX_PCS_CFG0 = 16'b0000000100000000; + parameter [15:0] CH0_RX_PCS_CFG1 = 16'b0000000000000000; + parameter [15:0] CH0_TX_ANA_CFG0 = 16'b0000001010101111; + parameter [15:0] CH0_TX_ANA_CFG1 = 16'b0000000100000000; + parameter [15:0] CH0_TX_ANA_CFG2 = 16'b1000000000010100; + parameter [15:0] CH0_TX_ANA_CFG3 = 16'b0000101000100010; + parameter [15:0] CH0_TX_ANA_CFG4 = 16'b0000000000000000; + parameter [15:0] CH0_TX_CAL_CFG0 = 16'b0000000000100000; + parameter [15:0] CH0_TX_CAL_CFG1 = 16'b0000000001000000; + parameter [15:0] CH0_TX_DRV_CFG0 = 16'b0000000000000000; + parameter [15:0] CH0_TX_DRV_CFG1 = 16'b0000000000100111; + parameter [15:0] CH0_TX_DRV_CFG2 = 16'b0000000000000000; + parameter [15:0] CH0_TX_DRV_CFG3 = 16'b0110110000000000; + parameter [15:0] CH0_TX_DRV_CFG4 = 16'b0000000011000101; + parameter [15:0] CH0_TX_DRV_CFG5 = 16'b0000000000000000; + parameter [15:0] CH0_TX_LPBK_CFG0 = 16'b0000000000000011; + parameter [15:0] CH0_TX_LPBK_CFG1 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG0 = 16'b0000000101100000; + parameter [15:0] CH0_TX_PCS_CFG1 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG10 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG11 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG12 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG13 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG14 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG15 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG16 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG17 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG2 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG3 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG4 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG5 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG6 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG7 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG8 = 16'b0000000000000000; + parameter [15:0] CH0_TX_PCS_CFG9 = 16'b0000000000000000; + parameter [15:0] CH1_A_CH_CFG0 = 16'b0000000000000011; + parameter [15:0] CH1_A_CH_CFG1 = 16'b0000000000000000; + parameter [15:0] CH1_A_CH_CFG2 = 16'b0111101111110000; + parameter [15:0] CH1_A_CH_CFG3 = 16'b0000000000000000; + parameter [15:0] CH1_A_CH_CFG4 = 16'b0000000000000000; + parameter [15:0] CH1_A_CH_CFG5 = 16'b0000000000000000; + parameter [15:0] CH1_A_CH_CFG6 = 16'b0000000000000000; + parameter [15:0] CH1_RST_LP_CFG0 = 16'b0001000000010000; + parameter [15:0] CH1_RST_LP_CFG1 = 16'b0011001000010000; + parameter [15:0] CH1_RST_LP_CFG2 = 16'b0110010100000100; + parameter [15:0] CH1_RST_LP_CFG3 = 16'b0011001000010000; + parameter [15:0] CH1_RST_LP_CFG4 = 16'b0000000001000100; + parameter [15:0] CH1_RST_LP_ID_CFG0 = 16'b0011000001110000; + parameter [15:0] CH1_RST_LP_ID_CFG1 = 16'b0001000000010000; + parameter [15:0] CH1_RST_TIME_CFG0 = 16'b0000010000100001; + parameter [15:0] CH1_RST_TIME_CFG1 = 16'b0000010000100001; + parameter [15:0] CH1_RST_TIME_CFG2 = 16'b0000010000100001; + parameter [15:0] CH1_RST_TIME_CFG3 = 16'b0000010000100000; + parameter [15:0] CH1_RST_TIME_CFG4 = 16'b0000010000100001; + parameter [15:0] CH1_RST_TIME_CFG5 = 16'b0000000000000001; + parameter [15:0] CH1_RST_TIME_CFG6 = 16'b0000000000100001; + parameter [15:0] CH1_RX_ADC_CFG0 = 16'b0011010010001111; + parameter [15:0] CH1_RX_ADC_CFG1 = 16'b0011111001010101; + parameter [15:0] CH1_RX_ANA_CFG0 = 16'b1000000000011101; + parameter [15:0] CH1_RX_ANA_CFG1 = 16'b1110100010000000; + parameter [15:0] CH1_RX_ANA_CFG2 = 16'b0000000010001010; + parameter [15:0] CH1_RX_APT_CFG0A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG0B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG10A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG10B = 16'b0000000001010000; + parameter [15:0] CH1_RX_APT_CFG11A = 16'b0000000001000000; + parameter [15:0] CH1_RX_APT_CFG11B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG12A = 16'b0000000001010000; + parameter [15:0] CH1_RX_APT_CFG12B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG13A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG13B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG14A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG14B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG15A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG15B = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG16A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG16B = 16'b0010000000000000; + parameter [15:0] CH1_RX_APT_CFG17A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG17B = 16'b0001000001000000; + parameter [15:0] CH1_RX_APT_CFG18A = 16'b0000100000100000; + parameter [15:0] CH1_RX_APT_CFG18B = 16'b0000100010000000; + parameter [15:0] CH1_RX_APT_CFG19A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG19B = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG1A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG1B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG20A = 16'b1110000000100000; + parameter [15:0] CH1_RX_APT_CFG20B = 16'b0000000001000000; + parameter [15:0] CH1_RX_APT_CFG21A = 16'b0001000000000100; + parameter [15:0] CH1_RX_APT_CFG21B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG22A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG22B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG23A = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG23B = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG24A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG24B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG25A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG25B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG26A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG26B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG27A = 16'b0100000000000000; + parameter [15:0] CH1_RX_APT_CFG27B = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG28A = 16'b0000000000000000; + parameter [15:0] CH1_RX_APT_CFG28B = 16'b1000000000000000; + parameter [15:0] CH1_RX_APT_CFG2A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG2B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG3A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG3B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG4A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG4B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG5A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG5B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG6A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG6B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG7A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG7B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG8A = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG8B = 16'b0000100000000000; + parameter [15:0] CH1_RX_APT_CFG9A = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CFG9B = 16'b0000000001110000; + parameter [15:0] CH1_RX_APT_CTRL_CFG2 = 16'b0000000000000100; + parameter [15:0] CH1_RX_APT_CTRL_CFG3 = 16'b0000000000000000; + parameter [15:0] CH1_RX_CAL_CFG0A = 16'b0000000000000000; + parameter [15:0] CH1_RX_CAL_CFG0B = 16'b0011001100110000; + parameter [15:0] CH1_RX_CAL_CFG1A = 16'b1110111011100001; + parameter [15:0] CH1_RX_CAL_CFG1B = 16'b1111111100000100; + parameter [15:0] CH1_RX_CAL_CFG2A = 16'b0000000000000000; + parameter [15:0] CH1_RX_CAL_CFG2B = 16'b0011000000000000; + parameter [15:0] CH1_RX_CDR_CFG0A = 16'b0000000000000011; + parameter [15:0] CH1_RX_CDR_CFG0B = 16'b0000000000000000; + parameter [15:0] CH1_RX_CDR_CFG1A = 16'b0000000000000000; + parameter [15:0] CH1_RX_CDR_CFG1B = 16'b0000000000000000; + parameter [15:0] CH1_RX_CDR_CFG2A = 16'b1001000101100100; + parameter [15:0] CH1_RX_CDR_CFG2B = 16'b0000000100100100; + parameter [15:0] CH1_RX_CDR_CFG3A = 16'b0101110011110110; + parameter [15:0] CH1_RX_CDR_CFG3B = 16'b0000000000001011; + parameter [15:0] CH1_RX_CDR_CFG4A = 16'b0000000000000110; + parameter [15:0] CH1_RX_CDR_CFG4B = 16'b0000000000000000; + parameter [15:0] CH1_RX_CLKGN_CFG0 = 16'b1100000000000000; + parameter [15:0] CH1_RX_CLKGN_CFG1 = 16'b0000000110000000; + parameter [15:0] CH1_RX_CTLE_CFG0 = 16'b0011010010001000; + parameter [15:0] CH1_RX_CTLE_CFG1 = 16'b0010000000100010; + parameter [15:0] CH1_RX_CTLE_CFG2 = 16'b0000101000000000; + parameter [15:0] CH1_RX_CTLE_CFG3 = 16'b1111001001000000; + parameter [15:0] CH1_RX_DSP_CFG = 16'b0000000000000000; + parameter [15:0] CH1_RX_MON_CFG = 16'b0000000000000000; + parameter [15:0] CH1_RX_PAD_CFG0 = 16'b0001111000000000; + parameter [15:0] CH1_RX_PAD_CFG1 = 16'b0001100000001010; + parameter [15:0] CH1_RX_PCS_CFG0 = 16'b0000000100000000; + parameter [15:0] CH1_RX_PCS_CFG1 = 16'b0000000000000000; + parameter [15:0] CH1_TX_ANA_CFG0 = 16'b0000001010101111; + parameter [15:0] CH1_TX_ANA_CFG1 = 16'b0000000100000000; + parameter [15:0] CH1_TX_ANA_CFG2 = 16'b1000000000010100; + parameter [15:0] CH1_TX_ANA_CFG3 = 16'b0000101000100010; + parameter [15:0] CH1_TX_ANA_CFG4 = 16'b0000000000000000; + parameter [15:0] CH1_TX_CAL_CFG0 = 16'b0000000000100000; + parameter [15:0] CH1_TX_CAL_CFG1 = 16'b0000000001000000; + parameter [15:0] CH1_TX_DRV_CFG0 = 16'b0000000000000000; + parameter [15:0] CH1_TX_DRV_CFG1 = 16'b0000000000100111; + parameter [15:0] CH1_TX_DRV_CFG2 = 16'b0000000000000000; + parameter [15:0] CH1_TX_DRV_CFG3 = 16'b0110110000000000; + parameter [15:0] CH1_TX_DRV_CFG4 = 16'b0000000011000101; + parameter [15:0] CH1_TX_DRV_CFG5 = 16'b0000000000000000; + parameter [15:0] CH1_TX_LPBK_CFG0 = 16'b0000000000000011; + parameter [15:0] CH1_TX_LPBK_CFG1 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG0 = 16'b0000000101100000; + parameter [15:0] CH1_TX_PCS_CFG1 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG10 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG11 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG12 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG13 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG14 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG15 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG16 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG17 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG2 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG3 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG4 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG5 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG6 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG7 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG8 = 16'b0000000000000000; + parameter [15:0] CH1_TX_PCS_CFG9 = 16'b0000000000000000; + parameter real DATARATE = 10.000; + parameter [15:0] DRPEN_CFG = 16'b0000000000000000; + parameter [15:0] FEC_CFG0 = 16'b0000000000000000; + parameter [15:0] FEC_CFG1 = 16'b0000000000000000; + parameter [15:0] FEC_CFG10 = 16'b0000000000000000; + parameter [15:0] FEC_CFG11 = 16'b0000000000000000; + parameter [15:0] FEC_CFG12 = 16'b0000000000000000; + parameter [15:0] FEC_CFG13 = 16'b0000000000000000; + parameter [15:0] FEC_CFG14 = 16'b0000000000000000; + parameter [15:0] FEC_CFG15 = 16'b0000000000000000; + parameter [15:0] FEC_CFG16 = 16'b0000000000000000; + parameter [15:0] FEC_CFG17 = 16'b0000000000000000; + parameter [15:0] FEC_CFG18 = 16'b0000000000000000; + parameter [15:0] FEC_CFG19 = 16'b0000000000000000; + parameter [15:0] FEC_CFG2 = 16'b0000000000000000; + parameter [15:0] FEC_CFG20 = 16'b0000000000000000; + parameter [15:0] FEC_CFG21 = 16'b0000000000000000; + parameter [15:0] FEC_CFG22 = 16'b0000000000000000; + parameter [15:0] FEC_CFG23 = 16'b0000000000000000; + parameter [15:0] FEC_CFG24 = 16'b0000000000000000; + parameter [15:0] FEC_CFG25 = 16'b0000000000000000; + parameter [15:0] FEC_CFG26 = 16'b0000000000000000; + parameter [15:0] FEC_CFG27 = 16'b0000000000000000; + parameter [15:0] FEC_CFG3 = 16'b0000000000000000; + parameter [15:0] FEC_CFG4 = 16'b0000000000000000; + parameter [15:0] FEC_CFG5 = 16'b0000000000000000; + parameter [15:0] FEC_CFG6 = 16'b0000000000000000; + parameter [15:0] FEC_CFG7 = 16'b0000000000000000; + parameter [15:0] FEC_CFG8 = 16'b0000000000000000; + parameter [15:0] FEC_CFG9 = 16'b0000000000000000; + parameter FEC_MODE = "BYPASS"; + parameter real INS_LOSS_NYQ = 20.000; + parameter integer INTERFACE_WIDTH = 64; + parameter MODULATION_MODE = "NRZ"; + parameter [15:0] PLL_CFG0 = 16'b0001100111110000; + parameter [15:0] PLL_CFG1 = 16'b0000111101110000; + parameter [15:0] PLL_CFG2 = 16'b1000000111101000; + parameter [15:0] PLL_CFG3 = 16'b0100000000000000; + parameter [15:0] PLL_CFG4 = 16'b0111111111101010; + parameter [15:0] PLL_CFG5 = 16'b0100101100111000; + parameter [15:0] PLL_CFG6 = 16'b0000000000100101; + parameter [15:0] PLL_CRS_CTRL_CFG0 = 16'b0000101100100000; + parameter [15:0] PLL_CRS_CTRL_CFG1 = 16'b1100010111010100; + parameter [0:0] PLL_IPS_PIN_EN = 1'b1; + parameter integer PLL_IPS_REFCLK_SEL = 0; + parameter [0:0] RCALSAP_TESTEN = 1'b0; + parameter [0:0] RCAL_APROBE = 1'b0; + parameter [15:0] RST_CFG = 16'b0000000000000010; + parameter [15:0] RST_PLL_CFG0 = 16'b0111011000010100; + parameter [15:0] SAP_CFG0 = 16'b0000000000000000; + parameter [15:0] SDM_CFG0 = 16'b0001100001000000; + parameter [15:0] SDM_CFG1 = 16'b0000000000000000; + parameter [15:0] SDM_CFG2 = 16'b0000000000000000; + parameter [15:0] SDM_SEED_CFG0 = 16'b0000000000000000; + parameter [15:0] SDM_SEED_CFG1 = 16'b0000000000000000; + parameter SIM_DEVICE = "ULTRASCALE_PLUS_ES1"; + parameter SIM_RESET_SPEEDUP = "TRUE"; + parameter integer TX_AMPLITUDE_SWING = 250; + output [27:0] CH0_AXISTDATA; + output CH0_AXISTLAST; + output CH0_AXISTVALID; + output [31:0] CH0_DMONITOROUT; + output CH0_DMONITOROUTCLK; + output CH0_GTMTXN; + output CH0_GTMTXP; + output [15:0] CH0_PCSRSVDOUT; + output [15:0] CH0_PMARSVDOUT; + output CH0_RESETEXCEPTION; + output [2:0] CH0_RXBUFSTATUS; + output [255:0] CH0_RXDATA; + output [3:0] CH0_RXDATAFLAGS; + output CH0_RXDATAISAM; + output CH0_RXDATASTART; + output CH0_RXOUTCLK; + output CH0_RXPMARESETDONE; + output CH0_RXPRBSERR; + output CH0_RXPRBSLOCKED; + output CH0_RXPRGDIVRESETDONE; + output CH0_RXPROGDIVCLK; + output CH0_RXRESETDONE; + output [1:0] CH0_TXBUFSTATUS; + output CH0_TXOUTCLK; + output CH0_TXPMARESETDONE; + output CH0_TXPRGDIVRESETDONE; + output CH0_TXPROGDIVCLK; + output CH0_TXRESETDONE; + output [27:0] CH1_AXISTDATA; + output CH1_AXISTLAST; + output CH1_AXISTVALID; + output [31:0] CH1_DMONITOROUT; + output CH1_DMONITOROUTCLK; + output CH1_GTMTXN; + output CH1_GTMTXP; + output [15:0] CH1_PCSRSVDOUT; + output [15:0] CH1_PMARSVDOUT; + output CH1_RESETEXCEPTION; + output [2:0] CH1_RXBUFSTATUS; + output [255:0] CH1_RXDATA; + output [3:0] CH1_RXDATAFLAGS; + output CH1_RXDATAISAM; + output CH1_RXDATASTART; + output CH1_RXOUTCLK; + output CH1_RXPMARESETDONE; + output CH1_RXPRBSERR; + output CH1_RXPRBSLOCKED; + output CH1_RXPRGDIVRESETDONE; + output CH1_RXPROGDIVCLK; + output CH1_RXRESETDONE; + output [1:0] CH1_TXBUFSTATUS; + output CH1_TXOUTCLK; + output CH1_TXPMARESETDONE; + output CH1_TXPRGDIVRESETDONE; + output CH1_TXPROGDIVCLK; + output CH1_TXRESETDONE; + output CLKTESTSIG2PAD; + output DMONITOROUTPLLCLK; + output [15:0] DRPDO; + output DRPRDY; + output FECRX0ALIGNED; + output FECRX0CORRCWINC; + output FECRX0CWINC; + output FECRX0UNCORRCWINC; + output FECRX1ALIGNED; + output FECRX1CORRCWINC; + output FECRX1CWINC; + output FECRX1UNCORRCWINC; + output [7:0] FECRXLN0BITERR0TO1INC; + output [7:0] FECRXLN0BITERR1TO0INC; + output [14:0] FECRXLN0DLY; + output [3:0] FECRXLN0ERRCNTINC; + output [1:0] FECRXLN0MAPPING; + output [7:0] FECRXLN1BITERR0TO1INC; + output [7:0] FECRXLN1BITERR1TO0INC; + output [14:0] FECRXLN1DLY; + output [3:0] FECRXLN1ERRCNTINC; + output [1:0] FECRXLN1MAPPING; + output [7:0] FECRXLN2BITERR0TO1INC; + output [7:0] FECRXLN2BITERR1TO0INC; + output [14:0] FECRXLN2DLY; + output [3:0] FECRXLN2ERRCNTINC; + output [1:0] FECRXLN2MAPPING; + output [7:0] FECRXLN3BITERR0TO1INC; + output [7:0] FECRXLN3BITERR1TO0INC; + output [14:0] FECRXLN3DLY; + output [3:0] FECRXLN3ERRCNTINC; + output [1:0] FECRXLN3MAPPING; + output FECTRXLN0LOCK; + output FECTRXLN1LOCK; + output FECTRXLN2LOCK; + output FECTRXLN3LOCK; + output GTPOWERGOOD; + output PLLFBCLKLOST; + output PLLLOCK; + output PLLREFCLKLOST; + output PLLREFCLKMONITOR; + output PLLRESETDONE; + output [15:0] PLLRSVDOUT; + output RCALCMP; + output [4:0] RCALOUT; + output RXRECCLK0; + output RXRECCLK1; + input BGBYPASSB; + input BGMONITORENB; + input BGPDB; + input [4:0] BGRCALOVRD; + input BGRCALOVRDENB; + input CH0_AXISEN; + input CH0_AXISRST; + input CH0_AXISTRDY; + input CH0_CFGRESET; + input CH0_DMONFIFORESET; + input CH0_DMONITORCLK; + input CH0_GTMRXN; + input CH0_GTMRXP; + input CH0_GTRXRESET; + input CH0_GTTXRESET; + input [2:0] CH0_LOOPBACK; + input [15:0] CH0_PCSRSVDIN; + input [15:0] CH0_PMARSVDIN; + input CH0_RESETOVRD; + input CH0_RXADAPTRESET; + input CH0_RXADCCALRESET; + input CH0_RXADCCLKGENRESET; + input CH0_RXBUFRESET; + input CH0_RXCDRFREQOS; + input CH0_RXCDRFRRESET; + input CH0_RXCDRHOLD; + input CH0_RXCDRINCPCTRL; + input CH0_RXCDROVRDEN; + input CH0_RXCDRPHRESET; + input CH0_RXDFERESET; + input CH0_RXDSPRESET; + input CH0_RXEQTRAINING; + input CH0_RXEYESCANRESET; + input CH0_RXFECRESET; + input [2:0] CH0_RXOUTCLKSEL; + input CH0_RXPCSRESET; + input [3:0] CH0_RXPCSRESETMASK; + input CH0_RXPMARESET; + input [7:0] CH0_RXPMARESETMASK; + input CH0_RXPOLARITY; + input CH0_RXPRBSCNTSTOP; + input CH0_RXPRBSCSCNTRST; + input [3:0] CH0_RXPRBSPTN; + input CH0_RXPROGDIVRESET; + input CH0_RXQPRBSEN; + input [1:0] CH0_RXRESETMODE; + input CH0_RXSPCSEQADV; + input CH0_RXUSRCLK; + input CH0_RXUSRCLK2; + input CH0_RXUSRRDY; + input CH0_RXUSRSTART; + input CH0_RXUSRSTOP; + input CH0_TXCKALRESET; + input [5:0] CH0_TXCTLFIRDAT; + input [255:0] CH0_TXDATA; + input CH0_TXDATASTART; + input [4:0] CH0_TXDRVAMP; + input [5:0] CH0_TXEMPMAIN; + input [4:0] CH0_TXEMPPOST; + input [4:0] CH0_TXEMPPRE; + input [3:0] CH0_TXEMPPRE2; + input CH0_TXFECRESET; + input CH0_TXINHIBIT; + input CH0_TXMUXDCDEXHOLD; + input CH0_TXMUXDCDORWREN; + input [2:0] CH0_TXOUTCLKSEL; + input CH0_TXPCSRESET; + input [1:0] CH0_TXPCSRESETMASK; + input CH0_TXPMARESET; + input [1:0] CH0_TXPMARESETMASK; + input CH0_TXPOLARITY; + input CH0_TXPRBSINERR; + input [3:0] CH0_TXPRBSPTN; + input CH0_TXPROGDIVRESET; + input CH0_TXQPRBSEN; + input [1:0] CH0_TXRESETMODE; + input CH0_TXSPCSEQADV; + input CH0_TXUSRCLK; + input CH0_TXUSRCLK2; + input CH0_TXUSRRDY; + input CH1_AXISEN; + input CH1_AXISRST; + input CH1_AXISTRDY; + input CH1_CFGRESET; + input CH1_DMONFIFORESET; + input CH1_DMONITORCLK; + input CH1_GTMRXN; + input CH1_GTMRXP; + input CH1_GTRXRESET; + input CH1_GTTXRESET; + input [2:0] CH1_LOOPBACK; + input [15:0] CH1_PCSRSVDIN; + input [15:0] CH1_PMARSVDIN; + input CH1_RESETOVRD; + input CH1_RXADAPTRESET; + input CH1_RXADCCALRESET; + input CH1_RXADCCLKGENRESET; + input CH1_RXBUFRESET; + input CH1_RXCDRFREQOS; + input CH1_RXCDRFRRESET; + input CH1_RXCDRHOLD; + input CH1_RXCDRINCPCTRL; + input CH1_RXCDROVRDEN; + input CH1_RXCDRPHRESET; + input CH1_RXDFERESET; + input CH1_RXDSPRESET; + input CH1_RXEQTRAINING; + input CH1_RXEYESCANRESET; + input CH1_RXFECRESET; + input [2:0] CH1_RXOUTCLKSEL; + input CH1_RXPCSRESET; + input [3:0] CH1_RXPCSRESETMASK; + input CH1_RXPMARESET; + input [7:0] CH1_RXPMARESETMASK; + input CH1_RXPOLARITY; + input CH1_RXPRBSCNTSTOP; + input CH1_RXPRBSCSCNTRST; + input [3:0] CH1_RXPRBSPTN; + input CH1_RXPROGDIVRESET; + input CH1_RXQPRBSEN; + input [1:0] CH1_RXRESETMODE; + input CH1_RXSPCSEQADV; + input CH1_RXUSRCLK; + input CH1_RXUSRCLK2; + input CH1_RXUSRRDY; + input CH1_RXUSRSTART; + input CH1_RXUSRSTOP; + input CH1_TXCKALRESET; + input [5:0] CH1_TXCTLFIRDAT; + input [255:0] CH1_TXDATA; + input CH1_TXDATASTART; + input [4:0] CH1_TXDRVAMP; + input [5:0] CH1_TXEMPMAIN; + input [4:0] CH1_TXEMPPOST; + input [4:0] CH1_TXEMPPRE; + input [3:0] CH1_TXEMPPRE2; + input CH1_TXFECRESET; + input CH1_TXINHIBIT; + input CH1_TXMUXDCDEXHOLD; + input CH1_TXMUXDCDORWREN; + input [2:0] CH1_TXOUTCLKSEL; + input CH1_TXPCSRESET; + input [1:0] CH1_TXPCSRESETMASK; + input CH1_TXPMARESET; + input [1:0] CH1_TXPMARESETMASK; + input CH1_TXPOLARITY; + input CH1_TXPRBSINERR; + input [3:0] CH1_TXPRBSPTN; + input CH1_TXPROGDIVRESET; + input CH1_TXQPRBSEN; + input [1:0] CH1_TXRESETMODE; + input CH1_TXSPCSEQADV; + input CH1_TXUSRCLK; + input CH1_TXUSRCLK2; + input CH1_TXUSRRDY; + input [10:0] DRPADDR; + input DRPCLK; + input [15:0] DRPDI; + input DRPEN; + input DRPRST; + input DRPWE; + input FECCTRLRX0BITSLIPFS; + input FECCTRLRX1BITSLIPFS; + input GTGREFCLK2PLL; + input GTNORTHREFCLK; + input GTREFCLK; + input GTSOUTHREFCLK; + input [7:0] PLLFBDIV; + input PLLMONCLK; + input PLLPD; + input [2:0] PLLREFCLKSEL; + input PLLRESET; + input PLLRESETBYPASSMODE; + input [1:0] PLLRESETMASK; + input [15:0] PLLRSVDIN; + input RCALENB; + input [25:0] SDMDATA; + input SDMTOGGLE; +endmodule + +module IBUFDS_GTM (...); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; - parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; + parameter integer REFCLK_HROW_CK_SEL = 0; + parameter integer REFCLK_ICNTL_RX = 0; + output O; + output ODIV2; + input CEB; + (* iopad_external_pin *) + input I; + (* iopad_external_pin *) + input IB; +endmodule + +module OBUFDS_GTM (...); + parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; + parameter integer REFCLK_ICNTL_TX = 0; (* iopad_external_pin *) output O; (* iopad_external_pin *) @@ -18214,16 +18921,259 @@ module OBUFDS_GTE4 (...); input I; endmodule -module OBUFDS_GTE4_ADV (...); +module OBUFDS_GTM_ADV (...); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; - parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; + parameter integer REFCLK_ICNTL_TX = 0; + parameter [1:0] RXRECCLK_SEL = 2'b00; (* iopad_external_pin *) output O; (* iopad_external_pin *) output OB; input CEB; input [3:0] I; - input [1:0] RXRECCLK_SEL; +endmodule + +module HSDAC (...); + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter integer XPA_CFG0 = 0; + parameter integer XPA_CFG1 = 0; + parameter integer XPA_NUM_DACS = 0; + parameter integer XPA_NUM_DUCS = 0; + parameter XPA_PLL_USED = "No"; + parameter integer XPA_SAMPLE_RATE_MSPS = 0; + output CLK_DAC; + output [15:0] DOUT; + output DRDY; + output PLL_DMON_OUT; + output PLL_REFCLK_OUT; + output [15:0] STATUS_COMMON; + output [15:0] STATUS_DAC0; + output [15:0] STATUS_DAC1; + output [15:0] STATUS_DAC2; + output [15:0] STATUS_DAC3; + output SYSREF_OUT_NORTH; + output SYSREF_OUT_SOUTH; + output VOUT0_N; + output VOUT0_P; + output VOUT1_N; + output VOUT1_P; + output VOUT2_N; + output VOUT2_P; + output VOUT3_N; + output VOUT3_P; + input CLK_FIFO_LM; + input [15:0] CONTROL_COMMON; + input [15:0] CONTROL_DAC0; + input [15:0] CONTROL_DAC1; + input [15:0] CONTROL_DAC2; + input [15:0] CONTROL_DAC3; + input DAC_CLK_N; + input DAC_CLK_P; + input [11:0] DADDR; + input [255:0] DATA_DAC0; + input [255:0] DATA_DAC1; + input [255:0] DATA_DAC2; + input [255:0] DATA_DAC3; + input DCLK; + input DEN; + input [15:0] DI; + input DWE; + input FABRIC_CLK; + input PLL_MONCLK; + input PLL_REFCLK_IN; + input SYSREF_IN_NORTH; + input SYSREF_IN_SOUTH; + input SYSREF_N; + input SYSREF_P; +endmodule + +module HSADC (...); + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter integer XPA_CFG0 = 0; + parameter integer XPA_CFG1 = 0; + parameter XPA_NUM_ADCS = "0"; + parameter integer XPA_NUM_DDCS = 0; + parameter XPA_PLL_USED = "No"; + parameter integer XPA_SAMPLE_RATE_MSPS = 0; + output CLK_ADC; + output [127:0] DATA_ADC0; + output [127:0] DATA_ADC1; + output [127:0] DATA_ADC2; + output [127:0] DATA_ADC3; + output [15:0] DOUT; + output DRDY; + output PLL_DMON_OUT; + output PLL_REFCLK_OUT; + output [15:0] STATUS_ADC0; + output [15:0] STATUS_ADC1; + output [15:0] STATUS_ADC2; + output [15:0] STATUS_ADC3; + output [15:0] STATUS_COMMON; + output SYSREF_OUT_NORTH; + output SYSREF_OUT_SOUTH; + input ADC_CLK_N; + input ADC_CLK_P; + input CLK_FIFO_LM; + input [15:0] CONTROL_ADC0; + input [15:0] CONTROL_ADC1; + input [15:0] CONTROL_ADC2; + input [15:0] CONTROL_ADC3; + input [15:0] CONTROL_COMMON; + input [11:0] DADDR; + input DCLK; + input DEN; + input [15:0] DI; + input DWE; + input FABRIC_CLK; + input PLL_MONCLK; + input PLL_REFCLK_IN; + input SYSREF_IN_NORTH; + input SYSREF_IN_SOUTH; + input SYSREF_N; + input SYSREF_P; + input VIN0_N; + input VIN0_P; + input VIN1_N; + input VIN1_P; + input VIN2_N; + input VIN2_P; + input VIN3_N; + input VIN3_P; + input VIN_I01_N; + input VIN_I01_P; + input VIN_I23_N; + input VIN_I23_P; +endmodule + +module RFDAC (...); + parameter integer OPT_CLK_DIST = 0; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter integer XPA_ACTIVE_DUTYCYCLE = 100; + parameter integer XPA_CFG0 = 0; + parameter integer XPA_CFG1 = 0; + parameter integer XPA_CFG2 = 0; + parameter integer XPA_NUM_DACS = 0; + parameter integer XPA_NUM_DUCS = 0; + parameter XPA_PLL_USED = "EXTERNAL"; + parameter integer XPA_SAMPLE_RATE_MSPS = 0; + output CLK_DAC; + output CLK_DIST_OUT_NORTH; + output CLK_DIST_OUT_SOUTH; + output [15:0] DOUT; + output DRDY; + output PLL_DMON_OUT; + output PLL_REFCLK_OUT; + output [23:0] STATUS_COMMON; + output [23:0] STATUS_DAC0; + output [23:0] STATUS_DAC1; + output [23:0] STATUS_DAC2; + output [23:0] STATUS_DAC3; + output SYSREF_OUT_NORTH; + output SYSREF_OUT_SOUTH; + output T1_ALLOWED_SOUTH; + output VOUT0_N; + output VOUT0_P; + output VOUT1_N; + output VOUT1_P; + output VOUT2_N; + output VOUT2_P; + output VOUT3_N; + output VOUT3_P; + input CLK_DIST_IN_NORTH; + input CLK_DIST_IN_SOUTH; + input CLK_FIFO_LM; + input [15:0] CONTROL_COMMON; + input [15:0] CONTROL_DAC0; + input [15:0] CONTROL_DAC1; + input [15:0] CONTROL_DAC2; + input [15:0] CONTROL_DAC3; + input DAC_CLK_N; + input DAC_CLK_P; + input [11:0] DADDR; + input [255:0] DATA_DAC0; + input [255:0] DATA_DAC1; + input [255:0] DATA_DAC2; + input [255:0] DATA_DAC3; + input DCLK; + input DEN; + input [15:0] DI; + input DWE; + input FABRIC_CLK; + input PLL_MONCLK; + input PLL_REFCLK_IN; + input SYSREF_IN_NORTH; + input SYSREF_IN_SOUTH; + input SYSREF_N; + input SYSREF_P; + input T1_ALLOWED_NORTH; +endmodule + +module RFADC (...); + parameter integer OPT_ANALOG = 0; + parameter integer OPT_CLK_DIST = 0; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter integer XPA_ACTIVE_DUTYCYCLE = 100; + parameter integer XPA_CFG0 = 0; + parameter integer XPA_CFG1 = 0; + parameter integer XPA_CFG2 = 0; + parameter XPA_NUM_ADCS = "0"; + parameter integer XPA_NUM_DDCS = 0; + parameter XPA_PLL_USED = "EXTERNAL"; + parameter integer XPA_SAMPLE_RATE_MSPS = 0; + output CLK_ADC; + output CLK_DIST_OUT_NORTH; + output CLK_DIST_OUT_SOUTH; + output [191:0] DATA_ADC0; + output [191:0] DATA_ADC1; + output [191:0] DATA_ADC2; + output [191:0] DATA_ADC3; + output [15:0] DOUT; + output DRDY; + output PLL_DMON_OUT; + output PLL_REFCLK_OUT; + output [23:0] STATUS_ADC0; + output [23:0] STATUS_ADC1; + output [23:0] STATUS_ADC2; + output [23:0] STATUS_ADC3; + output [23:0] STATUS_COMMON; + output SYSREF_OUT_NORTH; + output SYSREF_OUT_SOUTH; + output T1_ALLOWED_SOUTH; + input ADC_CLK_N; + input ADC_CLK_P; + input CLK_DIST_IN_NORTH; + input CLK_DIST_IN_SOUTH; + input CLK_FIFO_LM; + input [15:0] CONTROL_ADC0; + input [15:0] CONTROL_ADC1; + input [15:0] CONTROL_ADC2; + input [15:0] CONTROL_ADC3; + input [15:0] CONTROL_COMMON; + input [11:0] DADDR; + input DCLK; + input DEN; + input [15:0] DI; + input DWE; + input FABRIC_CLK; + input PLL_MONCLK; + input PLL_REFCLK_IN; + input SYSREF_IN_NORTH; + input SYSREF_IN_SOUTH; + input SYSREF_N; + input SYSREF_P; + input T1_ALLOWED_NORTH; + input VIN0_N; + input VIN0_P; + input VIN1_N; + input VIN1_P; + input VIN2_N; + input VIN2_P; + input VIN3_N; + input VIN3_P; + input VIN_I01_N; + input VIN_I01_P; + input VIN_I23_N; + input VIN_I23_P; endmodule module PCIE_A1 (...); @@ -23603,2093 +24553,2804 @@ module PCIE40E4 (...); input [31:0] USERSPAREIN; endmodule -module EMAC (...); - parameter EMAC0_MODE = "RGMII"; - parameter EMAC1_MODE = "RGMII"; - output DCRHOSTDONEIR; - output EMAC0CLIENTANINTERRUPT; - output EMAC0CLIENTRXBADFRAME; - output EMAC0CLIENTRXCLIENTCLKOUT; - output EMAC0CLIENTRXDVLD; - output EMAC0CLIENTRXDVLDMSW; - output EMAC0CLIENTRXDVREG6; - output EMAC0CLIENTRXFRAMEDROP; - output EMAC0CLIENTRXGOODFRAME; - output EMAC0CLIENTRXSTATSBYTEVLD; - output EMAC0CLIENTRXSTATSVLD; - output EMAC0CLIENTTXACK; - output EMAC0CLIENTTXCLIENTCLKOUT; - output EMAC0CLIENTTXCOLLISION; - output EMAC0CLIENTTXGMIIMIICLKOUT; - output EMAC0CLIENTTXRETRANSMIT; - output EMAC0CLIENTTXSTATS; - output EMAC0CLIENTTXSTATSBYTEVLD; - output EMAC0CLIENTTXSTATSVLD; - output EMAC0PHYENCOMMAALIGN; - output EMAC0PHYLOOPBACKMSB; - output EMAC0PHYMCLKOUT; - output EMAC0PHYMDOUT; - output EMAC0PHYMDTRI; - output EMAC0PHYMGTRXRESET; - output EMAC0PHYMGTTXRESET; - output EMAC0PHYPOWERDOWN; - output EMAC0PHYSYNCACQSTATUS; - output EMAC0PHYTXCHARDISPMODE; - output EMAC0PHYTXCHARDISPVAL; - output EMAC0PHYTXCHARISK; - output EMAC0PHYTXCLK; - output EMAC0PHYTXEN; - output EMAC0PHYTXER; - output EMAC1CLIENTANINTERRUPT; - output EMAC1CLIENTRXBADFRAME; - output EMAC1CLIENTRXCLIENTCLKOUT; - output EMAC1CLIENTRXDVLD; - output EMAC1CLIENTRXDVLDMSW; - output EMAC1CLIENTRXDVREG6; - output EMAC1CLIENTRXFRAMEDROP; - output EMAC1CLIENTRXGOODFRAME; - output EMAC1CLIENTRXSTATSBYTEVLD; - output EMAC1CLIENTRXSTATSVLD; - output EMAC1CLIENTTXACK; - output EMAC1CLIENTTXCLIENTCLKOUT; - output EMAC1CLIENTTXCOLLISION; - output EMAC1CLIENTTXGMIIMIICLKOUT; - output EMAC1CLIENTTXRETRANSMIT; - output EMAC1CLIENTTXSTATS; - output EMAC1CLIENTTXSTATSBYTEVLD; - output EMAC1CLIENTTXSTATSVLD; - output EMAC1PHYENCOMMAALIGN; - output EMAC1PHYLOOPBACKMSB; - output EMAC1PHYMCLKOUT; - output EMAC1PHYMDOUT; - output EMAC1PHYMDTRI; - output EMAC1PHYMGTRXRESET; - output EMAC1PHYMGTTXRESET; - output EMAC1PHYPOWERDOWN; - output EMAC1PHYSYNCACQSTATUS; - output EMAC1PHYTXCHARDISPMODE; - output EMAC1PHYTXCHARDISPVAL; - output EMAC1PHYTXCHARISK; - output EMAC1PHYTXCLK; - output EMAC1PHYTXEN; - output EMAC1PHYTXER; - output EMACDCRACK; - output HOSTMIIMRDY; - output [0:31] EMACDCRDBUS; - output [15:0] EMAC0CLIENTRXD; - output [15:0] EMAC1CLIENTRXD; - output [31:0] HOSTRDDATA; - output [6:0] EMAC0CLIENTRXSTATS; - output [6:0] EMAC1CLIENTRXSTATS; - output [7:0] EMAC0PHYTXD; - output [7:0] EMAC1PHYTXD; - input CLIENTEMAC0DCMLOCKED; - input CLIENTEMAC0PAUSEREQ; - input CLIENTEMAC0RXCLIENTCLKIN; - input CLIENTEMAC0TXCLIENTCLKIN; - input CLIENTEMAC0TXDVLD; - input CLIENTEMAC0TXDVLDMSW; - input CLIENTEMAC0TXFIRSTBYTE; - input CLIENTEMAC0TXGMIIMIICLKIN; - input CLIENTEMAC0TXUNDERRUN; - input CLIENTEMAC1DCMLOCKED; - input CLIENTEMAC1PAUSEREQ; - input CLIENTEMAC1RXCLIENTCLKIN; - input CLIENTEMAC1TXCLIENTCLKIN; - input CLIENTEMAC1TXDVLD; - input CLIENTEMAC1TXDVLDMSW; - input CLIENTEMAC1TXFIRSTBYTE; - input CLIENTEMAC1TXGMIIMIICLKIN; - input CLIENTEMAC1TXUNDERRUN; - input DCREMACCLK; - input DCREMACENABLE; - input DCREMACREAD; - input DCREMACWRITE; - input HOSTCLK; - input HOSTEMAC1SEL; - input HOSTMIIMSEL; - input HOSTREQ; - input PHYEMAC0COL; - input PHYEMAC0CRS; - input PHYEMAC0GTXCLK; - input PHYEMAC0MCLKIN; - input PHYEMAC0MDIN; - input PHYEMAC0MIITXCLK; - input PHYEMAC0RXBUFERR; - input PHYEMAC0RXCHARISCOMMA; - input PHYEMAC0RXCHARISK; - input PHYEMAC0RXCHECKINGCRC; - input PHYEMAC0RXCLK; - input PHYEMAC0RXCOMMADET; - input PHYEMAC0RXDISPERR; - input PHYEMAC0RXDV; - input PHYEMAC0RXER; - input PHYEMAC0RXNOTINTABLE; - input PHYEMAC0RXRUNDISP; - input PHYEMAC0SIGNALDET; - input PHYEMAC0TXBUFERR; - input PHYEMAC1COL; - input PHYEMAC1CRS; - input PHYEMAC1GTXCLK; - input PHYEMAC1MCLKIN; - input PHYEMAC1MDIN; - input PHYEMAC1MIITXCLK; - input PHYEMAC1RXBUFERR; - input PHYEMAC1RXCHARISCOMMA; - input PHYEMAC1RXCHARISK; - input PHYEMAC1RXCHECKINGCRC; - input PHYEMAC1RXCLK; - input PHYEMAC1RXCOMMADET; - input PHYEMAC1RXDISPERR; - input PHYEMAC1RXDV; - input PHYEMAC1RXER; - input PHYEMAC1RXNOTINTABLE; - input PHYEMAC1RXRUNDISP; - input PHYEMAC1SIGNALDET; - input PHYEMAC1TXBUFERR; - input RESET; - input [0:31] DCREMACDBUS; - input [15:0] CLIENTEMAC0PAUSEVAL; - input [15:0] CLIENTEMAC0TXD; - input [15:0] CLIENTEMAC1PAUSEVAL; - input [15:0] CLIENTEMAC1TXD; - input [1:0] HOSTOPCODE; - input [1:0] PHYEMAC0RXBUFSTATUS; - input [1:0] PHYEMAC0RXLOSSOFSYNC; - input [1:0] PHYEMAC1RXBUFSTATUS; - input [1:0] PHYEMAC1RXLOSSOFSYNC; - input [2:0] PHYEMAC0RXCLKCORCNT; - input [2:0] PHYEMAC1RXCLKCORCNT; - input [31:0] HOSTWRDATA; - input [47:0] TIEEMAC0UNICASTADDR; - input [47:0] TIEEMAC1UNICASTADDR; - input [4:0] PHYEMAC0PHYAD; - input [4:0] PHYEMAC1PHYAD; - input [79:0] TIEEMAC0CONFIGVEC; - input [79:0] TIEEMAC1CONFIGVEC; - input [7:0] CLIENTEMAC0TXIFGDELAY; - input [7:0] CLIENTEMAC1TXIFGDELAY; - input [7:0] PHYEMAC0RXD; - input [7:0] PHYEMAC1RXD; - input [8:9] DCREMACABUS; - input [9:0] HOSTADDR; -endmodule - -module TEMAC (...); - parameter EMAC0_1000BASEX_ENABLE = "FALSE"; - parameter EMAC0_ADDRFILTER_ENABLE = "FALSE"; - parameter EMAC0_BYTEPHY = "FALSE"; - parameter EMAC0_CONFIGVEC_79 = "FALSE"; - parameter EMAC0_GTLOOPBACK = "FALSE"; - parameter EMAC0_HOST_ENABLE = "FALSE"; - parameter EMAC0_LTCHECK_DISABLE = "FALSE"; - parameter EMAC0_MDIO_ENABLE = "FALSE"; - parameter EMAC0_PHYINITAUTONEG_ENABLE = "FALSE"; - parameter EMAC0_PHYISOLATE = "FALSE"; - parameter EMAC0_PHYLOOPBACKMSB = "FALSE"; - parameter EMAC0_PHYPOWERDOWN = "FALSE"; - parameter EMAC0_PHYRESET = "FALSE"; - parameter EMAC0_RGMII_ENABLE = "FALSE"; - parameter EMAC0_RX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC0_RXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC0_RXHALFDUPLEX = "FALSE"; - parameter EMAC0_RXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC0_RXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC0_RXRESET = "FALSE"; - parameter EMAC0_RXVLAN_ENABLE = "FALSE"; - parameter EMAC0_RX_ENABLE = "FALSE"; - parameter EMAC0_SGMII_ENABLE = "FALSE"; - parameter EMAC0_SPEED_LSB = "FALSE"; - parameter EMAC0_SPEED_MSB = "FALSE"; - parameter EMAC0_TX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC0_TXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC0_TXHALFDUPLEX = "FALSE"; - parameter EMAC0_TXIFGADJUST_ENABLE = "FALSE"; - parameter EMAC0_TXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC0_TXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC0_TXRESET = "FALSE"; - parameter EMAC0_TXVLAN_ENABLE = "FALSE"; - parameter EMAC0_TX_ENABLE = "FALSE"; - parameter EMAC0_UNIDIRECTION_ENABLE = "FALSE"; - parameter EMAC0_USECLKEN = "FALSE"; - parameter EMAC1_1000BASEX_ENABLE = "FALSE"; - parameter EMAC1_ADDRFILTER_ENABLE = "FALSE"; - parameter EMAC1_BYTEPHY = "FALSE"; - parameter EMAC1_CONFIGVEC_79 = "FALSE"; - parameter EMAC1_GTLOOPBACK = "FALSE"; - parameter EMAC1_HOST_ENABLE = "FALSE"; - parameter EMAC1_LTCHECK_DISABLE = "FALSE"; - parameter EMAC1_MDIO_ENABLE = "FALSE"; - parameter EMAC1_PHYINITAUTONEG_ENABLE = "FALSE"; - parameter EMAC1_PHYISOLATE = "FALSE"; - parameter EMAC1_PHYLOOPBACKMSB = "FALSE"; - parameter EMAC1_PHYPOWERDOWN = "FALSE"; - parameter EMAC1_PHYRESET = "FALSE"; - parameter EMAC1_RGMII_ENABLE = "FALSE"; - parameter EMAC1_RX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC1_RXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC1_RXHALFDUPLEX = "FALSE"; - parameter EMAC1_RXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC1_RXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC1_RXRESET = "FALSE"; - parameter EMAC1_RXVLAN_ENABLE = "FALSE"; - parameter EMAC1_RX_ENABLE = "FALSE"; - parameter EMAC1_SGMII_ENABLE = "FALSE"; - parameter EMAC1_SPEED_LSB = "FALSE"; - parameter EMAC1_SPEED_MSB = "FALSE"; - parameter EMAC1_TX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC1_TXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC1_TXHALFDUPLEX = "FALSE"; - parameter EMAC1_TXIFGADJUST_ENABLE = "FALSE"; - parameter EMAC1_TXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC1_TXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC1_TXRESET = "FALSE"; - parameter EMAC1_TXVLAN_ENABLE = "FALSE"; - parameter EMAC1_TX_ENABLE = "FALSE"; - parameter EMAC1_UNIDIRECTION_ENABLE = "FALSE"; - parameter EMAC1_USECLKEN = "FALSE"; - parameter [0:7] EMAC0_DCRBASEADDR = 8'h00; - parameter [0:7] EMAC1_DCRBASEADDR = 8'h00; - parameter [47:0] EMAC0_PAUSEADDR = 48'h000000000000; - parameter [47:0] EMAC0_UNICASTADDR = 48'h000000000000; - parameter [47:0] EMAC1_PAUSEADDR = 48'h000000000000; - parameter [47:0] EMAC1_UNICASTADDR = 48'h000000000000; - parameter [8:0] EMAC0_LINKTIMERVAL = 9'h000; - parameter [8:0] EMAC1_LINKTIMERVAL = 9'h000; - output DCRHOSTDONEIR; - output EMAC0CLIENTANINTERRUPT; - output EMAC0CLIENTRXBADFRAME; - output EMAC0CLIENTRXCLIENTCLKOUT; - output EMAC0CLIENTRXDVLD; - output EMAC0CLIENTRXDVLDMSW; - output EMAC0CLIENTRXFRAMEDROP; - output EMAC0CLIENTRXGOODFRAME; - output EMAC0CLIENTRXSTATSBYTEVLD; - output EMAC0CLIENTRXSTATSVLD; - output EMAC0CLIENTTXACK; - output EMAC0CLIENTTXCLIENTCLKOUT; - output EMAC0CLIENTTXCOLLISION; - output EMAC0CLIENTTXRETRANSMIT; - output EMAC0CLIENTTXSTATS; - output EMAC0CLIENTTXSTATSBYTEVLD; - output EMAC0CLIENTTXSTATSVLD; - output EMAC0PHYENCOMMAALIGN; - output EMAC0PHYLOOPBACKMSB; - output EMAC0PHYMCLKOUT; - output EMAC0PHYMDOUT; - output EMAC0PHYMDTRI; - output EMAC0PHYMGTRXRESET; - output EMAC0PHYMGTTXRESET; - output EMAC0PHYPOWERDOWN; - output EMAC0PHYSYNCACQSTATUS; - output EMAC0PHYTXCHARDISPMODE; - output EMAC0PHYTXCHARDISPVAL; - output EMAC0PHYTXCHARISK; - output EMAC0PHYTXCLK; - output EMAC0PHYTXEN; - output EMAC0PHYTXER; - output EMAC0PHYTXGMIIMIICLKOUT; - output EMAC0SPEEDIS10100; - output EMAC1CLIENTANINTERRUPT; - output EMAC1CLIENTRXBADFRAME; - output EMAC1CLIENTRXCLIENTCLKOUT; - output EMAC1CLIENTRXDVLD; - output EMAC1CLIENTRXDVLDMSW; - output EMAC1CLIENTRXFRAMEDROP; - output EMAC1CLIENTRXGOODFRAME; - output EMAC1CLIENTRXSTATSBYTEVLD; - output EMAC1CLIENTRXSTATSVLD; - output EMAC1CLIENTTXACK; - output EMAC1CLIENTTXCLIENTCLKOUT; - output EMAC1CLIENTTXCOLLISION; - output EMAC1CLIENTTXRETRANSMIT; - output EMAC1CLIENTTXSTATS; - output EMAC1CLIENTTXSTATSBYTEVLD; - output EMAC1CLIENTTXSTATSVLD; - output EMAC1PHYENCOMMAALIGN; - output EMAC1PHYLOOPBACKMSB; - output EMAC1PHYMCLKOUT; - output EMAC1PHYMDOUT; - output EMAC1PHYMDTRI; - output EMAC1PHYMGTRXRESET; - output EMAC1PHYMGTTXRESET; - output EMAC1PHYPOWERDOWN; - output EMAC1PHYSYNCACQSTATUS; - output EMAC1PHYTXCHARDISPMODE; - output EMAC1PHYTXCHARDISPVAL; - output EMAC1PHYTXCHARISK; - output EMAC1PHYTXCLK; - output EMAC1PHYTXEN; - output EMAC1PHYTXER; - output EMAC1PHYTXGMIIMIICLKOUT; - output EMAC1SPEEDIS10100; - output EMACDCRACK; - output HOSTMIIMRDY; - output [0:31] EMACDCRDBUS; - output [15:0] EMAC0CLIENTRXD; - output [15:0] EMAC1CLIENTRXD; - output [31:0] HOSTRDDATA; - output [6:0] EMAC0CLIENTRXSTATS; - output [6:0] EMAC1CLIENTRXSTATS; - output [7:0] EMAC0PHYTXD; - output [7:0] EMAC1PHYTXD; - input CLIENTEMAC0DCMLOCKED; - input CLIENTEMAC0PAUSEREQ; - input CLIENTEMAC0RXCLIENTCLKIN; - input CLIENTEMAC0TXCLIENTCLKIN; - input CLIENTEMAC0TXDVLD; - input CLIENTEMAC0TXDVLDMSW; - input CLIENTEMAC0TXFIRSTBYTE; - input CLIENTEMAC0TXUNDERRUN; - input CLIENTEMAC1DCMLOCKED; - input CLIENTEMAC1PAUSEREQ; - input CLIENTEMAC1RXCLIENTCLKIN; - input CLIENTEMAC1TXCLIENTCLKIN; - input CLIENTEMAC1TXDVLD; - input CLIENTEMAC1TXDVLDMSW; - input CLIENTEMAC1TXFIRSTBYTE; - input CLIENTEMAC1TXUNDERRUN; - input DCREMACCLK; - input DCREMACENABLE; - input DCREMACREAD; - input DCREMACWRITE; - input HOSTCLK; - input HOSTEMAC1SEL; - input HOSTMIIMSEL; - input HOSTREQ; - input PHYEMAC0COL; - input PHYEMAC0CRS; - input PHYEMAC0GTXCLK; - input PHYEMAC0MCLKIN; - input PHYEMAC0MDIN; - input PHYEMAC0MIITXCLK; - input PHYEMAC0RXBUFERR; - input PHYEMAC0RXCHARISCOMMA; - input PHYEMAC0RXCHARISK; - input PHYEMAC0RXCHECKINGCRC; - input PHYEMAC0RXCLK; - input PHYEMAC0RXCOMMADET; - input PHYEMAC0RXDISPERR; - input PHYEMAC0RXDV; - input PHYEMAC0RXER; - input PHYEMAC0RXNOTINTABLE; - input PHYEMAC0RXRUNDISP; - input PHYEMAC0SIGNALDET; - input PHYEMAC0TXBUFERR; - input PHYEMAC0TXGMIIMIICLKIN; - input PHYEMAC1COL; - input PHYEMAC1CRS; - input PHYEMAC1GTXCLK; - input PHYEMAC1MCLKIN; - input PHYEMAC1MDIN; - input PHYEMAC1MIITXCLK; - input PHYEMAC1RXBUFERR; - input PHYEMAC1RXCHARISCOMMA; - input PHYEMAC1RXCHARISK; - input PHYEMAC1RXCHECKINGCRC; - input PHYEMAC1RXCLK; - input PHYEMAC1RXCOMMADET; - input PHYEMAC1RXDISPERR; - input PHYEMAC1RXDV; - input PHYEMAC1RXER; - input PHYEMAC1RXNOTINTABLE; - input PHYEMAC1RXRUNDISP; - input PHYEMAC1SIGNALDET; - input PHYEMAC1TXBUFERR; - input PHYEMAC1TXGMIIMIICLKIN; - input RESET; - input [0:31] DCREMACDBUS; - input [0:9] DCREMACABUS; - input [15:0] CLIENTEMAC0PAUSEVAL; - input [15:0] CLIENTEMAC0TXD; - input [15:0] CLIENTEMAC1PAUSEVAL; - input [15:0] CLIENTEMAC1TXD; - input [1:0] HOSTOPCODE; - input [1:0] PHYEMAC0RXBUFSTATUS; - input [1:0] PHYEMAC0RXLOSSOFSYNC; - input [1:0] PHYEMAC1RXBUFSTATUS; - input [1:0] PHYEMAC1RXLOSSOFSYNC; - input [2:0] PHYEMAC0RXCLKCORCNT; - input [2:0] PHYEMAC1RXCLKCORCNT; - input [31:0] HOSTWRDATA; - input [4:0] PHYEMAC0PHYAD; - input [4:0] PHYEMAC1PHYAD; - input [7:0] CLIENTEMAC0TXIFGDELAY; - input [7:0] CLIENTEMAC1TXIFGDELAY; - input [7:0] PHYEMAC0RXD; - input [7:0] PHYEMAC1RXD; - input [9:0] HOSTADDR; -endmodule - -module TEMAC_SINGLE (...); - parameter EMAC_1000BASEX_ENABLE = "FALSE"; - parameter EMAC_ADDRFILTER_ENABLE = "FALSE"; - parameter EMAC_BYTEPHY = "FALSE"; - parameter EMAC_CTRLLENCHECK_DISABLE = "FALSE"; - parameter [0:7] EMAC_DCRBASEADDR = 8'h00; - parameter EMAC_GTLOOPBACK = "FALSE"; - parameter EMAC_HOST_ENABLE = "FALSE"; - parameter [8:0] EMAC_LINKTIMERVAL = 9'h000; - parameter EMAC_LTCHECK_DISABLE = "FALSE"; - parameter EMAC_MDIO_ENABLE = "FALSE"; - parameter EMAC_MDIO_IGNORE_PHYADZERO = "FALSE"; - parameter [47:0] EMAC_PAUSEADDR = 48'h000000000000; - parameter EMAC_PHYINITAUTONEG_ENABLE = "FALSE"; - parameter EMAC_PHYISOLATE = "FALSE"; - parameter EMAC_PHYLOOPBACKMSB = "FALSE"; - parameter EMAC_PHYPOWERDOWN = "FALSE"; - parameter EMAC_PHYRESET = "FALSE"; - parameter EMAC_RGMII_ENABLE = "FALSE"; - parameter EMAC_RX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC_RXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC_RXHALFDUPLEX = "FALSE"; - parameter EMAC_RXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC_RXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC_RXRESET = "FALSE"; - parameter EMAC_RXVLAN_ENABLE = "FALSE"; - parameter EMAC_RX_ENABLE = "TRUE"; - parameter EMAC_SGMII_ENABLE = "FALSE"; - parameter EMAC_SPEED_LSB = "FALSE"; - parameter EMAC_SPEED_MSB = "FALSE"; - parameter EMAC_TX16BITCLIENT_ENABLE = "FALSE"; - parameter EMAC_TXFLOWCTRL_ENABLE = "FALSE"; - parameter EMAC_TXHALFDUPLEX = "FALSE"; - parameter EMAC_TXIFGADJUST_ENABLE = "FALSE"; - parameter EMAC_TXINBANDFCS_ENABLE = "FALSE"; - parameter EMAC_TXJUMBOFRAME_ENABLE = "FALSE"; - parameter EMAC_TXRESET = "FALSE"; - parameter EMAC_TXVLAN_ENABLE = "FALSE"; - parameter EMAC_TX_ENABLE = "TRUE"; - parameter [47:0] EMAC_UNICASTADDR = 48'h000000000000; - parameter EMAC_UNIDIRECTION_ENABLE = "FALSE"; - parameter EMAC_USECLKEN = "FALSE"; - parameter SIM_VERSION = "1.0"; - output DCRHOSTDONEIR; - output EMACCLIENTANINTERRUPT; - output EMACCLIENTRXBADFRAME; - output EMACCLIENTRXCLIENTCLKOUT; - output EMACCLIENTRXDVLD; - output EMACCLIENTRXDVLDMSW; - output EMACCLIENTRXFRAMEDROP; - output EMACCLIENTRXGOODFRAME; - output EMACCLIENTRXSTATSBYTEVLD; - output EMACCLIENTRXSTATSVLD; - output EMACCLIENTTXACK; - output EMACCLIENTTXCLIENTCLKOUT; - output EMACCLIENTTXCOLLISION; - output EMACCLIENTTXRETRANSMIT; - output EMACCLIENTTXSTATS; - output EMACCLIENTTXSTATSBYTEVLD; - output EMACCLIENTTXSTATSVLD; - output EMACDCRACK; - output EMACPHYENCOMMAALIGN; - output EMACPHYLOOPBACKMSB; - output EMACPHYMCLKOUT; - output EMACPHYMDOUT; - output EMACPHYMDTRI; - output EMACPHYMGTRXRESET; - output EMACPHYMGTTXRESET; - output EMACPHYPOWERDOWN; - output EMACPHYSYNCACQSTATUS; - output EMACPHYTXCHARDISPMODE; - output EMACPHYTXCHARDISPVAL; - output EMACPHYTXCHARISK; - output EMACPHYTXCLK; - output EMACPHYTXEN; - output EMACPHYTXER; - output EMACPHYTXGMIIMIICLKOUT; - output EMACSPEEDIS10100; - output HOSTMIIMRDY; - output [0:31] EMACDCRDBUS; - output [15:0] EMACCLIENTRXD; - output [31:0] HOSTRDDATA; - output [6:0] EMACCLIENTRXSTATS; - output [7:0] EMACPHYTXD; - input CLIENTEMACDCMLOCKED; - input CLIENTEMACPAUSEREQ; - input CLIENTEMACRXCLIENTCLKIN; - input CLIENTEMACTXCLIENTCLKIN; - input CLIENTEMACTXDVLD; - input CLIENTEMACTXDVLDMSW; - input CLIENTEMACTXFIRSTBYTE; - input CLIENTEMACTXUNDERRUN; - input DCREMACCLK; - input DCREMACENABLE; - input DCREMACREAD; - input DCREMACWRITE; - input HOSTCLK; - input HOSTMIIMSEL; - input HOSTREQ; - input PHYEMACCOL; - input PHYEMACCRS; - input PHYEMACGTXCLK; - input PHYEMACMCLKIN; - input PHYEMACMDIN; - input PHYEMACMIITXCLK; - input PHYEMACRXCHARISCOMMA; - input PHYEMACRXCHARISK; - input PHYEMACRXCLK; - input PHYEMACRXDISPERR; - input PHYEMACRXDV; - input PHYEMACRXER; - input PHYEMACRXNOTINTABLE; - input PHYEMACRXRUNDISP; - input PHYEMACSIGNALDET; - input PHYEMACTXBUFERR; - input PHYEMACTXGMIIMIICLKIN; - input RESET; - input [0:31] DCREMACDBUS; - input [0:9] DCREMACABUS; - input [15:0] CLIENTEMACPAUSEVAL; - input [15:0] CLIENTEMACTXD; - input [1:0] HOSTOPCODE; - input [1:0] PHYEMACRXBUFSTATUS; - input [2:0] PHYEMACRXCLKCORCNT; - input [31:0] HOSTWRDATA; - input [4:0] PHYEMACPHYAD; - input [7:0] CLIENTEMACTXIFGDELAY; - input [7:0] PHYEMACRXD; - input [9:0] HOSTADDR; -endmodule - -module CMAC (...); - parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; - parameter CTL_RX_CHECK_ACK = "TRUE"; - parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; - parameter CTL_RX_CHECK_SFD = "FALSE"; - parameter CTL_RX_DELETE_FCS = "TRUE"; - parameter [15:0] CTL_RX_ETYPE_GCP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_GPP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_PCP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_PPP = 16'h8808; - parameter CTL_RX_FORWARD_CONTROL = "FALSE"; - parameter CTL_RX_IGNORE_FCS = "FALSE"; - parameter [14:0] CTL_RX_MAX_PACKET_LEN = 15'h2580; - parameter [7:0] CTL_RX_MIN_PACKET_LEN = 8'h40; - parameter [15:0] CTL_RX_OPCODE_GPP = 16'h0001; - parameter [15:0] CTL_RX_OPCODE_MAX_GCP = 16'hFFFF; - parameter [15:0] CTL_RX_OPCODE_MAX_PCP = 16'hFFFF; - parameter [15:0] CTL_RX_OPCODE_MIN_GCP = 16'h0000; - parameter [15:0] CTL_RX_OPCODE_MIN_PCP = 16'h0000; - parameter [15:0] CTL_RX_OPCODE_PPP = 16'h0001; - parameter [47:0] CTL_RX_PAUSE_DA_MCAST = 48'h0180C2000001; - parameter [47:0] CTL_RX_PAUSE_DA_UCAST = 48'h000000000000; - parameter [47:0] CTL_RX_PAUSE_SA = 48'h000000000000; - parameter CTL_RX_PROCESS_LFI = "FALSE"; - parameter [15:0] CTL_RX_VL_LENGTH_MINUS1 = 16'h3FFF; - parameter [63:0] CTL_RX_VL_MARKER_ID0 = 64'hC16821003E97DE00; - parameter [63:0] CTL_RX_VL_MARKER_ID1 = 64'h9D718E00628E7100; - parameter [63:0] CTL_RX_VL_MARKER_ID10 = 64'hFD6C990002936600; - parameter [63:0] CTL_RX_VL_MARKER_ID11 = 64'hB9915500466EAA00; - parameter [63:0] CTL_RX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; - parameter [63:0] CTL_RX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; - parameter [63:0] CTL_RX_VL_MARKER_ID14 = 64'h83C7CA007C383500; - parameter [63:0] CTL_RX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; - parameter [63:0] CTL_RX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; - parameter [63:0] CTL_RX_VL_MARKER_ID17 = 64'hADD6B70052294800; - parameter [63:0] CTL_RX_VL_MARKER_ID18 = 64'h5F662A00A099D500; - parameter [63:0] CTL_RX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; - parameter [63:0] CTL_RX_VL_MARKER_ID2 = 64'h594BE800A6B41700; - parameter [63:0] CTL_RX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; - parameter [63:0] CTL_RX_VL_MARKER_ID4 = 64'hF50709000AF8F600; - parameter [63:0] CTL_RX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; - parameter [63:0] CTL_RX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; - parameter [63:0] CTL_RX_VL_MARKER_ID7 = 64'h7B45660084BA9900; - parameter [63:0] CTL_RX_VL_MARKER_ID8 = 64'hA02476005FDB8900; - parameter [63:0] CTL_RX_VL_MARKER_ID9 = 64'h68C9FB0097360400; - parameter CTL_TEST_MODE_PIN_CHAR = "FALSE"; - parameter [47:0] CTL_TX_DA_GPP = 48'h0180C2000001; - parameter [47:0] CTL_TX_DA_PPP = 48'h0180C2000001; - parameter [15:0] CTL_TX_ETHERTYPE_GPP = 16'h8808; - parameter [15:0] CTL_TX_ETHERTYPE_PPP = 16'h8808; - parameter CTL_TX_FCS_INS_ENABLE = "TRUE"; - parameter CTL_TX_IGNORE_FCS = "FALSE"; - parameter [15:0] CTL_TX_OPCODE_GPP = 16'h0001; - parameter [15:0] CTL_TX_OPCODE_PPP = 16'h0001; - parameter CTL_TX_PTP_1STEP_ENABLE = "FALSE"; - parameter [10:0] CTL_TX_PTP_LATENCY_ADJUST = 11'h2C1; - parameter [47:0] CTL_TX_SA_GPP = 48'h000000000000; - parameter [47:0] CTL_TX_SA_PPP = 48'h000000000000; - parameter [15:0] CTL_TX_VL_LENGTH_MINUS1 = 16'h3FFF; - parameter [63:0] CTL_TX_VL_MARKER_ID0 = 64'hC16821003E97DE00; - parameter [63:0] CTL_TX_VL_MARKER_ID1 = 64'h9D718E00628E7100; - parameter [63:0] CTL_TX_VL_MARKER_ID10 = 64'hFD6C990002936600; - parameter [63:0] CTL_TX_VL_MARKER_ID11 = 64'hB9915500466EAA00; - parameter [63:0] CTL_TX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; - parameter [63:0] CTL_TX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; - parameter [63:0] CTL_TX_VL_MARKER_ID14 = 64'h83C7CA007C383500; - parameter [63:0] CTL_TX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; - parameter [63:0] CTL_TX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; - parameter [63:0] CTL_TX_VL_MARKER_ID17 = 64'hADD6B70052294800; - parameter [63:0] CTL_TX_VL_MARKER_ID18 = 64'h5F662A00A099D500; - parameter [63:0] CTL_TX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; - parameter [63:0] CTL_TX_VL_MARKER_ID2 = 64'h594BE800A6B41700; - parameter [63:0] CTL_TX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; - parameter [63:0] CTL_TX_VL_MARKER_ID4 = 64'hF50709000AF8F600; - parameter [63:0] CTL_TX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; - parameter [63:0] CTL_TX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; - parameter [63:0] CTL_TX_VL_MARKER_ID7 = 64'h7B45660084BA9900; - parameter [63:0] CTL_TX_VL_MARKER_ID8 = 64'hA02476005FDB8900; - parameter [63:0] CTL_TX_VL_MARKER_ID9 = 64'h68C9FB0097360400; - parameter SIM_VERSION = "2.0"; - parameter TEST_MODE_PIN_CHAR = "FALSE"; - output [15:0] DRP_DO; - output DRP_RDY; - output [127:0] RX_DATAOUT0; - output [127:0] RX_DATAOUT1; - output [127:0] RX_DATAOUT2; - output [127:0] RX_DATAOUT3; - output RX_ENAOUT0; - output RX_ENAOUT1; - output RX_ENAOUT2; - output RX_ENAOUT3; - output RX_EOPOUT0; - output RX_EOPOUT1; - output RX_EOPOUT2; - output RX_EOPOUT3; - output RX_ERROUT0; - output RX_ERROUT1; - output RX_ERROUT2; - output RX_ERROUT3; - output [6:0] RX_LANE_ALIGNER_FILL_0; - output [6:0] RX_LANE_ALIGNER_FILL_1; - output [6:0] RX_LANE_ALIGNER_FILL_10; - output [6:0] RX_LANE_ALIGNER_FILL_11; - output [6:0] RX_LANE_ALIGNER_FILL_12; - output [6:0] RX_LANE_ALIGNER_FILL_13; - output [6:0] RX_LANE_ALIGNER_FILL_14; - output [6:0] RX_LANE_ALIGNER_FILL_15; - output [6:0] RX_LANE_ALIGNER_FILL_16; - output [6:0] RX_LANE_ALIGNER_FILL_17; - output [6:0] RX_LANE_ALIGNER_FILL_18; - output [6:0] RX_LANE_ALIGNER_FILL_19; - output [6:0] RX_LANE_ALIGNER_FILL_2; - output [6:0] RX_LANE_ALIGNER_FILL_3; - output [6:0] RX_LANE_ALIGNER_FILL_4; - output [6:0] RX_LANE_ALIGNER_FILL_5; - output [6:0] RX_LANE_ALIGNER_FILL_6; - output [6:0] RX_LANE_ALIGNER_FILL_7; - output [6:0] RX_LANE_ALIGNER_FILL_8; - output [6:0] RX_LANE_ALIGNER_FILL_9; - output [3:0] RX_MTYOUT0; - output [3:0] RX_MTYOUT1; - output [3:0] RX_MTYOUT2; - output [3:0] RX_MTYOUT3; - output [4:0] RX_PTP_PCSLANE_OUT; - output [79:0] RX_PTP_TSTAMP_OUT; - output RX_SOPOUT0; - output RX_SOPOUT1; - output RX_SOPOUT2; - output RX_SOPOUT3; - output STAT_RX_ALIGNED; - output STAT_RX_ALIGNED_ERR; - output [6:0] STAT_RX_BAD_CODE; - output [3:0] STAT_RX_BAD_FCS; - output STAT_RX_BAD_PREAMBLE; - output STAT_RX_BAD_SFD; - output STAT_RX_BIP_ERR_0; - output STAT_RX_BIP_ERR_1; - output STAT_RX_BIP_ERR_10; - output STAT_RX_BIP_ERR_11; - output STAT_RX_BIP_ERR_12; - output STAT_RX_BIP_ERR_13; - output STAT_RX_BIP_ERR_14; - output STAT_RX_BIP_ERR_15; - output STAT_RX_BIP_ERR_16; - output STAT_RX_BIP_ERR_17; - output STAT_RX_BIP_ERR_18; - output STAT_RX_BIP_ERR_19; - output STAT_RX_BIP_ERR_2; - output STAT_RX_BIP_ERR_3; - output STAT_RX_BIP_ERR_4; - output STAT_RX_BIP_ERR_5; - output STAT_RX_BIP_ERR_6; - output STAT_RX_BIP_ERR_7; - output STAT_RX_BIP_ERR_8; - output STAT_RX_BIP_ERR_9; - output [19:0] STAT_RX_BLOCK_LOCK; - output STAT_RX_BROADCAST; - output [3:0] STAT_RX_FRAGMENT; - output [3:0] STAT_RX_FRAMING_ERR_0; - output [3:0] STAT_RX_FRAMING_ERR_1; - output [3:0] STAT_RX_FRAMING_ERR_10; - output [3:0] STAT_RX_FRAMING_ERR_11; - output [3:0] STAT_RX_FRAMING_ERR_12; - output [3:0] STAT_RX_FRAMING_ERR_13; - output [3:0] STAT_RX_FRAMING_ERR_14; - output [3:0] STAT_RX_FRAMING_ERR_15; - output [3:0] STAT_RX_FRAMING_ERR_16; - output [3:0] STAT_RX_FRAMING_ERR_17; - output [3:0] STAT_RX_FRAMING_ERR_18; - output [3:0] STAT_RX_FRAMING_ERR_19; - output [3:0] STAT_RX_FRAMING_ERR_2; - output [3:0] STAT_RX_FRAMING_ERR_3; - output [3:0] STAT_RX_FRAMING_ERR_4; - output [3:0] STAT_RX_FRAMING_ERR_5; - output [3:0] STAT_RX_FRAMING_ERR_6; - output [3:0] STAT_RX_FRAMING_ERR_7; - output [3:0] STAT_RX_FRAMING_ERR_8; - output [3:0] STAT_RX_FRAMING_ERR_9; - output STAT_RX_FRAMING_ERR_VALID_0; - output STAT_RX_FRAMING_ERR_VALID_1; - output STAT_RX_FRAMING_ERR_VALID_10; - output STAT_RX_FRAMING_ERR_VALID_11; - output STAT_RX_FRAMING_ERR_VALID_12; - output STAT_RX_FRAMING_ERR_VALID_13; - output STAT_RX_FRAMING_ERR_VALID_14; - output STAT_RX_FRAMING_ERR_VALID_15; - output STAT_RX_FRAMING_ERR_VALID_16; - output STAT_RX_FRAMING_ERR_VALID_17; - output STAT_RX_FRAMING_ERR_VALID_18; - output STAT_RX_FRAMING_ERR_VALID_19; - output STAT_RX_FRAMING_ERR_VALID_2; - output STAT_RX_FRAMING_ERR_VALID_3; - output STAT_RX_FRAMING_ERR_VALID_4; - output STAT_RX_FRAMING_ERR_VALID_5; - output STAT_RX_FRAMING_ERR_VALID_6; - output STAT_RX_FRAMING_ERR_VALID_7; - output STAT_RX_FRAMING_ERR_VALID_8; - output STAT_RX_FRAMING_ERR_VALID_9; - output STAT_RX_GOT_SIGNAL_OS; - output STAT_RX_HI_BER; - output STAT_RX_INRANGEERR; - output STAT_RX_INTERNAL_LOCAL_FAULT; - output STAT_RX_JABBER; - output [7:0] STAT_RX_LANE0_VLM_BIP7; - output STAT_RX_LANE0_VLM_BIP7_VALID; - output STAT_RX_LOCAL_FAULT; - output [19:0] STAT_RX_MF_ERR; - output [19:0] STAT_RX_MF_LEN_ERR; - output [19:0] STAT_RX_MF_REPEAT_ERR; - output STAT_RX_MISALIGNED; - output STAT_RX_MULTICAST; - output STAT_RX_OVERSIZE; - output STAT_RX_PACKET_1024_1518_BYTES; - output STAT_RX_PACKET_128_255_BYTES; - output STAT_RX_PACKET_1519_1522_BYTES; - output STAT_RX_PACKET_1523_1548_BYTES; - output STAT_RX_PACKET_1549_2047_BYTES; - output STAT_RX_PACKET_2048_4095_BYTES; - output STAT_RX_PACKET_256_511_BYTES; - output STAT_RX_PACKET_4096_8191_BYTES; - output STAT_RX_PACKET_512_1023_BYTES; - output STAT_RX_PACKET_64_BYTES; - output STAT_RX_PACKET_65_127_BYTES; - output STAT_RX_PACKET_8192_9215_BYTES; - output STAT_RX_PACKET_BAD_FCS; - output STAT_RX_PACKET_LARGE; - output [3:0] STAT_RX_PACKET_SMALL; - output STAT_RX_PAUSE; - output [15:0] STAT_RX_PAUSE_QUANTA0; - output [15:0] STAT_RX_PAUSE_QUANTA1; - output [15:0] STAT_RX_PAUSE_QUANTA2; - output [15:0] STAT_RX_PAUSE_QUANTA3; - output [15:0] STAT_RX_PAUSE_QUANTA4; - output [15:0] STAT_RX_PAUSE_QUANTA5; - output [15:0] STAT_RX_PAUSE_QUANTA6; - output [15:0] STAT_RX_PAUSE_QUANTA7; - output [15:0] STAT_RX_PAUSE_QUANTA8; - output [8:0] STAT_RX_PAUSE_REQ; - output [8:0] STAT_RX_PAUSE_VALID; - output STAT_RX_RECEIVED_LOCAL_FAULT; - output STAT_RX_REMOTE_FAULT; - output STAT_RX_STATUS; - output [3:0] STAT_RX_STOMPED_FCS; - output [19:0] STAT_RX_SYNCED; - output [19:0] STAT_RX_SYNCED_ERR; - output [2:0] STAT_RX_TEST_PATTERN_MISMATCH; - output STAT_RX_TOOLONG; - output [7:0] STAT_RX_TOTAL_BYTES; - output [13:0] STAT_RX_TOTAL_GOOD_BYTES; - output STAT_RX_TOTAL_GOOD_PACKETS; - output [3:0] STAT_RX_TOTAL_PACKETS; - output STAT_RX_TRUNCATED; - output [3:0] STAT_RX_UNDERSIZE; - output STAT_RX_UNICAST; - output STAT_RX_USER_PAUSE; - output STAT_RX_VLAN; - output [19:0] STAT_RX_VL_DEMUXED; - output [4:0] STAT_RX_VL_NUMBER_0; - output [4:0] STAT_RX_VL_NUMBER_1; - output [4:0] STAT_RX_VL_NUMBER_10; - output [4:0] STAT_RX_VL_NUMBER_11; - output [4:0] STAT_RX_VL_NUMBER_12; - output [4:0] STAT_RX_VL_NUMBER_13; - output [4:0] STAT_RX_VL_NUMBER_14; - output [4:0] STAT_RX_VL_NUMBER_15; - output [4:0] STAT_RX_VL_NUMBER_16; - output [4:0] STAT_RX_VL_NUMBER_17; - output [4:0] STAT_RX_VL_NUMBER_18; - output [4:0] STAT_RX_VL_NUMBER_19; - output [4:0] STAT_RX_VL_NUMBER_2; - output [4:0] STAT_RX_VL_NUMBER_3; - output [4:0] STAT_RX_VL_NUMBER_4; - output [4:0] STAT_RX_VL_NUMBER_5; - output [4:0] STAT_RX_VL_NUMBER_6; - output [4:0] STAT_RX_VL_NUMBER_7; - output [4:0] STAT_RX_VL_NUMBER_8; - output [4:0] STAT_RX_VL_NUMBER_9; - output STAT_TX_BAD_FCS; - output STAT_TX_BROADCAST; - output STAT_TX_FRAME_ERROR; - output STAT_TX_LOCAL_FAULT; - output STAT_TX_MULTICAST; - output STAT_TX_PACKET_1024_1518_BYTES; - output STAT_TX_PACKET_128_255_BYTES; - output STAT_TX_PACKET_1519_1522_BYTES; - output STAT_TX_PACKET_1523_1548_BYTES; - output STAT_TX_PACKET_1549_2047_BYTES; - output STAT_TX_PACKET_2048_4095_BYTES; - output STAT_TX_PACKET_256_511_BYTES; - output STAT_TX_PACKET_4096_8191_BYTES; - output STAT_TX_PACKET_512_1023_BYTES; - output STAT_TX_PACKET_64_BYTES; - output STAT_TX_PACKET_65_127_BYTES; - output STAT_TX_PACKET_8192_9215_BYTES; - output STAT_TX_PACKET_LARGE; - output STAT_TX_PACKET_SMALL; - output STAT_TX_PAUSE; - output [8:0] STAT_TX_PAUSE_VALID; - output STAT_TX_PTP_FIFO_READ_ERROR; - output STAT_TX_PTP_FIFO_WRITE_ERROR; - output [6:0] STAT_TX_TOTAL_BYTES; - output [13:0] STAT_TX_TOTAL_GOOD_BYTES; - output STAT_TX_TOTAL_GOOD_PACKETS; - output STAT_TX_TOTAL_PACKETS; - output STAT_TX_UNICAST; - output STAT_TX_USER_PAUSE; - output STAT_TX_VLAN; - output TX_OVFOUT; - output [4:0] TX_PTP_PCSLANE_OUT; - output [79:0] TX_PTP_TSTAMP_OUT; - output [15:0] TX_PTP_TSTAMP_TAG_OUT; - output TX_PTP_TSTAMP_VALID_OUT; - output TX_RDYOUT; - output [15:0] TX_SERDES_ALT_DATA0; - output [15:0] TX_SERDES_ALT_DATA1; - output [15:0] TX_SERDES_ALT_DATA2; - output [15:0] TX_SERDES_ALT_DATA3; - output [63:0] TX_SERDES_DATA0; - output [63:0] TX_SERDES_DATA1; - output [63:0] TX_SERDES_DATA2; - output [63:0] TX_SERDES_DATA3; - output [31:0] TX_SERDES_DATA4; - output [31:0] TX_SERDES_DATA5; - output [31:0] TX_SERDES_DATA6; - output [31:0] TX_SERDES_DATA7; - output [31:0] TX_SERDES_DATA8; - output [31:0] TX_SERDES_DATA9; - output TX_UNFOUT; - input CTL_CAUI4_MODE; - input CTL_RX_CHECK_ETYPE_GCP; - input CTL_RX_CHECK_ETYPE_GPP; - input CTL_RX_CHECK_ETYPE_PCP; - input CTL_RX_CHECK_ETYPE_PPP; - input CTL_RX_CHECK_MCAST_GCP; - input CTL_RX_CHECK_MCAST_GPP; - input CTL_RX_CHECK_MCAST_PCP; - input CTL_RX_CHECK_MCAST_PPP; - input CTL_RX_CHECK_OPCODE_GCP; - input CTL_RX_CHECK_OPCODE_GPP; - input CTL_RX_CHECK_OPCODE_PCP; - input CTL_RX_CHECK_OPCODE_PPP; - input CTL_RX_CHECK_SA_GCP; - input CTL_RX_CHECK_SA_GPP; - input CTL_RX_CHECK_SA_PCP; - input CTL_RX_CHECK_SA_PPP; - input CTL_RX_CHECK_UCAST_GCP; - input CTL_RX_CHECK_UCAST_GPP; - input CTL_RX_CHECK_UCAST_PCP; - input CTL_RX_CHECK_UCAST_PPP; - input CTL_RX_ENABLE; - input CTL_RX_ENABLE_GCP; - input CTL_RX_ENABLE_GPP; - input CTL_RX_ENABLE_PCP; - input CTL_RX_ENABLE_PPP; - input CTL_RX_FORCE_RESYNC; - input [8:0] CTL_RX_PAUSE_ACK; - input [8:0] CTL_RX_PAUSE_ENABLE; - input [79:0] CTL_RX_SYSTEMTIMERIN; - input CTL_RX_TEST_PATTERN; - input CTL_TX_ENABLE; - input CTL_TX_LANE0_VLM_BIP7_OVERRIDE; - input [7:0] CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE; - input [8:0] CTL_TX_PAUSE_ENABLE; - input [15:0] CTL_TX_PAUSE_QUANTA0; - input [15:0] CTL_TX_PAUSE_QUANTA1; - input [15:0] CTL_TX_PAUSE_QUANTA2; - input [15:0] CTL_TX_PAUSE_QUANTA3; - input [15:0] CTL_TX_PAUSE_QUANTA4; - input [15:0] CTL_TX_PAUSE_QUANTA5; - input [15:0] CTL_TX_PAUSE_QUANTA6; - input [15:0] CTL_TX_PAUSE_QUANTA7; - input [15:0] CTL_TX_PAUSE_QUANTA8; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER0; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER1; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER2; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER3; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER4; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER5; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER6; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER7; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER8; - input [8:0] CTL_TX_PAUSE_REQ; - input CTL_TX_PTP_VLANE_ADJUST_MODE; - input CTL_TX_RESEND_PAUSE; - input CTL_TX_SEND_IDLE; - input CTL_TX_SEND_RFI; - input [79:0] CTL_TX_SYSTEMTIMERIN; - input CTL_TX_TEST_PATTERN; - input [9:0] DRP_ADDR; - input DRP_CLK; - input [15:0] DRP_DI; - input DRP_EN; - input DRP_WE; - input RX_CLK; - input RX_RESET; - input [15:0] RX_SERDES_ALT_DATA0; - input [15:0] RX_SERDES_ALT_DATA1; - input [15:0] RX_SERDES_ALT_DATA2; - input [15:0] RX_SERDES_ALT_DATA3; - input [9:0] RX_SERDES_CLK; - input [63:0] RX_SERDES_DATA0; - input [63:0] RX_SERDES_DATA1; - input [63:0] RX_SERDES_DATA2; - input [63:0] RX_SERDES_DATA3; - input [31:0] RX_SERDES_DATA4; - input [31:0] RX_SERDES_DATA5; - input [31:0] RX_SERDES_DATA6; - input [31:0] RX_SERDES_DATA7; - input [31:0] RX_SERDES_DATA8; - input [31:0] RX_SERDES_DATA9; - input [9:0] RX_SERDES_RESET; - input TX_CLK; - input [127:0] TX_DATAIN0; - input [127:0] TX_DATAIN1; - input [127:0] TX_DATAIN2; - input [127:0] TX_DATAIN3; - input TX_ENAIN0; - input TX_ENAIN1; - input TX_ENAIN2; - input TX_ENAIN3; - input TX_EOPIN0; - input TX_EOPIN1; - input TX_EOPIN2; - input TX_EOPIN3; - input TX_ERRIN0; - input TX_ERRIN1; - input TX_ERRIN2; - input TX_ERRIN3; - input [3:0] TX_MTYIN0; - input [3:0] TX_MTYIN1; - input [3:0] TX_MTYIN2; - input [3:0] TX_MTYIN3; - input [1:0] TX_PTP_1588OP_IN; - input [15:0] TX_PTP_CHKSUM_OFFSET_IN; - input [63:0] TX_PTP_RXTSTAMP_IN; - input [15:0] TX_PTP_TAG_FIELD_IN; - input [15:0] TX_PTP_TSTAMP_OFFSET_IN; - input TX_PTP_UPD_CHKSUM_IN; - input TX_RESET; - input TX_SOPIN0; - input TX_SOPIN1; - input TX_SOPIN2; - input TX_SOPIN3; -endmodule - -module CMACE4 (...); - parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; - parameter CTL_RX_CHECK_ACK = "TRUE"; - parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; - parameter CTL_RX_CHECK_SFD = "FALSE"; - parameter CTL_RX_DELETE_FCS = "TRUE"; - parameter [15:0] CTL_RX_ETYPE_GCP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_GPP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_PCP = 16'h8808; - parameter [15:0] CTL_RX_ETYPE_PPP = 16'h8808; - parameter CTL_RX_FORWARD_CONTROL = "FALSE"; - parameter CTL_RX_IGNORE_FCS = "FALSE"; - parameter [14:0] CTL_RX_MAX_PACKET_LEN = 15'h2580; - parameter [7:0] CTL_RX_MIN_PACKET_LEN = 8'h40; - parameter [15:0] CTL_RX_OPCODE_GPP = 16'h0001; - parameter [15:0] CTL_RX_OPCODE_MAX_GCP = 16'hFFFF; - parameter [15:0] CTL_RX_OPCODE_MAX_PCP = 16'hFFFF; - parameter [15:0] CTL_RX_OPCODE_MIN_GCP = 16'h0000; - parameter [15:0] CTL_RX_OPCODE_MIN_PCP = 16'h0000; - parameter [15:0] CTL_RX_OPCODE_PPP = 16'h0001; - parameter [47:0] CTL_RX_PAUSE_DA_MCAST = 48'h0180C2000001; - parameter [47:0] CTL_RX_PAUSE_DA_UCAST = 48'h000000000000; - parameter [47:0] CTL_RX_PAUSE_SA = 48'h000000000000; - parameter CTL_RX_PROCESS_LFI = "FALSE"; - parameter [8:0] CTL_RX_RSFEC_AM_THRESHOLD = 9'h046; - parameter [1:0] CTL_RX_RSFEC_FILL_ADJUST = 2'h0; - parameter [15:0] CTL_RX_VL_LENGTH_MINUS1 = 16'h3FFF; - parameter [63:0] CTL_RX_VL_MARKER_ID0 = 64'hC16821003E97DE00; - parameter [63:0] CTL_RX_VL_MARKER_ID1 = 64'h9D718E00628E7100; - parameter [63:0] CTL_RX_VL_MARKER_ID10 = 64'hFD6C990002936600; - parameter [63:0] CTL_RX_VL_MARKER_ID11 = 64'hB9915500466EAA00; - parameter [63:0] CTL_RX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; - parameter [63:0] CTL_RX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; - parameter [63:0] CTL_RX_VL_MARKER_ID14 = 64'h83C7CA007C383500; - parameter [63:0] CTL_RX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; - parameter [63:0] CTL_RX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; - parameter [63:0] CTL_RX_VL_MARKER_ID17 = 64'hADD6B70052294800; - parameter [63:0] CTL_RX_VL_MARKER_ID18 = 64'h5F662A00A099D500; - parameter [63:0] CTL_RX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; - parameter [63:0] CTL_RX_VL_MARKER_ID2 = 64'h594BE800A6B41700; - parameter [63:0] CTL_RX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; - parameter [63:0] CTL_RX_VL_MARKER_ID4 = 64'hF50709000AF8F600; - parameter [63:0] CTL_RX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; - parameter [63:0] CTL_RX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; - parameter [63:0] CTL_RX_VL_MARKER_ID7 = 64'h7B45660084BA9900; - parameter [63:0] CTL_RX_VL_MARKER_ID8 = 64'hA02476005FDB8900; - parameter [63:0] CTL_RX_VL_MARKER_ID9 = 64'h68C9FB0097360400; - parameter CTL_TEST_MODE_PIN_CHAR = "FALSE"; - parameter CTL_TX_CUSTOM_PREAMBLE_ENABLE = "FALSE"; - parameter [47:0] CTL_TX_DA_GPP = 48'h0180C2000001; - parameter [47:0] CTL_TX_DA_PPP = 48'h0180C2000001; - parameter [15:0] CTL_TX_ETHERTYPE_GPP = 16'h8808; - parameter [15:0] CTL_TX_ETHERTYPE_PPP = 16'h8808; - parameter CTL_TX_FCS_INS_ENABLE = "TRUE"; - parameter CTL_TX_IGNORE_FCS = "FALSE"; - parameter [3:0] CTL_TX_IPG_VALUE = 4'hC; - parameter [15:0] CTL_TX_OPCODE_GPP = 16'h0001; - parameter [15:0] CTL_TX_OPCODE_PPP = 16'h0001; - parameter CTL_TX_PTP_1STEP_ENABLE = "FALSE"; - parameter [10:0] CTL_TX_PTP_LATENCY_ADJUST = 11'h2C1; - parameter [47:0] CTL_TX_SA_GPP = 48'h000000000000; - parameter [47:0] CTL_TX_SA_PPP = 48'h000000000000; - parameter [15:0] CTL_TX_VL_LENGTH_MINUS1 = 16'h3FFF; - parameter [63:0] CTL_TX_VL_MARKER_ID0 = 64'hC16821003E97DE00; - parameter [63:0] CTL_TX_VL_MARKER_ID1 = 64'h9D718E00628E7100; - parameter [63:0] CTL_TX_VL_MARKER_ID10 = 64'hFD6C990002936600; - parameter [63:0] CTL_TX_VL_MARKER_ID11 = 64'hB9915500466EAA00; - parameter [63:0] CTL_TX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; - parameter [63:0] CTL_TX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; - parameter [63:0] CTL_TX_VL_MARKER_ID14 = 64'h83C7CA007C383500; - parameter [63:0] CTL_TX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; - parameter [63:0] CTL_TX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; - parameter [63:0] CTL_TX_VL_MARKER_ID17 = 64'hADD6B70052294800; - parameter [63:0] CTL_TX_VL_MARKER_ID18 = 64'h5F662A00A099D500; - parameter [63:0] CTL_TX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; - parameter [63:0] CTL_TX_VL_MARKER_ID2 = 64'h594BE800A6B41700; - parameter [63:0] CTL_TX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; - parameter [63:0] CTL_TX_VL_MARKER_ID4 = 64'hF50709000AF8F600; - parameter [63:0] CTL_TX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; - parameter [63:0] CTL_TX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; - parameter [63:0] CTL_TX_VL_MARKER_ID7 = 64'h7B45660084BA9900; - parameter [63:0] CTL_TX_VL_MARKER_ID8 = 64'hA02476005FDB8900; - parameter [63:0] CTL_TX_VL_MARKER_ID9 = 64'h68C9FB0097360400; - parameter SIM_DEVICE = "ULTRASCALE_PLUS"; - parameter TEST_MODE_PIN_CHAR = "FALSE"; - output [15:0] DRP_DO; - output DRP_RDY; - output [329:0] RSFEC_BYPASS_RX_DOUT; - output RSFEC_BYPASS_RX_DOUT_CW_START; - output RSFEC_BYPASS_RX_DOUT_VALID; - output [329:0] RSFEC_BYPASS_TX_DOUT; - output RSFEC_BYPASS_TX_DOUT_CW_START; - output RSFEC_BYPASS_TX_DOUT_VALID; - output [127:0] RX_DATAOUT0; - output [127:0] RX_DATAOUT1; - output [127:0] RX_DATAOUT2; - output [127:0] RX_DATAOUT3; - output RX_ENAOUT0; - output RX_ENAOUT1; - output RX_ENAOUT2; - output RX_ENAOUT3; - output RX_EOPOUT0; - output RX_EOPOUT1; - output RX_EOPOUT2; - output RX_EOPOUT3; - output RX_ERROUT0; - output RX_ERROUT1; - output RX_ERROUT2; - output RX_ERROUT3; - output [6:0] RX_LANE_ALIGNER_FILL_0; - output [6:0] RX_LANE_ALIGNER_FILL_1; - output [6:0] RX_LANE_ALIGNER_FILL_10; - output [6:0] RX_LANE_ALIGNER_FILL_11; - output [6:0] RX_LANE_ALIGNER_FILL_12; - output [6:0] RX_LANE_ALIGNER_FILL_13; - output [6:0] RX_LANE_ALIGNER_FILL_14; - output [6:0] RX_LANE_ALIGNER_FILL_15; - output [6:0] RX_LANE_ALIGNER_FILL_16; - output [6:0] RX_LANE_ALIGNER_FILL_17; - output [6:0] RX_LANE_ALIGNER_FILL_18; - output [6:0] RX_LANE_ALIGNER_FILL_19; - output [6:0] RX_LANE_ALIGNER_FILL_2; - output [6:0] RX_LANE_ALIGNER_FILL_3; - output [6:0] RX_LANE_ALIGNER_FILL_4; - output [6:0] RX_LANE_ALIGNER_FILL_5; - output [6:0] RX_LANE_ALIGNER_FILL_6; - output [6:0] RX_LANE_ALIGNER_FILL_7; - output [6:0] RX_LANE_ALIGNER_FILL_8; - output [6:0] RX_LANE_ALIGNER_FILL_9; - output [3:0] RX_MTYOUT0; - output [3:0] RX_MTYOUT1; - output [3:0] RX_MTYOUT2; - output [3:0] RX_MTYOUT3; - output [7:0] RX_OTN_BIP8_0; - output [7:0] RX_OTN_BIP8_1; - output [7:0] RX_OTN_BIP8_2; - output [7:0] RX_OTN_BIP8_3; - output [7:0] RX_OTN_BIP8_4; - output [65:0] RX_OTN_DATA_0; - output [65:0] RX_OTN_DATA_1; - output [65:0] RX_OTN_DATA_2; - output [65:0] RX_OTN_DATA_3; - output [65:0] RX_OTN_DATA_4; - output RX_OTN_ENA; - output RX_OTN_LANE0; - output RX_OTN_VLMARKER; - output [55:0] RX_PREOUT; - output [4:0] RX_PTP_PCSLANE_OUT; - output [79:0] RX_PTP_TSTAMP_OUT; - output RX_SOPOUT0; - output RX_SOPOUT1; - output RX_SOPOUT2; - output RX_SOPOUT3; - output STAT_RX_ALIGNED; - output STAT_RX_ALIGNED_ERR; - output [2:0] STAT_RX_BAD_CODE; - output [2:0] STAT_RX_BAD_FCS; - output STAT_RX_BAD_PREAMBLE; - output STAT_RX_BAD_SFD; - output STAT_RX_BIP_ERR_0; - output STAT_RX_BIP_ERR_1; - output STAT_RX_BIP_ERR_10; - output STAT_RX_BIP_ERR_11; - output STAT_RX_BIP_ERR_12; - output STAT_RX_BIP_ERR_13; - output STAT_RX_BIP_ERR_14; - output STAT_RX_BIP_ERR_15; - output STAT_RX_BIP_ERR_16; - output STAT_RX_BIP_ERR_17; - output STAT_RX_BIP_ERR_18; - output STAT_RX_BIP_ERR_19; - output STAT_RX_BIP_ERR_2; - output STAT_RX_BIP_ERR_3; - output STAT_RX_BIP_ERR_4; - output STAT_RX_BIP_ERR_5; - output STAT_RX_BIP_ERR_6; - output STAT_RX_BIP_ERR_7; - output STAT_RX_BIP_ERR_8; - output STAT_RX_BIP_ERR_9; - output [19:0] STAT_RX_BLOCK_LOCK; - output STAT_RX_BROADCAST; - output [2:0] STAT_RX_FRAGMENT; - output [1:0] STAT_RX_FRAMING_ERR_0; - output [1:0] STAT_RX_FRAMING_ERR_1; - output [1:0] STAT_RX_FRAMING_ERR_10; - output [1:0] STAT_RX_FRAMING_ERR_11; - output [1:0] STAT_RX_FRAMING_ERR_12; - output [1:0] STAT_RX_FRAMING_ERR_13; - output [1:0] STAT_RX_FRAMING_ERR_14; - output [1:0] STAT_RX_FRAMING_ERR_15; - output [1:0] STAT_RX_FRAMING_ERR_16; - output [1:0] STAT_RX_FRAMING_ERR_17; - output [1:0] STAT_RX_FRAMING_ERR_18; - output [1:0] STAT_RX_FRAMING_ERR_19; - output [1:0] STAT_RX_FRAMING_ERR_2; - output [1:0] STAT_RX_FRAMING_ERR_3; - output [1:0] STAT_RX_FRAMING_ERR_4; - output [1:0] STAT_RX_FRAMING_ERR_5; - output [1:0] STAT_RX_FRAMING_ERR_6; - output [1:0] STAT_RX_FRAMING_ERR_7; - output [1:0] STAT_RX_FRAMING_ERR_8; - output [1:0] STAT_RX_FRAMING_ERR_9; - output STAT_RX_FRAMING_ERR_VALID_0; - output STAT_RX_FRAMING_ERR_VALID_1; - output STAT_RX_FRAMING_ERR_VALID_10; - output STAT_RX_FRAMING_ERR_VALID_11; - output STAT_RX_FRAMING_ERR_VALID_12; - output STAT_RX_FRAMING_ERR_VALID_13; - output STAT_RX_FRAMING_ERR_VALID_14; - output STAT_RX_FRAMING_ERR_VALID_15; - output STAT_RX_FRAMING_ERR_VALID_16; - output STAT_RX_FRAMING_ERR_VALID_17; - output STAT_RX_FRAMING_ERR_VALID_18; - output STAT_RX_FRAMING_ERR_VALID_19; - output STAT_RX_FRAMING_ERR_VALID_2; - output STAT_RX_FRAMING_ERR_VALID_3; - output STAT_RX_FRAMING_ERR_VALID_4; - output STAT_RX_FRAMING_ERR_VALID_5; - output STAT_RX_FRAMING_ERR_VALID_6; - output STAT_RX_FRAMING_ERR_VALID_7; - output STAT_RX_FRAMING_ERR_VALID_8; - output STAT_RX_FRAMING_ERR_VALID_9; - output STAT_RX_GOT_SIGNAL_OS; - output STAT_RX_HI_BER; - output STAT_RX_INRANGEERR; - output STAT_RX_INTERNAL_LOCAL_FAULT; - output STAT_RX_JABBER; - output [7:0] STAT_RX_LANE0_VLM_BIP7; - output STAT_RX_LANE0_VLM_BIP7_VALID; - output STAT_RX_LOCAL_FAULT; - output [19:0] STAT_RX_MF_ERR; - output [19:0] STAT_RX_MF_LEN_ERR; - output [19:0] STAT_RX_MF_REPEAT_ERR; - output STAT_RX_MISALIGNED; - output STAT_RX_MULTICAST; - output STAT_RX_OVERSIZE; - output STAT_RX_PACKET_1024_1518_BYTES; - output STAT_RX_PACKET_128_255_BYTES; - output STAT_RX_PACKET_1519_1522_BYTES; - output STAT_RX_PACKET_1523_1548_BYTES; - output STAT_RX_PACKET_1549_2047_BYTES; - output STAT_RX_PACKET_2048_4095_BYTES; - output STAT_RX_PACKET_256_511_BYTES; - output STAT_RX_PACKET_4096_8191_BYTES; - output STAT_RX_PACKET_512_1023_BYTES; - output STAT_RX_PACKET_64_BYTES; - output STAT_RX_PACKET_65_127_BYTES; - output STAT_RX_PACKET_8192_9215_BYTES; - output STAT_RX_PACKET_BAD_FCS; - output STAT_RX_PACKET_LARGE; - output [2:0] STAT_RX_PACKET_SMALL; - output STAT_RX_PAUSE; - output [15:0] STAT_RX_PAUSE_QUANTA0; - output [15:0] STAT_RX_PAUSE_QUANTA1; - output [15:0] STAT_RX_PAUSE_QUANTA2; - output [15:0] STAT_RX_PAUSE_QUANTA3; - output [15:0] STAT_RX_PAUSE_QUANTA4; - output [15:0] STAT_RX_PAUSE_QUANTA5; - output [15:0] STAT_RX_PAUSE_QUANTA6; - output [15:0] STAT_RX_PAUSE_QUANTA7; - output [15:0] STAT_RX_PAUSE_QUANTA8; - output [8:0] STAT_RX_PAUSE_REQ; - output [8:0] STAT_RX_PAUSE_VALID; - output STAT_RX_RECEIVED_LOCAL_FAULT; - output STAT_RX_REMOTE_FAULT; - output STAT_RX_RSFEC_AM_LOCK0; - output STAT_RX_RSFEC_AM_LOCK1; - output STAT_RX_RSFEC_AM_LOCK2; - output STAT_RX_RSFEC_AM_LOCK3; - output STAT_RX_RSFEC_CORRECTED_CW_INC; - output STAT_RX_RSFEC_CW_INC; - output [2:0] STAT_RX_RSFEC_ERR_COUNT0_INC; - output [2:0] STAT_RX_RSFEC_ERR_COUNT1_INC; - output [2:0] STAT_RX_RSFEC_ERR_COUNT2_INC; - output [2:0] STAT_RX_RSFEC_ERR_COUNT3_INC; - output STAT_RX_RSFEC_HI_SER; - output STAT_RX_RSFEC_LANE_ALIGNMENT_STATUS; - output [13:0] STAT_RX_RSFEC_LANE_FILL_0; - output [13:0] STAT_RX_RSFEC_LANE_FILL_1; - output [13:0] STAT_RX_RSFEC_LANE_FILL_2; - output [13:0] STAT_RX_RSFEC_LANE_FILL_3; - output [7:0] STAT_RX_RSFEC_LANE_MAPPING; - output [31:0] STAT_RX_RSFEC_RSVD; - output STAT_RX_RSFEC_UNCORRECTED_CW_INC; - output STAT_RX_STATUS; - output [2:0] STAT_RX_STOMPED_FCS; - output [19:0] STAT_RX_SYNCED; - output [19:0] STAT_RX_SYNCED_ERR; - output [2:0] STAT_RX_TEST_PATTERN_MISMATCH; - output STAT_RX_TOOLONG; - output [6:0] STAT_RX_TOTAL_BYTES; - output [13:0] STAT_RX_TOTAL_GOOD_BYTES; - output STAT_RX_TOTAL_GOOD_PACKETS; - output [2:0] STAT_RX_TOTAL_PACKETS; - output STAT_RX_TRUNCATED; - output [2:0] STAT_RX_UNDERSIZE; - output STAT_RX_UNICAST; - output STAT_RX_USER_PAUSE; - output STAT_RX_VLAN; - output [19:0] STAT_RX_VL_DEMUXED; - output [4:0] STAT_RX_VL_NUMBER_0; - output [4:0] STAT_RX_VL_NUMBER_1; - output [4:0] STAT_RX_VL_NUMBER_10; - output [4:0] STAT_RX_VL_NUMBER_11; - output [4:0] STAT_RX_VL_NUMBER_12; - output [4:0] STAT_RX_VL_NUMBER_13; - output [4:0] STAT_RX_VL_NUMBER_14; - output [4:0] STAT_RX_VL_NUMBER_15; - output [4:0] STAT_RX_VL_NUMBER_16; - output [4:0] STAT_RX_VL_NUMBER_17; - output [4:0] STAT_RX_VL_NUMBER_18; - output [4:0] STAT_RX_VL_NUMBER_19; - output [4:0] STAT_RX_VL_NUMBER_2; - output [4:0] STAT_RX_VL_NUMBER_3; - output [4:0] STAT_RX_VL_NUMBER_4; - output [4:0] STAT_RX_VL_NUMBER_5; - output [4:0] STAT_RX_VL_NUMBER_6; - output [4:0] STAT_RX_VL_NUMBER_7; - output [4:0] STAT_RX_VL_NUMBER_8; - output [4:0] STAT_RX_VL_NUMBER_9; - output STAT_TX_BAD_FCS; - output STAT_TX_BROADCAST; - output STAT_TX_FRAME_ERROR; - output STAT_TX_LOCAL_FAULT; - output STAT_TX_MULTICAST; - output STAT_TX_PACKET_1024_1518_BYTES; - output STAT_TX_PACKET_128_255_BYTES; - output STAT_TX_PACKET_1519_1522_BYTES; - output STAT_TX_PACKET_1523_1548_BYTES; - output STAT_TX_PACKET_1549_2047_BYTES; - output STAT_TX_PACKET_2048_4095_BYTES; - output STAT_TX_PACKET_256_511_BYTES; - output STAT_TX_PACKET_4096_8191_BYTES; - output STAT_TX_PACKET_512_1023_BYTES; - output STAT_TX_PACKET_64_BYTES; - output STAT_TX_PACKET_65_127_BYTES; - output STAT_TX_PACKET_8192_9215_BYTES; - output STAT_TX_PACKET_LARGE; - output STAT_TX_PACKET_SMALL; - output STAT_TX_PAUSE; - output [8:0] STAT_TX_PAUSE_VALID; - output STAT_TX_PTP_FIFO_READ_ERROR; - output STAT_TX_PTP_FIFO_WRITE_ERROR; - output [5:0] STAT_TX_TOTAL_BYTES; - output [13:0] STAT_TX_TOTAL_GOOD_BYTES; - output STAT_TX_TOTAL_GOOD_PACKETS; - output STAT_TX_TOTAL_PACKETS; - output STAT_TX_UNICAST; - output STAT_TX_USER_PAUSE; - output STAT_TX_VLAN; - output TX_OVFOUT; - output [4:0] TX_PTP_PCSLANE_OUT; - output [79:0] TX_PTP_TSTAMP_OUT; - output [15:0] TX_PTP_TSTAMP_TAG_OUT; - output TX_PTP_TSTAMP_VALID_OUT; - output TX_RDYOUT; - output [15:0] TX_SERDES_ALT_DATA0; - output [15:0] TX_SERDES_ALT_DATA1; - output [15:0] TX_SERDES_ALT_DATA2; - output [15:0] TX_SERDES_ALT_DATA3; - output [63:0] TX_SERDES_DATA0; - output [63:0] TX_SERDES_DATA1; - output [63:0] TX_SERDES_DATA2; - output [63:0] TX_SERDES_DATA3; - output [31:0] TX_SERDES_DATA4; - output [31:0] TX_SERDES_DATA5; - output [31:0] TX_SERDES_DATA6; - output [31:0] TX_SERDES_DATA7; - output [31:0] TX_SERDES_DATA8; - output [31:0] TX_SERDES_DATA9; - output TX_UNFOUT; - input CTL_CAUI4_MODE; - input CTL_RSFEC_ENABLE_TRANSCODER_BYPASS_MODE; - input CTL_RSFEC_IEEE_ERROR_INDICATION_MODE; - input CTL_RX_CHECK_ETYPE_GCP; - input CTL_RX_CHECK_ETYPE_GPP; - input CTL_RX_CHECK_ETYPE_PCP; - input CTL_RX_CHECK_ETYPE_PPP; - input CTL_RX_CHECK_MCAST_GCP; - input CTL_RX_CHECK_MCAST_GPP; - input CTL_RX_CHECK_MCAST_PCP; - input CTL_RX_CHECK_MCAST_PPP; - input CTL_RX_CHECK_OPCODE_GCP; - input CTL_RX_CHECK_OPCODE_GPP; - input CTL_RX_CHECK_OPCODE_PCP; - input CTL_RX_CHECK_OPCODE_PPP; - input CTL_RX_CHECK_SA_GCP; - input CTL_RX_CHECK_SA_GPP; - input CTL_RX_CHECK_SA_PCP; - input CTL_RX_CHECK_SA_PPP; - input CTL_RX_CHECK_UCAST_GCP; - input CTL_RX_CHECK_UCAST_GPP; - input CTL_RX_CHECK_UCAST_PCP; - input CTL_RX_CHECK_UCAST_PPP; - input CTL_RX_ENABLE; - input CTL_RX_ENABLE_GCP; - input CTL_RX_ENABLE_GPP; - input CTL_RX_ENABLE_PCP; - input CTL_RX_ENABLE_PPP; - input CTL_RX_FORCE_RESYNC; - input [8:0] CTL_RX_PAUSE_ACK; - input [8:0] CTL_RX_PAUSE_ENABLE; - input CTL_RX_RSFEC_ENABLE; - input CTL_RX_RSFEC_ENABLE_CORRECTION; - input CTL_RX_RSFEC_ENABLE_INDICATION; - input [79:0] CTL_RX_SYSTEMTIMERIN; - input CTL_RX_TEST_PATTERN; - input CTL_TX_ENABLE; - input CTL_TX_LANE0_VLM_BIP7_OVERRIDE; - input [7:0] CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE; - input [8:0] CTL_TX_PAUSE_ENABLE; - input [15:0] CTL_TX_PAUSE_QUANTA0; - input [15:0] CTL_TX_PAUSE_QUANTA1; - input [15:0] CTL_TX_PAUSE_QUANTA2; - input [15:0] CTL_TX_PAUSE_QUANTA3; - input [15:0] CTL_TX_PAUSE_QUANTA4; - input [15:0] CTL_TX_PAUSE_QUANTA5; - input [15:0] CTL_TX_PAUSE_QUANTA6; - input [15:0] CTL_TX_PAUSE_QUANTA7; - input [15:0] CTL_TX_PAUSE_QUANTA8; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER0; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER1; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER2; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER3; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER4; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER5; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER6; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER7; - input [15:0] CTL_TX_PAUSE_REFRESH_TIMER8; - input [8:0] CTL_TX_PAUSE_REQ; - input CTL_TX_PTP_VLANE_ADJUST_MODE; - input CTL_TX_RESEND_PAUSE; - input CTL_TX_RSFEC_ENABLE; - input CTL_TX_SEND_IDLE; - input CTL_TX_SEND_LFI; - input CTL_TX_SEND_RFI; - input [79:0] CTL_TX_SYSTEMTIMERIN; - input CTL_TX_TEST_PATTERN; - input [9:0] DRP_ADDR; - input DRP_CLK; - input [15:0] DRP_DI; - input DRP_EN; - input DRP_WE; - input [329:0] RSFEC_BYPASS_RX_DIN; - input RSFEC_BYPASS_RX_DIN_CW_START; - input [329:0] RSFEC_BYPASS_TX_DIN; - input RSFEC_BYPASS_TX_DIN_CW_START; - input RX_CLK; - input RX_RESET; - input [15:0] RX_SERDES_ALT_DATA0; - input [15:0] RX_SERDES_ALT_DATA1; - input [15:0] RX_SERDES_ALT_DATA2; - input [15:0] RX_SERDES_ALT_DATA3; - input [9:0] RX_SERDES_CLK; - input [63:0] RX_SERDES_DATA0; - input [63:0] RX_SERDES_DATA1; - input [63:0] RX_SERDES_DATA2; - input [63:0] RX_SERDES_DATA3; - input [31:0] RX_SERDES_DATA4; - input [31:0] RX_SERDES_DATA5; - input [31:0] RX_SERDES_DATA6; - input [31:0] RX_SERDES_DATA7; - input [31:0] RX_SERDES_DATA8; - input [31:0] RX_SERDES_DATA9; - input [9:0] RX_SERDES_RESET; - input TX_CLK; - input [127:0] TX_DATAIN0; - input [127:0] TX_DATAIN1; - input [127:0] TX_DATAIN2; - input [127:0] TX_DATAIN3; - input TX_ENAIN0; - input TX_ENAIN1; - input TX_ENAIN2; - input TX_ENAIN3; - input TX_EOPIN0; - input TX_EOPIN1; - input TX_EOPIN2; - input TX_EOPIN3; - input TX_ERRIN0; - input TX_ERRIN1; - input TX_ERRIN2; - input TX_ERRIN3; - input [3:0] TX_MTYIN0; - input [3:0] TX_MTYIN1; - input [3:0] TX_MTYIN2; - input [3:0] TX_MTYIN3; - input [55:0] TX_PREIN; - input [1:0] TX_PTP_1588OP_IN; - input [15:0] TX_PTP_CHKSUM_OFFSET_IN; - input [63:0] TX_PTP_RXTSTAMP_IN; - input [15:0] TX_PTP_TAG_FIELD_IN; - input [15:0] TX_PTP_TSTAMP_OFFSET_IN; - input TX_PTP_UPD_CHKSUM_IN; - input TX_RESET; - input TX_SOPIN0; - input TX_SOPIN1; - input TX_SOPIN2; - input TX_SOPIN3; -endmodule - -module PPC405_ADV (...); - parameter in_delay=100; - parameter out_delay=100; - output APUFCMDECODED; - output APUFCMDECUDIVALID; - output APUFCMENDIAN; - output APUFCMFLUSH; - output APUFCMINSTRVALID; - output APUFCMLOADDVALID; - output APUFCMOPERANDVALID; - output APUFCMWRITEBACKOK; - output APUFCMXERCA; - output C405CPMCORESLEEPREQ; - output C405CPMMSRCE; - output C405CPMMSREE; - output C405CPMTIMERIRQ; - output C405CPMTIMERRESETREQ; - output C405DBGLOADDATAONAPUDBUS; - output C405DBGMSRWE; - output C405DBGSTOPACK; - output C405DBGWBCOMPLETE; - output C405DBGWBFULL; - output C405JTGCAPTUREDR; - output C405JTGEXTEST; - output C405JTGPGMOUT; - output C405JTGSHIFTDR; - output C405JTGTDO; - output C405JTGTDOEN; - output C405JTGUPDATEDR; - output C405PLBDCUABORT; - output C405PLBDCUCACHEABLE; - output C405PLBDCUGUARDED; - output C405PLBDCUREQUEST; - output C405PLBDCURNW; - output C405PLBDCUSIZE2; - output C405PLBDCUU0ATTR; - output C405PLBDCUWRITETHRU; - output C405PLBICUABORT; - output C405PLBICUCACHEABLE; - output C405PLBICUREQUEST; - output C405PLBICUU0ATTR; - output C405RSTCHIPRESETREQ; - output C405RSTCORERESETREQ; - output C405RSTSYSRESETREQ; - output C405TRCCYCLE; - output C405TRCTRIGGEREVENTOUT; - output C405XXXMACHINECHECK; - output DCREMACCLK; - output DCREMACENABLER; - output DCREMACREAD; - output DCREMACWRITE; - output DSOCMBRAMEN; - output DSOCMBUSY; - output DSOCMRDADDRVALID; - output DSOCMWRADDRVALID; - output EXTDCRREAD; - output EXTDCRWRITE; - output ISOCMBRAMEN; - output ISOCMBRAMEVENWRITEEN; - output ISOCMBRAMODDWRITEEN; - output ISOCMDCRBRAMEVENEN; - output ISOCMDCRBRAMODDEN; - output ISOCMDCRBRAMRDSELECT; - output [0:10] C405TRCTRIGGEREVENTTYPE; - output [0:1] C405PLBDCUPRIORITY; - output [0:1] C405PLBICUPRIORITY; - output [0:1] C405TRCEVENEXECUTIONSTATUS; - output [0:1] C405TRCODDEXECUTIONSTATUS; - output [0:29] C405DBGWBIAR; - output [0:29] C405PLBICUABUS; - output [0:2] APUFCMDECUDI; - output [0:31] APUFCMINSTRUCTION; - output [0:31] APUFCMLOADDATA; - output [0:31] APUFCMRADATA; - output [0:31] APUFCMRBDATA; - output [0:31] C405PLBDCUABUS; - output [0:31] DCREMACDBUS; - output [0:31] DSOCMBRAMWRDBUS; - output [0:31] EXTDCRDBUSOUT; - output [0:31] ISOCMBRAMWRDBUS; - output [0:3] APUFCMLOADBYTEEN; - output [0:3] C405TRCTRACESTATUS; - output [0:3] DSOCMBRAMBYTEWRITE; - output [0:63] C405PLBDCUWRDBUS; - output [0:7] C405PLBDCUBE; - output [0:9] EXTDCRABUS; - output [2:3] C405PLBICUSIZE; - output [8:28] ISOCMBRAMRDABUS; - output [8:28] ISOCMBRAMWRABUS; - output [8:29] DSOCMBRAMABUS; - output [8:9] DCREMACABUS; - input BRAMDSOCMCLK; - input BRAMISOCMCLK; - input CPMC405CLOCK; - input CPMC405CORECLKINACTIVE; - input CPMC405CPUCLKEN; - input CPMC405JTAGCLKEN; - input CPMC405SYNCBYPASS; - input CPMC405TIMERCLKEN; - input CPMC405TIMERTICK; - input CPMDCRCLK; - input CPMFCMCLK; - input DBGC405DEBUGHALT; - input DBGC405EXTBUSHOLDACK; - input DBGC405UNCONDDEBUGEVENT; - input DSOCMRWCOMPLETE; - input EICC405CRITINPUTIRQ; - input EICC405EXTINPUTIRQ; - input EMACDCRACK; - input EXTDCRACK; - input FCMAPUDCDCREN; - input FCMAPUDCDFORCEALIGN; - input FCMAPUDCDFORCEBESTEERING; - input FCMAPUDCDFPUOP; - input FCMAPUDCDGPRWRITE; - input FCMAPUDCDLDSTBYTE; - input FCMAPUDCDLDSTDW; - input FCMAPUDCDLDSTHW; - input FCMAPUDCDLDSTQW; - input FCMAPUDCDLDSTWD; - input FCMAPUDCDLOAD; - input FCMAPUDCDPRIVOP; - input FCMAPUDCDRAEN; - input FCMAPUDCDRBEN; - input FCMAPUDCDSTORE; - input FCMAPUDCDTRAPBE; - input FCMAPUDCDTRAPLE; - input FCMAPUDCDUPDATE; - input FCMAPUDCDXERCAEN; - input FCMAPUDCDXEROVEN; - input FCMAPUDECODEBUSY; - input FCMAPUDONE; - input FCMAPUEXCEPTION; - input FCMAPUEXEBLOCKINGMCO; - input FCMAPUEXENONBLOCKINGMCO; - input FCMAPUINSTRACK; - input FCMAPULOADWAIT; - input FCMAPURESULTVALID; - input FCMAPUSLEEPNOTREADY; - input FCMAPUXERCA; - input FCMAPUXEROV; - input JTGC405BNDSCANTDO; - input JTGC405TCK; - input JTGC405TDI; - input JTGC405TMS; - input JTGC405TRSTNEG; - input MCBCPUCLKEN; - input MCBJTAGEN; - input MCBTIMEREN; - input MCPPCRST; - input PLBC405DCUADDRACK; - input PLBC405DCUBUSY; - input PLBC405DCUERR; - input PLBC405DCURDDACK; - input PLBC405DCUSSIZE1; - input PLBC405DCUWRDACK; - input PLBC405ICUADDRACK; - input PLBC405ICUBUSY; - input PLBC405ICUERR; - input PLBC405ICURDDACK; - input PLBC405ICUSSIZE1; - input PLBCLK; - input RSTC405RESETCHIP; - input RSTC405RESETCORE; - input RSTC405RESETSYS; - input TIEC405DETERMINISTICMULT; - input TIEC405DISOPERANDFWD; - input TIEC405MMUEN; - input TIEPVRBIT10; - input TIEPVRBIT11; - input TIEPVRBIT28; - input TIEPVRBIT29; - input TIEPVRBIT30; - input TIEPVRBIT31; - input TIEPVRBIT8; - input TIEPVRBIT9; - input TRCC405TRACEDISABLE; - input TRCC405TRIGGEREVENTIN; - input [0:15] TIEAPUCONTROL; - input [0:23] TIEAPUUDI1; - input [0:23] TIEAPUUDI2; - input [0:23] TIEAPUUDI3; - input [0:23] TIEAPUUDI4; - input [0:23] TIEAPUUDI5; - input [0:23] TIEAPUUDI6; - input [0:23] TIEAPUUDI7; - input [0:23] TIEAPUUDI8; - input [0:2] FCMAPUEXECRFIELD; - input [0:31] BRAMDSOCMRDDBUS; - input [0:31] BRAMISOCMDCRRDDBUS; - input [0:31] EMACDCRDBUS; - input [0:31] EXTDCRDBUSIN; - input [0:31] FCMAPURESULT; - input [0:3] FCMAPUCR; - input [0:5] TIEDCRADDR; - input [0:63] BRAMISOCMRDDBUS; - input [0:63] PLBC405DCURDDBUS; - input [0:63] PLBC405ICURDDBUS; - input [0:7] DSARCVALUE; - input [0:7] DSCNTLVALUE; - input [0:7] ISARCVALUE; - input [0:7] ISCNTLVALUE; - input [1:3] PLBC405DCURDWDADDR; - input [1:3] PLBC405ICURDWDADDR; -endmodule - -module PPC440 (...); - parameter CLOCK_DELAY = "FALSE"; - parameter DCR_AUTOLOCK_ENABLE = "TRUE"; - parameter PPCDM_ASYNCMODE = "FALSE"; - parameter PPCDS_ASYNCMODE = "FALSE"; - parameter PPCS0_WIDTH_128N64 = "TRUE"; - parameter PPCS1_WIDTH_128N64 = "TRUE"; - parameter [0:16] APU_CONTROL = 17'h02000; - parameter [0:23] APU_UDI0 = 24'h000000; - parameter [0:23] APU_UDI1 = 24'h000000; - parameter [0:23] APU_UDI10 = 24'h000000; - parameter [0:23] APU_UDI11 = 24'h000000; - parameter [0:23] APU_UDI12 = 24'h000000; - parameter [0:23] APU_UDI13 = 24'h000000; - parameter [0:23] APU_UDI14 = 24'h000000; - parameter [0:23] APU_UDI15 = 24'h000000; - parameter [0:23] APU_UDI2 = 24'h000000; - parameter [0:23] APU_UDI3 = 24'h000000; - parameter [0:23] APU_UDI4 = 24'h000000; - parameter [0:23] APU_UDI5 = 24'h000000; - parameter [0:23] APU_UDI6 = 24'h000000; - parameter [0:23] APU_UDI7 = 24'h000000; - parameter [0:23] APU_UDI8 = 24'h000000; - parameter [0:23] APU_UDI9 = 24'h000000; - parameter [0:31] DMA0_RXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA0_TXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA1_RXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA1_TXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA2_RXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA2_TXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA3_RXCHANNELCTRL = 32'h01010000; - parameter [0:31] DMA3_TXCHANNELCTRL = 32'h01010000; - parameter [0:31] INTERCONNECT_IMASK = 32'hFFFFFFFF; - parameter [0:31] INTERCONNECT_TMPL_SEL = 32'h3FFFFFFF; - parameter [0:31] MI_ARBCONFIG = 32'h00432010; - parameter [0:31] MI_BANKCONFLICT_MASK = 32'h00000000; - parameter [0:31] MI_CONTROL = 32'h0000008F; - parameter [0:31] MI_ROWCONFLICT_MASK = 32'h00000000; - parameter [0:31] PPCM_ARBCONFIG = 32'h00432010; - parameter [0:31] PPCM_CONTROL = 32'h8000019F; - parameter [0:31] PPCM_COUNTER = 32'h00000500; - parameter [0:31] PPCS0_ADDRMAP_TMPL0 = 32'hFFFFFFFF; - parameter [0:31] PPCS0_ADDRMAP_TMPL1 = 32'hFFFFFFFF; - parameter [0:31] PPCS0_ADDRMAP_TMPL2 = 32'hFFFFFFFF; - parameter [0:31] PPCS0_ADDRMAP_TMPL3 = 32'hFFFFFFFF; - parameter [0:31] PPCS0_CONTROL = 32'h8033336C; - parameter [0:31] PPCS1_ADDRMAP_TMPL0 = 32'hFFFFFFFF; - parameter [0:31] PPCS1_ADDRMAP_TMPL1 = 32'hFFFFFFFF; - parameter [0:31] PPCS1_ADDRMAP_TMPL2 = 32'hFFFFFFFF; - parameter [0:31] PPCS1_ADDRMAP_TMPL3 = 32'hFFFFFFFF; - parameter [0:31] PPCS1_CONTROL = 32'h8033336C; - parameter [0:31] XBAR_ADDRMAP_TMPL0 = 32'hFFFF0000; - parameter [0:31] XBAR_ADDRMAP_TMPL1 = 32'h00000000; - parameter [0:31] XBAR_ADDRMAP_TMPL2 = 32'h00000000; - parameter [0:31] XBAR_ADDRMAP_TMPL3 = 32'h00000000; - parameter [0:7] DMA0_CONTROL = 8'h00; - parameter [0:7] DMA1_CONTROL = 8'h00; - parameter [0:7] DMA2_CONTROL = 8'h00; - parameter [0:7] DMA3_CONTROL = 8'h00; - parameter [0:9] DMA0_RXIRQTIMER = 10'h3FF; - parameter [0:9] DMA0_TXIRQTIMER = 10'h3FF; - parameter [0:9] DMA1_RXIRQTIMER = 10'h3FF; - parameter [0:9] DMA1_TXIRQTIMER = 10'h3FF; - parameter [0:9] DMA2_RXIRQTIMER = 10'h3FF; - parameter [0:9] DMA2_TXIRQTIMER = 10'h3FF; - parameter [0:9] DMA3_RXIRQTIMER = 10'h3FF; - parameter [0:9] DMA3_TXIRQTIMER = 10'h3FF; - output APUFCMDECFPUOP; - output APUFCMDECLOAD; - output APUFCMDECNONAUTON; - output APUFCMDECSTORE; - output APUFCMDECUDIVALID; - output APUFCMENDIAN; - output APUFCMFLUSH; - output APUFCMINSTRVALID; - output APUFCMLOADDVALID; - output APUFCMMSRFE0; - output APUFCMMSRFE1; - output APUFCMNEXTINSTRREADY; - output APUFCMOPERANDVALID; - output APUFCMWRITEBACKOK; - output C440CPMCORESLEEPREQ; - output C440CPMDECIRPTREQ; - output C440CPMFITIRPTREQ; - output C440CPMMSRCE; - output C440CPMMSREE; - output C440CPMTIMERRESETREQ; - output C440CPMWDIRPTREQ; - output C440JTGTDO; - output C440JTGTDOEN; - output C440MACHINECHECK; - output C440RSTCHIPRESETREQ; - output C440RSTCORERESETREQ; - output C440RSTSYSTEMRESETREQ; - output C440TRCCYCLE; - output C440TRCTRIGGEREVENTOUT; - output DMA0LLRSTENGINEACK; - output DMA0LLRXDSTRDYN; - output DMA0LLTXEOFN; - output DMA0LLTXEOPN; - output DMA0LLTXSOFN; - output DMA0LLTXSOPN; - output DMA0LLTXSRCRDYN; - output DMA0RXIRQ; - output DMA0TXIRQ; - output DMA1LLRSTENGINEACK; - output DMA1LLRXDSTRDYN; - output DMA1LLTXEOFN; - output DMA1LLTXEOPN; - output DMA1LLTXSOFN; - output DMA1LLTXSOPN; - output DMA1LLTXSRCRDYN; - output DMA1RXIRQ; - output DMA1TXIRQ; - output DMA2LLRSTENGINEACK; - output DMA2LLRXDSTRDYN; - output DMA2LLTXEOFN; - output DMA2LLTXEOPN; - output DMA2LLTXSOFN; - output DMA2LLTXSOPN; - output DMA2LLTXSRCRDYN; - output DMA2RXIRQ; - output DMA2TXIRQ; - output DMA3LLRSTENGINEACK; - output DMA3LLRXDSTRDYN; - output DMA3LLTXEOFN; - output DMA3LLTXEOPN; - output DMA3LLTXSOFN; - output DMA3LLTXSOPN; - output DMA3LLTXSRCRDYN; - output DMA3RXIRQ; - output DMA3TXIRQ; - output MIMCADDRESSVALID; - output MIMCBANKCONFLICT; - output MIMCREADNOTWRITE; - output MIMCROWCONFLICT; - output MIMCWRITEDATAVALID; - output PPCCPMINTERCONNECTBUSY; - output PPCDMDCRREAD; - output PPCDMDCRWRITE; - output PPCDSDCRACK; - output PPCDSDCRTIMEOUTWAIT; - output PPCEICINTERCONNECTIRQ; - output PPCMPLBABORT; - output PPCMPLBBUSLOCK; - output PPCMPLBLOCKERR; - output PPCMPLBRDBURST; - output PPCMPLBREQUEST; - output PPCMPLBRNW; - output PPCMPLBWRBURST; - output PPCS0PLBADDRACK; - output PPCS0PLBRDBTERM; - output PPCS0PLBRDCOMP; - output PPCS0PLBRDDACK; - output PPCS0PLBREARBITRATE; - output PPCS0PLBWAIT; - output PPCS0PLBWRBTERM; - output PPCS0PLBWRCOMP; - output PPCS0PLBWRDACK; - output PPCS1PLBADDRACK; - output PPCS1PLBRDBTERM; - output PPCS1PLBRDCOMP; - output PPCS1PLBRDDACK; - output PPCS1PLBREARBITRATE; - output PPCS1PLBWAIT; - output PPCS1PLBWRBTERM; - output PPCS1PLBWRCOMP; - output PPCS1PLBWRDACK; - output [0:127] APUFCMLOADDATA; - output [0:127] MIMCWRITEDATA; - output [0:127] PPCMPLBWRDBUS; - output [0:127] PPCS0PLBRDDBUS; - output [0:127] PPCS1PLBRDDBUS; - output [0:13] C440TRCTRIGGEREVENTTYPE; - output [0:15] MIMCBYTEENABLE; - output [0:15] PPCMPLBBE; - output [0:15] PPCMPLBTATTRIBUTE; - output [0:1] PPCMPLBPRIORITY; - output [0:1] PPCS0PLBSSIZE; - output [0:1] PPCS1PLBSSIZE; - output [0:2] APUFCMDECLDSTXFERSIZE; - output [0:2] C440TRCBRANCHSTATUS; - output [0:2] PPCMPLBTYPE; - output [0:31] APUFCMINSTRUCTION; - output [0:31] APUFCMRADATA; - output [0:31] APUFCMRBDATA; - output [0:31] DMA0LLTXD; - output [0:31] DMA1LLTXD; - output [0:31] DMA2LLTXD; - output [0:31] DMA3LLTXD; - output [0:31] PPCDMDCRDBUSOUT; - output [0:31] PPCDSDCRDBUSIN; - output [0:31] PPCMPLBABUS; - output [0:35] MIMCADDRESS; - output [0:3] APUFCMDECUDI; - output [0:3] APUFCMLOADBYTEADDR; - output [0:3] DMA0LLTXREM; - output [0:3] DMA1LLTXREM; - output [0:3] DMA2LLTXREM; - output [0:3] DMA3LLTXREM; - output [0:3] PPCMPLBSIZE; - output [0:3] PPCS0PLBMBUSY; - output [0:3] PPCS0PLBMIRQ; - output [0:3] PPCS0PLBMRDERR; - output [0:3] PPCS0PLBMWRERR; - output [0:3] PPCS0PLBRDWDADDR; - output [0:3] PPCS1PLBMBUSY; - output [0:3] PPCS1PLBMIRQ; - output [0:3] PPCS1PLBMRDERR; - output [0:3] PPCS1PLBMWRERR; - output [0:3] PPCS1PLBRDWDADDR; - output [0:4] C440TRCEXECUTIONSTATUS; - output [0:6] C440TRCTRACESTATUS; - output [0:7] C440DBGSYSTEMCONTROL; - output [0:9] PPCDMDCRABUS; - output [20:21] PPCDMDCRUABUS; - output [28:31] PPCMPLBUABUS; - input CPMC440CLK; - input CPMC440CLKEN; - input CPMC440CORECLOCKINACTIVE; - input CPMC440TIMERCLOCK; - input CPMDCRCLK; - input CPMDMA0LLCLK; - input CPMDMA1LLCLK; - input CPMDMA2LLCLK; - input CPMDMA3LLCLK; - input CPMFCMCLK; - input CPMINTERCONNECTCLK; - input CPMINTERCONNECTCLKEN; - input CPMINTERCONNECTCLKNTO1; - input CPMMCCLK; - input CPMPPCMPLBCLK; - input CPMPPCS0PLBCLK; - input CPMPPCS1PLBCLK; - input DBGC440DEBUGHALT; - input DBGC440UNCONDDEBUGEVENT; - input DCRPPCDMACK; - input DCRPPCDMTIMEOUTWAIT; - input DCRPPCDSREAD; - input DCRPPCDSWRITE; - input EICC440CRITIRQ; - input EICC440EXTIRQ; - input FCMAPUCONFIRMINSTR; - input FCMAPUDONE; - input FCMAPUEXCEPTION; - input FCMAPUFPSCRFEX; - input FCMAPURESULTVALID; - input FCMAPUSLEEPNOTREADY; - input JTGC440TCK; - input JTGC440TDI; - input JTGC440TMS; - input JTGC440TRSTNEG; - input LLDMA0RSTENGINEREQ; - input LLDMA0RXEOFN; - input LLDMA0RXEOPN; - input LLDMA0RXSOFN; - input LLDMA0RXSOPN; - input LLDMA0RXSRCRDYN; - input LLDMA0TXDSTRDYN; - input LLDMA1RSTENGINEREQ; - input LLDMA1RXEOFN; - input LLDMA1RXEOPN; - input LLDMA1RXSOFN; - input LLDMA1RXSOPN; - input LLDMA1RXSRCRDYN; - input LLDMA1TXDSTRDYN; - input LLDMA2RSTENGINEREQ; - input LLDMA2RXEOFN; - input LLDMA2RXEOPN; - input LLDMA2RXSOFN; - input LLDMA2RXSOPN; - input LLDMA2RXSRCRDYN; - input LLDMA2TXDSTRDYN; - input LLDMA3RSTENGINEREQ; - input LLDMA3RXEOFN; - input LLDMA3RXEOPN; - input LLDMA3RXSOFN; - input LLDMA3RXSOPN; - input LLDMA3RXSRCRDYN; - input LLDMA3TXDSTRDYN; - input MCMIADDRREADYTOACCEPT; - input MCMIREADDATAERR; - input MCMIREADDATAVALID; - input PLBPPCMADDRACK; - input PLBPPCMMBUSY; - input PLBPPCMMIRQ; - input PLBPPCMMRDERR; - input PLBPPCMMWRERR; - input PLBPPCMRDBTERM; - input PLBPPCMRDDACK; - input PLBPPCMRDPENDREQ; - input PLBPPCMREARBITRATE; - input PLBPPCMTIMEOUT; - input PLBPPCMWRBTERM; - input PLBPPCMWRDACK; - input PLBPPCMWRPENDREQ; - input PLBPPCS0ABORT; - input PLBPPCS0BUSLOCK; - input PLBPPCS0LOCKERR; - input PLBPPCS0PAVALID; - input PLBPPCS0RDBURST; - input PLBPPCS0RDPENDREQ; - input PLBPPCS0RDPRIM; - input PLBPPCS0RNW; - input PLBPPCS0SAVALID; - input PLBPPCS0WRBURST; - input PLBPPCS0WRPENDREQ; - input PLBPPCS0WRPRIM; - input PLBPPCS1ABORT; - input PLBPPCS1BUSLOCK; - input PLBPPCS1LOCKERR; - input PLBPPCS1PAVALID; - input PLBPPCS1RDBURST; - input PLBPPCS1RDPENDREQ; - input PLBPPCS1RDPRIM; - input PLBPPCS1RNW; - input PLBPPCS1SAVALID; - input PLBPPCS1WRBURST; - input PLBPPCS1WRPENDREQ; - input PLBPPCS1WRPRIM; - input RSTC440RESETCHIP; - input RSTC440RESETCORE; - input RSTC440RESETSYSTEM; - input TIEC440ENDIANRESET; - input TRCC440TRACEDISABLE; - input TRCC440TRIGGEREVENTIN; - input [0:127] FCMAPUSTOREDATA; - input [0:127] MCMIREADDATA; - input [0:127] PLBPPCMRDDBUS; - input [0:127] PLBPPCS0WRDBUS; - input [0:127] PLBPPCS1WRDBUS; - input [0:15] PLBPPCS0BE; - input [0:15] PLBPPCS0TATTRIBUTE; - input [0:15] PLBPPCS1BE; - input [0:15] PLBPPCS1TATTRIBUTE; - input [0:1] PLBPPCMRDPENDPRI; - input [0:1] PLBPPCMREQPRI; - input [0:1] PLBPPCMSSIZE; - input [0:1] PLBPPCMWRPENDPRI; - input [0:1] PLBPPCS0MASTERID; - input [0:1] PLBPPCS0MSIZE; - input [0:1] PLBPPCS0RDPENDPRI; - input [0:1] PLBPPCS0REQPRI; - input [0:1] PLBPPCS0WRPENDPRI; - input [0:1] PLBPPCS1MASTERID; - input [0:1] PLBPPCS1MSIZE; - input [0:1] PLBPPCS1RDPENDPRI; - input [0:1] PLBPPCS1REQPRI; - input [0:1] PLBPPCS1WRPENDPRI; - input [0:1] TIEC440DCURDLDCACHEPLBPRIO; - input [0:1] TIEC440DCURDNONCACHEPLBPRIO; - input [0:1] TIEC440DCURDTOUCHPLBPRIO; - input [0:1] TIEC440DCURDURGENTPLBPRIO; - input [0:1] TIEC440DCUWRFLUSHPLBPRIO; - input [0:1] TIEC440DCUWRSTOREPLBPRIO; - input [0:1] TIEC440DCUWRURGENTPLBPRIO; - input [0:1] TIEC440ICURDFETCHPLBPRIO; - input [0:1] TIEC440ICURDSPECPLBPRIO; - input [0:1] TIEC440ICURDTOUCHPLBPRIO; - input [0:1] TIEDCRBASEADDR; - input [0:2] PLBPPCS0TYPE; - input [0:2] PLBPPCS1TYPE; - input [0:31] DCRPPCDMDBUSIN; - input [0:31] DCRPPCDSDBUSOUT; - input [0:31] FCMAPURESULT; - input [0:31] LLDMA0RXD; - input [0:31] LLDMA1RXD; - input [0:31] LLDMA2RXD; - input [0:31] LLDMA3RXD; - input [0:31] PLBPPCS0ABUS; - input [0:31] PLBPPCS1ABUS; - input [0:3] FCMAPUCR; - input [0:3] LLDMA0RXREM; - input [0:3] LLDMA1RXREM; - input [0:3] LLDMA2RXREM; - input [0:3] LLDMA3RXREM; - input [0:3] PLBPPCMRDWDADDR; - input [0:3] PLBPPCS0SIZE; - input [0:3] PLBPPCS1SIZE; - input [0:3] TIEC440ERPNRESET; - input [0:3] TIEC440USERRESET; - input [0:4] DBGC440SYSTEMSTATUS; - input [0:9] DCRPPCDSABUS; - input [28:31] PLBPPCS0UABUS; - input [28:31] PLBPPCS1UABUS; - input [28:31] TIEC440PIR; - input [28:31] TIEC440PVR; +module PCIE4CE4 (...); + parameter ARI_CAP_ENABLE = "FALSE"; + parameter AUTO_FLR_RESPONSE = "FALSE"; + parameter [7:0] AXISTEN_IF_CCIX_RX_CREDIT_LIMIT = 8'h08; + parameter [7:0] AXISTEN_IF_CCIX_TX_CREDIT_LIMIT = 8'h08; + parameter AXISTEN_IF_CCIX_TX_REGISTERED_TREADY = "FALSE"; + parameter [1:0] AXISTEN_IF_CC_ALIGNMENT_MODE = 2'h0; + parameter [23:0] AXISTEN_IF_COMPL_TIMEOUT_REG0 = 24'hBEBC20; + parameter [27:0] AXISTEN_IF_COMPL_TIMEOUT_REG1 = 28'h2FAF080; + parameter [1:0] AXISTEN_IF_CQ_ALIGNMENT_MODE = 2'h0; + parameter AXISTEN_IF_CQ_EN_POISONED_MEM_WR = "FALSE"; + parameter AXISTEN_IF_ENABLE_256_TAGS = "FALSE"; + parameter AXISTEN_IF_ENABLE_CLIENT_TAG = "FALSE"; + parameter AXISTEN_IF_ENABLE_INTERNAL_MSIX_TABLE = "FALSE"; + parameter AXISTEN_IF_ENABLE_MESSAGE_RID_CHECK = "TRUE"; + parameter [17:0] AXISTEN_IF_ENABLE_MSG_ROUTE = 18'h00000; + parameter AXISTEN_IF_ENABLE_RX_MSG_INTFC = "FALSE"; + parameter AXISTEN_IF_EXT_512 = "FALSE"; + parameter AXISTEN_IF_EXT_512_CC_STRADDLE = "FALSE"; + parameter AXISTEN_IF_EXT_512_CQ_STRADDLE = "FALSE"; + parameter AXISTEN_IF_EXT_512_RC_STRADDLE = "FALSE"; + parameter AXISTEN_IF_EXT_512_RQ_STRADDLE = "FALSE"; + parameter AXISTEN_IF_LEGACY_MODE_ENABLE = "FALSE"; + parameter AXISTEN_IF_MSIX_FROM_RAM_PIPELINE = "FALSE"; + parameter AXISTEN_IF_MSIX_RX_PARITY_EN = "TRUE"; + parameter AXISTEN_IF_MSIX_TO_RAM_PIPELINE = "FALSE"; + parameter [1:0] AXISTEN_IF_RC_ALIGNMENT_MODE = 2'h0; + parameter AXISTEN_IF_RC_STRADDLE = "FALSE"; + parameter [1:0] AXISTEN_IF_RQ_ALIGNMENT_MODE = 2'h0; + parameter AXISTEN_IF_RX_PARITY_EN = "TRUE"; + parameter AXISTEN_IF_SIM_SHORT_CPL_TIMEOUT = "FALSE"; + parameter AXISTEN_IF_TX_PARITY_EN = "TRUE"; + parameter [1:0] AXISTEN_IF_WIDTH = 2'h2; + parameter CCIX_DIRECT_ATTACH_MODE = "FALSE"; + parameter CCIX_ENABLE = "FALSE"; + parameter [15:0] CCIX_VENDOR_ID = 16'h0000; + parameter CFG_BYPASS_MODE_ENABLE = "FALSE"; + parameter CRM_CORE_CLK_FREQ_500 = "TRUE"; + parameter [1:0] CRM_USER_CLK_FREQ = 2'h2; + parameter [15:0] DEBUG_AXI4ST_SPARE = 16'h0000; + parameter [7:0] DEBUG_AXIST_DISABLE_FEATURE_BIT = 8'h00; + parameter [3:0] DEBUG_CAR_SPARE = 4'h0; + parameter [15:0] DEBUG_CFG_SPARE = 16'h0000; + parameter [15:0] DEBUG_LL_SPARE = 16'h0000; + parameter DEBUG_PL_DISABLE_LES_UPDATE_ON_DEFRAMER_ERROR = "FALSE"; + parameter DEBUG_PL_DISABLE_LES_UPDATE_ON_SKP_ERROR = "FALSE"; + parameter DEBUG_PL_DISABLE_LES_UPDATE_ON_SKP_PARITY_ERROR = "FALSE"; + parameter DEBUG_PL_DISABLE_REC_ENTRY_ON_DYNAMIC_DSKEW_FAIL = "FALSE"; + parameter DEBUG_PL_DISABLE_REC_ENTRY_ON_RX_BUFFER_UNDER_OVER_FLOW = "FALSE"; + parameter DEBUG_PL_DISABLE_SCRAMBLING = "FALSE"; + parameter DEBUG_PL_SIM_RESET_LFSR = "FALSE"; + parameter [15:0] DEBUG_PL_SPARE = 16'h0000; + parameter DEBUG_TL_DISABLE_FC_TIMEOUT = "FALSE"; + parameter DEBUG_TL_DISABLE_RX_TLP_ORDER_CHECKS = "FALSE"; + parameter [15:0] DEBUG_TL_SPARE = 16'h0000; + parameter [7:0] DNSTREAM_LINK_NUM = 8'h00; + parameter DSN_CAP_ENABLE = "FALSE"; + parameter EXTENDED_CFG_EXTEND_INTERFACE_ENABLE = "FALSE"; + parameter HEADER_TYPE_OVERRIDE = "FALSE"; + parameter IS_SWITCH_PORT = "FALSE"; + parameter LEGACY_CFG_EXTEND_INTERFACE_ENABLE = "FALSE"; + parameter [8:0] LL_ACK_TIMEOUT = 9'h000; + parameter LL_ACK_TIMEOUT_EN = "FALSE"; + parameter integer LL_ACK_TIMEOUT_FUNC = 0; + parameter LL_DISABLE_SCHED_TX_NAK = "FALSE"; + parameter LL_REPLAY_FROM_RAM_PIPELINE = "FALSE"; + parameter [8:0] LL_REPLAY_TIMEOUT = 9'h000; + parameter LL_REPLAY_TIMEOUT_EN = "FALSE"; + parameter integer LL_REPLAY_TIMEOUT_FUNC = 0; + parameter LL_REPLAY_TO_RAM_PIPELINE = "FALSE"; + parameter LL_RX_TLP_PARITY_GEN = "TRUE"; + parameter LL_TX_TLP_PARITY_CHK = "TRUE"; + parameter [15:0] LL_USER_SPARE = 16'h0000; + parameter [9:0] LTR_TX_MESSAGE_MINIMUM_INTERVAL = 10'h250; + parameter LTR_TX_MESSAGE_ON_FUNC_POWER_STATE_CHANGE = "FALSE"; + parameter LTR_TX_MESSAGE_ON_LTR_ENABLE = "FALSE"; + parameter [11:0] MCAP_CAP_NEXTPTR = 12'h000; + parameter MCAP_CONFIGURE_OVERRIDE = "FALSE"; + parameter MCAP_ENABLE = "FALSE"; + parameter MCAP_EOS_DESIGN_SWITCH = "FALSE"; + parameter [31:0] MCAP_FPGA_BITSTREAM_VERSION = 32'h00000000; + parameter MCAP_GATE_IO_ENABLE_DESIGN_SWITCH = "FALSE"; + parameter MCAP_GATE_MEM_ENABLE_DESIGN_SWITCH = "FALSE"; + parameter MCAP_INPUT_GATE_DESIGN_SWITCH = "FALSE"; + parameter MCAP_INTERRUPT_ON_MCAP_EOS = "FALSE"; + parameter MCAP_INTERRUPT_ON_MCAP_ERROR = "FALSE"; + parameter [15:0] MCAP_VSEC_ID = 16'h0000; + parameter [11:0] MCAP_VSEC_LEN = 12'h02C; + parameter [3:0] MCAP_VSEC_REV = 4'h0; + parameter PF0_AER_CAP_ECRC_GEN_AND_CHECK_CAPABLE = "FALSE"; + parameter [11:0] PF0_AER_CAP_NEXTPTR = 12'h000; + parameter [11:0] PF0_ARI_CAP_NEXTPTR = 12'h000; + parameter [7:0] PF0_ARI_CAP_NEXT_FUNC = 8'h00; + parameter [3:0] PF0_ARI_CAP_VER = 4'h1; + parameter [4:0] PF0_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] PF0_ATS_CAP_NEXTPTR = 12'h000; + parameter PF0_ATS_CAP_ON = "FALSE"; + parameter [5:0] PF0_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_BAR0_CONTROL = 3'h4; + parameter [4:0] PF0_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF0_BAR1_CONTROL = 3'h0; + parameter [5:0] PF0_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_BAR2_CONTROL = 3'h4; + parameter [4:0] PF0_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF0_BAR3_CONTROL = 3'h0; + parameter [5:0] PF0_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_BAR4_CONTROL = 3'h4; + parameter [4:0] PF0_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF0_BAR5_CONTROL = 3'h0; + parameter [7:0] PF0_CAPABILITY_POINTER = 8'h80; + parameter [23:0] PF0_CLASS_CODE = 24'h000000; + parameter PF0_DEV_CAP2_128B_CAS_ATOMIC_COMPLETER_SUPPORT = "TRUE"; + parameter PF0_DEV_CAP2_32B_ATOMIC_COMPLETER_SUPPORT = "TRUE"; + parameter PF0_DEV_CAP2_64B_ATOMIC_COMPLETER_SUPPORT = "TRUE"; + parameter PF0_DEV_CAP2_ARI_FORWARD_ENABLE = "FALSE"; + parameter PF0_DEV_CAP2_CPL_TIMEOUT_DISABLE = "TRUE"; + parameter PF0_DEV_CAP2_LTR_SUPPORT = "TRUE"; + parameter [1:0] PF0_DEV_CAP2_OBFF_SUPPORT = 2'h0; + parameter PF0_DEV_CAP2_TPH_COMPLETER_SUPPORT = "FALSE"; + parameter integer PF0_DEV_CAP_ENDPOINT_L0S_LATENCY = 0; + parameter integer PF0_DEV_CAP_ENDPOINT_L1_LATENCY = 0; + parameter PF0_DEV_CAP_EXT_TAG_SUPPORTED = "TRUE"; + parameter PF0_DEV_CAP_FUNCTION_LEVEL_RESET_CAPABLE = "TRUE"; + parameter [2:0] PF0_DEV_CAP_MAX_PAYLOAD_SIZE = 3'h3; + parameter [11:0] PF0_DSN_CAP_NEXTPTR = 12'h10C; + parameter [4:0] PF0_EXPANSION_ROM_APERTURE_SIZE = 5'h03; + parameter PF0_EXPANSION_ROM_ENABLE = "FALSE"; + parameter [2:0] PF0_INTERRUPT_PIN = 3'h1; + parameter integer PF0_LINK_CAP_ASPM_SUPPORT = 0; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_COMCLK_GEN1 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_COMCLK_GEN2 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_COMCLK_GEN3 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_COMCLK_GEN4 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_GEN1 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_GEN2 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_GEN3 = 7; + parameter integer PF0_LINK_CAP_L0S_EXIT_LATENCY_GEN4 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_COMCLK_GEN1 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_COMCLK_GEN2 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_COMCLK_GEN3 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_COMCLK_GEN4 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_GEN1 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_GEN2 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_GEN3 = 7; + parameter integer PF0_LINK_CAP_L1_EXIT_LATENCY_GEN4 = 7; + parameter [0:0] PF0_LINK_CONTROL_RCB = 1'h0; + parameter PF0_LINK_STATUS_SLOT_CLOCK_CONFIG = "TRUE"; + parameter [9:0] PF0_LTR_CAP_MAX_NOSNOOP_LAT = 10'h000; + parameter [9:0] PF0_LTR_CAP_MAX_SNOOP_LAT = 10'h000; + parameter [11:0] PF0_LTR_CAP_NEXTPTR = 12'h000; + parameter [3:0] PF0_LTR_CAP_VER = 4'h1; + parameter [7:0] PF0_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer PF0_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] PF0_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer PF0_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] PF0_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] PF0_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter [5:0] PF0_MSIX_VECTOR_COUNT = 6'h04; + parameter integer PF0_MSI_CAP_MULTIMSGCAP = 0; + parameter [7:0] PF0_MSI_CAP_NEXTPTR = 8'h00; + parameter PF0_MSI_CAP_PERVECMASKCAP = "FALSE"; + parameter [7:0] PF0_PCIE_CAP_NEXTPTR = 8'h00; + parameter [7:0] PF0_PM_CAP_ID = 8'h01; + parameter [7:0] PF0_PM_CAP_NEXTPTR = 8'h00; + parameter PF0_PM_CAP_PMESUPPORT_D0 = "TRUE"; + parameter PF0_PM_CAP_PMESUPPORT_D1 = "TRUE"; + parameter PF0_PM_CAP_PMESUPPORT_D3HOT = "TRUE"; + parameter PF0_PM_CAP_SUPP_D1_STATE = "TRUE"; + parameter [2:0] PF0_PM_CAP_VER_ID = 3'h3; + parameter PF0_PM_CSR_NOSOFTRESET = "TRUE"; + parameter [11:0] PF0_PRI_CAP_NEXTPTR = 12'h000; + parameter PF0_PRI_CAP_ON = "FALSE"; + parameter [31:0] PF0_PRI_OST_PR_CAPACITY = 32'h00000000; + parameter [11:0] PF0_SECONDARY_PCIE_CAP_NEXTPTR = 12'h000; + parameter PF0_SRIOV_ARI_CAPBL_HIER_PRESERVED = "FALSE"; + parameter [5:0] PF0_SRIOV_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_SRIOV_BAR0_CONTROL = 3'h4; + parameter [4:0] PF0_SRIOV_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF0_SRIOV_BAR1_CONTROL = 3'h0; + parameter [5:0] PF0_SRIOV_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_SRIOV_BAR2_CONTROL = 3'h4; + parameter [4:0] PF0_SRIOV_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF0_SRIOV_BAR3_CONTROL = 3'h0; + parameter [5:0] PF0_SRIOV_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF0_SRIOV_BAR4_CONTROL = 3'h4; + parameter [4:0] PF0_SRIOV_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF0_SRIOV_BAR5_CONTROL = 3'h0; + parameter [15:0] PF0_SRIOV_CAP_INITIAL_VF = 16'h0000; + parameter [11:0] PF0_SRIOV_CAP_NEXTPTR = 12'h000; + parameter [15:0] PF0_SRIOV_CAP_TOTAL_VF = 16'h0000; + parameter [3:0] PF0_SRIOV_CAP_VER = 4'h1; + parameter [15:0] PF0_SRIOV_FIRST_VF_OFFSET = 16'h0000; + parameter [15:0] PF0_SRIOV_FUNC_DEP_LINK = 16'h0000; + parameter [31:0] PF0_SRIOV_SUPPORTED_PAGE_SIZE = 32'h00000000; + parameter [15:0] PF0_SRIOV_VF_DEVICE_ID = 16'h0000; + parameter PF0_TPHR_CAP_DEV_SPECIFIC_MODE = "TRUE"; + parameter PF0_TPHR_CAP_ENABLE = "FALSE"; + parameter PF0_TPHR_CAP_INT_VEC_MODE = "TRUE"; + parameter [11:0] PF0_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] PF0_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [1:0] PF0_TPHR_CAP_ST_TABLE_LOC = 2'h0; + parameter [10:0] PF0_TPHR_CAP_ST_TABLE_SIZE = 11'h000; + parameter [3:0] PF0_TPHR_CAP_VER = 4'h1; + parameter [3:0] PF0_VC_ARB_CAPABILITY = 4'h0; + parameter [7:0] PF0_VC_ARB_TBL_OFFSET = 8'h00; + parameter PF0_VC_CAP_ENABLE = "FALSE"; + parameter [11:0] PF0_VC_CAP_NEXTPTR = 12'h000; + parameter [3:0] PF0_VC_CAP_VER = 4'h1; + parameter PF0_VC_EXTENDED_COUNT = "FALSE"; + parameter PF0_VC_LOW_PRIORITY_EXTENDED_COUNT = "FALSE"; + parameter [11:0] PF1_AER_CAP_NEXTPTR = 12'h000; + parameter [11:0] PF1_ARI_CAP_NEXTPTR = 12'h000; + parameter [7:0] PF1_ARI_CAP_NEXT_FUNC = 8'h00; + parameter [4:0] PF1_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] PF1_ATS_CAP_NEXTPTR = 12'h000; + parameter PF1_ATS_CAP_ON = "FALSE"; + parameter [5:0] PF1_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_BAR0_CONTROL = 3'h4; + parameter [4:0] PF1_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF1_BAR1_CONTROL = 3'h0; + parameter [5:0] PF1_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_BAR2_CONTROL = 3'h4; + parameter [4:0] PF1_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF1_BAR3_CONTROL = 3'h0; + parameter [5:0] PF1_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_BAR4_CONTROL = 3'h4; + parameter [4:0] PF1_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF1_BAR5_CONTROL = 3'h0; + parameter [7:0] PF1_CAPABILITY_POINTER = 8'h80; + parameter [23:0] PF1_CLASS_CODE = 24'h000000; + parameter [2:0] PF1_DEV_CAP_MAX_PAYLOAD_SIZE = 3'h3; + parameter [11:0] PF1_DSN_CAP_NEXTPTR = 12'h10C; + parameter [4:0] PF1_EXPANSION_ROM_APERTURE_SIZE = 5'h03; + parameter PF1_EXPANSION_ROM_ENABLE = "FALSE"; + parameter [2:0] PF1_INTERRUPT_PIN = 3'h1; + parameter [7:0] PF1_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer PF1_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] PF1_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer PF1_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] PF1_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] PF1_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter integer PF1_MSI_CAP_MULTIMSGCAP = 0; + parameter [7:0] PF1_MSI_CAP_NEXTPTR = 8'h00; + parameter PF1_MSI_CAP_PERVECMASKCAP = "FALSE"; + parameter [7:0] PF1_PCIE_CAP_NEXTPTR = 8'h00; + parameter [7:0] PF1_PM_CAP_NEXTPTR = 8'h00; + parameter [11:0] PF1_PRI_CAP_NEXTPTR = 12'h000; + parameter PF1_PRI_CAP_ON = "FALSE"; + parameter [31:0] PF1_PRI_OST_PR_CAPACITY = 32'h00000000; + parameter PF1_SRIOV_ARI_CAPBL_HIER_PRESERVED = "FALSE"; + parameter [5:0] PF1_SRIOV_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_SRIOV_BAR0_CONTROL = 3'h4; + parameter [4:0] PF1_SRIOV_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF1_SRIOV_BAR1_CONTROL = 3'h0; + parameter [5:0] PF1_SRIOV_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_SRIOV_BAR2_CONTROL = 3'h4; + parameter [4:0] PF1_SRIOV_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF1_SRIOV_BAR3_CONTROL = 3'h0; + parameter [5:0] PF1_SRIOV_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF1_SRIOV_BAR4_CONTROL = 3'h4; + parameter [4:0] PF1_SRIOV_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF1_SRIOV_BAR5_CONTROL = 3'h0; + parameter [15:0] PF1_SRIOV_CAP_INITIAL_VF = 16'h0000; + parameter [11:0] PF1_SRIOV_CAP_NEXTPTR = 12'h000; + parameter [15:0] PF1_SRIOV_CAP_TOTAL_VF = 16'h0000; + parameter [3:0] PF1_SRIOV_CAP_VER = 4'h1; + parameter [15:0] PF1_SRIOV_FIRST_VF_OFFSET = 16'h0000; + parameter [15:0] PF1_SRIOV_FUNC_DEP_LINK = 16'h0000; + parameter [31:0] PF1_SRIOV_SUPPORTED_PAGE_SIZE = 32'h00000000; + parameter [15:0] PF1_SRIOV_VF_DEVICE_ID = 16'h0000; + parameter [11:0] PF1_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] PF1_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [11:0] PF2_AER_CAP_NEXTPTR = 12'h000; + parameter [11:0] PF2_ARI_CAP_NEXTPTR = 12'h000; + parameter [7:0] PF2_ARI_CAP_NEXT_FUNC = 8'h00; + parameter [4:0] PF2_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] PF2_ATS_CAP_NEXTPTR = 12'h000; + parameter PF2_ATS_CAP_ON = "FALSE"; + parameter [5:0] PF2_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_BAR0_CONTROL = 3'h4; + parameter [4:0] PF2_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF2_BAR1_CONTROL = 3'h0; + parameter [5:0] PF2_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_BAR2_CONTROL = 3'h4; + parameter [4:0] PF2_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF2_BAR3_CONTROL = 3'h0; + parameter [5:0] PF2_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_BAR4_CONTROL = 3'h4; + parameter [4:0] PF2_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF2_BAR5_CONTROL = 3'h0; + parameter [7:0] PF2_CAPABILITY_POINTER = 8'h80; + parameter [23:0] PF2_CLASS_CODE = 24'h000000; + parameter [2:0] PF2_DEV_CAP_MAX_PAYLOAD_SIZE = 3'h3; + parameter [11:0] PF2_DSN_CAP_NEXTPTR = 12'h10C; + parameter [4:0] PF2_EXPANSION_ROM_APERTURE_SIZE = 5'h03; + parameter PF2_EXPANSION_ROM_ENABLE = "FALSE"; + parameter [2:0] PF2_INTERRUPT_PIN = 3'h1; + parameter [7:0] PF2_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer PF2_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] PF2_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer PF2_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] PF2_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] PF2_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter integer PF2_MSI_CAP_MULTIMSGCAP = 0; + parameter [7:0] PF2_MSI_CAP_NEXTPTR = 8'h00; + parameter PF2_MSI_CAP_PERVECMASKCAP = "FALSE"; + parameter [7:0] PF2_PCIE_CAP_NEXTPTR = 8'h00; + parameter [7:0] PF2_PM_CAP_NEXTPTR = 8'h00; + parameter [11:0] PF2_PRI_CAP_NEXTPTR = 12'h000; + parameter PF2_PRI_CAP_ON = "FALSE"; + parameter [31:0] PF2_PRI_OST_PR_CAPACITY = 32'h00000000; + parameter PF2_SRIOV_ARI_CAPBL_HIER_PRESERVED = "FALSE"; + parameter [5:0] PF2_SRIOV_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_SRIOV_BAR0_CONTROL = 3'h4; + parameter [4:0] PF2_SRIOV_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF2_SRIOV_BAR1_CONTROL = 3'h0; + parameter [5:0] PF2_SRIOV_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_SRIOV_BAR2_CONTROL = 3'h4; + parameter [4:0] PF2_SRIOV_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF2_SRIOV_BAR3_CONTROL = 3'h0; + parameter [5:0] PF2_SRIOV_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF2_SRIOV_BAR4_CONTROL = 3'h4; + parameter [4:0] PF2_SRIOV_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF2_SRIOV_BAR5_CONTROL = 3'h0; + parameter [15:0] PF2_SRIOV_CAP_INITIAL_VF = 16'h0000; + parameter [11:0] PF2_SRIOV_CAP_NEXTPTR = 12'h000; + parameter [15:0] PF2_SRIOV_CAP_TOTAL_VF = 16'h0000; + parameter [3:0] PF2_SRIOV_CAP_VER = 4'h1; + parameter [15:0] PF2_SRIOV_FIRST_VF_OFFSET = 16'h0000; + parameter [15:0] PF2_SRIOV_FUNC_DEP_LINK = 16'h0000; + parameter [31:0] PF2_SRIOV_SUPPORTED_PAGE_SIZE = 32'h00000000; + parameter [15:0] PF2_SRIOV_VF_DEVICE_ID = 16'h0000; + parameter [11:0] PF2_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] PF2_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [11:0] PF3_AER_CAP_NEXTPTR = 12'h000; + parameter [11:0] PF3_ARI_CAP_NEXTPTR = 12'h000; + parameter [7:0] PF3_ARI_CAP_NEXT_FUNC = 8'h00; + parameter [4:0] PF3_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] PF3_ATS_CAP_NEXTPTR = 12'h000; + parameter PF3_ATS_CAP_ON = "FALSE"; + parameter [5:0] PF3_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_BAR0_CONTROL = 3'h4; + parameter [4:0] PF3_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF3_BAR1_CONTROL = 3'h0; + parameter [5:0] PF3_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_BAR2_CONTROL = 3'h4; + parameter [4:0] PF3_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF3_BAR3_CONTROL = 3'h0; + parameter [5:0] PF3_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_BAR4_CONTROL = 3'h4; + parameter [4:0] PF3_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF3_BAR5_CONTROL = 3'h0; + parameter [7:0] PF3_CAPABILITY_POINTER = 8'h80; + parameter [23:0] PF3_CLASS_CODE = 24'h000000; + parameter [2:0] PF3_DEV_CAP_MAX_PAYLOAD_SIZE = 3'h3; + parameter [11:0] PF3_DSN_CAP_NEXTPTR = 12'h10C; + parameter [4:0] PF3_EXPANSION_ROM_APERTURE_SIZE = 5'h03; + parameter PF3_EXPANSION_ROM_ENABLE = "FALSE"; + parameter [2:0] PF3_INTERRUPT_PIN = 3'h1; + parameter [7:0] PF3_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer PF3_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] PF3_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer PF3_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] PF3_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] PF3_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter integer PF3_MSI_CAP_MULTIMSGCAP = 0; + parameter [7:0] PF3_MSI_CAP_NEXTPTR = 8'h00; + parameter PF3_MSI_CAP_PERVECMASKCAP = "FALSE"; + parameter [7:0] PF3_PCIE_CAP_NEXTPTR = 8'h00; + parameter [7:0] PF3_PM_CAP_NEXTPTR = 8'h00; + parameter [11:0] PF3_PRI_CAP_NEXTPTR = 12'h000; + parameter PF3_PRI_CAP_ON = "FALSE"; + parameter [31:0] PF3_PRI_OST_PR_CAPACITY = 32'h00000000; + parameter PF3_SRIOV_ARI_CAPBL_HIER_PRESERVED = "FALSE"; + parameter [5:0] PF3_SRIOV_BAR0_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_SRIOV_BAR0_CONTROL = 3'h4; + parameter [4:0] PF3_SRIOV_BAR1_APERTURE_SIZE = 5'h00; + parameter [2:0] PF3_SRIOV_BAR1_CONTROL = 3'h0; + parameter [5:0] PF3_SRIOV_BAR2_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_SRIOV_BAR2_CONTROL = 3'h4; + parameter [4:0] PF3_SRIOV_BAR3_APERTURE_SIZE = 5'h03; + parameter [2:0] PF3_SRIOV_BAR3_CONTROL = 3'h0; + parameter [5:0] PF3_SRIOV_BAR4_APERTURE_SIZE = 6'h03; + parameter [2:0] PF3_SRIOV_BAR4_CONTROL = 3'h4; + parameter [4:0] PF3_SRIOV_BAR5_APERTURE_SIZE = 5'h03; + parameter [2:0] PF3_SRIOV_BAR5_CONTROL = 3'h0; + parameter [15:0] PF3_SRIOV_CAP_INITIAL_VF = 16'h0000; + parameter [11:0] PF3_SRIOV_CAP_NEXTPTR = 12'h000; + parameter [15:0] PF3_SRIOV_CAP_TOTAL_VF = 16'h0000; + parameter [3:0] PF3_SRIOV_CAP_VER = 4'h1; + parameter [15:0] PF3_SRIOV_FIRST_VF_OFFSET = 16'h0000; + parameter [15:0] PF3_SRIOV_FUNC_DEP_LINK = 16'h0000; + parameter [31:0] PF3_SRIOV_SUPPORTED_PAGE_SIZE = 32'h00000000; + parameter [15:0] PF3_SRIOV_VF_DEVICE_ID = 16'h0000; + parameter [11:0] PF3_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] PF3_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter PL_CFG_STATE_ROBUSTNESS_ENABLE = "TRUE"; + parameter PL_CTRL_SKP_GEN_ENABLE = "FALSE"; + parameter PL_CTRL_SKP_PARITY_AND_CRC_CHECK_DISABLE = "TRUE"; + parameter PL_DEEMPH_SOURCE_SELECT = "TRUE"; + parameter PL_DESKEW_ON_SKIP_IN_GEN12 = "FALSE"; + parameter PL_DISABLE_AUTO_EQ_SPEED_CHANGE_TO_GEN3 = "FALSE"; + parameter PL_DISABLE_AUTO_EQ_SPEED_CHANGE_TO_GEN4 = "FALSE"; + parameter PL_DISABLE_AUTO_SPEED_CHANGE_TO_GEN2 = "FALSE"; + parameter PL_DISABLE_DC_BALANCE = "FALSE"; + parameter PL_DISABLE_EI_INFER_IN_L0 = "FALSE"; + parameter PL_DISABLE_LANE_REVERSAL = "FALSE"; + parameter [1:0] PL_DISABLE_LFSR_UPDATE_ON_SKP = 2'h0; + parameter PL_DISABLE_RETRAIN_ON_EB_ERROR = "FALSE"; + parameter PL_DISABLE_RETRAIN_ON_FRAMING_ERROR = "FALSE"; + parameter [15:0] PL_DISABLE_RETRAIN_ON_SPECIFIC_FRAMING_ERROR = 16'h0000; + parameter PL_DISABLE_UPCONFIG_CAPABLE = "FALSE"; + parameter [1:0] PL_EQ_ADAPT_DISABLE_COEFF_CHECK = 2'h0; + parameter [1:0] PL_EQ_ADAPT_DISABLE_PRESET_CHECK = 2'h0; + parameter [4:0] PL_EQ_ADAPT_ITER_COUNT = 5'h02; + parameter [1:0] PL_EQ_ADAPT_REJECT_RETRY_COUNT = 2'h1; + parameter [1:0] PL_EQ_BYPASS_PHASE23 = 2'h0; + parameter [5:0] PL_EQ_DEFAULT_RX_PRESET_HINT = 6'h33; + parameter [7:0] PL_EQ_DEFAULT_TX_PRESET = 8'h44; + parameter PL_EQ_DISABLE_MISMATCH_CHECK = "TRUE"; + parameter [1:0] PL_EQ_RX_ADAPT_EQ_PHASE0 = 2'h0; + parameter [1:0] PL_EQ_RX_ADAPT_EQ_PHASE1 = 2'h0; + parameter PL_EQ_SHORT_ADAPT_PHASE = "FALSE"; + parameter PL_EQ_TX_8G_EQ_TS2_ENABLE = "FALSE"; + parameter PL_EXIT_LOOPBACK_ON_EI_ENTRY = "TRUE"; + parameter PL_INFER_EI_DISABLE_LPBK_ACTIVE = "TRUE"; + parameter PL_INFER_EI_DISABLE_REC_RC = "FALSE"; + parameter PL_INFER_EI_DISABLE_REC_SPD = "FALSE"; + parameter [31:0] PL_LANE0_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE10_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE11_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE12_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE13_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE14_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE15_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE1_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE2_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE3_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE4_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE5_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE6_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE7_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE8_EQ_CONTROL = 32'h00003F00; + parameter [31:0] PL_LANE9_EQ_CONTROL = 32'h00003F00; + parameter [3:0] PL_LINK_CAP_MAX_LINK_SPEED = 4'h4; + parameter [4:0] PL_LINK_CAP_MAX_LINK_WIDTH = 5'h08; + parameter integer PL_N_FTS = 255; + parameter PL_QUIESCE_GUARANTEE_DISABLE = "FALSE"; + parameter PL_REDO_EQ_SOURCE_SELECT = "TRUE"; + parameter [7:0] PL_REPORT_ALL_PHY_ERRORS = 8'h00; + parameter [1:0] PL_RX_ADAPT_TIMER_CLWS_CLOBBER_TX_TS = 2'h0; + parameter [3:0] PL_RX_ADAPT_TIMER_CLWS_GEN3 = 4'h0; + parameter [3:0] PL_RX_ADAPT_TIMER_CLWS_GEN4 = 4'h0; + parameter [1:0] PL_RX_ADAPT_TIMER_RRL_CLOBBER_TX_TS = 2'h0; + parameter [3:0] PL_RX_ADAPT_TIMER_RRL_GEN3 = 4'h0; + parameter [3:0] PL_RX_ADAPT_TIMER_RRL_GEN4 = 4'h0; + parameter [1:0] PL_RX_L0S_EXIT_TO_RECOVERY = 2'h0; + parameter [1:0] PL_SIM_FAST_LINK_TRAINING = 2'h0; + parameter PL_SRIS_ENABLE = "FALSE"; + parameter [6:0] PL_SRIS_SKPOS_GEN_SPD_VEC = 7'h00; + parameter [6:0] PL_SRIS_SKPOS_REC_SPD_VEC = 7'h00; + parameter PL_UPSTREAM_FACING = "TRUE"; + parameter [15:0] PL_USER_SPARE = 16'h0000; + parameter [15:0] PL_USER_SPARE2 = 16'h0000; + parameter [15:0] PM_ASPML0S_TIMEOUT = 16'h1500; + parameter [19:0] PM_ASPML1_ENTRY_DELAY = 20'h003E8; + parameter PM_ENABLE_L23_ENTRY = "FALSE"; + parameter PM_ENABLE_SLOT_POWER_CAPTURE = "TRUE"; + parameter [31:0] PM_L1_REENTRY_DELAY = 32'h00000100; + parameter [19:0] PM_PME_SERVICE_TIMEOUT_DELAY = 20'h00000; + parameter [15:0] PM_PME_TURNOFF_ACK_DELAY = 16'h0100; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter [31:0] SIM_JTAG_IDCODE = 32'h00000000; + parameter SIM_VERSION = "1.0"; + parameter SPARE_BIT0 = "FALSE"; + parameter integer SPARE_BIT1 = 0; + parameter integer SPARE_BIT2 = 0; + parameter SPARE_BIT3 = "FALSE"; + parameter integer SPARE_BIT4 = 0; + parameter integer SPARE_BIT5 = 0; + parameter integer SPARE_BIT6 = 0; + parameter integer SPARE_BIT7 = 0; + parameter integer SPARE_BIT8 = 0; + parameter [7:0] SPARE_BYTE0 = 8'h00; + parameter [7:0] SPARE_BYTE1 = 8'h00; + parameter [7:0] SPARE_BYTE2 = 8'h00; + parameter [7:0] SPARE_BYTE3 = 8'h00; + parameter [31:0] SPARE_WORD0 = 32'h00000000; + parameter [31:0] SPARE_WORD1 = 32'h00000000; + parameter [31:0] SPARE_WORD2 = 32'h00000000; + parameter [31:0] SPARE_WORD3 = 32'h00000000; + parameter [3:0] SRIOV_CAP_ENABLE = 4'h0; + parameter TL2CFG_IF_PARITY_CHK = "TRUE"; + parameter [1:0] TL_COMPLETION_RAM_NUM_TLPS = 2'h0; + parameter [1:0] TL_COMPLETION_RAM_SIZE = 2'h1; + parameter [11:0] TL_CREDITS_CD = 12'h000; + parameter [11:0] TL_CREDITS_CD_VC1 = 12'h000; + parameter [7:0] TL_CREDITS_CH = 8'h00; + parameter [7:0] TL_CREDITS_CH_VC1 = 8'h00; + parameter [11:0] TL_CREDITS_NPD = 12'h004; + parameter [11:0] TL_CREDITS_NPD_VC1 = 12'h000; + parameter [7:0] TL_CREDITS_NPH = 8'h20; + parameter [7:0] TL_CREDITS_NPH_VC1 = 8'h01; + parameter [11:0] TL_CREDITS_PD = 12'h0E0; + parameter [11:0] TL_CREDITS_PD_VC1 = 12'h3E0; + parameter [7:0] TL_CREDITS_PH = 8'h20; + parameter [7:0] TL_CREDITS_PH_VC1 = 8'h20; + parameter [4:0] TL_FC_UPDATE_MIN_INTERVAL_TIME = 5'h02; + parameter [4:0] TL_FC_UPDATE_MIN_INTERVAL_TIME_VC1 = 5'h02; + parameter [4:0] TL_FC_UPDATE_MIN_INTERVAL_TLP_COUNT = 5'h08; + parameter [4:0] TL_FC_UPDATE_MIN_INTERVAL_TLP_COUNT_VC1 = 5'h08; + parameter TL_FEATURE_ENABLE_FC_SCALING = "FALSE"; + parameter [1:0] TL_PF_ENABLE_REG = 2'h0; + parameter [0:0] TL_POSTED_RAM_SIZE = 1'h0; + parameter TL_RX_COMPLETION_FROM_RAM_READ_PIPELINE = "FALSE"; + parameter TL_RX_COMPLETION_TO_RAM_READ_PIPELINE = "FALSE"; + parameter TL_RX_COMPLETION_TO_RAM_WRITE_PIPELINE = "FALSE"; + parameter TL_RX_POSTED_FROM_RAM_READ_PIPELINE = "FALSE"; + parameter TL_RX_POSTED_TO_RAM_READ_PIPELINE = "FALSE"; + parameter TL_RX_POSTED_TO_RAM_WRITE_PIPELINE = "FALSE"; + parameter TL_TX_MUX_STRICT_PRIORITY = "TRUE"; + parameter TL_TX_TLP_STRADDLE_ENABLE = "FALSE"; + parameter TL_TX_TLP_TERMINATE_PARITY = "FALSE"; + parameter [15:0] TL_USER_SPARE = 16'h0000; + parameter TPH_FROM_RAM_PIPELINE = "FALSE"; + parameter TPH_TO_RAM_PIPELINE = "FALSE"; + parameter [7:0] VF0_CAPABILITY_POINTER = 8'h80; + parameter [11:0] VFG0_ARI_CAP_NEXTPTR = 12'h000; + parameter [4:0] VFG0_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] VFG0_ATS_CAP_NEXTPTR = 12'h000; + parameter VFG0_ATS_CAP_ON = "FALSE"; + parameter [7:0] VFG0_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer VFG0_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] VFG0_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer VFG0_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] VFG0_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] VFG0_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter [7:0] VFG0_PCIE_CAP_NEXTPTR = 8'h00; + parameter [11:0] VFG0_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] VFG0_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [11:0] VFG1_ARI_CAP_NEXTPTR = 12'h000; + parameter [4:0] VFG1_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] VFG1_ATS_CAP_NEXTPTR = 12'h000; + parameter VFG1_ATS_CAP_ON = "FALSE"; + parameter [7:0] VFG1_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer VFG1_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] VFG1_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer VFG1_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] VFG1_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] VFG1_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter [7:0] VFG1_PCIE_CAP_NEXTPTR = 8'h00; + parameter [11:0] VFG1_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] VFG1_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [11:0] VFG2_ARI_CAP_NEXTPTR = 12'h000; + parameter [4:0] VFG2_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] VFG2_ATS_CAP_NEXTPTR = 12'h000; + parameter VFG2_ATS_CAP_ON = "FALSE"; + parameter [7:0] VFG2_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer VFG2_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] VFG2_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer VFG2_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] VFG2_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] VFG2_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter [7:0] VFG2_PCIE_CAP_NEXTPTR = 8'h00; + parameter [11:0] VFG2_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] VFG2_TPHR_CAP_ST_MODE_SEL = 3'h0; + parameter [11:0] VFG3_ARI_CAP_NEXTPTR = 12'h000; + parameter [4:0] VFG3_ATS_CAP_INV_QUEUE_DEPTH = 5'h00; + parameter [11:0] VFG3_ATS_CAP_NEXTPTR = 12'h000; + parameter VFG3_ATS_CAP_ON = "FALSE"; + parameter [7:0] VFG3_MSIX_CAP_NEXTPTR = 8'h00; + parameter integer VFG3_MSIX_CAP_PBA_BIR = 0; + parameter [28:0] VFG3_MSIX_CAP_PBA_OFFSET = 29'h00000050; + parameter integer VFG3_MSIX_CAP_TABLE_BIR = 0; + parameter [28:0] VFG3_MSIX_CAP_TABLE_OFFSET = 29'h00000040; + parameter [10:0] VFG3_MSIX_CAP_TABLE_SIZE = 11'h000; + parameter [7:0] VFG3_PCIE_CAP_NEXTPTR = 8'h00; + parameter [11:0] VFG3_TPHR_CAP_NEXTPTR = 12'h000; + parameter [2:0] VFG3_TPHR_CAP_ST_MODE_SEL = 3'h0; + output [7:0] AXIUSEROUT; + output CCIXTXCREDIT; + output [7:0] CFGBUSNUMBER; + output [1:0] CFGCURRENTSPEED; + output CFGERRCOROUT; + output CFGERRFATALOUT; + output CFGERRNONFATALOUT; + output [7:0] CFGEXTFUNCTIONNUMBER; + output CFGEXTREADRECEIVED; + output [9:0] CFGEXTREGISTERNUMBER; + output [3:0] CFGEXTWRITEBYTEENABLE; + output [31:0] CFGEXTWRITEDATA; + output CFGEXTWRITERECEIVED; + output [11:0] CFGFCCPLD; + output [7:0] CFGFCCPLH; + output [11:0] CFGFCNPD; + output [7:0] CFGFCNPH; + output [11:0] CFGFCPD; + output [7:0] CFGFCPH; + output [3:0] CFGFLRINPROCESS; + output [11:0] CFGFUNCTIONPOWERSTATE; + output [15:0] CFGFUNCTIONSTATUS; + output CFGHOTRESETOUT; + output [31:0] CFGINTERRUPTMSIDATA; + output [3:0] CFGINTERRUPTMSIENABLE; + output CFGINTERRUPTMSIFAIL; + output CFGINTERRUPTMSIMASKUPDATE; + output [11:0] CFGINTERRUPTMSIMMENABLE; + output CFGINTERRUPTMSISENT; + output [3:0] CFGINTERRUPTMSIXENABLE; + output [3:0] CFGINTERRUPTMSIXMASK; + output CFGINTERRUPTMSIXVECPENDINGSTATUS; + output CFGINTERRUPTSENT; + output [1:0] CFGLINKPOWERSTATE; + output [4:0] CFGLOCALERROROUT; + output CFGLOCALERRORVALID; + output CFGLTRENABLE; + output [5:0] CFGLTSSMSTATE; + output [1:0] CFGMAXPAYLOAD; + output [2:0] CFGMAXREADREQ; + output [31:0] CFGMGMTREADDATA; + output CFGMGMTREADWRITEDONE; + output CFGMSGRECEIVED; + output [7:0] CFGMSGRECEIVEDDATA; + output [4:0] CFGMSGRECEIVEDTYPE; + output CFGMSGTRANSMITDONE; + output [12:0] CFGMSIXRAMADDRESS; + output CFGMSIXRAMREADENABLE; + output [3:0] CFGMSIXRAMWRITEBYTEENABLE; + output [35:0] CFGMSIXRAMWRITEDATA; + output [2:0] CFGNEGOTIATEDWIDTH; + output [1:0] CFGOBFFENABLE; + output CFGPHYLINKDOWN; + output [1:0] CFGPHYLINKSTATUS; + output CFGPLSTATUSCHANGE; + output CFGPOWERSTATECHANGEINTERRUPT; + output [3:0] CFGRCBSTATUS; + output [1:0] CFGRXPMSTATE; + output [11:0] CFGTPHRAMADDRESS; + output CFGTPHRAMREADENABLE; + output [3:0] CFGTPHRAMWRITEBYTEENABLE; + output [35:0] CFGTPHRAMWRITEDATA; + output [3:0] CFGTPHREQUESTERENABLE; + output [11:0] CFGTPHSTMODE; + output [1:0] CFGTXPMSTATE; + output CFGVC1ENABLE; + output CFGVC1NEGOTIATIONPENDING; + output CONFMCAPDESIGNSWITCH; + output CONFMCAPEOS; + output CONFMCAPINUSEBYPCIE; + output CONFREQREADY; + output [31:0] CONFRESPRDATA; + output CONFRESPVALID; + output [129:0] DBGCCIXOUT; + output [31:0] DBGCTRL0OUT; + output [31:0] DBGCTRL1OUT; + output [255:0] DBGDATA0OUT; + output [255:0] DBGDATA1OUT; + output [15:0] DRPDO; + output DRPRDY; + output [45:0] MAXISCCIXRXTUSER; + output MAXISCCIXRXTVALID; + output [255:0] MAXISCQTDATA; + output [7:0] MAXISCQTKEEP; + output MAXISCQTLAST; + output [87:0] MAXISCQTUSER; + output MAXISCQTVALID; + output [255:0] MAXISRCTDATA; + output [7:0] MAXISRCTKEEP; + output MAXISRCTLAST; + output [74:0] MAXISRCTUSER; + output MAXISRCTVALID; + output [8:0] MIREPLAYRAMADDRESS0; + output [8:0] MIREPLAYRAMADDRESS1; + output MIREPLAYRAMREADENABLE0; + output MIREPLAYRAMREADENABLE1; + output [127:0] MIREPLAYRAMWRITEDATA0; + output [127:0] MIREPLAYRAMWRITEDATA1; + output MIREPLAYRAMWRITEENABLE0; + output MIREPLAYRAMWRITEENABLE1; + output [8:0] MIRXCOMPLETIONRAMREADADDRESS0; + output [8:0] MIRXCOMPLETIONRAMREADADDRESS1; + output [1:0] MIRXCOMPLETIONRAMREADENABLE0; + output [1:0] MIRXCOMPLETIONRAMREADENABLE1; + output [8:0] MIRXCOMPLETIONRAMWRITEADDRESS0; + output [8:0] MIRXCOMPLETIONRAMWRITEADDRESS1; + output [143:0] MIRXCOMPLETIONRAMWRITEDATA0; + output [143:0] MIRXCOMPLETIONRAMWRITEDATA1; + output [1:0] MIRXCOMPLETIONRAMWRITEENABLE0; + output [1:0] MIRXCOMPLETIONRAMWRITEENABLE1; + output [8:0] MIRXPOSTEDREQUESTRAMREADADDRESS0; + output [8:0] MIRXPOSTEDREQUESTRAMREADADDRESS1; + output MIRXPOSTEDREQUESTRAMREADENABLE0; + output MIRXPOSTEDREQUESTRAMREADENABLE1; + output [8:0] MIRXPOSTEDREQUESTRAMWRITEADDRESS0; + output [8:0] MIRXPOSTEDREQUESTRAMWRITEADDRESS1; + output [143:0] MIRXPOSTEDREQUESTRAMWRITEDATA0; + output [143:0] MIRXPOSTEDREQUESTRAMWRITEDATA1; + output MIRXPOSTEDREQUESTRAMWRITEENABLE0; + output MIRXPOSTEDREQUESTRAMWRITEENABLE1; + output [5:0] PCIECQNPREQCOUNT; + output PCIEPERST0B; + output PCIEPERST1B; + output [5:0] PCIERQSEQNUM0; + output [5:0] PCIERQSEQNUM1; + output PCIERQSEQNUMVLD0; + output PCIERQSEQNUMVLD1; + output [7:0] PCIERQTAG0; + output [7:0] PCIERQTAG1; + output [3:0] PCIERQTAGAV; + output PCIERQTAGVLD0; + output PCIERQTAGVLD1; + output [3:0] PCIETFCNPDAV; + output [3:0] PCIETFCNPHAV; + output [1:0] PIPERX00EQCONTROL; + output PIPERX00POLARITY; + output [1:0] PIPERX01EQCONTROL; + output PIPERX01POLARITY; + output [1:0] PIPERX02EQCONTROL; + output PIPERX02POLARITY; + output [1:0] PIPERX03EQCONTROL; + output PIPERX03POLARITY; + output [1:0] PIPERX04EQCONTROL; + output PIPERX04POLARITY; + output [1:0] PIPERX05EQCONTROL; + output PIPERX05POLARITY; + output [1:0] PIPERX06EQCONTROL; + output PIPERX06POLARITY; + output [1:0] PIPERX07EQCONTROL; + output PIPERX07POLARITY; + output [1:0] PIPERX08EQCONTROL; + output PIPERX08POLARITY; + output [1:0] PIPERX09EQCONTROL; + output PIPERX09POLARITY; + output [1:0] PIPERX10EQCONTROL; + output PIPERX10POLARITY; + output [1:0] PIPERX11EQCONTROL; + output PIPERX11POLARITY; + output [1:0] PIPERX12EQCONTROL; + output PIPERX12POLARITY; + output [1:0] PIPERX13EQCONTROL; + output PIPERX13POLARITY; + output [1:0] PIPERX14EQCONTROL; + output PIPERX14POLARITY; + output [1:0] PIPERX15EQCONTROL; + output PIPERX15POLARITY; + output [5:0] PIPERXEQLPLFFS; + output [3:0] PIPERXEQLPTXPRESET; + output [1:0] PIPETX00CHARISK; + output PIPETX00COMPLIANCE; + output [31:0] PIPETX00DATA; + output PIPETX00DATAVALID; + output PIPETX00ELECIDLE; + output [1:0] PIPETX00EQCONTROL; + output [5:0] PIPETX00EQDEEMPH; + output [1:0] PIPETX00POWERDOWN; + output PIPETX00STARTBLOCK; + output [1:0] PIPETX00SYNCHEADER; + output [1:0] PIPETX01CHARISK; + output PIPETX01COMPLIANCE; + output [31:0] PIPETX01DATA; + output PIPETX01DATAVALID; + output PIPETX01ELECIDLE; + output [1:0] PIPETX01EQCONTROL; + output [5:0] PIPETX01EQDEEMPH; + output [1:0] PIPETX01POWERDOWN; + output PIPETX01STARTBLOCK; + output [1:0] PIPETX01SYNCHEADER; + output [1:0] PIPETX02CHARISK; + output PIPETX02COMPLIANCE; + output [31:0] PIPETX02DATA; + output PIPETX02DATAVALID; + output PIPETX02ELECIDLE; + output [1:0] PIPETX02EQCONTROL; + output [5:0] PIPETX02EQDEEMPH; + output [1:0] PIPETX02POWERDOWN; + output PIPETX02STARTBLOCK; + output [1:0] PIPETX02SYNCHEADER; + output [1:0] PIPETX03CHARISK; + output PIPETX03COMPLIANCE; + output [31:0] PIPETX03DATA; + output PIPETX03DATAVALID; + output PIPETX03ELECIDLE; + output [1:0] PIPETX03EQCONTROL; + output [5:0] PIPETX03EQDEEMPH; + output [1:0] PIPETX03POWERDOWN; + output PIPETX03STARTBLOCK; + output [1:0] PIPETX03SYNCHEADER; + output [1:0] PIPETX04CHARISK; + output PIPETX04COMPLIANCE; + output [31:0] PIPETX04DATA; + output PIPETX04DATAVALID; + output PIPETX04ELECIDLE; + output [1:0] PIPETX04EQCONTROL; + output [5:0] PIPETX04EQDEEMPH; + output [1:0] PIPETX04POWERDOWN; + output PIPETX04STARTBLOCK; + output [1:0] PIPETX04SYNCHEADER; + output [1:0] PIPETX05CHARISK; + output PIPETX05COMPLIANCE; + output [31:0] PIPETX05DATA; + output PIPETX05DATAVALID; + output PIPETX05ELECIDLE; + output [1:0] PIPETX05EQCONTROL; + output [5:0] PIPETX05EQDEEMPH; + output [1:0] PIPETX05POWERDOWN; + output PIPETX05STARTBLOCK; + output [1:0] PIPETX05SYNCHEADER; + output [1:0] PIPETX06CHARISK; + output PIPETX06COMPLIANCE; + output [31:0] PIPETX06DATA; + output PIPETX06DATAVALID; + output PIPETX06ELECIDLE; + output [1:0] PIPETX06EQCONTROL; + output [5:0] PIPETX06EQDEEMPH; + output [1:0] PIPETX06POWERDOWN; + output PIPETX06STARTBLOCK; + output [1:0] PIPETX06SYNCHEADER; + output [1:0] PIPETX07CHARISK; + output PIPETX07COMPLIANCE; + output [31:0] PIPETX07DATA; + output PIPETX07DATAVALID; + output PIPETX07ELECIDLE; + output [1:0] PIPETX07EQCONTROL; + output [5:0] PIPETX07EQDEEMPH; + output [1:0] PIPETX07POWERDOWN; + output PIPETX07STARTBLOCK; + output [1:0] PIPETX07SYNCHEADER; + output [1:0] PIPETX08CHARISK; + output PIPETX08COMPLIANCE; + output [31:0] PIPETX08DATA; + output PIPETX08DATAVALID; + output PIPETX08ELECIDLE; + output [1:0] PIPETX08EQCONTROL; + output [5:0] PIPETX08EQDEEMPH; + output [1:0] PIPETX08POWERDOWN; + output PIPETX08STARTBLOCK; + output [1:0] PIPETX08SYNCHEADER; + output [1:0] PIPETX09CHARISK; + output PIPETX09COMPLIANCE; + output [31:0] PIPETX09DATA; + output PIPETX09DATAVALID; + output PIPETX09ELECIDLE; + output [1:0] PIPETX09EQCONTROL; + output [5:0] PIPETX09EQDEEMPH; + output [1:0] PIPETX09POWERDOWN; + output PIPETX09STARTBLOCK; + output [1:0] PIPETX09SYNCHEADER; + output [1:0] PIPETX10CHARISK; + output PIPETX10COMPLIANCE; + output [31:0] PIPETX10DATA; + output PIPETX10DATAVALID; + output PIPETX10ELECIDLE; + output [1:0] PIPETX10EQCONTROL; + output [5:0] PIPETX10EQDEEMPH; + output [1:0] PIPETX10POWERDOWN; + output PIPETX10STARTBLOCK; + output [1:0] PIPETX10SYNCHEADER; + output [1:0] PIPETX11CHARISK; + output PIPETX11COMPLIANCE; + output [31:0] PIPETX11DATA; + output PIPETX11DATAVALID; + output PIPETX11ELECIDLE; + output [1:0] PIPETX11EQCONTROL; + output [5:0] PIPETX11EQDEEMPH; + output [1:0] PIPETX11POWERDOWN; + output PIPETX11STARTBLOCK; + output [1:0] PIPETX11SYNCHEADER; + output [1:0] PIPETX12CHARISK; + output PIPETX12COMPLIANCE; + output [31:0] PIPETX12DATA; + output PIPETX12DATAVALID; + output PIPETX12ELECIDLE; + output [1:0] PIPETX12EQCONTROL; + output [5:0] PIPETX12EQDEEMPH; + output [1:0] PIPETX12POWERDOWN; + output PIPETX12STARTBLOCK; + output [1:0] PIPETX12SYNCHEADER; + output [1:0] PIPETX13CHARISK; + output PIPETX13COMPLIANCE; + output [31:0] PIPETX13DATA; + output PIPETX13DATAVALID; + output PIPETX13ELECIDLE; + output [1:0] PIPETX13EQCONTROL; + output [5:0] PIPETX13EQDEEMPH; + output [1:0] PIPETX13POWERDOWN; + output PIPETX13STARTBLOCK; + output [1:0] PIPETX13SYNCHEADER; + output [1:0] PIPETX14CHARISK; + output PIPETX14COMPLIANCE; + output [31:0] PIPETX14DATA; + output PIPETX14DATAVALID; + output PIPETX14ELECIDLE; + output [1:0] PIPETX14EQCONTROL; + output [5:0] PIPETX14EQDEEMPH; + output [1:0] PIPETX14POWERDOWN; + output PIPETX14STARTBLOCK; + output [1:0] PIPETX14SYNCHEADER; + output [1:0] PIPETX15CHARISK; + output PIPETX15COMPLIANCE; + output [31:0] PIPETX15DATA; + output PIPETX15DATAVALID; + output PIPETX15ELECIDLE; + output [1:0] PIPETX15EQCONTROL; + output [5:0] PIPETX15EQDEEMPH; + output [1:0] PIPETX15POWERDOWN; + output PIPETX15STARTBLOCK; + output [1:0] PIPETX15SYNCHEADER; + output PIPETXDEEMPH; + output [2:0] PIPETXMARGIN; + output [1:0] PIPETXRATE; + output PIPETXRCVRDET; + output PIPETXRESET; + output PIPETXSWING; + output PLEQINPROGRESS; + output [1:0] PLEQPHASE; + output PLGEN34EQMISMATCH; + output [3:0] SAXISCCTREADY; + output [3:0] SAXISRQTREADY; + output [23:0] USERSPAREOUT; + input [7:0] AXIUSERIN; + input CCIXOPTIMIZEDTLPTXANDRXENABLE; + input CCIXRXCORRECTABLEERRORDETECTED; + input CCIXRXFIFOOVERFLOW; + input CCIXRXTLPFORWARDED0; + input CCIXRXTLPFORWARDED1; + input [5:0] CCIXRXTLPFORWARDEDLENGTH0; + input [5:0] CCIXRXTLPFORWARDEDLENGTH1; + input CCIXRXUNCORRECTABLEERRORDETECTED; + input CFGCONFIGSPACEENABLE; + input [15:0] CFGDEVIDPF0; + input [15:0] CFGDEVIDPF1; + input [15:0] CFGDEVIDPF2; + input [15:0] CFGDEVIDPF3; + input [7:0] CFGDSBUSNUMBER; + input [4:0] CFGDSDEVICENUMBER; + input [2:0] CFGDSFUNCTIONNUMBER; + input [63:0] CFGDSN; + input [7:0] CFGDSPORTNUMBER; + input CFGERRCORIN; + input CFGERRUNCORIN; + input [31:0] CFGEXTREADDATA; + input CFGEXTREADDATAVALID; + input [2:0] CFGFCSEL; + input CFGFCVCSEL; + input [3:0] CFGFLRDONE; + input CFGHOTRESETIN; + input [3:0] CFGINTERRUPTINT; + input [2:0] CFGINTERRUPTMSIATTR; + input [7:0] CFGINTERRUPTMSIFUNCTIONNUMBER; + input [31:0] CFGINTERRUPTMSIINT; + input [31:0] CFGINTERRUPTMSIPENDINGSTATUS; + input CFGINTERRUPTMSIPENDINGSTATUSDATAENABLE; + input [1:0] CFGINTERRUPTMSIPENDINGSTATUSFUNCTIONNUM; + input [1:0] CFGINTERRUPTMSISELECT; + input CFGINTERRUPTMSITPHPRESENT; + input [7:0] CFGINTERRUPTMSITPHSTTAG; + input [1:0] CFGINTERRUPTMSITPHTYPE; + input [63:0] CFGINTERRUPTMSIXADDRESS; + input [31:0] CFGINTERRUPTMSIXDATA; + input CFGINTERRUPTMSIXINT; + input [1:0] CFGINTERRUPTMSIXVECPENDING; + input [3:0] CFGINTERRUPTPENDING; + input CFGLINKTRAININGENABLE; + input [9:0] CFGMGMTADDR; + input [3:0] CFGMGMTBYTEENABLE; + input CFGMGMTDEBUGACCESS; + input [7:0] CFGMGMTFUNCTIONNUMBER; + input CFGMGMTREAD; + input CFGMGMTWRITE; + input [31:0] CFGMGMTWRITEDATA; + input CFGMSGTRANSMIT; + input [31:0] CFGMSGTRANSMITDATA; + input [2:0] CFGMSGTRANSMITTYPE; + input [35:0] CFGMSIXRAMREADDATA; + input CFGPMASPML1ENTRYREJECT; + input CFGPMASPMTXL0SENTRYDISABLE; + input CFGPOWERSTATECHANGEACK; + input CFGREQPMTRANSITIONL23READY; + input [7:0] CFGREVIDPF0; + input [7:0] CFGREVIDPF1; + input [7:0] CFGREVIDPF2; + input [7:0] CFGREVIDPF3; + input [15:0] CFGSUBSYSIDPF0; + input [15:0] CFGSUBSYSIDPF1; + input [15:0] CFGSUBSYSIDPF2; + input [15:0] CFGSUBSYSIDPF3; + input [15:0] CFGSUBSYSVENDID; + input [35:0] CFGTPHRAMREADDATA; + input [15:0] CFGVENDID; + input CFGVFFLRDONE; + input [7:0] CFGVFFLRFUNCNUM; + input CONFMCAPREQUESTBYCONF; + input [31:0] CONFREQDATA; + input [3:0] CONFREQREGNUM; + input [1:0] CONFREQTYPE; + input CONFREQVALID; + input CORECLK; + input CORECLKCCIX; + input CORECLKMIREPLAYRAM0; + input CORECLKMIREPLAYRAM1; + input CORECLKMIRXCOMPLETIONRAM0; + input CORECLKMIRXCOMPLETIONRAM1; + input CORECLKMIRXPOSTEDREQUESTRAM0; + input CORECLKMIRXPOSTEDREQUESTRAM1; + input [5:0] DBGSEL0; + input [5:0] DBGSEL1; + input [9:0] DRPADDR; + input DRPCLK; + input [15:0] DRPDI; + input DRPEN; + input DRPWE; + input [21:0] MAXISCQTREADY; + input [21:0] MAXISRCTREADY; + input MCAPCLK; + input MCAPPERST0B; + input MCAPPERST1B; + input MGMTRESETN; + input MGMTSTICKYRESETN; + input [5:0] MIREPLAYRAMERRCOR; + input [5:0] MIREPLAYRAMERRUNCOR; + input [127:0] MIREPLAYRAMREADDATA0; + input [127:0] MIREPLAYRAMREADDATA1; + input [11:0] MIRXCOMPLETIONRAMERRCOR; + input [11:0] MIRXCOMPLETIONRAMERRUNCOR; + input [143:0] MIRXCOMPLETIONRAMREADDATA0; + input [143:0] MIRXCOMPLETIONRAMREADDATA1; + input [5:0] MIRXPOSTEDREQUESTRAMERRCOR; + input [5:0] MIRXPOSTEDREQUESTRAMERRUNCOR; + input [143:0] MIRXPOSTEDREQUESTRAMREADDATA0; + input [143:0] MIRXPOSTEDREQUESTRAMREADDATA1; + input [1:0] PCIECOMPLDELIVERED; + input [7:0] PCIECOMPLDELIVEREDTAG0; + input [7:0] PCIECOMPLDELIVEREDTAG1; + input [1:0] PCIECQNPREQ; + input PCIECQNPUSERCREDITRCVD; + input PCIECQPIPELINEEMPTY; + input PCIEPOSTEDREQDELIVERED; + input PIPECLK; + input PIPECLKEN; + input [5:0] PIPEEQFS; + input [5:0] PIPEEQLF; + input PIPERESETN; + input [1:0] PIPERX00CHARISK; + input [31:0] PIPERX00DATA; + input PIPERX00DATAVALID; + input PIPERX00ELECIDLE; + input PIPERX00EQDONE; + input PIPERX00EQLPADAPTDONE; + input PIPERX00EQLPLFFSSEL; + input [17:0] PIPERX00EQLPNEWTXCOEFFORPRESET; + input PIPERX00PHYSTATUS; + input [1:0] PIPERX00STARTBLOCK; + input [2:0] PIPERX00STATUS; + input [1:0] PIPERX00SYNCHEADER; + input PIPERX00VALID; + input [1:0] PIPERX01CHARISK; + input [31:0] PIPERX01DATA; + input PIPERX01DATAVALID; + input PIPERX01ELECIDLE; + input PIPERX01EQDONE; + input PIPERX01EQLPADAPTDONE; + input PIPERX01EQLPLFFSSEL; + input [17:0] PIPERX01EQLPNEWTXCOEFFORPRESET; + input PIPERX01PHYSTATUS; + input [1:0] PIPERX01STARTBLOCK; + input [2:0] PIPERX01STATUS; + input [1:0] PIPERX01SYNCHEADER; + input PIPERX01VALID; + input [1:0] PIPERX02CHARISK; + input [31:0] PIPERX02DATA; + input PIPERX02DATAVALID; + input PIPERX02ELECIDLE; + input PIPERX02EQDONE; + input PIPERX02EQLPADAPTDONE; + input PIPERX02EQLPLFFSSEL; + input [17:0] PIPERX02EQLPNEWTXCOEFFORPRESET; + input PIPERX02PHYSTATUS; + input [1:0] PIPERX02STARTBLOCK; + input [2:0] PIPERX02STATUS; + input [1:0] PIPERX02SYNCHEADER; + input PIPERX02VALID; + input [1:0] PIPERX03CHARISK; + input [31:0] PIPERX03DATA; + input PIPERX03DATAVALID; + input PIPERX03ELECIDLE; + input PIPERX03EQDONE; + input PIPERX03EQLPADAPTDONE; + input PIPERX03EQLPLFFSSEL; + input [17:0] PIPERX03EQLPNEWTXCOEFFORPRESET; + input PIPERX03PHYSTATUS; + input [1:0] PIPERX03STARTBLOCK; + input [2:0] PIPERX03STATUS; + input [1:0] PIPERX03SYNCHEADER; + input PIPERX03VALID; + input [1:0] PIPERX04CHARISK; + input [31:0] PIPERX04DATA; + input PIPERX04DATAVALID; + input PIPERX04ELECIDLE; + input PIPERX04EQDONE; + input PIPERX04EQLPADAPTDONE; + input PIPERX04EQLPLFFSSEL; + input [17:0] PIPERX04EQLPNEWTXCOEFFORPRESET; + input PIPERX04PHYSTATUS; + input [1:0] PIPERX04STARTBLOCK; + input [2:0] PIPERX04STATUS; + input [1:0] PIPERX04SYNCHEADER; + input PIPERX04VALID; + input [1:0] PIPERX05CHARISK; + input [31:0] PIPERX05DATA; + input PIPERX05DATAVALID; + input PIPERX05ELECIDLE; + input PIPERX05EQDONE; + input PIPERX05EQLPADAPTDONE; + input PIPERX05EQLPLFFSSEL; + input [17:0] PIPERX05EQLPNEWTXCOEFFORPRESET; + input PIPERX05PHYSTATUS; + input [1:0] PIPERX05STARTBLOCK; + input [2:0] PIPERX05STATUS; + input [1:0] PIPERX05SYNCHEADER; + input PIPERX05VALID; + input [1:0] PIPERX06CHARISK; + input [31:0] PIPERX06DATA; + input PIPERX06DATAVALID; + input PIPERX06ELECIDLE; + input PIPERX06EQDONE; + input PIPERX06EQLPADAPTDONE; + input PIPERX06EQLPLFFSSEL; + input [17:0] PIPERX06EQLPNEWTXCOEFFORPRESET; + input PIPERX06PHYSTATUS; + input [1:0] PIPERX06STARTBLOCK; + input [2:0] PIPERX06STATUS; + input [1:0] PIPERX06SYNCHEADER; + input PIPERX06VALID; + input [1:0] PIPERX07CHARISK; + input [31:0] PIPERX07DATA; + input PIPERX07DATAVALID; + input PIPERX07ELECIDLE; + input PIPERX07EQDONE; + input PIPERX07EQLPADAPTDONE; + input PIPERX07EQLPLFFSSEL; + input [17:0] PIPERX07EQLPNEWTXCOEFFORPRESET; + input PIPERX07PHYSTATUS; + input [1:0] PIPERX07STARTBLOCK; + input [2:0] PIPERX07STATUS; + input [1:0] PIPERX07SYNCHEADER; + input PIPERX07VALID; + input [1:0] PIPERX08CHARISK; + input [31:0] PIPERX08DATA; + input PIPERX08DATAVALID; + input PIPERX08ELECIDLE; + input PIPERX08EQDONE; + input PIPERX08EQLPADAPTDONE; + input PIPERX08EQLPLFFSSEL; + input [17:0] PIPERX08EQLPNEWTXCOEFFORPRESET; + input PIPERX08PHYSTATUS; + input [1:0] PIPERX08STARTBLOCK; + input [2:0] PIPERX08STATUS; + input [1:0] PIPERX08SYNCHEADER; + input PIPERX08VALID; + input [1:0] PIPERX09CHARISK; + input [31:0] PIPERX09DATA; + input PIPERX09DATAVALID; + input PIPERX09ELECIDLE; + input PIPERX09EQDONE; + input PIPERX09EQLPADAPTDONE; + input PIPERX09EQLPLFFSSEL; + input [17:0] PIPERX09EQLPNEWTXCOEFFORPRESET; + input PIPERX09PHYSTATUS; + input [1:0] PIPERX09STARTBLOCK; + input [2:0] PIPERX09STATUS; + input [1:0] PIPERX09SYNCHEADER; + input PIPERX09VALID; + input [1:0] PIPERX10CHARISK; + input [31:0] PIPERX10DATA; + input PIPERX10DATAVALID; + input PIPERX10ELECIDLE; + input PIPERX10EQDONE; + input PIPERX10EQLPADAPTDONE; + input PIPERX10EQLPLFFSSEL; + input [17:0] PIPERX10EQLPNEWTXCOEFFORPRESET; + input PIPERX10PHYSTATUS; + input [1:0] PIPERX10STARTBLOCK; + input [2:0] PIPERX10STATUS; + input [1:0] PIPERX10SYNCHEADER; + input PIPERX10VALID; + input [1:0] PIPERX11CHARISK; + input [31:0] PIPERX11DATA; + input PIPERX11DATAVALID; + input PIPERX11ELECIDLE; + input PIPERX11EQDONE; + input PIPERX11EQLPADAPTDONE; + input PIPERX11EQLPLFFSSEL; + input [17:0] PIPERX11EQLPNEWTXCOEFFORPRESET; + input PIPERX11PHYSTATUS; + input [1:0] PIPERX11STARTBLOCK; + input [2:0] PIPERX11STATUS; + input [1:0] PIPERX11SYNCHEADER; + input PIPERX11VALID; + input [1:0] PIPERX12CHARISK; + input [31:0] PIPERX12DATA; + input PIPERX12DATAVALID; + input PIPERX12ELECIDLE; + input PIPERX12EQDONE; + input PIPERX12EQLPADAPTDONE; + input PIPERX12EQLPLFFSSEL; + input [17:0] PIPERX12EQLPNEWTXCOEFFORPRESET; + input PIPERX12PHYSTATUS; + input [1:0] PIPERX12STARTBLOCK; + input [2:0] PIPERX12STATUS; + input [1:0] PIPERX12SYNCHEADER; + input PIPERX12VALID; + input [1:0] PIPERX13CHARISK; + input [31:0] PIPERX13DATA; + input PIPERX13DATAVALID; + input PIPERX13ELECIDLE; + input PIPERX13EQDONE; + input PIPERX13EQLPADAPTDONE; + input PIPERX13EQLPLFFSSEL; + input [17:0] PIPERX13EQLPNEWTXCOEFFORPRESET; + input PIPERX13PHYSTATUS; + input [1:0] PIPERX13STARTBLOCK; + input [2:0] PIPERX13STATUS; + input [1:0] PIPERX13SYNCHEADER; + input PIPERX13VALID; + input [1:0] PIPERX14CHARISK; + input [31:0] PIPERX14DATA; + input PIPERX14DATAVALID; + input PIPERX14ELECIDLE; + input PIPERX14EQDONE; + input PIPERX14EQLPADAPTDONE; + input PIPERX14EQLPLFFSSEL; + input [17:0] PIPERX14EQLPNEWTXCOEFFORPRESET; + input PIPERX14PHYSTATUS; + input [1:0] PIPERX14STARTBLOCK; + input [2:0] PIPERX14STATUS; + input [1:0] PIPERX14SYNCHEADER; + input PIPERX14VALID; + input [1:0] PIPERX15CHARISK; + input [31:0] PIPERX15DATA; + input PIPERX15DATAVALID; + input PIPERX15ELECIDLE; + input PIPERX15EQDONE; + input PIPERX15EQLPADAPTDONE; + input PIPERX15EQLPLFFSSEL; + input [17:0] PIPERX15EQLPNEWTXCOEFFORPRESET; + input PIPERX15PHYSTATUS; + input [1:0] PIPERX15STARTBLOCK; + input [2:0] PIPERX15STATUS; + input [1:0] PIPERX15SYNCHEADER; + input PIPERX15VALID; + input [17:0] PIPETX00EQCOEFF; + input PIPETX00EQDONE; + input [17:0] PIPETX01EQCOEFF; + input PIPETX01EQDONE; + input [17:0] PIPETX02EQCOEFF; + input PIPETX02EQDONE; + input [17:0] PIPETX03EQCOEFF; + input PIPETX03EQDONE; + input [17:0] PIPETX04EQCOEFF; + input PIPETX04EQDONE; + input [17:0] PIPETX05EQCOEFF; + input PIPETX05EQDONE; + input [17:0] PIPETX06EQCOEFF; + input PIPETX06EQDONE; + input [17:0] PIPETX07EQCOEFF; + input PIPETX07EQDONE; + input [17:0] PIPETX08EQCOEFF; + input PIPETX08EQDONE; + input [17:0] PIPETX09EQCOEFF; + input PIPETX09EQDONE; + input [17:0] PIPETX10EQCOEFF; + input PIPETX10EQDONE; + input [17:0] PIPETX11EQCOEFF; + input PIPETX11EQDONE; + input [17:0] PIPETX12EQCOEFF; + input PIPETX12EQDONE; + input [17:0] PIPETX13EQCOEFF; + input PIPETX13EQDONE; + input [17:0] PIPETX14EQCOEFF; + input PIPETX14EQDONE; + input [17:0] PIPETX15EQCOEFF; + input PIPETX15EQDONE; + input PLEQRESETEIEOSCOUNT; + input PLGEN2UPSTREAMPREFERDEEMPH; + input PLGEN34REDOEQSPEED; + input PLGEN34REDOEQUALIZATION; + input RESETN; + input [255:0] SAXISCCIXTXTDATA; + input [45:0] SAXISCCIXTXTUSER; + input SAXISCCIXTXTVALID; + input [255:0] SAXISCCTDATA; + input [7:0] SAXISCCTKEEP; + input SAXISCCTLAST; + input [32:0] SAXISCCTUSER; + input SAXISCCTVALID; + input [255:0] SAXISRQTDATA; + input [7:0] SAXISRQTKEEP; + input SAXISRQTLAST; + input [61:0] SAXISRQTUSER; + input SAXISRQTVALID; + input USERCLK; + input USERCLK2; + input USERCLKEN; + input [31:0] USERSPAREIN; +endmodule + +module EMAC (...); + parameter EMAC0_MODE = "RGMII"; + parameter EMAC1_MODE = "RGMII"; + output DCRHOSTDONEIR; + output EMAC0CLIENTANINTERRUPT; + output EMAC0CLIENTRXBADFRAME; + output EMAC0CLIENTRXCLIENTCLKOUT; + output EMAC0CLIENTRXDVLD; + output EMAC0CLIENTRXDVLDMSW; + output EMAC0CLIENTRXDVREG6; + output EMAC0CLIENTRXFRAMEDROP; + output EMAC0CLIENTRXGOODFRAME; + output EMAC0CLIENTRXSTATSBYTEVLD; + output EMAC0CLIENTRXSTATSVLD; + output EMAC0CLIENTTXACK; + output EMAC0CLIENTTXCLIENTCLKOUT; + output EMAC0CLIENTTXCOLLISION; + output EMAC0CLIENTTXGMIIMIICLKOUT; + output EMAC0CLIENTTXRETRANSMIT; + output EMAC0CLIENTTXSTATS; + output EMAC0CLIENTTXSTATSBYTEVLD; + output EMAC0CLIENTTXSTATSVLD; + output EMAC0PHYENCOMMAALIGN; + output EMAC0PHYLOOPBACKMSB; + output EMAC0PHYMCLKOUT; + output EMAC0PHYMDOUT; + output EMAC0PHYMDTRI; + output EMAC0PHYMGTRXRESET; + output EMAC0PHYMGTTXRESET; + output EMAC0PHYPOWERDOWN; + output EMAC0PHYSYNCACQSTATUS; + output EMAC0PHYTXCHARDISPMODE; + output EMAC0PHYTXCHARDISPVAL; + output EMAC0PHYTXCHARISK; + output EMAC0PHYTXCLK; + output EMAC0PHYTXEN; + output EMAC0PHYTXER; + output EMAC1CLIENTANINTERRUPT; + output EMAC1CLIENTRXBADFRAME; + output EMAC1CLIENTRXCLIENTCLKOUT; + output EMAC1CLIENTRXDVLD; + output EMAC1CLIENTRXDVLDMSW; + output EMAC1CLIENTRXDVREG6; + output EMAC1CLIENTRXFRAMEDROP; + output EMAC1CLIENTRXGOODFRAME; + output EMAC1CLIENTRXSTATSBYTEVLD; + output EMAC1CLIENTRXSTATSVLD; + output EMAC1CLIENTTXACK; + output EMAC1CLIENTTXCLIENTCLKOUT; + output EMAC1CLIENTTXCOLLISION; + output EMAC1CLIENTTXGMIIMIICLKOUT; + output EMAC1CLIENTTXRETRANSMIT; + output EMAC1CLIENTTXSTATS; + output EMAC1CLIENTTXSTATSBYTEVLD; + output EMAC1CLIENTTXSTATSVLD; + output EMAC1PHYENCOMMAALIGN; + output EMAC1PHYLOOPBACKMSB; + output EMAC1PHYMCLKOUT; + output EMAC1PHYMDOUT; + output EMAC1PHYMDTRI; + output EMAC1PHYMGTRXRESET; + output EMAC1PHYMGTTXRESET; + output EMAC1PHYPOWERDOWN; + output EMAC1PHYSYNCACQSTATUS; + output EMAC1PHYTXCHARDISPMODE; + output EMAC1PHYTXCHARDISPVAL; + output EMAC1PHYTXCHARISK; + output EMAC1PHYTXCLK; + output EMAC1PHYTXEN; + output EMAC1PHYTXER; + output EMACDCRACK; + output HOSTMIIMRDY; + output [0:31] EMACDCRDBUS; + output [15:0] EMAC0CLIENTRXD; + output [15:0] EMAC1CLIENTRXD; + output [31:0] HOSTRDDATA; + output [6:0] EMAC0CLIENTRXSTATS; + output [6:0] EMAC1CLIENTRXSTATS; + output [7:0] EMAC0PHYTXD; + output [7:0] EMAC1PHYTXD; + input CLIENTEMAC0DCMLOCKED; + input CLIENTEMAC0PAUSEREQ; + input CLIENTEMAC0RXCLIENTCLKIN; + input CLIENTEMAC0TXCLIENTCLKIN; + input CLIENTEMAC0TXDVLD; + input CLIENTEMAC0TXDVLDMSW; + input CLIENTEMAC0TXFIRSTBYTE; + input CLIENTEMAC0TXGMIIMIICLKIN; + input CLIENTEMAC0TXUNDERRUN; + input CLIENTEMAC1DCMLOCKED; + input CLIENTEMAC1PAUSEREQ; + input CLIENTEMAC1RXCLIENTCLKIN; + input CLIENTEMAC1TXCLIENTCLKIN; + input CLIENTEMAC1TXDVLD; + input CLIENTEMAC1TXDVLDMSW; + input CLIENTEMAC1TXFIRSTBYTE; + input CLIENTEMAC1TXGMIIMIICLKIN; + input CLIENTEMAC1TXUNDERRUN; + input DCREMACCLK; + input DCREMACENABLE; + input DCREMACREAD; + input DCREMACWRITE; + input HOSTCLK; + input HOSTEMAC1SEL; + input HOSTMIIMSEL; + input HOSTREQ; + input PHYEMAC0COL; + input PHYEMAC0CRS; + input PHYEMAC0GTXCLK; + input PHYEMAC0MCLKIN; + input PHYEMAC0MDIN; + input PHYEMAC0MIITXCLK; + input PHYEMAC0RXBUFERR; + input PHYEMAC0RXCHARISCOMMA; + input PHYEMAC0RXCHARISK; + input PHYEMAC0RXCHECKINGCRC; + input PHYEMAC0RXCLK; + input PHYEMAC0RXCOMMADET; + input PHYEMAC0RXDISPERR; + input PHYEMAC0RXDV; + input PHYEMAC0RXER; + input PHYEMAC0RXNOTINTABLE; + input PHYEMAC0RXRUNDISP; + input PHYEMAC0SIGNALDET; + input PHYEMAC0TXBUFERR; + input PHYEMAC1COL; + input PHYEMAC1CRS; + input PHYEMAC1GTXCLK; + input PHYEMAC1MCLKIN; + input PHYEMAC1MDIN; + input PHYEMAC1MIITXCLK; + input PHYEMAC1RXBUFERR; + input PHYEMAC1RXCHARISCOMMA; + input PHYEMAC1RXCHARISK; + input PHYEMAC1RXCHECKINGCRC; + input PHYEMAC1RXCLK; + input PHYEMAC1RXCOMMADET; + input PHYEMAC1RXDISPERR; + input PHYEMAC1RXDV; + input PHYEMAC1RXER; + input PHYEMAC1RXNOTINTABLE; + input PHYEMAC1RXRUNDISP; + input PHYEMAC1SIGNALDET; + input PHYEMAC1TXBUFERR; + input RESET; + input [0:31] DCREMACDBUS; + input [15:0] CLIENTEMAC0PAUSEVAL; + input [15:0] CLIENTEMAC0TXD; + input [15:0] CLIENTEMAC1PAUSEVAL; + input [15:0] CLIENTEMAC1TXD; + input [1:0] HOSTOPCODE; + input [1:0] PHYEMAC0RXBUFSTATUS; + input [1:0] PHYEMAC0RXLOSSOFSYNC; + input [1:0] PHYEMAC1RXBUFSTATUS; + input [1:0] PHYEMAC1RXLOSSOFSYNC; + input [2:0] PHYEMAC0RXCLKCORCNT; + input [2:0] PHYEMAC1RXCLKCORCNT; + input [31:0] HOSTWRDATA; + input [47:0] TIEEMAC0UNICASTADDR; + input [47:0] TIEEMAC1UNICASTADDR; + input [4:0] PHYEMAC0PHYAD; + input [4:0] PHYEMAC1PHYAD; + input [79:0] TIEEMAC0CONFIGVEC; + input [79:0] TIEEMAC1CONFIGVEC; + input [7:0] CLIENTEMAC0TXIFGDELAY; + input [7:0] CLIENTEMAC1TXIFGDELAY; + input [7:0] PHYEMAC0RXD; + input [7:0] PHYEMAC1RXD; + input [8:9] DCREMACABUS; + input [9:0] HOSTADDR; +endmodule + +module TEMAC (...); + parameter EMAC0_1000BASEX_ENABLE = "FALSE"; + parameter EMAC0_ADDRFILTER_ENABLE = "FALSE"; + parameter EMAC0_BYTEPHY = "FALSE"; + parameter EMAC0_CONFIGVEC_79 = "FALSE"; + parameter EMAC0_GTLOOPBACK = "FALSE"; + parameter EMAC0_HOST_ENABLE = "FALSE"; + parameter EMAC0_LTCHECK_DISABLE = "FALSE"; + parameter EMAC0_MDIO_ENABLE = "FALSE"; + parameter EMAC0_PHYINITAUTONEG_ENABLE = "FALSE"; + parameter EMAC0_PHYISOLATE = "FALSE"; + parameter EMAC0_PHYLOOPBACKMSB = "FALSE"; + parameter EMAC0_PHYPOWERDOWN = "FALSE"; + parameter EMAC0_PHYRESET = "FALSE"; + parameter EMAC0_RGMII_ENABLE = "FALSE"; + parameter EMAC0_RX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC0_RXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC0_RXHALFDUPLEX = "FALSE"; + parameter EMAC0_RXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC0_RXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC0_RXRESET = "FALSE"; + parameter EMAC0_RXVLAN_ENABLE = "FALSE"; + parameter EMAC0_RX_ENABLE = "FALSE"; + parameter EMAC0_SGMII_ENABLE = "FALSE"; + parameter EMAC0_SPEED_LSB = "FALSE"; + parameter EMAC0_SPEED_MSB = "FALSE"; + parameter EMAC0_TX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC0_TXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC0_TXHALFDUPLEX = "FALSE"; + parameter EMAC0_TXIFGADJUST_ENABLE = "FALSE"; + parameter EMAC0_TXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC0_TXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC0_TXRESET = "FALSE"; + parameter EMAC0_TXVLAN_ENABLE = "FALSE"; + parameter EMAC0_TX_ENABLE = "FALSE"; + parameter EMAC0_UNIDIRECTION_ENABLE = "FALSE"; + parameter EMAC0_USECLKEN = "FALSE"; + parameter EMAC1_1000BASEX_ENABLE = "FALSE"; + parameter EMAC1_ADDRFILTER_ENABLE = "FALSE"; + parameter EMAC1_BYTEPHY = "FALSE"; + parameter EMAC1_CONFIGVEC_79 = "FALSE"; + parameter EMAC1_GTLOOPBACK = "FALSE"; + parameter EMAC1_HOST_ENABLE = "FALSE"; + parameter EMAC1_LTCHECK_DISABLE = "FALSE"; + parameter EMAC1_MDIO_ENABLE = "FALSE"; + parameter EMAC1_PHYINITAUTONEG_ENABLE = "FALSE"; + parameter EMAC1_PHYISOLATE = "FALSE"; + parameter EMAC1_PHYLOOPBACKMSB = "FALSE"; + parameter EMAC1_PHYPOWERDOWN = "FALSE"; + parameter EMAC1_PHYRESET = "FALSE"; + parameter EMAC1_RGMII_ENABLE = "FALSE"; + parameter EMAC1_RX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC1_RXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC1_RXHALFDUPLEX = "FALSE"; + parameter EMAC1_RXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC1_RXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC1_RXRESET = "FALSE"; + parameter EMAC1_RXVLAN_ENABLE = "FALSE"; + parameter EMAC1_RX_ENABLE = "FALSE"; + parameter EMAC1_SGMII_ENABLE = "FALSE"; + parameter EMAC1_SPEED_LSB = "FALSE"; + parameter EMAC1_SPEED_MSB = "FALSE"; + parameter EMAC1_TX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC1_TXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC1_TXHALFDUPLEX = "FALSE"; + parameter EMAC1_TXIFGADJUST_ENABLE = "FALSE"; + parameter EMAC1_TXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC1_TXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC1_TXRESET = "FALSE"; + parameter EMAC1_TXVLAN_ENABLE = "FALSE"; + parameter EMAC1_TX_ENABLE = "FALSE"; + parameter EMAC1_UNIDIRECTION_ENABLE = "FALSE"; + parameter EMAC1_USECLKEN = "FALSE"; + parameter [0:7] EMAC0_DCRBASEADDR = 8'h00; + parameter [0:7] EMAC1_DCRBASEADDR = 8'h00; + parameter [47:0] EMAC0_PAUSEADDR = 48'h000000000000; + parameter [47:0] EMAC0_UNICASTADDR = 48'h000000000000; + parameter [47:0] EMAC1_PAUSEADDR = 48'h000000000000; + parameter [47:0] EMAC1_UNICASTADDR = 48'h000000000000; + parameter [8:0] EMAC0_LINKTIMERVAL = 9'h000; + parameter [8:0] EMAC1_LINKTIMERVAL = 9'h000; + output DCRHOSTDONEIR; + output EMAC0CLIENTANINTERRUPT; + output EMAC0CLIENTRXBADFRAME; + output EMAC0CLIENTRXCLIENTCLKOUT; + output EMAC0CLIENTRXDVLD; + output EMAC0CLIENTRXDVLDMSW; + output EMAC0CLIENTRXFRAMEDROP; + output EMAC0CLIENTRXGOODFRAME; + output EMAC0CLIENTRXSTATSBYTEVLD; + output EMAC0CLIENTRXSTATSVLD; + output EMAC0CLIENTTXACK; + output EMAC0CLIENTTXCLIENTCLKOUT; + output EMAC0CLIENTTXCOLLISION; + output EMAC0CLIENTTXRETRANSMIT; + output EMAC0CLIENTTXSTATS; + output EMAC0CLIENTTXSTATSBYTEVLD; + output EMAC0CLIENTTXSTATSVLD; + output EMAC0PHYENCOMMAALIGN; + output EMAC0PHYLOOPBACKMSB; + output EMAC0PHYMCLKOUT; + output EMAC0PHYMDOUT; + output EMAC0PHYMDTRI; + output EMAC0PHYMGTRXRESET; + output EMAC0PHYMGTTXRESET; + output EMAC0PHYPOWERDOWN; + output EMAC0PHYSYNCACQSTATUS; + output EMAC0PHYTXCHARDISPMODE; + output EMAC0PHYTXCHARDISPVAL; + output EMAC0PHYTXCHARISK; + output EMAC0PHYTXCLK; + output EMAC0PHYTXEN; + output EMAC0PHYTXER; + output EMAC0PHYTXGMIIMIICLKOUT; + output EMAC0SPEEDIS10100; + output EMAC1CLIENTANINTERRUPT; + output EMAC1CLIENTRXBADFRAME; + output EMAC1CLIENTRXCLIENTCLKOUT; + output EMAC1CLIENTRXDVLD; + output EMAC1CLIENTRXDVLDMSW; + output EMAC1CLIENTRXFRAMEDROP; + output EMAC1CLIENTRXGOODFRAME; + output EMAC1CLIENTRXSTATSBYTEVLD; + output EMAC1CLIENTRXSTATSVLD; + output EMAC1CLIENTTXACK; + output EMAC1CLIENTTXCLIENTCLKOUT; + output EMAC1CLIENTTXCOLLISION; + output EMAC1CLIENTTXRETRANSMIT; + output EMAC1CLIENTTXSTATS; + output EMAC1CLIENTTXSTATSBYTEVLD; + output EMAC1CLIENTTXSTATSVLD; + output EMAC1PHYENCOMMAALIGN; + output EMAC1PHYLOOPBACKMSB; + output EMAC1PHYMCLKOUT; + output EMAC1PHYMDOUT; + output EMAC1PHYMDTRI; + output EMAC1PHYMGTRXRESET; + output EMAC1PHYMGTTXRESET; + output EMAC1PHYPOWERDOWN; + output EMAC1PHYSYNCACQSTATUS; + output EMAC1PHYTXCHARDISPMODE; + output EMAC1PHYTXCHARDISPVAL; + output EMAC1PHYTXCHARISK; + output EMAC1PHYTXCLK; + output EMAC1PHYTXEN; + output EMAC1PHYTXER; + output EMAC1PHYTXGMIIMIICLKOUT; + output EMAC1SPEEDIS10100; + output EMACDCRACK; + output HOSTMIIMRDY; + output [0:31] EMACDCRDBUS; + output [15:0] EMAC0CLIENTRXD; + output [15:0] EMAC1CLIENTRXD; + output [31:0] HOSTRDDATA; + output [6:0] EMAC0CLIENTRXSTATS; + output [6:0] EMAC1CLIENTRXSTATS; + output [7:0] EMAC0PHYTXD; + output [7:0] EMAC1PHYTXD; + input CLIENTEMAC0DCMLOCKED; + input CLIENTEMAC0PAUSEREQ; + input CLIENTEMAC0RXCLIENTCLKIN; + input CLIENTEMAC0TXCLIENTCLKIN; + input CLIENTEMAC0TXDVLD; + input CLIENTEMAC0TXDVLDMSW; + input CLIENTEMAC0TXFIRSTBYTE; + input CLIENTEMAC0TXUNDERRUN; + input CLIENTEMAC1DCMLOCKED; + input CLIENTEMAC1PAUSEREQ; + input CLIENTEMAC1RXCLIENTCLKIN; + input CLIENTEMAC1TXCLIENTCLKIN; + input CLIENTEMAC1TXDVLD; + input CLIENTEMAC1TXDVLDMSW; + input CLIENTEMAC1TXFIRSTBYTE; + input CLIENTEMAC1TXUNDERRUN; + input DCREMACCLK; + input DCREMACENABLE; + input DCREMACREAD; + input DCREMACWRITE; + input HOSTCLK; + input HOSTEMAC1SEL; + input HOSTMIIMSEL; + input HOSTREQ; + input PHYEMAC0COL; + input PHYEMAC0CRS; + input PHYEMAC0GTXCLK; + input PHYEMAC0MCLKIN; + input PHYEMAC0MDIN; + input PHYEMAC0MIITXCLK; + input PHYEMAC0RXBUFERR; + input PHYEMAC0RXCHARISCOMMA; + input PHYEMAC0RXCHARISK; + input PHYEMAC0RXCHECKINGCRC; + input PHYEMAC0RXCLK; + input PHYEMAC0RXCOMMADET; + input PHYEMAC0RXDISPERR; + input PHYEMAC0RXDV; + input PHYEMAC0RXER; + input PHYEMAC0RXNOTINTABLE; + input PHYEMAC0RXRUNDISP; + input PHYEMAC0SIGNALDET; + input PHYEMAC0TXBUFERR; + input PHYEMAC0TXGMIIMIICLKIN; + input PHYEMAC1COL; + input PHYEMAC1CRS; + input PHYEMAC1GTXCLK; + input PHYEMAC1MCLKIN; + input PHYEMAC1MDIN; + input PHYEMAC1MIITXCLK; + input PHYEMAC1RXBUFERR; + input PHYEMAC1RXCHARISCOMMA; + input PHYEMAC1RXCHARISK; + input PHYEMAC1RXCHECKINGCRC; + input PHYEMAC1RXCLK; + input PHYEMAC1RXCOMMADET; + input PHYEMAC1RXDISPERR; + input PHYEMAC1RXDV; + input PHYEMAC1RXER; + input PHYEMAC1RXNOTINTABLE; + input PHYEMAC1RXRUNDISP; + input PHYEMAC1SIGNALDET; + input PHYEMAC1TXBUFERR; + input PHYEMAC1TXGMIIMIICLKIN; + input RESET; + input [0:31] DCREMACDBUS; + input [0:9] DCREMACABUS; + input [15:0] CLIENTEMAC0PAUSEVAL; + input [15:0] CLIENTEMAC0TXD; + input [15:0] CLIENTEMAC1PAUSEVAL; + input [15:0] CLIENTEMAC1TXD; + input [1:0] HOSTOPCODE; + input [1:0] PHYEMAC0RXBUFSTATUS; + input [1:0] PHYEMAC0RXLOSSOFSYNC; + input [1:0] PHYEMAC1RXBUFSTATUS; + input [1:0] PHYEMAC1RXLOSSOFSYNC; + input [2:0] PHYEMAC0RXCLKCORCNT; + input [2:0] PHYEMAC1RXCLKCORCNT; + input [31:0] HOSTWRDATA; + input [4:0] PHYEMAC0PHYAD; + input [4:0] PHYEMAC1PHYAD; + input [7:0] CLIENTEMAC0TXIFGDELAY; + input [7:0] CLIENTEMAC1TXIFGDELAY; + input [7:0] PHYEMAC0RXD; + input [7:0] PHYEMAC1RXD; + input [9:0] HOSTADDR; +endmodule + +module TEMAC_SINGLE (...); + parameter EMAC_1000BASEX_ENABLE = "FALSE"; + parameter EMAC_ADDRFILTER_ENABLE = "FALSE"; + parameter EMAC_BYTEPHY = "FALSE"; + parameter EMAC_CTRLLENCHECK_DISABLE = "FALSE"; + parameter [0:7] EMAC_DCRBASEADDR = 8'h00; + parameter EMAC_GTLOOPBACK = "FALSE"; + parameter EMAC_HOST_ENABLE = "FALSE"; + parameter [8:0] EMAC_LINKTIMERVAL = 9'h000; + parameter EMAC_LTCHECK_DISABLE = "FALSE"; + parameter EMAC_MDIO_ENABLE = "FALSE"; + parameter EMAC_MDIO_IGNORE_PHYADZERO = "FALSE"; + parameter [47:0] EMAC_PAUSEADDR = 48'h000000000000; + parameter EMAC_PHYINITAUTONEG_ENABLE = "FALSE"; + parameter EMAC_PHYISOLATE = "FALSE"; + parameter EMAC_PHYLOOPBACKMSB = "FALSE"; + parameter EMAC_PHYPOWERDOWN = "FALSE"; + parameter EMAC_PHYRESET = "FALSE"; + parameter EMAC_RGMII_ENABLE = "FALSE"; + parameter EMAC_RX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC_RXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC_RXHALFDUPLEX = "FALSE"; + parameter EMAC_RXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC_RXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC_RXRESET = "FALSE"; + parameter EMAC_RXVLAN_ENABLE = "FALSE"; + parameter EMAC_RX_ENABLE = "TRUE"; + parameter EMAC_SGMII_ENABLE = "FALSE"; + parameter EMAC_SPEED_LSB = "FALSE"; + parameter EMAC_SPEED_MSB = "FALSE"; + parameter EMAC_TX16BITCLIENT_ENABLE = "FALSE"; + parameter EMAC_TXFLOWCTRL_ENABLE = "FALSE"; + parameter EMAC_TXHALFDUPLEX = "FALSE"; + parameter EMAC_TXIFGADJUST_ENABLE = "FALSE"; + parameter EMAC_TXINBANDFCS_ENABLE = "FALSE"; + parameter EMAC_TXJUMBOFRAME_ENABLE = "FALSE"; + parameter EMAC_TXRESET = "FALSE"; + parameter EMAC_TXVLAN_ENABLE = "FALSE"; + parameter EMAC_TX_ENABLE = "TRUE"; + parameter [47:0] EMAC_UNICASTADDR = 48'h000000000000; + parameter EMAC_UNIDIRECTION_ENABLE = "FALSE"; + parameter EMAC_USECLKEN = "FALSE"; + parameter SIM_VERSION = "1.0"; + output DCRHOSTDONEIR; + output EMACCLIENTANINTERRUPT; + output EMACCLIENTRXBADFRAME; + output EMACCLIENTRXCLIENTCLKOUT; + output EMACCLIENTRXDVLD; + output EMACCLIENTRXDVLDMSW; + output EMACCLIENTRXFRAMEDROP; + output EMACCLIENTRXGOODFRAME; + output EMACCLIENTRXSTATSBYTEVLD; + output EMACCLIENTRXSTATSVLD; + output EMACCLIENTTXACK; + output EMACCLIENTTXCLIENTCLKOUT; + output EMACCLIENTTXCOLLISION; + output EMACCLIENTTXRETRANSMIT; + output EMACCLIENTTXSTATS; + output EMACCLIENTTXSTATSBYTEVLD; + output EMACCLIENTTXSTATSVLD; + output EMACDCRACK; + output EMACPHYENCOMMAALIGN; + output EMACPHYLOOPBACKMSB; + output EMACPHYMCLKOUT; + output EMACPHYMDOUT; + output EMACPHYMDTRI; + output EMACPHYMGTRXRESET; + output EMACPHYMGTTXRESET; + output EMACPHYPOWERDOWN; + output EMACPHYSYNCACQSTATUS; + output EMACPHYTXCHARDISPMODE; + output EMACPHYTXCHARDISPVAL; + output EMACPHYTXCHARISK; + output EMACPHYTXCLK; + output EMACPHYTXEN; + output EMACPHYTXER; + output EMACPHYTXGMIIMIICLKOUT; + output EMACSPEEDIS10100; + output HOSTMIIMRDY; + output [0:31] EMACDCRDBUS; + output [15:0] EMACCLIENTRXD; + output [31:0] HOSTRDDATA; + output [6:0] EMACCLIENTRXSTATS; + output [7:0] EMACPHYTXD; + input CLIENTEMACDCMLOCKED; + input CLIENTEMACPAUSEREQ; + input CLIENTEMACRXCLIENTCLKIN; + input CLIENTEMACTXCLIENTCLKIN; + input CLIENTEMACTXDVLD; + input CLIENTEMACTXDVLDMSW; + input CLIENTEMACTXFIRSTBYTE; + input CLIENTEMACTXUNDERRUN; + input DCREMACCLK; + input DCREMACENABLE; + input DCREMACREAD; + input DCREMACWRITE; + input HOSTCLK; + input HOSTMIIMSEL; + input HOSTREQ; + input PHYEMACCOL; + input PHYEMACCRS; + input PHYEMACGTXCLK; + input PHYEMACMCLKIN; + input PHYEMACMDIN; + input PHYEMACMIITXCLK; + input PHYEMACRXCHARISCOMMA; + input PHYEMACRXCHARISK; + input PHYEMACRXCLK; + input PHYEMACRXDISPERR; + input PHYEMACRXDV; + input PHYEMACRXER; + input PHYEMACRXNOTINTABLE; + input PHYEMACRXRUNDISP; + input PHYEMACSIGNALDET; + input PHYEMACTXBUFERR; + input PHYEMACTXGMIIMIICLKIN; + input RESET; + input [0:31] DCREMACDBUS; + input [0:9] DCREMACABUS; + input [15:0] CLIENTEMACPAUSEVAL; + input [15:0] CLIENTEMACTXD; + input [1:0] HOSTOPCODE; + input [1:0] PHYEMACRXBUFSTATUS; + input [2:0] PHYEMACRXCLKCORCNT; + input [31:0] HOSTWRDATA; + input [4:0] PHYEMACPHYAD; + input [7:0] CLIENTEMACTXIFGDELAY; + input [7:0] PHYEMACRXD; + input [9:0] HOSTADDR; +endmodule + +module CMAC (...); + parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; + parameter CTL_RX_CHECK_ACK = "TRUE"; + parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; + parameter CTL_RX_CHECK_SFD = "FALSE"; + parameter CTL_RX_DELETE_FCS = "TRUE"; + parameter [15:0] CTL_RX_ETYPE_GCP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_GPP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_PCP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_PPP = 16'h8808; + parameter CTL_RX_FORWARD_CONTROL = "FALSE"; + parameter CTL_RX_IGNORE_FCS = "FALSE"; + parameter [14:0] CTL_RX_MAX_PACKET_LEN = 15'h2580; + parameter [7:0] CTL_RX_MIN_PACKET_LEN = 8'h40; + parameter [15:0] CTL_RX_OPCODE_GPP = 16'h0001; + parameter [15:0] CTL_RX_OPCODE_MAX_GCP = 16'hFFFF; + parameter [15:0] CTL_RX_OPCODE_MAX_PCP = 16'hFFFF; + parameter [15:0] CTL_RX_OPCODE_MIN_GCP = 16'h0000; + parameter [15:0] CTL_RX_OPCODE_MIN_PCP = 16'h0000; + parameter [15:0] CTL_RX_OPCODE_PPP = 16'h0001; + parameter [47:0] CTL_RX_PAUSE_DA_MCAST = 48'h0180C2000001; + parameter [47:0] CTL_RX_PAUSE_DA_UCAST = 48'h000000000000; + parameter [47:0] CTL_RX_PAUSE_SA = 48'h000000000000; + parameter CTL_RX_PROCESS_LFI = "FALSE"; + parameter [15:0] CTL_RX_VL_LENGTH_MINUS1 = 16'h3FFF; + parameter [63:0] CTL_RX_VL_MARKER_ID0 = 64'hC16821003E97DE00; + parameter [63:0] CTL_RX_VL_MARKER_ID1 = 64'h9D718E00628E7100; + parameter [63:0] CTL_RX_VL_MARKER_ID10 = 64'hFD6C990002936600; + parameter [63:0] CTL_RX_VL_MARKER_ID11 = 64'hB9915500466EAA00; + parameter [63:0] CTL_RX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; + parameter [63:0] CTL_RX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; + parameter [63:0] CTL_RX_VL_MARKER_ID14 = 64'h83C7CA007C383500; + parameter [63:0] CTL_RX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; + parameter [63:0] CTL_RX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; + parameter [63:0] CTL_RX_VL_MARKER_ID17 = 64'hADD6B70052294800; + parameter [63:0] CTL_RX_VL_MARKER_ID18 = 64'h5F662A00A099D500; + parameter [63:0] CTL_RX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; + parameter [63:0] CTL_RX_VL_MARKER_ID2 = 64'h594BE800A6B41700; + parameter [63:0] CTL_RX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; + parameter [63:0] CTL_RX_VL_MARKER_ID4 = 64'hF50709000AF8F600; + parameter [63:0] CTL_RX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; + parameter [63:0] CTL_RX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; + parameter [63:0] CTL_RX_VL_MARKER_ID7 = 64'h7B45660084BA9900; + parameter [63:0] CTL_RX_VL_MARKER_ID8 = 64'hA02476005FDB8900; + parameter [63:0] CTL_RX_VL_MARKER_ID9 = 64'h68C9FB0097360400; + parameter CTL_TEST_MODE_PIN_CHAR = "FALSE"; + parameter [47:0] CTL_TX_DA_GPP = 48'h0180C2000001; + parameter [47:0] CTL_TX_DA_PPP = 48'h0180C2000001; + parameter [15:0] CTL_TX_ETHERTYPE_GPP = 16'h8808; + parameter [15:0] CTL_TX_ETHERTYPE_PPP = 16'h8808; + parameter CTL_TX_FCS_INS_ENABLE = "TRUE"; + parameter CTL_TX_IGNORE_FCS = "FALSE"; + parameter [15:0] CTL_TX_OPCODE_GPP = 16'h0001; + parameter [15:0] CTL_TX_OPCODE_PPP = 16'h0001; + parameter CTL_TX_PTP_1STEP_ENABLE = "FALSE"; + parameter [10:0] CTL_TX_PTP_LATENCY_ADJUST = 11'h2C1; + parameter [47:0] CTL_TX_SA_GPP = 48'h000000000000; + parameter [47:0] CTL_TX_SA_PPP = 48'h000000000000; + parameter [15:0] CTL_TX_VL_LENGTH_MINUS1 = 16'h3FFF; + parameter [63:0] CTL_TX_VL_MARKER_ID0 = 64'hC16821003E97DE00; + parameter [63:0] CTL_TX_VL_MARKER_ID1 = 64'h9D718E00628E7100; + parameter [63:0] CTL_TX_VL_MARKER_ID10 = 64'hFD6C990002936600; + parameter [63:0] CTL_TX_VL_MARKER_ID11 = 64'hB9915500466EAA00; + parameter [63:0] CTL_TX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; + parameter [63:0] CTL_TX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; + parameter [63:0] CTL_TX_VL_MARKER_ID14 = 64'h83C7CA007C383500; + parameter [63:0] CTL_TX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; + parameter [63:0] CTL_TX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; + parameter [63:0] CTL_TX_VL_MARKER_ID17 = 64'hADD6B70052294800; + parameter [63:0] CTL_TX_VL_MARKER_ID18 = 64'h5F662A00A099D500; + parameter [63:0] CTL_TX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; + parameter [63:0] CTL_TX_VL_MARKER_ID2 = 64'h594BE800A6B41700; + parameter [63:0] CTL_TX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; + parameter [63:0] CTL_TX_VL_MARKER_ID4 = 64'hF50709000AF8F600; + parameter [63:0] CTL_TX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; + parameter [63:0] CTL_TX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; + parameter [63:0] CTL_TX_VL_MARKER_ID7 = 64'h7B45660084BA9900; + parameter [63:0] CTL_TX_VL_MARKER_ID8 = 64'hA02476005FDB8900; + parameter [63:0] CTL_TX_VL_MARKER_ID9 = 64'h68C9FB0097360400; + parameter SIM_VERSION = "2.0"; + parameter TEST_MODE_PIN_CHAR = "FALSE"; + output [15:0] DRP_DO; + output DRP_RDY; + output [127:0] RX_DATAOUT0; + output [127:0] RX_DATAOUT1; + output [127:0] RX_DATAOUT2; + output [127:0] RX_DATAOUT3; + output RX_ENAOUT0; + output RX_ENAOUT1; + output RX_ENAOUT2; + output RX_ENAOUT3; + output RX_EOPOUT0; + output RX_EOPOUT1; + output RX_EOPOUT2; + output RX_EOPOUT3; + output RX_ERROUT0; + output RX_ERROUT1; + output RX_ERROUT2; + output RX_ERROUT3; + output [6:0] RX_LANE_ALIGNER_FILL_0; + output [6:0] RX_LANE_ALIGNER_FILL_1; + output [6:0] RX_LANE_ALIGNER_FILL_10; + output [6:0] RX_LANE_ALIGNER_FILL_11; + output [6:0] RX_LANE_ALIGNER_FILL_12; + output [6:0] RX_LANE_ALIGNER_FILL_13; + output [6:0] RX_LANE_ALIGNER_FILL_14; + output [6:0] RX_LANE_ALIGNER_FILL_15; + output [6:0] RX_LANE_ALIGNER_FILL_16; + output [6:0] RX_LANE_ALIGNER_FILL_17; + output [6:0] RX_LANE_ALIGNER_FILL_18; + output [6:0] RX_LANE_ALIGNER_FILL_19; + output [6:0] RX_LANE_ALIGNER_FILL_2; + output [6:0] RX_LANE_ALIGNER_FILL_3; + output [6:0] RX_LANE_ALIGNER_FILL_4; + output [6:0] RX_LANE_ALIGNER_FILL_5; + output [6:0] RX_LANE_ALIGNER_FILL_6; + output [6:0] RX_LANE_ALIGNER_FILL_7; + output [6:0] RX_LANE_ALIGNER_FILL_8; + output [6:0] RX_LANE_ALIGNER_FILL_9; + output [3:0] RX_MTYOUT0; + output [3:0] RX_MTYOUT1; + output [3:0] RX_MTYOUT2; + output [3:0] RX_MTYOUT3; + output [4:0] RX_PTP_PCSLANE_OUT; + output [79:0] RX_PTP_TSTAMP_OUT; + output RX_SOPOUT0; + output RX_SOPOUT1; + output RX_SOPOUT2; + output RX_SOPOUT3; + output STAT_RX_ALIGNED; + output STAT_RX_ALIGNED_ERR; + output [6:0] STAT_RX_BAD_CODE; + output [3:0] STAT_RX_BAD_FCS; + output STAT_RX_BAD_PREAMBLE; + output STAT_RX_BAD_SFD; + output STAT_RX_BIP_ERR_0; + output STAT_RX_BIP_ERR_1; + output STAT_RX_BIP_ERR_10; + output STAT_RX_BIP_ERR_11; + output STAT_RX_BIP_ERR_12; + output STAT_RX_BIP_ERR_13; + output STAT_RX_BIP_ERR_14; + output STAT_RX_BIP_ERR_15; + output STAT_RX_BIP_ERR_16; + output STAT_RX_BIP_ERR_17; + output STAT_RX_BIP_ERR_18; + output STAT_RX_BIP_ERR_19; + output STAT_RX_BIP_ERR_2; + output STAT_RX_BIP_ERR_3; + output STAT_RX_BIP_ERR_4; + output STAT_RX_BIP_ERR_5; + output STAT_RX_BIP_ERR_6; + output STAT_RX_BIP_ERR_7; + output STAT_RX_BIP_ERR_8; + output STAT_RX_BIP_ERR_9; + output [19:0] STAT_RX_BLOCK_LOCK; + output STAT_RX_BROADCAST; + output [3:0] STAT_RX_FRAGMENT; + output [3:0] STAT_RX_FRAMING_ERR_0; + output [3:0] STAT_RX_FRAMING_ERR_1; + output [3:0] STAT_RX_FRAMING_ERR_10; + output [3:0] STAT_RX_FRAMING_ERR_11; + output [3:0] STAT_RX_FRAMING_ERR_12; + output [3:0] STAT_RX_FRAMING_ERR_13; + output [3:0] STAT_RX_FRAMING_ERR_14; + output [3:0] STAT_RX_FRAMING_ERR_15; + output [3:0] STAT_RX_FRAMING_ERR_16; + output [3:0] STAT_RX_FRAMING_ERR_17; + output [3:0] STAT_RX_FRAMING_ERR_18; + output [3:0] STAT_RX_FRAMING_ERR_19; + output [3:0] STAT_RX_FRAMING_ERR_2; + output [3:0] STAT_RX_FRAMING_ERR_3; + output [3:0] STAT_RX_FRAMING_ERR_4; + output [3:0] STAT_RX_FRAMING_ERR_5; + output [3:0] STAT_RX_FRAMING_ERR_6; + output [3:0] STAT_RX_FRAMING_ERR_7; + output [3:0] STAT_RX_FRAMING_ERR_8; + output [3:0] STAT_RX_FRAMING_ERR_9; + output STAT_RX_FRAMING_ERR_VALID_0; + output STAT_RX_FRAMING_ERR_VALID_1; + output STAT_RX_FRAMING_ERR_VALID_10; + output STAT_RX_FRAMING_ERR_VALID_11; + output STAT_RX_FRAMING_ERR_VALID_12; + output STAT_RX_FRAMING_ERR_VALID_13; + output STAT_RX_FRAMING_ERR_VALID_14; + output STAT_RX_FRAMING_ERR_VALID_15; + output STAT_RX_FRAMING_ERR_VALID_16; + output STAT_RX_FRAMING_ERR_VALID_17; + output STAT_RX_FRAMING_ERR_VALID_18; + output STAT_RX_FRAMING_ERR_VALID_19; + output STAT_RX_FRAMING_ERR_VALID_2; + output STAT_RX_FRAMING_ERR_VALID_3; + output STAT_RX_FRAMING_ERR_VALID_4; + output STAT_RX_FRAMING_ERR_VALID_5; + output STAT_RX_FRAMING_ERR_VALID_6; + output STAT_RX_FRAMING_ERR_VALID_7; + output STAT_RX_FRAMING_ERR_VALID_8; + output STAT_RX_FRAMING_ERR_VALID_9; + output STAT_RX_GOT_SIGNAL_OS; + output STAT_RX_HI_BER; + output STAT_RX_INRANGEERR; + output STAT_RX_INTERNAL_LOCAL_FAULT; + output STAT_RX_JABBER; + output [7:0] STAT_RX_LANE0_VLM_BIP7; + output STAT_RX_LANE0_VLM_BIP7_VALID; + output STAT_RX_LOCAL_FAULT; + output [19:0] STAT_RX_MF_ERR; + output [19:0] STAT_RX_MF_LEN_ERR; + output [19:0] STAT_RX_MF_REPEAT_ERR; + output STAT_RX_MISALIGNED; + output STAT_RX_MULTICAST; + output STAT_RX_OVERSIZE; + output STAT_RX_PACKET_1024_1518_BYTES; + output STAT_RX_PACKET_128_255_BYTES; + output STAT_RX_PACKET_1519_1522_BYTES; + output STAT_RX_PACKET_1523_1548_BYTES; + output STAT_RX_PACKET_1549_2047_BYTES; + output STAT_RX_PACKET_2048_4095_BYTES; + output STAT_RX_PACKET_256_511_BYTES; + output STAT_RX_PACKET_4096_8191_BYTES; + output STAT_RX_PACKET_512_1023_BYTES; + output STAT_RX_PACKET_64_BYTES; + output STAT_RX_PACKET_65_127_BYTES; + output STAT_RX_PACKET_8192_9215_BYTES; + output STAT_RX_PACKET_BAD_FCS; + output STAT_RX_PACKET_LARGE; + output [3:0] STAT_RX_PACKET_SMALL; + output STAT_RX_PAUSE; + output [15:0] STAT_RX_PAUSE_QUANTA0; + output [15:0] STAT_RX_PAUSE_QUANTA1; + output [15:0] STAT_RX_PAUSE_QUANTA2; + output [15:0] STAT_RX_PAUSE_QUANTA3; + output [15:0] STAT_RX_PAUSE_QUANTA4; + output [15:0] STAT_RX_PAUSE_QUANTA5; + output [15:0] STAT_RX_PAUSE_QUANTA6; + output [15:0] STAT_RX_PAUSE_QUANTA7; + output [15:0] STAT_RX_PAUSE_QUANTA8; + output [8:0] STAT_RX_PAUSE_REQ; + output [8:0] STAT_RX_PAUSE_VALID; + output STAT_RX_RECEIVED_LOCAL_FAULT; + output STAT_RX_REMOTE_FAULT; + output STAT_RX_STATUS; + output [3:0] STAT_RX_STOMPED_FCS; + output [19:0] STAT_RX_SYNCED; + output [19:0] STAT_RX_SYNCED_ERR; + output [2:0] STAT_RX_TEST_PATTERN_MISMATCH; + output STAT_RX_TOOLONG; + output [7:0] STAT_RX_TOTAL_BYTES; + output [13:0] STAT_RX_TOTAL_GOOD_BYTES; + output STAT_RX_TOTAL_GOOD_PACKETS; + output [3:0] STAT_RX_TOTAL_PACKETS; + output STAT_RX_TRUNCATED; + output [3:0] STAT_RX_UNDERSIZE; + output STAT_RX_UNICAST; + output STAT_RX_USER_PAUSE; + output STAT_RX_VLAN; + output [19:0] STAT_RX_VL_DEMUXED; + output [4:0] STAT_RX_VL_NUMBER_0; + output [4:0] STAT_RX_VL_NUMBER_1; + output [4:0] STAT_RX_VL_NUMBER_10; + output [4:0] STAT_RX_VL_NUMBER_11; + output [4:0] STAT_RX_VL_NUMBER_12; + output [4:0] STAT_RX_VL_NUMBER_13; + output [4:0] STAT_RX_VL_NUMBER_14; + output [4:0] STAT_RX_VL_NUMBER_15; + output [4:0] STAT_RX_VL_NUMBER_16; + output [4:0] STAT_RX_VL_NUMBER_17; + output [4:0] STAT_RX_VL_NUMBER_18; + output [4:0] STAT_RX_VL_NUMBER_19; + output [4:0] STAT_RX_VL_NUMBER_2; + output [4:0] STAT_RX_VL_NUMBER_3; + output [4:0] STAT_RX_VL_NUMBER_4; + output [4:0] STAT_RX_VL_NUMBER_5; + output [4:0] STAT_RX_VL_NUMBER_6; + output [4:0] STAT_RX_VL_NUMBER_7; + output [4:0] STAT_RX_VL_NUMBER_8; + output [4:0] STAT_RX_VL_NUMBER_9; + output STAT_TX_BAD_FCS; + output STAT_TX_BROADCAST; + output STAT_TX_FRAME_ERROR; + output STAT_TX_LOCAL_FAULT; + output STAT_TX_MULTICAST; + output STAT_TX_PACKET_1024_1518_BYTES; + output STAT_TX_PACKET_128_255_BYTES; + output STAT_TX_PACKET_1519_1522_BYTES; + output STAT_TX_PACKET_1523_1548_BYTES; + output STAT_TX_PACKET_1549_2047_BYTES; + output STAT_TX_PACKET_2048_4095_BYTES; + output STAT_TX_PACKET_256_511_BYTES; + output STAT_TX_PACKET_4096_8191_BYTES; + output STAT_TX_PACKET_512_1023_BYTES; + output STAT_TX_PACKET_64_BYTES; + output STAT_TX_PACKET_65_127_BYTES; + output STAT_TX_PACKET_8192_9215_BYTES; + output STAT_TX_PACKET_LARGE; + output STAT_TX_PACKET_SMALL; + output STAT_TX_PAUSE; + output [8:0] STAT_TX_PAUSE_VALID; + output STAT_TX_PTP_FIFO_READ_ERROR; + output STAT_TX_PTP_FIFO_WRITE_ERROR; + output [6:0] STAT_TX_TOTAL_BYTES; + output [13:0] STAT_TX_TOTAL_GOOD_BYTES; + output STAT_TX_TOTAL_GOOD_PACKETS; + output STAT_TX_TOTAL_PACKETS; + output STAT_TX_UNICAST; + output STAT_TX_USER_PAUSE; + output STAT_TX_VLAN; + output TX_OVFOUT; + output [4:0] TX_PTP_PCSLANE_OUT; + output [79:0] TX_PTP_TSTAMP_OUT; + output [15:0] TX_PTP_TSTAMP_TAG_OUT; + output TX_PTP_TSTAMP_VALID_OUT; + output TX_RDYOUT; + output [15:0] TX_SERDES_ALT_DATA0; + output [15:0] TX_SERDES_ALT_DATA1; + output [15:0] TX_SERDES_ALT_DATA2; + output [15:0] TX_SERDES_ALT_DATA3; + output [63:0] TX_SERDES_DATA0; + output [63:0] TX_SERDES_DATA1; + output [63:0] TX_SERDES_DATA2; + output [63:0] TX_SERDES_DATA3; + output [31:0] TX_SERDES_DATA4; + output [31:0] TX_SERDES_DATA5; + output [31:0] TX_SERDES_DATA6; + output [31:0] TX_SERDES_DATA7; + output [31:0] TX_SERDES_DATA8; + output [31:0] TX_SERDES_DATA9; + output TX_UNFOUT; + input CTL_CAUI4_MODE; + input CTL_RX_CHECK_ETYPE_GCP; + input CTL_RX_CHECK_ETYPE_GPP; + input CTL_RX_CHECK_ETYPE_PCP; + input CTL_RX_CHECK_ETYPE_PPP; + input CTL_RX_CHECK_MCAST_GCP; + input CTL_RX_CHECK_MCAST_GPP; + input CTL_RX_CHECK_MCAST_PCP; + input CTL_RX_CHECK_MCAST_PPP; + input CTL_RX_CHECK_OPCODE_GCP; + input CTL_RX_CHECK_OPCODE_GPP; + input CTL_RX_CHECK_OPCODE_PCP; + input CTL_RX_CHECK_OPCODE_PPP; + input CTL_RX_CHECK_SA_GCP; + input CTL_RX_CHECK_SA_GPP; + input CTL_RX_CHECK_SA_PCP; + input CTL_RX_CHECK_SA_PPP; + input CTL_RX_CHECK_UCAST_GCP; + input CTL_RX_CHECK_UCAST_GPP; + input CTL_RX_CHECK_UCAST_PCP; + input CTL_RX_CHECK_UCAST_PPP; + input CTL_RX_ENABLE; + input CTL_RX_ENABLE_GCP; + input CTL_RX_ENABLE_GPP; + input CTL_RX_ENABLE_PCP; + input CTL_RX_ENABLE_PPP; + input CTL_RX_FORCE_RESYNC; + input [8:0] CTL_RX_PAUSE_ACK; + input [8:0] CTL_RX_PAUSE_ENABLE; + input [79:0] CTL_RX_SYSTEMTIMERIN; + input CTL_RX_TEST_PATTERN; + input CTL_TX_ENABLE; + input CTL_TX_LANE0_VLM_BIP7_OVERRIDE; + input [7:0] CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE; + input [8:0] CTL_TX_PAUSE_ENABLE; + input [15:0] CTL_TX_PAUSE_QUANTA0; + input [15:0] CTL_TX_PAUSE_QUANTA1; + input [15:0] CTL_TX_PAUSE_QUANTA2; + input [15:0] CTL_TX_PAUSE_QUANTA3; + input [15:0] CTL_TX_PAUSE_QUANTA4; + input [15:0] CTL_TX_PAUSE_QUANTA5; + input [15:0] CTL_TX_PAUSE_QUANTA6; + input [15:0] CTL_TX_PAUSE_QUANTA7; + input [15:0] CTL_TX_PAUSE_QUANTA8; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER0; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER1; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER2; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER3; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER4; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER5; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER6; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER7; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER8; + input [8:0] CTL_TX_PAUSE_REQ; + input CTL_TX_PTP_VLANE_ADJUST_MODE; + input CTL_TX_RESEND_PAUSE; + input CTL_TX_SEND_IDLE; + input CTL_TX_SEND_RFI; + input [79:0] CTL_TX_SYSTEMTIMERIN; + input CTL_TX_TEST_PATTERN; + input [9:0] DRP_ADDR; + input DRP_CLK; + input [15:0] DRP_DI; + input DRP_EN; + input DRP_WE; + input RX_CLK; + input RX_RESET; + input [15:0] RX_SERDES_ALT_DATA0; + input [15:0] RX_SERDES_ALT_DATA1; + input [15:0] RX_SERDES_ALT_DATA2; + input [15:0] RX_SERDES_ALT_DATA3; + input [9:0] RX_SERDES_CLK; + input [63:0] RX_SERDES_DATA0; + input [63:0] RX_SERDES_DATA1; + input [63:0] RX_SERDES_DATA2; + input [63:0] RX_SERDES_DATA3; + input [31:0] RX_SERDES_DATA4; + input [31:0] RX_SERDES_DATA5; + input [31:0] RX_SERDES_DATA6; + input [31:0] RX_SERDES_DATA7; + input [31:0] RX_SERDES_DATA8; + input [31:0] RX_SERDES_DATA9; + input [9:0] RX_SERDES_RESET; + input TX_CLK; + input [127:0] TX_DATAIN0; + input [127:0] TX_DATAIN1; + input [127:0] TX_DATAIN2; + input [127:0] TX_DATAIN3; + input TX_ENAIN0; + input TX_ENAIN1; + input TX_ENAIN2; + input TX_ENAIN3; + input TX_EOPIN0; + input TX_EOPIN1; + input TX_EOPIN2; + input TX_EOPIN3; + input TX_ERRIN0; + input TX_ERRIN1; + input TX_ERRIN2; + input TX_ERRIN3; + input [3:0] TX_MTYIN0; + input [3:0] TX_MTYIN1; + input [3:0] TX_MTYIN2; + input [3:0] TX_MTYIN3; + input [1:0] TX_PTP_1588OP_IN; + input [15:0] TX_PTP_CHKSUM_OFFSET_IN; + input [63:0] TX_PTP_RXTSTAMP_IN; + input [15:0] TX_PTP_TAG_FIELD_IN; + input [15:0] TX_PTP_TSTAMP_OFFSET_IN; + input TX_PTP_UPD_CHKSUM_IN; + input TX_RESET; + input TX_SOPIN0; + input TX_SOPIN1; + input TX_SOPIN2; + input TX_SOPIN3; +endmodule + +module CMACE4 (...); + parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; + parameter CTL_RX_CHECK_ACK = "TRUE"; + parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; + parameter CTL_RX_CHECK_SFD = "FALSE"; + parameter CTL_RX_DELETE_FCS = "TRUE"; + parameter [15:0] CTL_RX_ETYPE_GCP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_GPP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_PCP = 16'h8808; + parameter [15:0] CTL_RX_ETYPE_PPP = 16'h8808; + parameter CTL_RX_FORWARD_CONTROL = "FALSE"; + parameter CTL_RX_IGNORE_FCS = "FALSE"; + parameter [14:0] CTL_RX_MAX_PACKET_LEN = 15'h2580; + parameter [7:0] CTL_RX_MIN_PACKET_LEN = 8'h40; + parameter [15:0] CTL_RX_OPCODE_GPP = 16'h0001; + parameter [15:0] CTL_RX_OPCODE_MAX_GCP = 16'hFFFF; + parameter [15:0] CTL_RX_OPCODE_MAX_PCP = 16'hFFFF; + parameter [15:0] CTL_RX_OPCODE_MIN_GCP = 16'h0000; + parameter [15:0] CTL_RX_OPCODE_MIN_PCP = 16'h0000; + parameter [15:0] CTL_RX_OPCODE_PPP = 16'h0001; + parameter [47:0] CTL_RX_PAUSE_DA_MCAST = 48'h0180C2000001; + parameter [47:0] CTL_RX_PAUSE_DA_UCAST = 48'h000000000000; + parameter [47:0] CTL_RX_PAUSE_SA = 48'h000000000000; + parameter CTL_RX_PROCESS_LFI = "FALSE"; + parameter [8:0] CTL_RX_RSFEC_AM_THRESHOLD = 9'h046; + parameter [1:0] CTL_RX_RSFEC_FILL_ADJUST = 2'h0; + parameter [15:0] CTL_RX_VL_LENGTH_MINUS1 = 16'h3FFF; + parameter [63:0] CTL_RX_VL_MARKER_ID0 = 64'hC16821003E97DE00; + parameter [63:0] CTL_RX_VL_MARKER_ID1 = 64'h9D718E00628E7100; + parameter [63:0] CTL_RX_VL_MARKER_ID10 = 64'hFD6C990002936600; + parameter [63:0] CTL_RX_VL_MARKER_ID11 = 64'hB9915500466EAA00; + parameter [63:0] CTL_RX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; + parameter [63:0] CTL_RX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; + parameter [63:0] CTL_RX_VL_MARKER_ID14 = 64'h83C7CA007C383500; + parameter [63:0] CTL_RX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; + parameter [63:0] CTL_RX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; + parameter [63:0] CTL_RX_VL_MARKER_ID17 = 64'hADD6B70052294800; + parameter [63:0] CTL_RX_VL_MARKER_ID18 = 64'h5F662A00A099D500; + parameter [63:0] CTL_RX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; + parameter [63:0] CTL_RX_VL_MARKER_ID2 = 64'h594BE800A6B41700; + parameter [63:0] CTL_RX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; + parameter [63:0] CTL_RX_VL_MARKER_ID4 = 64'hF50709000AF8F600; + parameter [63:0] CTL_RX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; + parameter [63:0] CTL_RX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; + parameter [63:0] CTL_RX_VL_MARKER_ID7 = 64'h7B45660084BA9900; + parameter [63:0] CTL_RX_VL_MARKER_ID8 = 64'hA02476005FDB8900; + parameter [63:0] CTL_RX_VL_MARKER_ID9 = 64'h68C9FB0097360400; + parameter CTL_TEST_MODE_PIN_CHAR = "FALSE"; + parameter CTL_TX_CUSTOM_PREAMBLE_ENABLE = "FALSE"; + parameter [47:0] CTL_TX_DA_GPP = 48'h0180C2000001; + parameter [47:0] CTL_TX_DA_PPP = 48'h0180C2000001; + parameter [15:0] CTL_TX_ETHERTYPE_GPP = 16'h8808; + parameter [15:0] CTL_TX_ETHERTYPE_PPP = 16'h8808; + parameter CTL_TX_FCS_INS_ENABLE = "TRUE"; + parameter CTL_TX_IGNORE_FCS = "FALSE"; + parameter [3:0] CTL_TX_IPG_VALUE = 4'hC; + parameter [15:0] CTL_TX_OPCODE_GPP = 16'h0001; + parameter [15:0] CTL_TX_OPCODE_PPP = 16'h0001; + parameter CTL_TX_PTP_1STEP_ENABLE = "FALSE"; + parameter [10:0] CTL_TX_PTP_LATENCY_ADJUST = 11'h2C1; + parameter [47:0] CTL_TX_SA_GPP = 48'h000000000000; + parameter [47:0] CTL_TX_SA_PPP = 48'h000000000000; + parameter [15:0] CTL_TX_VL_LENGTH_MINUS1 = 16'h3FFF; + parameter [63:0] CTL_TX_VL_MARKER_ID0 = 64'hC16821003E97DE00; + parameter [63:0] CTL_TX_VL_MARKER_ID1 = 64'h9D718E00628E7100; + parameter [63:0] CTL_TX_VL_MARKER_ID10 = 64'hFD6C990002936600; + parameter [63:0] CTL_TX_VL_MARKER_ID11 = 64'hB9915500466EAA00; + parameter [63:0] CTL_TX_VL_MARKER_ID12 = 64'h5CB9B200A3464D00; + parameter [63:0] CTL_TX_VL_MARKER_ID13 = 64'h1AF8BD00E5074200; + parameter [63:0] CTL_TX_VL_MARKER_ID14 = 64'h83C7CA007C383500; + parameter [63:0] CTL_TX_VL_MARKER_ID15 = 64'h3536CD00CAC93200; + parameter [63:0] CTL_TX_VL_MARKER_ID16 = 64'hC4314C003BCEB300; + parameter [63:0] CTL_TX_VL_MARKER_ID17 = 64'hADD6B70052294800; + parameter [63:0] CTL_TX_VL_MARKER_ID18 = 64'h5F662A00A099D500; + parameter [63:0] CTL_TX_VL_MARKER_ID19 = 64'hC0F0E5003F0F1A00; + parameter [63:0] CTL_TX_VL_MARKER_ID2 = 64'h594BE800A6B41700; + parameter [63:0] CTL_TX_VL_MARKER_ID3 = 64'h4D957B00B26A8400; + parameter [63:0] CTL_TX_VL_MARKER_ID4 = 64'hF50709000AF8F600; + parameter [63:0] CTL_TX_VL_MARKER_ID5 = 64'hDD14C20022EB3D00; + parameter [63:0] CTL_TX_VL_MARKER_ID6 = 64'h9A4A260065B5D900; + parameter [63:0] CTL_TX_VL_MARKER_ID7 = 64'h7B45660084BA9900; + parameter [63:0] CTL_TX_VL_MARKER_ID8 = 64'hA02476005FDB8900; + parameter [63:0] CTL_TX_VL_MARKER_ID9 = 64'h68C9FB0097360400; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter TEST_MODE_PIN_CHAR = "FALSE"; + output [15:0] DRP_DO; + output DRP_RDY; + output [329:0] RSFEC_BYPASS_RX_DOUT; + output RSFEC_BYPASS_RX_DOUT_CW_START; + output RSFEC_BYPASS_RX_DOUT_VALID; + output [329:0] RSFEC_BYPASS_TX_DOUT; + output RSFEC_BYPASS_TX_DOUT_CW_START; + output RSFEC_BYPASS_TX_DOUT_VALID; + output [127:0] RX_DATAOUT0; + output [127:0] RX_DATAOUT1; + output [127:0] RX_DATAOUT2; + output [127:0] RX_DATAOUT3; + output RX_ENAOUT0; + output RX_ENAOUT1; + output RX_ENAOUT2; + output RX_ENAOUT3; + output RX_EOPOUT0; + output RX_EOPOUT1; + output RX_EOPOUT2; + output RX_EOPOUT3; + output RX_ERROUT0; + output RX_ERROUT1; + output RX_ERROUT2; + output RX_ERROUT3; + output [6:0] RX_LANE_ALIGNER_FILL_0; + output [6:0] RX_LANE_ALIGNER_FILL_1; + output [6:0] RX_LANE_ALIGNER_FILL_10; + output [6:0] RX_LANE_ALIGNER_FILL_11; + output [6:0] RX_LANE_ALIGNER_FILL_12; + output [6:0] RX_LANE_ALIGNER_FILL_13; + output [6:0] RX_LANE_ALIGNER_FILL_14; + output [6:0] RX_LANE_ALIGNER_FILL_15; + output [6:0] RX_LANE_ALIGNER_FILL_16; + output [6:0] RX_LANE_ALIGNER_FILL_17; + output [6:0] RX_LANE_ALIGNER_FILL_18; + output [6:0] RX_LANE_ALIGNER_FILL_19; + output [6:0] RX_LANE_ALIGNER_FILL_2; + output [6:0] RX_LANE_ALIGNER_FILL_3; + output [6:0] RX_LANE_ALIGNER_FILL_4; + output [6:0] RX_LANE_ALIGNER_FILL_5; + output [6:0] RX_LANE_ALIGNER_FILL_6; + output [6:0] RX_LANE_ALIGNER_FILL_7; + output [6:0] RX_LANE_ALIGNER_FILL_8; + output [6:0] RX_LANE_ALIGNER_FILL_9; + output [3:0] RX_MTYOUT0; + output [3:0] RX_MTYOUT1; + output [3:0] RX_MTYOUT2; + output [3:0] RX_MTYOUT3; + output [7:0] RX_OTN_BIP8_0; + output [7:0] RX_OTN_BIP8_1; + output [7:0] RX_OTN_BIP8_2; + output [7:0] RX_OTN_BIP8_3; + output [7:0] RX_OTN_BIP8_4; + output [65:0] RX_OTN_DATA_0; + output [65:0] RX_OTN_DATA_1; + output [65:0] RX_OTN_DATA_2; + output [65:0] RX_OTN_DATA_3; + output [65:0] RX_OTN_DATA_4; + output RX_OTN_ENA; + output RX_OTN_LANE0; + output RX_OTN_VLMARKER; + output [55:0] RX_PREOUT; + output [4:0] RX_PTP_PCSLANE_OUT; + output [79:0] RX_PTP_TSTAMP_OUT; + output RX_SOPOUT0; + output RX_SOPOUT1; + output RX_SOPOUT2; + output RX_SOPOUT3; + output STAT_RX_ALIGNED; + output STAT_RX_ALIGNED_ERR; + output [2:0] STAT_RX_BAD_CODE; + output [2:0] STAT_RX_BAD_FCS; + output STAT_RX_BAD_PREAMBLE; + output STAT_RX_BAD_SFD; + output STAT_RX_BIP_ERR_0; + output STAT_RX_BIP_ERR_1; + output STAT_RX_BIP_ERR_10; + output STAT_RX_BIP_ERR_11; + output STAT_RX_BIP_ERR_12; + output STAT_RX_BIP_ERR_13; + output STAT_RX_BIP_ERR_14; + output STAT_RX_BIP_ERR_15; + output STAT_RX_BIP_ERR_16; + output STAT_RX_BIP_ERR_17; + output STAT_RX_BIP_ERR_18; + output STAT_RX_BIP_ERR_19; + output STAT_RX_BIP_ERR_2; + output STAT_RX_BIP_ERR_3; + output STAT_RX_BIP_ERR_4; + output STAT_RX_BIP_ERR_5; + output STAT_RX_BIP_ERR_6; + output STAT_RX_BIP_ERR_7; + output STAT_RX_BIP_ERR_8; + output STAT_RX_BIP_ERR_9; + output [19:0] STAT_RX_BLOCK_LOCK; + output STAT_RX_BROADCAST; + output [2:0] STAT_RX_FRAGMENT; + output [1:0] STAT_RX_FRAMING_ERR_0; + output [1:0] STAT_RX_FRAMING_ERR_1; + output [1:0] STAT_RX_FRAMING_ERR_10; + output [1:0] STAT_RX_FRAMING_ERR_11; + output [1:0] STAT_RX_FRAMING_ERR_12; + output [1:0] STAT_RX_FRAMING_ERR_13; + output [1:0] STAT_RX_FRAMING_ERR_14; + output [1:0] STAT_RX_FRAMING_ERR_15; + output [1:0] STAT_RX_FRAMING_ERR_16; + output [1:0] STAT_RX_FRAMING_ERR_17; + output [1:0] STAT_RX_FRAMING_ERR_18; + output [1:0] STAT_RX_FRAMING_ERR_19; + output [1:0] STAT_RX_FRAMING_ERR_2; + output [1:0] STAT_RX_FRAMING_ERR_3; + output [1:0] STAT_RX_FRAMING_ERR_4; + output [1:0] STAT_RX_FRAMING_ERR_5; + output [1:0] STAT_RX_FRAMING_ERR_6; + output [1:0] STAT_RX_FRAMING_ERR_7; + output [1:0] STAT_RX_FRAMING_ERR_8; + output [1:0] STAT_RX_FRAMING_ERR_9; + output STAT_RX_FRAMING_ERR_VALID_0; + output STAT_RX_FRAMING_ERR_VALID_1; + output STAT_RX_FRAMING_ERR_VALID_10; + output STAT_RX_FRAMING_ERR_VALID_11; + output STAT_RX_FRAMING_ERR_VALID_12; + output STAT_RX_FRAMING_ERR_VALID_13; + output STAT_RX_FRAMING_ERR_VALID_14; + output STAT_RX_FRAMING_ERR_VALID_15; + output STAT_RX_FRAMING_ERR_VALID_16; + output STAT_RX_FRAMING_ERR_VALID_17; + output STAT_RX_FRAMING_ERR_VALID_18; + output STAT_RX_FRAMING_ERR_VALID_19; + output STAT_RX_FRAMING_ERR_VALID_2; + output STAT_RX_FRAMING_ERR_VALID_3; + output STAT_RX_FRAMING_ERR_VALID_4; + output STAT_RX_FRAMING_ERR_VALID_5; + output STAT_RX_FRAMING_ERR_VALID_6; + output STAT_RX_FRAMING_ERR_VALID_7; + output STAT_RX_FRAMING_ERR_VALID_8; + output STAT_RX_FRAMING_ERR_VALID_9; + output STAT_RX_GOT_SIGNAL_OS; + output STAT_RX_HI_BER; + output STAT_RX_INRANGEERR; + output STAT_RX_INTERNAL_LOCAL_FAULT; + output STAT_RX_JABBER; + output [7:0] STAT_RX_LANE0_VLM_BIP7; + output STAT_RX_LANE0_VLM_BIP7_VALID; + output STAT_RX_LOCAL_FAULT; + output [19:0] STAT_RX_MF_ERR; + output [19:0] STAT_RX_MF_LEN_ERR; + output [19:0] STAT_RX_MF_REPEAT_ERR; + output STAT_RX_MISALIGNED; + output STAT_RX_MULTICAST; + output STAT_RX_OVERSIZE; + output STAT_RX_PACKET_1024_1518_BYTES; + output STAT_RX_PACKET_128_255_BYTES; + output STAT_RX_PACKET_1519_1522_BYTES; + output STAT_RX_PACKET_1523_1548_BYTES; + output STAT_RX_PACKET_1549_2047_BYTES; + output STAT_RX_PACKET_2048_4095_BYTES; + output STAT_RX_PACKET_256_511_BYTES; + output STAT_RX_PACKET_4096_8191_BYTES; + output STAT_RX_PACKET_512_1023_BYTES; + output STAT_RX_PACKET_64_BYTES; + output STAT_RX_PACKET_65_127_BYTES; + output STAT_RX_PACKET_8192_9215_BYTES; + output STAT_RX_PACKET_BAD_FCS; + output STAT_RX_PACKET_LARGE; + output [2:0] STAT_RX_PACKET_SMALL; + output STAT_RX_PAUSE; + output [15:0] STAT_RX_PAUSE_QUANTA0; + output [15:0] STAT_RX_PAUSE_QUANTA1; + output [15:0] STAT_RX_PAUSE_QUANTA2; + output [15:0] STAT_RX_PAUSE_QUANTA3; + output [15:0] STAT_RX_PAUSE_QUANTA4; + output [15:0] STAT_RX_PAUSE_QUANTA5; + output [15:0] STAT_RX_PAUSE_QUANTA6; + output [15:0] STAT_RX_PAUSE_QUANTA7; + output [15:0] STAT_RX_PAUSE_QUANTA8; + output [8:0] STAT_RX_PAUSE_REQ; + output [8:0] STAT_RX_PAUSE_VALID; + output STAT_RX_RECEIVED_LOCAL_FAULT; + output STAT_RX_REMOTE_FAULT; + output STAT_RX_RSFEC_AM_LOCK0; + output STAT_RX_RSFEC_AM_LOCK1; + output STAT_RX_RSFEC_AM_LOCK2; + output STAT_RX_RSFEC_AM_LOCK3; + output STAT_RX_RSFEC_CORRECTED_CW_INC; + output STAT_RX_RSFEC_CW_INC; + output [2:0] STAT_RX_RSFEC_ERR_COUNT0_INC; + output [2:0] STAT_RX_RSFEC_ERR_COUNT1_INC; + output [2:0] STAT_RX_RSFEC_ERR_COUNT2_INC; + output [2:0] STAT_RX_RSFEC_ERR_COUNT3_INC; + output STAT_RX_RSFEC_HI_SER; + output STAT_RX_RSFEC_LANE_ALIGNMENT_STATUS; + output [13:0] STAT_RX_RSFEC_LANE_FILL_0; + output [13:0] STAT_RX_RSFEC_LANE_FILL_1; + output [13:0] STAT_RX_RSFEC_LANE_FILL_2; + output [13:0] STAT_RX_RSFEC_LANE_FILL_3; + output [7:0] STAT_RX_RSFEC_LANE_MAPPING; + output [31:0] STAT_RX_RSFEC_RSVD; + output STAT_RX_RSFEC_UNCORRECTED_CW_INC; + output STAT_RX_STATUS; + output [2:0] STAT_RX_STOMPED_FCS; + output [19:0] STAT_RX_SYNCED; + output [19:0] STAT_RX_SYNCED_ERR; + output [2:0] STAT_RX_TEST_PATTERN_MISMATCH; + output STAT_RX_TOOLONG; + output [6:0] STAT_RX_TOTAL_BYTES; + output [13:0] STAT_RX_TOTAL_GOOD_BYTES; + output STAT_RX_TOTAL_GOOD_PACKETS; + output [2:0] STAT_RX_TOTAL_PACKETS; + output STAT_RX_TRUNCATED; + output [2:0] STAT_RX_UNDERSIZE; + output STAT_RX_UNICAST; + output STAT_RX_USER_PAUSE; + output STAT_RX_VLAN; + output [19:0] STAT_RX_VL_DEMUXED; + output [4:0] STAT_RX_VL_NUMBER_0; + output [4:0] STAT_RX_VL_NUMBER_1; + output [4:0] STAT_RX_VL_NUMBER_10; + output [4:0] STAT_RX_VL_NUMBER_11; + output [4:0] STAT_RX_VL_NUMBER_12; + output [4:0] STAT_RX_VL_NUMBER_13; + output [4:0] STAT_RX_VL_NUMBER_14; + output [4:0] STAT_RX_VL_NUMBER_15; + output [4:0] STAT_RX_VL_NUMBER_16; + output [4:0] STAT_RX_VL_NUMBER_17; + output [4:0] STAT_RX_VL_NUMBER_18; + output [4:0] STAT_RX_VL_NUMBER_19; + output [4:0] STAT_RX_VL_NUMBER_2; + output [4:0] STAT_RX_VL_NUMBER_3; + output [4:0] STAT_RX_VL_NUMBER_4; + output [4:0] STAT_RX_VL_NUMBER_5; + output [4:0] STAT_RX_VL_NUMBER_6; + output [4:0] STAT_RX_VL_NUMBER_7; + output [4:0] STAT_RX_VL_NUMBER_8; + output [4:0] STAT_RX_VL_NUMBER_9; + output STAT_TX_BAD_FCS; + output STAT_TX_BROADCAST; + output STAT_TX_FRAME_ERROR; + output STAT_TX_LOCAL_FAULT; + output STAT_TX_MULTICAST; + output STAT_TX_PACKET_1024_1518_BYTES; + output STAT_TX_PACKET_128_255_BYTES; + output STAT_TX_PACKET_1519_1522_BYTES; + output STAT_TX_PACKET_1523_1548_BYTES; + output STAT_TX_PACKET_1549_2047_BYTES; + output STAT_TX_PACKET_2048_4095_BYTES; + output STAT_TX_PACKET_256_511_BYTES; + output STAT_TX_PACKET_4096_8191_BYTES; + output STAT_TX_PACKET_512_1023_BYTES; + output STAT_TX_PACKET_64_BYTES; + output STAT_TX_PACKET_65_127_BYTES; + output STAT_TX_PACKET_8192_9215_BYTES; + output STAT_TX_PACKET_LARGE; + output STAT_TX_PACKET_SMALL; + output STAT_TX_PAUSE; + output [8:0] STAT_TX_PAUSE_VALID; + output STAT_TX_PTP_FIFO_READ_ERROR; + output STAT_TX_PTP_FIFO_WRITE_ERROR; + output [5:0] STAT_TX_TOTAL_BYTES; + output [13:0] STAT_TX_TOTAL_GOOD_BYTES; + output STAT_TX_TOTAL_GOOD_PACKETS; + output STAT_TX_TOTAL_PACKETS; + output STAT_TX_UNICAST; + output STAT_TX_USER_PAUSE; + output STAT_TX_VLAN; + output TX_OVFOUT; + output [4:0] TX_PTP_PCSLANE_OUT; + output [79:0] TX_PTP_TSTAMP_OUT; + output [15:0] TX_PTP_TSTAMP_TAG_OUT; + output TX_PTP_TSTAMP_VALID_OUT; + output TX_RDYOUT; + output [15:0] TX_SERDES_ALT_DATA0; + output [15:0] TX_SERDES_ALT_DATA1; + output [15:0] TX_SERDES_ALT_DATA2; + output [15:0] TX_SERDES_ALT_DATA3; + output [63:0] TX_SERDES_DATA0; + output [63:0] TX_SERDES_DATA1; + output [63:0] TX_SERDES_DATA2; + output [63:0] TX_SERDES_DATA3; + output [31:0] TX_SERDES_DATA4; + output [31:0] TX_SERDES_DATA5; + output [31:0] TX_SERDES_DATA6; + output [31:0] TX_SERDES_DATA7; + output [31:0] TX_SERDES_DATA8; + output [31:0] TX_SERDES_DATA9; + output TX_UNFOUT; + input CTL_CAUI4_MODE; + input CTL_RSFEC_ENABLE_TRANSCODER_BYPASS_MODE; + input CTL_RSFEC_IEEE_ERROR_INDICATION_MODE; + input CTL_RX_CHECK_ETYPE_GCP; + input CTL_RX_CHECK_ETYPE_GPP; + input CTL_RX_CHECK_ETYPE_PCP; + input CTL_RX_CHECK_ETYPE_PPP; + input CTL_RX_CHECK_MCAST_GCP; + input CTL_RX_CHECK_MCAST_GPP; + input CTL_RX_CHECK_MCAST_PCP; + input CTL_RX_CHECK_MCAST_PPP; + input CTL_RX_CHECK_OPCODE_GCP; + input CTL_RX_CHECK_OPCODE_GPP; + input CTL_RX_CHECK_OPCODE_PCP; + input CTL_RX_CHECK_OPCODE_PPP; + input CTL_RX_CHECK_SA_GCP; + input CTL_RX_CHECK_SA_GPP; + input CTL_RX_CHECK_SA_PCP; + input CTL_RX_CHECK_SA_PPP; + input CTL_RX_CHECK_UCAST_GCP; + input CTL_RX_CHECK_UCAST_GPP; + input CTL_RX_CHECK_UCAST_PCP; + input CTL_RX_CHECK_UCAST_PPP; + input CTL_RX_ENABLE; + input CTL_RX_ENABLE_GCP; + input CTL_RX_ENABLE_GPP; + input CTL_RX_ENABLE_PCP; + input CTL_RX_ENABLE_PPP; + input CTL_RX_FORCE_RESYNC; + input [8:0] CTL_RX_PAUSE_ACK; + input [8:0] CTL_RX_PAUSE_ENABLE; + input CTL_RX_RSFEC_ENABLE; + input CTL_RX_RSFEC_ENABLE_CORRECTION; + input CTL_RX_RSFEC_ENABLE_INDICATION; + input [79:0] CTL_RX_SYSTEMTIMERIN; + input CTL_RX_TEST_PATTERN; + input CTL_TX_ENABLE; + input CTL_TX_LANE0_VLM_BIP7_OVERRIDE; + input [7:0] CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE; + input [8:0] CTL_TX_PAUSE_ENABLE; + input [15:0] CTL_TX_PAUSE_QUANTA0; + input [15:0] CTL_TX_PAUSE_QUANTA1; + input [15:0] CTL_TX_PAUSE_QUANTA2; + input [15:0] CTL_TX_PAUSE_QUANTA3; + input [15:0] CTL_TX_PAUSE_QUANTA4; + input [15:0] CTL_TX_PAUSE_QUANTA5; + input [15:0] CTL_TX_PAUSE_QUANTA6; + input [15:0] CTL_TX_PAUSE_QUANTA7; + input [15:0] CTL_TX_PAUSE_QUANTA8; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER0; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER1; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER2; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER3; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER4; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER5; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER6; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER7; + input [15:0] CTL_TX_PAUSE_REFRESH_TIMER8; + input [8:0] CTL_TX_PAUSE_REQ; + input CTL_TX_PTP_VLANE_ADJUST_MODE; + input CTL_TX_RESEND_PAUSE; + input CTL_TX_RSFEC_ENABLE; + input CTL_TX_SEND_IDLE; + input CTL_TX_SEND_LFI; + input CTL_TX_SEND_RFI; + input [79:0] CTL_TX_SYSTEMTIMERIN; + input CTL_TX_TEST_PATTERN; + input [9:0] DRP_ADDR; + input DRP_CLK; + input [15:0] DRP_DI; + input DRP_EN; + input DRP_WE; + input [329:0] RSFEC_BYPASS_RX_DIN; + input RSFEC_BYPASS_RX_DIN_CW_START; + input [329:0] RSFEC_BYPASS_TX_DIN; + input RSFEC_BYPASS_TX_DIN_CW_START; + input RX_CLK; + input RX_RESET; + input [15:0] RX_SERDES_ALT_DATA0; + input [15:0] RX_SERDES_ALT_DATA1; + input [15:0] RX_SERDES_ALT_DATA2; + input [15:0] RX_SERDES_ALT_DATA3; + input [9:0] RX_SERDES_CLK; + input [63:0] RX_SERDES_DATA0; + input [63:0] RX_SERDES_DATA1; + input [63:0] RX_SERDES_DATA2; + input [63:0] RX_SERDES_DATA3; + input [31:0] RX_SERDES_DATA4; + input [31:0] RX_SERDES_DATA5; + input [31:0] RX_SERDES_DATA6; + input [31:0] RX_SERDES_DATA7; + input [31:0] RX_SERDES_DATA8; + input [31:0] RX_SERDES_DATA9; + input [9:0] RX_SERDES_RESET; + input TX_CLK; + input [127:0] TX_DATAIN0; + input [127:0] TX_DATAIN1; + input [127:0] TX_DATAIN2; + input [127:0] TX_DATAIN3; + input TX_ENAIN0; + input TX_ENAIN1; + input TX_ENAIN2; + input TX_ENAIN3; + input TX_EOPIN0; + input TX_EOPIN1; + input TX_EOPIN2; + input TX_EOPIN3; + input TX_ERRIN0; + input TX_ERRIN1; + input TX_ERRIN2; + input TX_ERRIN3; + input [3:0] TX_MTYIN0; + input [3:0] TX_MTYIN1; + input [3:0] TX_MTYIN2; + input [3:0] TX_MTYIN3; + input [55:0] TX_PREIN; + input [1:0] TX_PTP_1588OP_IN; + input [15:0] TX_PTP_CHKSUM_OFFSET_IN; + input [63:0] TX_PTP_RXTSTAMP_IN; + input [15:0] TX_PTP_TAG_FIELD_IN; + input [15:0] TX_PTP_TSTAMP_OFFSET_IN; + input TX_PTP_UPD_CHKSUM_IN; + input TX_RESET; + input TX_SOPIN0; + input TX_SOPIN1; + input TX_SOPIN2; + input TX_SOPIN3; endmodule module MCB (...); @@ -25955,6 +27616,3401 @@ module MCB (...); input [5:0] P5CMDBL; endmodule +(* keep *) +module HBM_REF_CLK (...); + input REF_CLK; +endmodule + +(* keep *) +module HBM_SNGLBLI_INTF_APB (...); + parameter CLK_SEL = "FALSE"; + parameter [0:0] IS_PCLK_INVERTED = 1'b0; + parameter [0:0] IS_PRESET_N_INVERTED = 1'b0; + parameter MC_ENABLE = "FALSE"; + parameter PHY_ENABLE = "FALSE"; + parameter PHY_PCLK_INVERT = "FALSE"; + parameter SWITCH_ENABLE = "FALSE"; + output CATTRIP_PIPE; + output [31:0] PRDATA_PIPE; + output PREADY_PIPE; + output PSLVERR_PIPE; + output [2:0] TEMP_PIPE; + input [21:0] PADDR; + (* invertible_pin = "IS_PCLK_INVERTED" *) + input PCLK; + input PENABLE; + (* invertible_pin = "IS_PRESET_N_INVERTED" *) + input PRESET_N; + input PSEL; + input [31:0] PWDATA; + input PWRITE; +endmodule + +(* keep *) +module HBM_SNGLBLI_INTF_AXI (...); + parameter CLK_SEL = "FALSE"; + parameter integer DATARATE = 1800; + parameter [0:0] IS_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_ARESET_N_INVERTED = 1'b0; + parameter MC_ENABLE = "FALSE"; + parameter integer PAGEHIT_PERCENT = 75; + parameter PHY_ENABLE = "FALSE"; + parameter integer READ_PERCENT = 50; + parameter SWITCH_ENABLE = "FALSE"; + parameter integer WRITE_PERCENT = 50; + output ARREADY_PIPE; + output AWREADY_PIPE; + output [5:0] BID_PIPE; + output [1:0] BRESP_PIPE; + output BVALID_PIPE; + output [1:0] DFI_AW_AERR_N_PIPE; + output DFI_CLK_BUF; + output DFI_CTRLUPD_ACK_PIPE; + output [7:0] DFI_DBI_BYTE_DISABLE_PIPE; + output [20:0] DFI_DW_RDDATA_DBI_PIPE; + output [7:0] DFI_DW_RDDATA_DERR_PIPE; + output [1:0] DFI_DW_RDDATA_PAR_VALID_PIPE; + output [1:0] DFI_DW_RDDATA_VALID_PIPE; + output DFI_INIT_COMPLETE_PIPE; + output DFI_PHYUPD_REQ_PIPE; + output DFI_PHYUPD_TYPE_PIPE; + output DFI_PHY_LP_STATE_PIPE; + output DFI_RST_N_BUF; + output [5:0] MC_STATUS; + output [7:0] PHY_STATUS; + output [31:0] RDATA_PARITY_PIPE; + output [255:0] RDATA_PIPE; + output [5:0] RID_PIPE; + output RLAST_PIPE; + output [1:0] RRESP_PIPE; + output RVALID_PIPE; + output [5:0] STATUS; + output WREADY_PIPE; + (* invertible_pin = "IS_ACLK_INVERTED" *) + input ACLK; + input [36:0] ARADDR; + input [1:0] ARBURST; + (* invertible_pin = "IS_ARESET_N_INVERTED" *) + input ARESET_N; + input [5:0] ARID; + input [3:0] ARLEN; + input [2:0] ARSIZE; + input ARVALID; + input [36:0] AWADDR; + input [1:0] AWBURST; + input [5:0] AWID; + input [3:0] AWLEN; + input [2:0] AWSIZE; + input AWVALID; + input BREADY; + input BSCAN_CK; + input DFI_LP_PWR_X_REQ; + input MBIST_EN; + input RREADY; + input [255:0] WDATA; + input [31:0] WDATA_PARITY; + input WLAST; + input [31:0] WSTRB; + input WVALID; +endmodule + +(* keep *) +module HBM_ONE_STACK_INTF (...); + parameter CLK_SEL_00 = "FALSE"; + parameter CLK_SEL_01 = "FALSE"; + parameter CLK_SEL_02 = "FALSE"; + parameter CLK_SEL_03 = "FALSE"; + parameter CLK_SEL_04 = "FALSE"; + parameter CLK_SEL_05 = "FALSE"; + parameter CLK_SEL_06 = "FALSE"; + parameter CLK_SEL_07 = "FALSE"; + parameter CLK_SEL_08 = "FALSE"; + parameter CLK_SEL_09 = "FALSE"; + parameter CLK_SEL_10 = "FALSE"; + parameter CLK_SEL_11 = "FALSE"; + parameter CLK_SEL_12 = "FALSE"; + parameter CLK_SEL_13 = "FALSE"; + parameter CLK_SEL_14 = "FALSE"; + parameter CLK_SEL_15 = "FALSE"; + parameter integer DATARATE_00 = 1800; + parameter integer DATARATE_01 = 1800; + parameter integer DATARATE_02 = 1800; + parameter integer DATARATE_03 = 1800; + parameter integer DATARATE_04 = 1800; + parameter integer DATARATE_05 = 1800; + parameter integer DATARATE_06 = 1800; + parameter integer DATARATE_07 = 1800; + parameter DA_LOCKOUT = "FALSE"; + parameter [0:0] IS_APB_0_PCLK_INVERTED = 1'b0; + parameter [0:0] IS_APB_0_PRESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_00_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_00_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_01_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_01_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_02_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_02_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_03_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_03_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_04_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_04_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_05_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_05_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_06_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_06_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_07_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_07_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_08_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_08_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_09_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_09_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_10_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_10_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_11_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_11_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_12_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_12_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_13_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_13_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_14_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_14_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_15_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_15_ARESET_N_INVERTED = 1'b0; + parameter MC_ENABLE_0 = "FALSE"; + parameter MC_ENABLE_1 = "FALSE"; + parameter MC_ENABLE_2 = "FALSE"; + parameter MC_ENABLE_3 = "FALSE"; + parameter MC_ENABLE_4 = "FALSE"; + parameter MC_ENABLE_5 = "FALSE"; + parameter MC_ENABLE_6 = "FALSE"; + parameter MC_ENABLE_7 = "FALSE"; + parameter MC_ENABLE_APB = "FALSE"; + parameter integer PAGEHIT_PERCENT_00 = 75; + parameter PHY_ENABLE_00 = "FALSE"; + parameter PHY_ENABLE_01 = "FALSE"; + parameter PHY_ENABLE_02 = "FALSE"; + parameter PHY_ENABLE_03 = "FALSE"; + parameter PHY_ENABLE_04 = "FALSE"; + parameter PHY_ENABLE_05 = "FALSE"; + parameter PHY_ENABLE_06 = "FALSE"; + parameter PHY_ENABLE_07 = "FALSE"; + parameter PHY_ENABLE_08 = "FALSE"; + parameter PHY_ENABLE_09 = "FALSE"; + parameter PHY_ENABLE_10 = "FALSE"; + parameter PHY_ENABLE_11 = "FALSE"; + parameter PHY_ENABLE_12 = "FALSE"; + parameter PHY_ENABLE_13 = "FALSE"; + parameter PHY_ENABLE_14 = "FALSE"; + parameter PHY_ENABLE_15 = "FALSE"; + parameter PHY_ENABLE_APB = "FALSE"; + parameter PHY_PCLK_INVERT_01 = "FALSE"; + parameter integer READ_PERCENT_00 = 50; + parameter integer READ_PERCENT_01 = 50; + parameter integer READ_PERCENT_02 = 50; + parameter integer READ_PERCENT_03 = 50; + parameter integer READ_PERCENT_04 = 50; + parameter integer READ_PERCENT_05 = 50; + parameter integer READ_PERCENT_06 = 50; + parameter integer READ_PERCENT_07 = 50; + parameter integer READ_PERCENT_08 = 50; + parameter integer READ_PERCENT_09 = 50; + parameter integer READ_PERCENT_10 = 50; + parameter integer READ_PERCENT_11 = 50; + parameter integer READ_PERCENT_12 = 50; + parameter integer READ_PERCENT_13 = 50; + parameter integer READ_PERCENT_14 = 50; + parameter integer READ_PERCENT_15 = 50; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter integer STACK_LOCATION = 0; + parameter SWITCH_ENABLE = "FALSE"; + parameter integer WRITE_PERCENT_00 = 50; + parameter integer WRITE_PERCENT_01 = 50; + parameter integer WRITE_PERCENT_02 = 50; + parameter integer WRITE_PERCENT_03 = 50; + parameter integer WRITE_PERCENT_04 = 50; + parameter integer WRITE_PERCENT_05 = 50; + parameter integer WRITE_PERCENT_06 = 50; + parameter integer WRITE_PERCENT_07 = 50; + parameter integer WRITE_PERCENT_08 = 50; + parameter integer WRITE_PERCENT_09 = 50; + parameter integer WRITE_PERCENT_10 = 50; + parameter integer WRITE_PERCENT_11 = 50; + parameter integer WRITE_PERCENT_12 = 50; + parameter integer WRITE_PERCENT_13 = 50; + parameter integer WRITE_PERCENT_14 = 50; + parameter integer WRITE_PERCENT_15 = 50; + output [31:0] APB_0_PRDATA; + output APB_0_PREADY; + output APB_0_PSLVERR; + output AXI_00_ARREADY; + output AXI_00_AWREADY; + output [5:0] AXI_00_BID; + output [1:0] AXI_00_BRESP; + output AXI_00_BVALID; + output [1:0] AXI_00_DFI_AW_AERR_N; + output AXI_00_DFI_CLK_BUF; + output [7:0] AXI_00_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_00_DFI_DW_RDDATA_DBI; + output [7:0] AXI_00_DFI_DW_RDDATA_DERR; + output [1:0] AXI_00_DFI_DW_RDDATA_VALID; + output AXI_00_DFI_INIT_COMPLETE; + output AXI_00_DFI_PHYUPD_REQ; + output AXI_00_DFI_PHY_LP_STATE; + output AXI_00_DFI_RST_N_BUF; + output [5:0] AXI_00_MC_STATUS; + output [7:0] AXI_00_PHY_STATUS; + output [255:0] AXI_00_RDATA; + output [31:0] AXI_00_RDATA_PARITY; + output [5:0] AXI_00_RID; + output AXI_00_RLAST; + output [1:0] AXI_00_RRESP; + output AXI_00_RVALID; + output AXI_00_WREADY; + output AXI_01_ARREADY; + output AXI_01_AWREADY; + output [5:0] AXI_01_BID; + output [1:0] AXI_01_BRESP; + output AXI_01_BVALID; + output [1:0] AXI_01_DFI_AW_AERR_N; + output AXI_01_DFI_CLK_BUF; + output [7:0] AXI_01_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_01_DFI_DW_RDDATA_DBI; + output [7:0] AXI_01_DFI_DW_RDDATA_DERR; + output [1:0] AXI_01_DFI_DW_RDDATA_VALID; + output AXI_01_DFI_INIT_COMPLETE; + output AXI_01_DFI_PHYUPD_REQ; + output AXI_01_DFI_PHY_LP_STATE; + output AXI_01_DFI_RST_N_BUF; + output [255:0] AXI_01_RDATA; + output [31:0] AXI_01_RDATA_PARITY; + output [5:0] AXI_01_RID; + output AXI_01_RLAST; + output [1:0] AXI_01_RRESP; + output AXI_01_RVALID; + output AXI_01_WREADY; + output AXI_02_ARREADY; + output AXI_02_AWREADY; + output [5:0] AXI_02_BID; + output [1:0] AXI_02_BRESP; + output AXI_02_BVALID; + output [1:0] AXI_02_DFI_AW_AERR_N; + output AXI_02_DFI_CLK_BUF; + output [7:0] AXI_02_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_02_DFI_DW_RDDATA_DBI; + output [7:0] AXI_02_DFI_DW_RDDATA_DERR; + output [1:0] AXI_02_DFI_DW_RDDATA_VALID; + output AXI_02_DFI_INIT_COMPLETE; + output AXI_02_DFI_PHYUPD_REQ; + output AXI_02_DFI_PHY_LP_STATE; + output AXI_02_DFI_RST_N_BUF; + output [5:0] AXI_02_MC_STATUS; + output [7:0] AXI_02_PHY_STATUS; + output [255:0] AXI_02_RDATA; + output [31:0] AXI_02_RDATA_PARITY; + output [5:0] AXI_02_RID; + output AXI_02_RLAST; + output [1:0] AXI_02_RRESP; + output AXI_02_RVALID; + output AXI_02_WREADY; + output AXI_03_ARREADY; + output AXI_03_AWREADY; + output [5:0] AXI_03_BID; + output [1:0] AXI_03_BRESP; + output AXI_03_BVALID; + output [1:0] AXI_03_DFI_AW_AERR_N; + output AXI_03_DFI_CLK_BUF; + output [7:0] AXI_03_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_03_DFI_DW_RDDATA_DBI; + output [7:0] AXI_03_DFI_DW_RDDATA_DERR; + output [1:0] AXI_03_DFI_DW_RDDATA_VALID; + output AXI_03_DFI_INIT_COMPLETE; + output AXI_03_DFI_PHYUPD_REQ; + output AXI_03_DFI_PHY_LP_STATE; + output AXI_03_DFI_RST_N_BUF; + output [255:0] AXI_03_RDATA; + output [31:0] AXI_03_RDATA_PARITY; + output [5:0] AXI_03_RID; + output AXI_03_RLAST; + output [1:0] AXI_03_RRESP; + output AXI_03_RVALID; + output AXI_03_WREADY; + output AXI_04_ARREADY; + output AXI_04_AWREADY; + output [5:0] AXI_04_BID; + output [1:0] AXI_04_BRESP; + output AXI_04_BVALID; + output [1:0] AXI_04_DFI_AW_AERR_N; + output AXI_04_DFI_CLK_BUF; + output [7:0] AXI_04_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_04_DFI_DW_RDDATA_DBI; + output [7:0] AXI_04_DFI_DW_RDDATA_DERR; + output [1:0] AXI_04_DFI_DW_RDDATA_VALID; + output AXI_04_DFI_INIT_COMPLETE; + output AXI_04_DFI_PHYUPD_REQ; + output AXI_04_DFI_PHY_LP_STATE; + output AXI_04_DFI_RST_N_BUF; + output [5:0] AXI_04_MC_STATUS; + output [7:0] AXI_04_PHY_STATUS; + output [255:0] AXI_04_RDATA; + output [31:0] AXI_04_RDATA_PARITY; + output [5:0] AXI_04_RID; + output AXI_04_RLAST; + output [1:0] AXI_04_RRESP; + output AXI_04_RVALID; + output AXI_04_WREADY; + output AXI_05_ARREADY; + output AXI_05_AWREADY; + output [5:0] AXI_05_BID; + output [1:0] AXI_05_BRESP; + output AXI_05_BVALID; + output [1:0] AXI_05_DFI_AW_AERR_N; + output AXI_05_DFI_CLK_BUF; + output [7:0] AXI_05_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_05_DFI_DW_RDDATA_DBI; + output [7:0] AXI_05_DFI_DW_RDDATA_DERR; + output [1:0] AXI_05_DFI_DW_RDDATA_VALID; + output AXI_05_DFI_INIT_COMPLETE; + output AXI_05_DFI_PHYUPD_REQ; + output AXI_05_DFI_PHY_LP_STATE; + output AXI_05_DFI_RST_N_BUF; + output [255:0] AXI_05_RDATA; + output [31:0] AXI_05_RDATA_PARITY; + output [5:0] AXI_05_RID; + output AXI_05_RLAST; + output [1:0] AXI_05_RRESP; + output AXI_05_RVALID; + output AXI_05_WREADY; + output AXI_06_ARREADY; + output AXI_06_AWREADY; + output [5:0] AXI_06_BID; + output [1:0] AXI_06_BRESP; + output AXI_06_BVALID; + output [1:0] AXI_06_DFI_AW_AERR_N; + output AXI_06_DFI_CLK_BUF; + output [7:0] AXI_06_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_06_DFI_DW_RDDATA_DBI; + output [7:0] AXI_06_DFI_DW_RDDATA_DERR; + output [1:0] AXI_06_DFI_DW_RDDATA_VALID; + output AXI_06_DFI_INIT_COMPLETE; + output AXI_06_DFI_PHYUPD_REQ; + output AXI_06_DFI_PHY_LP_STATE; + output AXI_06_DFI_RST_N_BUF; + output [5:0] AXI_06_MC_STATUS; + output [7:0] AXI_06_PHY_STATUS; + output [255:0] AXI_06_RDATA; + output [31:0] AXI_06_RDATA_PARITY; + output [5:0] AXI_06_RID; + output AXI_06_RLAST; + output [1:0] AXI_06_RRESP; + output AXI_06_RVALID; + output AXI_06_WREADY; + output AXI_07_ARREADY; + output AXI_07_AWREADY; + output [5:0] AXI_07_BID; + output [1:0] AXI_07_BRESP; + output AXI_07_BVALID; + output [1:0] AXI_07_DFI_AW_AERR_N; + output AXI_07_DFI_CLK_BUF; + output [7:0] AXI_07_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_07_DFI_DW_RDDATA_DBI; + output [7:0] AXI_07_DFI_DW_RDDATA_DERR; + output [1:0] AXI_07_DFI_DW_RDDATA_VALID; + output AXI_07_DFI_INIT_COMPLETE; + output AXI_07_DFI_PHYUPD_REQ; + output AXI_07_DFI_PHY_LP_STATE; + output AXI_07_DFI_RST_N_BUF; + output [255:0] AXI_07_RDATA; + output [31:0] AXI_07_RDATA_PARITY; + output [5:0] AXI_07_RID; + output AXI_07_RLAST; + output [1:0] AXI_07_RRESP; + output AXI_07_RVALID; + output AXI_07_WREADY; + output AXI_08_ARREADY; + output AXI_08_AWREADY; + output [5:0] AXI_08_BID; + output [1:0] AXI_08_BRESP; + output AXI_08_BVALID; + output [1:0] AXI_08_DFI_AW_AERR_N; + output AXI_08_DFI_CLK_BUF; + output [7:0] AXI_08_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_08_DFI_DW_RDDATA_DBI; + output [7:0] AXI_08_DFI_DW_RDDATA_DERR; + output [1:0] AXI_08_DFI_DW_RDDATA_VALID; + output AXI_08_DFI_INIT_COMPLETE; + output AXI_08_DFI_PHYUPD_REQ; + output AXI_08_DFI_PHY_LP_STATE; + output AXI_08_DFI_RST_N_BUF; + output [5:0] AXI_08_MC_STATUS; + output [7:0] AXI_08_PHY_STATUS; + output [255:0] AXI_08_RDATA; + output [31:0] AXI_08_RDATA_PARITY; + output [5:0] AXI_08_RID; + output AXI_08_RLAST; + output [1:0] AXI_08_RRESP; + output AXI_08_RVALID; + output AXI_08_WREADY; + output AXI_09_ARREADY; + output AXI_09_AWREADY; + output [5:0] AXI_09_BID; + output [1:0] AXI_09_BRESP; + output AXI_09_BVALID; + output [1:0] AXI_09_DFI_AW_AERR_N; + output AXI_09_DFI_CLK_BUF; + output [7:0] AXI_09_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_09_DFI_DW_RDDATA_DBI; + output [7:0] AXI_09_DFI_DW_RDDATA_DERR; + output [1:0] AXI_09_DFI_DW_RDDATA_VALID; + output AXI_09_DFI_INIT_COMPLETE; + output AXI_09_DFI_PHYUPD_REQ; + output AXI_09_DFI_PHY_LP_STATE; + output AXI_09_DFI_RST_N_BUF; + output [255:0] AXI_09_RDATA; + output [31:0] AXI_09_RDATA_PARITY; + output [5:0] AXI_09_RID; + output AXI_09_RLAST; + output [1:0] AXI_09_RRESP; + output AXI_09_RVALID; + output AXI_09_WREADY; + output AXI_10_ARREADY; + output AXI_10_AWREADY; + output [5:0] AXI_10_BID; + output [1:0] AXI_10_BRESP; + output AXI_10_BVALID; + output [1:0] AXI_10_DFI_AW_AERR_N; + output AXI_10_DFI_CLK_BUF; + output [7:0] AXI_10_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_10_DFI_DW_RDDATA_DBI; + output [7:0] AXI_10_DFI_DW_RDDATA_DERR; + output [1:0] AXI_10_DFI_DW_RDDATA_VALID; + output AXI_10_DFI_INIT_COMPLETE; + output AXI_10_DFI_PHYUPD_REQ; + output AXI_10_DFI_PHY_LP_STATE; + output AXI_10_DFI_RST_N_BUF; + output [5:0] AXI_10_MC_STATUS; + output [7:0] AXI_10_PHY_STATUS; + output [255:0] AXI_10_RDATA; + output [31:0] AXI_10_RDATA_PARITY; + output [5:0] AXI_10_RID; + output AXI_10_RLAST; + output [1:0] AXI_10_RRESP; + output AXI_10_RVALID; + output AXI_10_WREADY; + output AXI_11_ARREADY; + output AXI_11_AWREADY; + output [5:0] AXI_11_BID; + output [1:0] AXI_11_BRESP; + output AXI_11_BVALID; + output [1:0] AXI_11_DFI_AW_AERR_N; + output AXI_11_DFI_CLK_BUF; + output [7:0] AXI_11_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_11_DFI_DW_RDDATA_DBI; + output [7:0] AXI_11_DFI_DW_RDDATA_DERR; + output [1:0] AXI_11_DFI_DW_RDDATA_VALID; + output AXI_11_DFI_INIT_COMPLETE; + output AXI_11_DFI_PHYUPD_REQ; + output AXI_11_DFI_PHY_LP_STATE; + output AXI_11_DFI_RST_N_BUF; + output [255:0] AXI_11_RDATA; + output [31:0] AXI_11_RDATA_PARITY; + output [5:0] AXI_11_RID; + output AXI_11_RLAST; + output [1:0] AXI_11_RRESP; + output AXI_11_RVALID; + output AXI_11_WREADY; + output AXI_12_ARREADY; + output AXI_12_AWREADY; + output [5:0] AXI_12_BID; + output [1:0] AXI_12_BRESP; + output AXI_12_BVALID; + output [1:0] AXI_12_DFI_AW_AERR_N; + output AXI_12_DFI_CLK_BUF; + output [7:0] AXI_12_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_12_DFI_DW_RDDATA_DBI; + output [7:0] AXI_12_DFI_DW_RDDATA_DERR; + output [1:0] AXI_12_DFI_DW_RDDATA_VALID; + output AXI_12_DFI_INIT_COMPLETE; + output AXI_12_DFI_PHYUPD_REQ; + output AXI_12_DFI_PHY_LP_STATE; + output AXI_12_DFI_RST_N_BUF; + output [5:0] AXI_12_MC_STATUS; + output [7:0] AXI_12_PHY_STATUS; + output [255:0] AXI_12_RDATA; + output [31:0] AXI_12_RDATA_PARITY; + output [5:0] AXI_12_RID; + output AXI_12_RLAST; + output [1:0] AXI_12_RRESP; + output AXI_12_RVALID; + output AXI_12_WREADY; + output AXI_13_ARREADY; + output AXI_13_AWREADY; + output [5:0] AXI_13_BID; + output [1:0] AXI_13_BRESP; + output AXI_13_BVALID; + output [1:0] AXI_13_DFI_AW_AERR_N; + output AXI_13_DFI_CLK_BUF; + output [7:0] AXI_13_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_13_DFI_DW_RDDATA_DBI; + output [7:0] AXI_13_DFI_DW_RDDATA_DERR; + output [1:0] AXI_13_DFI_DW_RDDATA_VALID; + output AXI_13_DFI_INIT_COMPLETE; + output AXI_13_DFI_PHYUPD_REQ; + output AXI_13_DFI_PHY_LP_STATE; + output AXI_13_DFI_RST_N_BUF; + output [255:0] AXI_13_RDATA; + output [31:0] AXI_13_RDATA_PARITY; + output [5:0] AXI_13_RID; + output AXI_13_RLAST; + output [1:0] AXI_13_RRESP; + output AXI_13_RVALID; + output AXI_13_WREADY; + output AXI_14_ARREADY; + output AXI_14_AWREADY; + output [5:0] AXI_14_BID; + output [1:0] AXI_14_BRESP; + output AXI_14_BVALID; + output [1:0] AXI_14_DFI_AW_AERR_N; + output AXI_14_DFI_CLK_BUF; + output [7:0] AXI_14_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_14_DFI_DW_RDDATA_DBI; + output [7:0] AXI_14_DFI_DW_RDDATA_DERR; + output [1:0] AXI_14_DFI_DW_RDDATA_VALID; + output AXI_14_DFI_INIT_COMPLETE; + output AXI_14_DFI_PHYUPD_REQ; + output AXI_14_DFI_PHY_LP_STATE; + output AXI_14_DFI_RST_N_BUF; + output [5:0] AXI_14_MC_STATUS; + output [7:0] AXI_14_PHY_STATUS; + output [255:0] AXI_14_RDATA; + output [31:0] AXI_14_RDATA_PARITY; + output [5:0] AXI_14_RID; + output AXI_14_RLAST; + output [1:0] AXI_14_RRESP; + output AXI_14_RVALID; + output AXI_14_WREADY; + output AXI_15_ARREADY; + output AXI_15_AWREADY; + output [5:0] AXI_15_BID; + output [1:0] AXI_15_BRESP; + output AXI_15_BVALID; + output [1:0] AXI_15_DFI_AW_AERR_N; + output AXI_15_DFI_CLK_BUF; + output [7:0] AXI_15_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_15_DFI_DW_RDDATA_DBI; + output [7:0] AXI_15_DFI_DW_RDDATA_DERR; + output [1:0] AXI_15_DFI_DW_RDDATA_VALID; + output AXI_15_DFI_INIT_COMPLETE; + output AXI_15_DFI_PHYUPD_REQ; + output AXI_15_DFI_PHY_LP_STATE; + output AXI_15_DFI_RST_N_BUF; + output [255:0] AXI_15_RDATA; + output [31:0] AXI_15_RDATA_PARITY; + output [5:0] AXI_15_RID; + output AXI_15_RLAST; + output [1:0] AXI_15_RRESP; + output AXI_15_RVALID; + output AXI_15_WREADY; + output DRAM_0_STAT_CATTRIP; + output [2:0] DRAM_0_STAT_TEMP; + input [21:0] APB_0_PADDR; + (* invertible_pin = "IS_APB_0_PCLK_INVERTED" *) + input APB_0_PCLK; + input APB_0_PENABLE; + (* invertible_pin = "IS_APB_0_PRESET_N_INVERTED" *) + input APB_0_PRESET_N; + input APB_0_PSEL; + input [31:0] APB_0_PWDATA; + input APB_0_PWRITE; + (* invertible_pin = "IS_AXI_00_ACLK_INVERTED" *) + input AXI_00_ACLK; + input [36:0] AXI_00_ARADDR; + input [1:0] AXI_00_ARBURST; + (* invertible_pin = "IS_AXI_00_ARESET_N_INVERTED" *) + input AXI_00_ARESET_N; + input [5:0] AXI_00_ARID; + input [3:0] AXI_00_ARLEN; + input [2:0] AXI_00_ARSIZE; + input AXI_00_ARVALID; + input [36:0] AXI_00_AWADDR; + input [1:0] AXI_00_AWBURST; + input [5:0] AXI_00_AWID; + input [3:0] AXI_00_AWLEN; + input [2:0] AXI_00_AWSIZE; + input AXI_00_AWVALID; + input AXI_00_BREADY; + input AXI_00_DFI_LP_PWR_X_REQ; + input AXI_00_RREADY; + input [255:0] AXI_00_WDATA; + input [31:0] AXI_00_WDATA_PARITY; + input AXI_00_WLAST; + input [31:0] AXI_00_WSTRB; + input AXI_00_WVALID; + (* invertible_pin = "IS_AXI_01_ACLK_INVERTED" *) + input AXI_01_ACLK; + input [36:0] AXI_01_ARADDR; + input [1:0] AXI_01_ARBURST; + (* invertible_pin = "IS_AXI_01_ARESET_N_INVERTED" *) + input AXI_01_ARESET_N; + input [5:0] AXI_01_ARID; + input [3:0] AXI_01_ARLEN; + input [2:0] AXI_01_ARSIZE; + input AXI_01_ARVALID; + input [36:0] AXI_01_AWADDR; + input [1:0] AXI_01_AWBURST; + input [5:0] AXI_01_AWID; + input [3:0] AXI_01_AWLEN; + input [2:0] AXI_01_AWSIZE; + input AXI_01_AWVALID; + input AXI_01_BREADY; + input AXI_01_DFI_LP_PWR_X_REQ; + input AXI_01_RREADY; + input [255:0] AXI_01_WDATA; + input [31:0] AXI_01_WDATA_PARITY; + input AXI_01_WLAST; + input [31:0] AXI_01_WSTRB; + input AXI_01_WVALID; + (* invertible_pin = "IS_AXI_02_ACLK_INVERTED" *) + input AXI_02_ACLK; + input [36:0] AXI_02_ARADDR; + input [1:0] AXI_02_ARBURST; + (* invertible_pin = "IS_AXI_02_ARESET_N_INVERTED" *) + input AXI_02_ARESET_N; + input [5:0] AXI_02_ARID; + input [3:0] AXI_02_ARLEN; + input [2:0] AXI_02_ARSIZE; + input AXI_02_ARVALID; + input [36:0] AXI_02_AWADDR; + input [1:0] AXI_02_AWBURST; + input [5:0] AXI_02_AWID; + input [3:0] AXI_02_AWLEN; + input [2:0] AXI_02_AWSIZE; + input AXI_02_AWVALID; + input AXI_02_BREADY; + input AXI_02_DFI_LP_PWR_X_REQ; + input AXI_02_RREADY; + input [255:0] AXI_02_WDATA; + input [31:0] AXI_02_WDATA_PARITY; + input AXI_02_WLAST; + input [31:0] AXI_02_WSTRB; + input AXI_02_WVALID; + (* invertible_pin = "IS_AXI_03_ACLK_INVERTED" *) + input AXI_03_ACLK; + input [36:0] AXI_03_ARADDR; + input [1:0] AXI_03_ARBURST; + (* invertible_pin = "IS_AXI_03_ARESET_N_INVERTED" *) + input AXI_03_ARESET_N; + input [5:0] AXI_03_ARID; + input [3:0] AXI_03_ARLEN; + input [2:0] AXI_03_ARSIZE; + input AXI_03_ARVALID; + input [36:0] AXI_03_AWADDR; + input [1:0] AXI_03_AWBURST; + input [5:0] AXI_03_AWID; + input [3:0] AXI_03_AWLEN; + input [2:0] AXI_03_AWSIZE; + input AXI_03_AWVALID; + input AXI_03_BREADY; + input AXI_03_DFI_LP_PWR_X_REQ; + input AXI_03_RREADY; + input [255:0] AXI_03_WDATA; + input [31:0] AXI_03_WDATA_PARITY; + input AXI_03_WLAST; + input [31:0] AXI_03_WSTRB; + input AXI_03_WVALID; + (* invertible_pin = "IS_AXI_04_ACLK_INVERTED" *) + input AXI_04_ACLK; + input [36:0] AXI_04_ARADDR; + input [1:0] AXI_04_ARBURST; + (* invertible_pin = "IS_AXI_04_ARESET_N_INVERTED" *) + input AXI_04_ARESET_N; + input [5:0] AXI_04_ARID; + input [3:0] AXI_04_ARLEN; + input [2:0] AXI_04_ARSIZE; + input AXI_04_ARVALID; + input [36:0] AXI_04_AWADDR; + input [1:0] AXI_04_AWBURST; + input [5:0] AXI_04_AWID; + input [3:0] AXI_04_AWLEN; + input [2:0] AXI_04_AWSIZE; + input AXI_04_AWVALID; + input AXI_04_BREADY; + input AXI_04_DFI_LP_PWR_X_REQ; + input AXI_04_RREADY; + input [255:0] AXI_04_WDATA; + input [31:0] AXI_04_WDATA_PARITY; + input AXI_04_WLAST; + input [31:0] AXI_04_WSTRB; + input AXI_04_WVALID; + (* invertible_pin = "IS_AXI_05_ACLK_INVERTED" *) + input AXI_05_ACLK; + input [36:0] AXI_05_ARADDR; + input [1:0] AXI_05_ARBURST; + (* invertible_pin = "IS_AXI_05_ARESET_N_INVERTED" *) + input AXI_05_ARESET_N; + input [5:0] AXI_05_ARID; + input [3:0] AXI_05_ARLEN; + input [2:0] AXI_05_ARSIZE; + input AXI_05_ARVALID; + input [36:0] AXI_05_AWADDR; + input [1:0] AXI_05_AWBURST; + input [5:0] AXI_05_AWID; + input [3:0] AXI_05_AWLEN; + input [2:0] AXI_05_AWSIZE; + input AXI_05_AWVALID; + input AXI_05_BREADY; + input AXI_05_DFI_LP_PWR_X_REQ; + input AXI_05_RREADY; + input [255:0] AXI_05_WDATA; + input [31:0] AXI_05_WDATA_PARITY; + input AXI_05_WLAST; + input [31:0] AXI_05_WSTRB; + input AXI_05_WVALID; + (* invertible_pin = "IS_AXI_06_ACLK_INVERTED" *) + input AXI_06_ACLK; + input [36:0] AXI_06_ARADDR; + input [1:0] AXI_06_ARBURST; + (* invertible_pin = "IS_AXI_06_ARESET_N_INVERTED" *) + input AXI_06_ARESET_N; + input [5:0] AXI_06_ARID; + input [3:0] AXI_06_ARLEN; + input [2:0] AXI_06_ARSIZE; + input AXI_06_ARVALID; + input [36:0] AXI_06_AWADDR; + input [1:0] AXI_06_AWBURST; + input [5:0] AXI_06_AWID; + input [3:0] AXI_06_AWLEN; + input [2:0] AXI_06_AWSIZE; + input AXI_06_AWVALID; + input AXI_06_BREADY; + input AXI_06_DFI_LP_PWR_X_REQ; + input AXI_06_RREADY; + input [255:0] AXI_06_WDATA; + input [31:0] AXI_06_WDATA_PARITY; + input AXI_06_WLAST; + input [31:0] AXI_06_WSTRB; + input AXI_06_WVALID; + (* invertible_pin = "IS_AXI_07_ACLK_INVERTED" *) + input AXI_07_ACLK; + input [36:0] AXI_07_ARADDR; + input [1:0] AXI_07_ARBURST; + (* invertible_pin = "IS_AXI_07_ARESET_N_INVERTED" *) + input AXI_07_ARESET_N; + input [5:0] AXI_07_ARID; + input [3:0] AXI_07_ARLEN; + input [2:0] AXI_07_ARSIZE; + input AXI_07_ARVALID; + input [36:0] AXI_07_AWADDR; + input [1:0] AXI_07_AWBURST; + input [5:0] AXI_07_AWID; + input [3:0] AXI_07_AWLEN; + input [2:0] AXI_07_AWSIZE; + input AXI_07_AWVALID; + input AXI_07_BREADY; + input AXI_07_DFI_LP_PWR_X_REQ; + input AXI_07_RREADY; + input [255:0] AXI_07_WDATA; + input [31:0] AXI_07_WDATA_PARITY; + input AXI_07_WLAST; + input [31:0] AXI_07_WSTRB; + input AXI_07_WVALID; + (* invertible_pin = "IS_AXI_08_ACLK_INVERTED" *) + input AXI_08_ACLK; + input [36:0] AXI_08_ARADDR; + input [1:0] AXI_08_ARBURST; + (* invertible_pin = "IS_AXI_08_ARESET_N_INVERTED" *) + input AXI_08_ARESET_N; + input [5:0] AXI_08_ARID; + input [3:0] AXI_08_ARLEN; + input [2:0] AXI_08_ARSIZE; + input AXI_08_ARVALID; + input [36:0] AXI_08_AWADDR; + input [1:0] AXI_08_AWBURST; + input [5:0] AXI_08_AWID; + input [3:0] AXI_08_AWLEN; + input [2:0] AXI_08_AWSIZE; + input AXI_08_AWVALID; + input AXI_08_BREADY; + input AXI_08_DFI_LP_PWR_X_REQ; + input AXI_08_RREADY; + input [255:0] AXI_08_WDATA; + input [31:0] AXI_08_WDATA_PARITY; + input AXI_08_WLAST; + input [31:0] AXI_08_WSTRB; + input AXI_08_WVALID; + (* invertible_pin = "IS_AXI_09_ACLK_INVERTED" *) + input AXI_09_ACLK; + input [36:0] AXI_09_ARADDR; + input [1:0] AXI_09_ARBURST; + (* invertible_pin = "IS_AXI_09_ARESET_N_INVERTED" *) + input AXI_09_ARESET_N; + input [5:0] AXI_09_ARID; + input [3:0] AXI_09_ARLEN; + input [2:0] AXI_09_ARSIZE; + input AXI_09_ARVALID; + input [36:0] AXI_09_AWADDR; + input [1:0] AXI_09_AWBURST; + input [5:0] AXI_09_AWID; + input [3:0] AXI_09_AWLEN; + input [2:0] AXI_09_AWSIZE; + input AXI_09_AWVALID; + input AXI_09_BREADY; + input AXI_09_DFI_LP_PWR_X_REQ; + input AXI_09_RREADY; + input [255:0] AXI_09_WDATA; + input [31:0] AXI_09_WDATA_PARITY; + input AXI_09_WLAST; + input [31:0] AXI_09_WSTRB; + input AXI_09_WVALID; + (* invertible_pin = "IS_AXI_10_ACLK_INVERTED" *) + input AXI_10_ACLK; + input [36:0] AXI_10_ARADDR; + input [1:0] AXI_10_ARBURST; + (* invertible_pin = "IS_AXI_10_ARESET_N_INVERTED" *) + input AXI_10_ARESET_N; + input [5:0] AXI_10_ARID; + input [3:0] AXI_10_ARLEN; + input [2:0] AXI_10_ARSIZE; + input AXI_10_ARVALID; + input [36:0] AXI_10_AWADDR; + input [1:0] AXI_10_AWBURST; + input [5:0] AXI_10_AWID; + input [3:0] AXI_10_AWLEN; + input [2:0] AXI_10_AWSIZE; + input AXI_10_AWVALID; + input AXI_10_BREADY; + input AXI_10_DFI_LP_PWR_X_REQ; + input AXI_10_RREADY; + input [255:0] AXI_10_WDATA; + input [31:0] AXI_10_WDATA_PARITY; + input AXI_10_WLAST; + input [31:0] AXI_10_WSTRB; + input AXI_10_WVALID; + (* invertible_pin = "IS_AXI_11_ACLK_INVERTED" *) + input AXI_11_ACLK; + input [36:0] AXI_11_ARADDR; + input [1:0] AXI_11_ARBURST; + (* invertible_pin = "IS_AXI_11_ARESET_N_INVERTED" *) + input AXI_11_ARESET_N; + input [5:0] AXI_11_ARID; + input [3:0] AXI_11_ARLEN; + input [2:0] AXI_11_ARSIZE; + input AXI_11_ARVALID; + input [36:0] AXI_11_AWADDR; + input [1:0] AXI_11_AWBURST; + input [5:0] AXI_11_AWID; + input [3:0] AXI_11_AWLEN; + input [2:0] AXI_11_AWSIZE; + input AXI_11_AWVALID; + input AXI_11_BREADY; + input AXI_11_DFI_LP_PWR_X_REQ; + input AXI_11_RREADY; + input [255:0] AXI_11_WDATA; + input [31:0] AXI_11_WDATA_PARITY; + input AXI_11_WLAST; + input [31:0] AXI_11_WSTRB; + input AXI_11_WVALID; + (* invertible_pin = "IS_AXI_12_ACLK_INVERTED" *) + input AXI_12_ACLK; + input [36:0] AXI_12_ARADDR; + input [1:0] AXI_12_ARBURST; + (* invertible_pin = "IS_AXI_12_ARESET_N_INVERTED" *) + input AXI_12_ARESET_N; + input [5:0] AXI_12_ARID; + input [3:0] AXI_12_ARLEN; + input [2:0] AXI_12_ARSIZE; + input AXI_12_ARVALID; + input [36:0] AXI_12_AWADDR; + input [1:0] AXI_12_AWBURST; + input [5:0] AXI_12_AWID; + input [3:0] AXI_12_AWLEN; + input [2:0] AXI_12_AWSIZE; + input AXI_12_AWVALID; + input AXI_12_BREADY; + input AXI_12_DFI_LP_PWR_X_REQ; + input AXI_12_RREADY; + input [255:0] AXI_12_WDATA; + input [31:0] AXI_12_WDATA_PARITY; + input AXI_12_WLAST; + input [31:0] AXI_12_WSTRB; + input AXI_12_WVALID; + (* invertible_pin = "IS_AXI_13_ACLK_INVERTED" *) + input AXI_13_ACLK; + input [36:0] AXI_13_ARADDR; + input [1:0] AXI_13_ARBURST; + (* invertible_pin = "IS_AXI_13_ARESET_N_INVERTED" *) + input AXI_13_ARESET_N; + input [5:0] AXI_13_ARID; + input [3:0] AXI_13_ARLEN; + input [2:0] AXI_13_ARSIZE; + input AXI_13_ARVALID; + input [36:0] AXI_13_AWADDR; + input [1:0] AXI_13_AWBURST; + input [5:0] AXI_13_AWID; + input [3:0] AXI_13_AWLEN; + input [2:0] AXI_13_AWSIZE; + input AXI_13_AWVALID; + input AXI_13_BREADY; + input AXI_13_DFI_LP_PWR_X_REQ; + input AXI_13_RREADY; + input [255:0] AXI_13_WDATA; + input [31:0] AXI_13_WDATA_PARITY; + input AXI_13_WLAST; + input [31:0] AXI_13_WSTRB; + input AXI_13_WVALID; + (* invertible_pin = "IS_AXI_14_ACLK_INVERTED" *) + input AXI_14_ACLK; + input [36:0] AXI_14_ARADDR; + input [1:0] AXI_14_ARBURST; + (* invertible_pin = "IS_AXI_14_ARESET_N_INVERTED" *) + input AXI_14_ARESET_N; + input [5:0] AXI_14_ARID; + input [3:0] AXI_14_ARLEN; + input [2:0] AXI_14_ARSIZE; + input AXI_14_ARVALID; + input [36:0] AXI_14_AWADDR; + input [1:0] AXI_14_AWBURST; + input [5:0] AXI_14_AWID; + input [3:0] AXI_14_AWLEN; + input [2:0] AXI_14_AWSIZE; + input AXI_14_AWVALID; + input AXI_14_BREADY; + input AXI_14_DFI_LP_PWR_X_REQ; + input AXI_14_RREADY; + input [255:0] AXI_14_WDATA; + input [31:0] AXI_14_WDATA_PARITY; + input AXI_14_WLAST; + input [31:0] AXI_14_WSTRB; + input AXI_14_WVALID; + (* invertible_pin = "IS_AXI_15_ACLK_INVERTED" *) + input AXI_15_ACLK; + input [36:0] AXI_15_ARADDR; + input [1:0] AXI_15_ARBURST; + (* invertible_pin = "IS_AXI_15_ARESET_N_INVERTED" *) + input AXI_15_ARESET_N; + input [5:0] AXI_15_ARID; + input [3:0] AXI_15_ARLEN; + input [2:0] AXI_15_ARSIZE; + input AXI_15_ARVALID; + input [36:0] AXI_15_AWADDR; + input [1:0] AXI_15_AWBURST; + input [5:0] AXI_15_AWID; + input [3:0] AXI_15_AWLEN; + input [2:0] AXI_15_AWSIZE; + input AXI_15_AWVALID; + input AXI_15_BREADY; + input AXI_15_DFI_LP_PWR_X_REQ; + input AXI_15_RREADY; + input [255:0] AXI_15_WDATA; + input [31:0] AXI_15_WDATA_PARITY; + input AXI_15_WLAST; + input [31:0] AXI_15_WSTRB; + input AXI_15_WVALID; + input BSCAN_DRCK; + input BSCAN_TCK; + input HBM_REF_CLK; + input MBIST_EN_00; + input MBIST_EN_01; + input MBIST_EN_02; + input MBIST_EN_03; + input MBIST_EN_04; + input MBIST_EN_05; + input MBIST_EN_06; + input MBIST_EN_07; +endmodule + +(* keep *) +module HBM_TWO_STACK_INTF (...); + parameter CLK_SEL_00 = "FALSE"; + parameter CLK_SEL_01 = "FALSE"; + parameter CLK_SEL_02 = "FALSE"; + parameter CLK_SEL_03 = "FALSE"; + parameter CLK_SEL_04 = "FALSE"; + parameter CLK_SEL_05 = "FALSE"; + parameter CLK_SEL_06 = "FALSE"; + parameter CLK_SEL_07 = "FALSE"; + parameter CLK_SEL_08 = "FALSE"; + parameter CLK_SEL_09 = "FALSE"; + parameter CLK_SEL_10 = "FALSE"; + parameter CLK_SEL_11 = "FALSE"; + parameter CLK_SEL_12 = "FALSE"; + parameter CLK_SEL_13 = "FALSE"; + parameter CLK_SEL_14 = "FALSE"; + parameter CLK_SEL_15 = "FALSE"; + parameter CLK_SEL_16 = "FALSE"; + parameter CLK_SEL_17 = "FALSE"; + parameter CLK_SEL_18 = "FALSE"; + parameter CLK_SEL_19 = "FALSE"; + parameter CLK_SEL_20 = "FALSE"; + parameter CLK_SEL_21 = "FALSE"; + parameter CLK_SEL_22 = "FALSE"; + parameter CLK_SEL_23 = "FALSE"; + parameter CLK_SEL_24 = "FALSE"; + parameter CLK_SEL_25 = "FALSE"; + parameter CLK_SEL_26 = "FALSE"; + parameter CLK_SEL_27 = "FALSE"; + parameter CLK_SEL_28 = "FALSE"; + parameter CLK_SEL_29 = "FALSE"; + parameter CLK_SEL_30 = "FALSE"; + parameter CLK_SEL_31 = "FALSE"; + parameter integer DATARATE_00 = 1800; + parameter integer DATARATE_01 = 1800; + parameter integer DATARATE_02 = 1800; + parameter integer DATARATE_03 = 1800; + parameter integer DATARATE_04 = 1800; + parameter integer DATARATE_05 = 1800; + parameter integer DATARATE_06 = 1800; + parameter integer DATARATE_07 = 1800; + parameter integer DATARATE_08 = 1800; + parameter integer DATARATE_09 = 1800; + parameter integer DATARATE_10 = 1800; + parameter integer DATARATE_11 = 1800; + parameter integer DATARATE_12 = 1800; + parameter integer DATARATE_13 = 1800; + parameter integer DATARATE_14 = 1800; + parameter integer DATARATE_15 = 1800; + parameter DA_LOCKOUT_0 = "FALSE"; + parameter DA_LOCKOUT_1 = "FALSE"; + parameter [0:0] IS_APB_0_PCLK_INVERTED = 1'b0; + parameter [0:0] IS_APB_0_PRESET_N_INVERTED = 1'b0; + parameter [0:0] IS_APB_1_PCLK_INVERTED = 1'b0; + parameter [0:0] IS_APB_1_PRESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_00_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_00_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_01_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_01_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_02_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_02_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_03_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_03_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_04_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_04_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_05_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_05_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_06_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_06_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_07_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_07_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_08_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_08_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_09_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_09_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_10_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_10_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_11_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_11_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_12_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_12_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_13_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_13_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_14_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_14_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_15_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_15_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_16_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_16_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_17_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_17_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_18_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_18_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_19_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_19_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_20_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_20_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_21_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_21_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_22_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_22_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_23_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_23_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_24_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_24_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_25_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_25_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_26_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_26_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_27_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_27_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_28_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_28_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_29_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_29_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_30_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_30_ARESET_N_INVERTED = 1'b0; + parameter [0:0] IS_AXI_31_ACLK_INVERTED = 1'b0; + parameter [0:0] IS_AXI_31_ARESET_N_INVERTED = 1'b0; + parameter MC_ENABLE_00 = "FALSE"; + parameter MC_ENABLE_01 = "FALSE"; + parameter MC_ENABLE_02 = "FALSE"; + parameter MC_ENABLE_03 = "FALSE"; + parameter MC_ENABLE_04 = "FALSE"; + parameter MC_ENABLE_05 = "FALSE"; + parameter MC_ENABLE_06 = "FALSE"; + parameter MC_ENABLE_07 = "FALSE"; + parameter MC_ENABLE_08 = "FALSE"; + parameter MC_ENABLE_09 = "FALSE"; + parameter MC_ENABLE_10 = "FALSE"; + parameter MC_ENABLE_11 = "FALSE"; + parameter MC_ENABLE_12 = "FALSE"; + parameter MC_ENABLE_13 = "FALSE"; + parameter MC_ENABLE_14 = "FALSE"; + parameter MC_ENABLE_15 = "FALSE"; + parameter MC_ENABLE_APB_00 = "FALSE"; + parameter MC_ENABLE_APB_01 = "FALSE"; + parameter integer PAGEHIT_PERCENT_00 = 75; + parameter integer PAGEHIT_PERCENT_01 = 75; + parameter PHY_ENABLE_00 = "FALSE"; + parameter PHY_ENABLE_01 = "FALSE"; + parameter PHY_ENABLE_02 = "FALSE"; + parameter PHY_ENABLE_03 = "FALSE"; + parameter PHY_ENABLE_04 = "FALSE"; + parameter PHY_ENABLE_05 = "FALSE"; + parameter PHY_ENABLE_06 = "FALSE"; + parameter PHY_ENABLE_07 = "FALSE"; + parameter PHY_ENABLE_08 = "FALSE"; + parameter PHY_ENABLE_09 = "FALSE"; + parameter PHY_ENABLE_10 = "FALSE"; + parameter PHY_ENABLE_11 = "FALSE"; + parameter PHY_ENABLE_12 = "FALSE"; + parameter PHY_ENABLE_13 = "FALSE"; + parameter PHY_ENABLE_14 = "FALSE"; + parameter PHY_ENABLE_15 = "FALSE"; + parameter PHY_ENABLE_16 = "FALSE"; + parameter PHY_ENABLE_17 = "FALSE"; + parameter PHY_ENABLE_18 = "FALSE"; + parameter PHY_ENABLE_19 = "FALSE"; + parameter PHY_ENABLE_20 = "FALSE"; + parameter PHY_ENABLE_21 = "FALSE"; + parameter PHY_ENABLE_22 = "FALSE"; + parameter PHY_ENABLE_23 = "FALSE"; + parameter PHY_ENABLE_24 = "FALSE"; + parameter PHY_ENABLE_25 = "FALSE"; + parameter PHY_ENABLE_26 = "FALSE"; + parameter PHY_ENABLE_27 = "FALSE"; + parameter PHY_ENABLE_28 = "FALSE"; + parameter PHY_ENABLE_29 = "FALSE"; + parameter PHY_ENABLE_30 = "FALSE"; + parameter PHY_ENABLE_31 = "FALSE"; + parameter PHY_ENABLE_APB_00 = "FALSE"; + parameter PHY_ENABLE_APB_01 = "FALSE"; + parameter PHY_PCLK_INVERT_01 = "FALSE"; + parameter PHY_PCLK_INVERT_02 = "FALSE"; + parameter integer READ_PERCENT_00 = 50; + parameter integer READ_PERCENT_01 = 50; + parameter integer READ_PERCENT_02 = 50; + parameter integer READ_PERCENT_03 = 50; + parameter integer READ_PERCENT_04 = 50; + parameter integer READ_PERCENT_05 = 50; + parameter integer READ_PERCENT_06 = 50; + parameter integer READ_PERCENT_07 = 50; + parameter integer READ_PERCENT_08 = 50; + parameter integer READ_PERCENT_09 = 50; + parameter integer READ_PERCENT_10 = 50; + parameter integer READ_PERCENT_11 = 50; + parameter integer READ_PERCENT_12 = 50; + parameter integer READ_PERCENT_13 = 50; + parameter integer READ_PERCENT_14 = 50; + parameter integer READ_PERCENT_15 = 50; + parameter integer READ_PERCENT_16 = 50; + parameter integer READ_PERCENT_17 = 50; + parameter integer READ_PERCENT_18 = 50; + parameter integer READ_PERCENT_19 = 50; + parameter integer READ_PERCENT_20 = 50; + parameter integer READ_PERCENT_21 = 50; + parameter integer READ_PERCENT_22 = 50; + parameter integer READ_PERCENT_23 = 50; + parameter integer READ_PERCENT_24 = 50; + parameter integer READ_PERCENT_25 = 50; + parameter integer READ_PERCENT_26 = 50; + parameter integer READ_PERCENT_27 = 50; + parameter integer READ_PERCENT_28 = 50; + parameter integer READ_PERCENT_29 = 50; + parameter integer READ_PERCENT_30 = 50; + parameter integer READ_PERCENT_31 = 50; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter SWITCH_ENABLE_00 = "FALSE"; + parameter SWITCH_ENABLE_01 = "FALSE"; + parameter integer WRITE_PERCENT_00 = 50; + parameter integer WRITE_PERCENT_01 = 50; + parameter integer WRITE_PERCENT_02 = 50; + parameter integer WRITE_PERCENT_03 = 50; + parameter integer WRITE_PERCENT_04 = 50; + parameter integer WRITE_PERCENT_05 = 50; + parameter integer WRITE_PERCENT_06 = 50; + parameter integer WRITE_PERCENT_07 = 50; + parameter integer WRITE_PERCENT_08 = 50; + parameter integer WRITE_PERCENT_09 = 50; + parameter integer WRITE_PERCENT_10 = 50; + parameter integer WRITE_PERCENT_11 = 50; + parameter integer WRITE_PERCENT_12 = 50; + parameter integer WRITE_PERCENT_13 = 50; + parameter integer WRITE_PERCENT_14 = 50; + parameter integer WRITE_PERCENT_15 = 50; + parameter integer WRITE_PERCENT_16 = 50; + parameter integer WRITE_PERCENT_17 = 50; + parameter integer WRITE_PERCENT_18 = 50; + parameter integer WRITE_PERCENT_19 = 50; + parameter integer WRITE_PERCENT_20 = 50; + parameter integer WRITE_PERCENT_21 = 50; + parameter integer WRITE_PERCENT_22 = 50; + parameter integer WRITE_PERCENT_23 = 50; + parameter integer WRITE_PERCENT_24 = 50; + parameter integer WRITE_PERCENT_25 = 50; + parameter integer WRITE_PERCENT_26 = 50; + parameter integer WRITE_PERCENT_27 = 50; + parameter integer WRITE_PERCENT_28 = 50; + parameter integer WRITE_PERCENT_29 = 50; + parameter integer WRITE_PERCENT_30 = 50; + parameter integer WRITE_PERCENT_31 = 50; + output [31:0] APB_0_PRDATA; + output APB_0_PREADY; + output APB_0_PSLVERR; + output [31:0] APB_1_PRDATA; + output APB_1_PREADY; + output APB_1_PSLVERR; + output AXI_00_ARREADY; + output AXI_00_AWREADY; + output [5:0] AXI_00_BID; + output [1:0] AXI_00_BRESP; + output AXI_00_BVALID; + output [1:0] AXI_00_DFI_AW_AERR_N; + output AXI_00_DFI_CLK_BUF; + output [7:0] AXI_00_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_00_DFI_DW_RDDATA_DBI; + output [7:0] AXI_00_DFI_DW_RDDATA_DERR; + output [1:0] AXI_00_DFI_DW_RDDATA_VALID; + output AXI_00_DFI_INIT_COMPLETE; + output AXI_00_DFI_PHYUPD_REQ; + output AXI_00_DFI_PHY_LP_STATE; + output AXI_00_DFI_RST_N_BUF; + output [5:0] AXI_00_MC_STATUS; + output [7:0] AXI_00_PHY_STATUS; + output [255:0] AXI_00_RDATA; + output [31:0] AXI_00_RDATA_PARITY; + output [5:0] AXI_00_RID; + output AXI_00_RLAST; + output [1:0] AXI_00_RRESP; + output AXI_00_RVALID; + output AXI_00_WREADY; + output AXI_01_ARREADY; + output AXI_01_AWREADY; + output [5:0] AXI_01_BID; + output [1:0] AXI_01_BRESP; + output AXI_01_BVALID; + output [1:0] AXI_01_DFI_AW_AERR_N; + output AXI_01_DFI_CLK_BUF; + output [7:0] AXI_01_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_01_DFI_DW_RDDATA_DBI; + output [7:0] AXI_01_DFI_DW_RDDATA_DERR; + output [1:0] AXI_01_DFI_DW_RDDATA_VALID; + output AXI_01_DFI_INIT_COMPLETE; + output AXI_01_DFI_PHYUPD_REQ; + output AXI_01_DFI_PHY_LP_STATE; + output AXI_01_DFI_RST_N_BUF; + output [255:0] AXI_01_RDATA; + output [31:0] AXI_01_RDATA_PARITY; + output [5:0] AXI_01_RID; + output AXI_01_RLAST; + output [1:0] AXI_01_RRESP; + output AXI_01_RVALID; + output AXI_01_WREADY; + output AXI_02_ARREADY; + output AXI_02_AWREADY; + output [5:0] AXI_02_BID; + output [1:0] AXI_02_BRESP; + output AXI_02_BVALID; + output [1:0] AXI_02_DFI_AW_AERR_N; + output AXI_02_DFI_CLK_BUF; + output [7:0] AXI_02_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_02_DFI_DW_RDDATA_DBI; + output [7:0] AXI_02_DFI_DW_RDDATA_DERR; + output [1:0] AXI_02_DFI_DW_RDDATA_VALID; + output AXI_02_DFI_INIT_COMPLETE; + output AXI_02_DFI_PHYUPD_REQ; + output AXI_02_DFI_PHY_LP_STATE; + output AXI_02_DFI_RST_N_BUF; + output [5:0] AXI_02_MC_STATUS; + output [7:0] AXI_02_PHY_STATUS; + output [255:0] AXI_02_RDATA; + output [31:0] AXI_02_RDATA_PARITY; + output [5:0] AXI_02_RID; + output AXI_02_RLAST; + output [1:0] AXI_02_RRESP; + output AXI_02_RVALID; + output AXI_02_WREADY; + output AXI_03_ARREADY; + output AXI_03_AWREADY; + output [5:0] AXI_03_BID; + output [1:0] AXI_03_BRESP; + output AXI_03_BVALID; + output [1:0] AXI_03_DFI_AW_AERR_N; + output AXI_03_DFI_CLK_BUF; + output [7:0] AXI_03_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_03_DFI_DW_RDDATA_DBI; + output [7:0] AXI_03_DFI_DW_RDDATA_DERR; + output [1:0] AXI_03_DFI_DW_RDDATA_VALID; + output AXI_03_DFI_INIT_COMPLETE; + output AXI_03_DFI_PHYUPD_REQ; + output AXI_03_DFI_PHY_LP_STATE; + output AXI_03_DFI_RST_N_BUF; + output [255:0] AXI_03_RDATA; + output [31:0] AXI_03_RDATA_PARITY; + output [5:0] AXI_03_RID; + output AXI_03_RLAST; + output [1:0] AXI_03_RRESP; + output AXI_03_RVALID; + output AXI_03_WREADY; + output AXI_04_ARREADY; + output AXI_04_AWREADY; + output [5:0] AXI_04_BID; + output [1:0] AXI_04_BRESP; + output AXI_04_BVALID; + output [1:0] AXI_04_DFI_AW_AERR_N; + output AXI_04_DFI_CLK_BUF; + output [7:0] AXI_04_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_04_DFI_DW_RDDATA_DBI; + output [7:0] AXI_04_DFI_DW_RDDATA_DERR; + output [1:0] AXI_04_DFI_DW_RDDATA_VALID; + output AXI_04_DFI_INIT_COMPLETE; + output AXI_04_DFI_PHYUPD_REQ; + output AXI_04_DFI_PHY_LP_STATE; + output AXI_04_DFI_RST_N_BUF; + output [5:0] AXI_04_MC_STATUS; + output [7:0] AXI_04_PHY_STATUS; + output [255:0] AXI_04_RDATA; + output [31:0] AXI_04_RDATA_PARITY; + output [5:0] AXI_04_RID; + output AXI_04_RLAST; + output [1:0] AXI_04_RRESP; + output AXI_04_RVALID; + output AXI_04_WREADY; + output AXI_05_ARREADY; + output AXI_05_AWREADY; + output [5:0] AXI_05_BID; + output [1:0] AXI_05_BRESP; + output AXI_05_BVALID; + output [1:0] AXI_05_DFI_AW_AERR_N; + output AXI_05_DFI_CLK_BUF; + output [7:0] AXI_05_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_05_DFI_DW_RDDATA_DBI; + output [7:0] AXI_05_DFI_DW_RDDATA_DERR; + output [1:0] AXI_05_DFI_DW_RDDATA_VALID; + output AXI_05_DFI_INIT_COMPLETE; + output AXI_05_DFI_PHYUPD_REQ; + output AXI_05_DFI_PHY_LP_STATE; + output AXI_05_DFI_RST_N_BUF; + output [255:0] AXI_05_RDATA; + output [31:0] AXI_05_RDATA_PARITY; + output [5:0] AXI_05_RID; + output AXI_05_RLAST; + output [1:0] AXI_05_RRESP; + output AXI_05_RVALID; + output AXI_05_WREADY; + output AXI_06_ARREADY; + output AXI_06_AWREADY; + output [5:0] AXI_06_BID; + output [1:0] AXI_06_BRESP; + output AXI_06_BVALID; + output [1:0] AXI_06_DFI_AW_AERR_N; + output AXI_06_DFI_CLK_BUF; + output [7:0] AXI_06_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_06_DFI_DW_RDDATA_DBI; + output [7:0] AXI_06_DFI_DW_RDDATA_DERR; + output [1:0] AXI_06_DFI_DW_RDDATA_VALID; + output AXI_06_DFI_INIT_COMPLETE; + output AXI_06_DFI_PHYUPD_REQ; + output AXI_06_DFI_PHY_LP_STATE; + output AXI_06_DFI_RST_N_BUF; + output [5:0] AXI_06_MC_STATUS; + output [7:0] AXI_06_PHY_STATUS; + output [255:0] AXI_06_RDATA; + output [31:0] AXI_06_RDATA_PARITY; + output [5:0] AXI_06_RID; + output AXI_06_RLAST; + output [1:0] AXI_06_RRESP; + output AXI_06_RVALID; + output AXI_06_WREADY; + output AXI_07_ARREADY; + output AXI_07_AWREADY; + output [5:0] AXI_07_BID; + output [1:0] AXI_07_BRESP; + output AXI_07_BVALID; + output [1:0] AXI_07_DFI_AW_AERR_N; + output AXI_07_DFI_CLK_BUF; + output [7:0] AXI_07_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_07_DFI_DW_RDDATA_DBI; + output [7:0] AXI_07_DFI_DW_RDDATA_DERR; + output [1:0] AXI_07_DFI_DW_RDDATA_VALID; + output AXI_07_DFI_INIT_COMPLETE; + output AXI_07_DFI_PHYUPD_REQ; + output AXI_07_DFI_PHY_LP_STATE; + output AXI_07_DFI_RST_N_BUF; + output [255:0] AXI_07_RDATA; + output [31:0] AXI_07_RDATA_PARITY; + output [5:0] AXI_07_RID; + output AXI_07_RLAST; + output [1:0] AXI_07_RRESP; + output AXI_07_RVALID; + output AXI_07_WREADY; + output AXI_08_ARREADY; + output AXI_08_AWREADY; + output [5:0] AXI_08_BID; + output [1:0] AXI_08_BRESP; + output AXI_08_BVALID; + output [1:0] AXI_08_DFI_AW_AERR_N; + output AXI_08_DFI_CLK_BUF; + output [7:0] AXI_08_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_08_DFI_DW_RDDATA_DBI; + output [7:0] AXI_08_DFI_DW_RDDATA_DERR; + output [1:0] AXI_08_DFI_DW_RDDATA_VALID; + output AXI_08_DFI_INIT_COMPLETE; + output AXI_08_DFI_PHYUPD_REQ; + output AXI_08_DFI_PHY_LP_STATE; + output AXI_08_DFI_RST_N_BUF; + output [5:0] AXI_08_MC_STATUS; + output [7:0] AXI_08_PHY_STATUS; + output [255:0] AXI_08_RDATA; + output [31:0] AXI_08_RDATA_PARITY; + output [5:0] AXI_08_RID; + output AXI_08_RLAST; + output [1:0] AXI_08_RRESP; + output AXI_08_RVALID; + output AXI_08_WREADY; + output AXI_09_ARREADY; + output AXI_09_AWREADY; + output [5:0] AXI_09_BID; + output [1:0] AXI_09_BRESP; + output AXI_09_BVALID; + output [1:0] AXI_09_DFI_AW_AERR_N; + output AXI_09_DFI_CLK_BUF; + output [7:0] AXI_09_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_09_DFI_DW_RDDATA_DBI; + output [7:0] AXI_09_DFI_DW_RDDATA_DERR; + output [1:0] AXI_09_DFI_DW_RDDATA_VALID; + output AXI_09_DFI_INIT_COMPLETE; + output AXI_09_DFI_PHYUPD_REQ; + output AXI_09_DFI_PHY_LP_STATE; + output AXI_09_DFI_RST_N_BUF; + output [255:0] AXI_09_RDATA; + output [31:0] AXI_09_RDATA_PARITY; + output [5:0] AXI_09_RID; + output AXI_09_RLAST; + output [1:0] AXI_09_RRESP; + output AXI_09_RVALID; + output AXI_09_WREADY; + output AXI_10_ARREADY; + output AXI_10_AWREADY; + output [5:0] AXI_10_BID; + output [1:0] AXI_10_BRESP; + output AXI_10_BVALID; + output [1:0] AXI_10_DFI_AW_AERR_N; + output AXI_10_DFI_CLK_BUF; + output [7:0] AXI_10_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_10_DFI_DW_RDDATA_DBI; + output [7:0] AXI_10_DFI_DW_RDDATA_DERR; + output [1:0] AXI_10_DFI_DW_RDDATA_VALID; + output AXI_10_DFI_INIT_COMPLETE; + output AXI_10_DFI_PHYUPD_REQ; + output AXI_10_DFI_PHY_LP_STATE; + output AXI_10_DFI_RST_N_BUF; + output [5:0] AXI_10_MC_STATUS; + output [7:0] AXI_10_PHY_STATUS; + output [255:0] AXI_10_RDATA; + output [31:0] AXI_10_RDATA_PARITY; + output [5:0] AXI_10_RID; + output AXI_10_RLAST; + output [1:0] AXI_10_RRESP; + output AXI_10_RVALID; + output AXI_10_WREADY; + output AXI_11_ARREADY; + output AXI_11_AWREADY; + output [5:0] AXI_11_BID; + output [1:0] AXI_11_BRESP; + output AXI_11_BVALID; + output [1:0] AXI_11_DFI_AW_AERR_N; + output AXI_11_DFI_CLK_BUF; + output [7:0] AXI_11_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_11_DFI_DW_RDDATA_DBI; + output [7:0] AXI_11_DFI_DW_RDDATA_DERR; + output [1:0] AXI_11_DFI_DW_RDDATA_VALID; + output AXI_11_DFI_INIT_COMPLETE; + output AXI_11_DFI_PHYUPD_REQ; + output AXI_11_DFI_PHY_LP_STATE; + output AXI_11_DFI_RST_N_BUF; + output [255:0] AXI_11_RDATA; + output [31:0] AXI_11_RDATA_PARITY; + output [5:0] AXI_11_RID; + output AXI_11_RLAST; + output [1:0] AXI_11_RRESP; + output AXI_11_RVALID; + output AXI_11_WREADY; + output AXI_12_ARREADY; + output AXI_12_AWREADY; + output [5:0] AXI_12_BID; + output [1:0] AXI_12_BRESP; + output AXI_12_BVALID; + output [1:0] AXI_12_DFI_AW_AERR_N; + output AXI_12_DFI_CLK_BUF; + output [7:0] AXI_12_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_12_DFI_DW_RDDATA_DBI; + output [7:0] AXI_12_DFI_DW_RDDATA_DERR; + output [1:0] AXI_12_DFI_DW_RDDATA_VALID; + output AXI_12_DFI_INIT_COMPLETE; + output AXI_12_DFI_PHYUPD_REQ; + output AXI_12_DFI_PHY_LP_STATE; + output AXI_12_DFI_RST_N_BUF; + output [5:0] AXI_12_MC_STATUS; + output [7:0] AXI_12_PHY_STATUS; + output [255:0] AXI_12_RDATA; + output [31:0] AXI_12_RDATA_PARITY; + output [5:0] AXI_12_RID; + output AXI_12_RLAST; + output [1:0] AXI_12_RRESP; + output AXI_12_RVALID; + output AXI_12_WREADY; + output AXI_13_ARREADY; + output AXI_13_AWREADY; + output [5:0] AXI_13_BID; + output [1:0] AXI_13_BRESP; + output AXI_13_BVALID; + output [1:0] AXI_13_DFI_AW_AERR_N; + output AXI_13_DFI_CLK_BUF; + output [7:0] AXI_13_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_13_DFI_DW_RDDATA_DBI; + output [7:0] AXI_13_DFI_DW_RDDATA_DERR; + output [1:0] AXI_13_DFI_DW_RDDATA_VALID; + output AXI_13_DFI_INIT_COMPLETE; + output AXI_13_DFI_PHYUPD_REQ; + output AXI_13_DFI_PHY_LP_STATE; + output AXI_13_DFI_RST_N_BUF; + output [255:0] AXI_13_RDATA; + output [31:0] AXI_13_RDATA_PARITY; + output [5:0] AXI_13_RID; + output AXI_13_RLAST; + output [1:0] AXI_13_RRESP; + output AXI_13_RVALID; + output AXI_13_WREADY; + output AXI_14_ARREADY; + output AXI_14_AWREADY; + output [5:0] AXI_14_BID; + output [1:0] AXI_14_BRESP; + output AXI_14_BVALID; + output [1:0] AXI_14_DFI_AW_AERR_N; + output AXI_14_DFI_CLK_BUF; + output [7:0] AXI_14_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_14_DFI_DW_RDDATA_DBI; + output [7:0] AXI_14_DFI_DW_RDDATA_DERR; + output [1:0] AXI_14_DFI_DW_RDDATA_VALID; + output AXI_14_DFI_INIT_COMPLETE; + output AXI_14_DFI_PHYUPD_REQ; + output AXI_14_DFI_PHY_LP_STATE; + output AXI_14_DFI_RST_N_BUF; + output [5:0] AXI_14_MC_STATUS; + output [7:0] AXI_14_PHY_STATUS; + output [255:0] AXI_14_RDATA; + output [31:0] AXI_14_RDATA_PARITY; + output [5:0] AXI_14_RID; + output AXI_14_RLAST; + output [1:0] AXI_14_RRESP; + output AXI_14_RVALID; + output AXI_14_WREADY; + output AXI_15_ARREADY; + output AXI_15_AWREADY; + output [5:0] AXI_15_BID; + output [1:0] AXI_15_BRESP; + output AXI_15_BVALID; + output [1:0] AXI_15_DFI_AW_AERR_N; + output AXI_15_DFI_CLK_BUF; + output [7:0] AXI_15_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_15_DFI_DW_RDDATA_DBI; + output [7:0] AXI_15_DFI_DW_RDDATA_DERR; + output [1:0] AXI_15_DFI_DW_RDDATA_VALID; + output AXI_15_DFI_INIT_COMPLETE; + output AXI_15_DFI_PHYUPD_REQ; + output AXI_15_DFI_PHY_LP_STATE; + output AXI_15_DFI_RST_N_BUF; + output [255:0] AXI_15_RDATA; + output [31:0] AXI_15_RDATA_PARITY; + output [5:0] AXI_15_RID; + output AXI_15_RLAST; + output [1:0] AXI_15_RRESP; + output AXI_15_RVALID; + output AXI_15_WREADY; + output AXI_16_ARREADY; + output AXI_16_AWREADY; + output [5:0] AXI_16_BID; + output [1:0] AXI_16_BRESP; + output AXI_16_BVALID; + output [1:0] AXI_16_DFI_AW_AERR_N; + output AXI_16_DFI_CLK_BUF; + output [7:0] AXI_16_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_16_DFI_DW_RDDATA_DBI; + output [7:0] AXI_16_DFI_DW_RDDATA_DERR; + output [1:0] AXI_16_DFI_DW_RDDATA_VALID; + output AXI_16_DFI_INIT_COMPLETE; + output AXI_16_DFI_PHYUPD_REQ; + output AXI_16_DFI_PHY_LP_STATE; + output AXI_16_DFI_RST_N_BUF; + output [5:0] AXI_16_MC_STATUS; + output [7:0] AXI_16_PHY_STATUS; + output [255:0] AXI_16_RDATA; + output [31:0] AXI_16_RDATA_PARITY; + output [5:0] AXI_16_RID; + output AXI_16_RLAST; + output [1:0] AXI_16_RRESP; + output AXI_16_RVALID; + output AXI_16_WREADY; + output AXI_17_ARREADY; + output AXI_17_AWREADY; + output [5:0] AXI_17_BID; + output [1:0] AXI_17_BRESP; + output AXI_17_BVALID; + output [1:0] AXI_17_DFI_AW_AERR_N; + output AXI_17_DFI_CLK_BUF; + output [7:0] AXI_17_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_17_DFI_DW_RDDATA_DBI; + output [7:0] AXI_17_DFI_DW_RDDATA_DERR; + output [1:0] AXI_17_DFI_DW_RDDATA_VALID; + output AXI_17_DFI_INIT_COMPLETE; + output AXI_17_DFI_PHYUPD_REQ; + output AXI_17_DFI_PHY_LP_STATE; + output AXI_17_DFI_RST_N_BUF; + output [255:0] AXI_17_RDATA; + output [31:0] AXI_17_RDATA_PARITY; + output [5:0] AXI_17_RID; + output AXI_17_RLAST; + output [1:0] AXI_17_RRESP; + output AXI_17_RVALID; + output AXI_17_WREADY; + output AXI_18_ARREADY; + output AXI_18_AWREADY; + output [5:0] AXI_18_BID; + output [1:0] AXI_18_BRESP; + output AXI_18_BVALID; + output [1:0] AXI_18_DFI_AW_AERR_N; + output AXI_18_DFI_CLK_BUF; + output [7:0] AXI_18_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_18_DFI_DW_RDDATA_DBI; + output [7:0] AXI_18_DFI_DW_RDDATA_DERR; + output [1:0] AXI_18_DFI_DW_RDDATA_VALID; + output AXI_18_DFI_INIT_COMPLETE; + output AXI_18_DFI_PHYUPD_REQ; + output AXI_18_DFI_PHY_LP_STATE; + output AXI_18_DFI_RST_N_BUF; + output [5:0] AXI_18_MC_STATUS; + output [7:0] AXI_18_PHY_STATUS; + output [255:0] AXI_18_RDATA; + output [31:0] AXI_18_RDATA_PARITY; + output [5:0] AXI_18_RID; + output AXI_18_RLAST; + output [1:0] AXI_18_RRESP; + output AXI_18_RVALID; + output AXI_18_WREADY; + output AXI_19_ARREADY; + output AXI_19_AWREADY; + output [5:0] AXI_19_BID; + output [1:0] AXI_19_BRESP; + output AXI_19_BVALID; + output [1:0] AXI_19_DFI_AW_AERR_N; + output AXI_19_DFI_CLK_BUF; + output [7:0] AXI_19_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_19_DFI_DW_RDDATA_DBI; + output [7:0] AXI_19_DFI_DW_RDDATA_DERR; + output [1:0] AXI_19_DFI_DW_RDDATA_VALID; + output AXI_19_DFI_INIT_COMPLETE; + output AXI_19_DFI_PHYUPD_REQ; + output AXI_19_DFI_PHY_LP_STATE; + output AXI_19_DFI_RST_N_BUF; + output [255:0] AXI_19_RDATA; + output [31:0] AXI_19_RDATA_PARITY; + output [5:0] AXI_19_RID; + output AXI_19_RLAST; + output [1:0] AXI_19_RRESP; + output AXI_19_RVALID; + output AXI_19_WREADY; + output AXI_20_ARREADY; + output AXI_20_AWREADY; + output [5:0] AXI_20_BID; + output [1:0] AXI_20_BRESP; + output AXI_20_BVALID; + output [1:0] AXI_20_DFI_AW_AERR_N; + output AXI_20_DFI_CLK_BUF; + output [7:0] AXI_20_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_20_DFI_DW_RDDATA_DBI; + output [7:0] AXI_20_DFI_DW_RDDATA_DERR; + output [1:0] AXI_20_DFI_DW_RDDATA_VALID; + output AXI_20_DFI_INIT_COMPLETE; + output AXI_20_DFI_PHYUPD_REQ; + output AXI_20_DFI_PHY_LP_STATE; + output AXI_20_DFI_RST_N_BUF; + output [5:0] AXI_20_MC_STATUS; + output [7:0] AXI_20_PHY_STATUS; + output [255:0] AXI_20_RDATA; + output [31:0] AXI_20_RDATA_PARITY; + output [5:0] AXI_20_RID; + output AXI_20_RLAST; + output [1:0] AXI_20_RRESP; + output AXI_20_RVALID; + output AXI_20_WREADY; + output AXI_21_ARREADY; + output AXI_21_AWREADY; + output [5:0] AXI_21_BID; + output [1:0] AXI_21_BRESP; + output AXI_21_BVALID; + output [1:0] AXI_21_DFI_AW_AERR_N; + output AXI_21_DFI_CLK_BUF; + output [7:0] AXI_21_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_21_DFI_DW_RDDATA_DBI; + output [7:0] AXI_21_DFI_DW_RDDATA_DERR; + output [1:0] AXI_21_DFI_DW_RDDATA_VALID; + output AXI_21_DFI_INIT_COMPLETE; + output AXI_21_DFI_PHYUPD_REQ; + output AXI_21_DFI_PHY_LP_STATE; + output AXI_21_DFI_RST_N_BUF; + output [255:0] AXI_21_RDATA; + output [31:0] AXI_21_RDATA_PARITY; + output [5:0] AXI_21_RID; + output AXI_21_RLAST; + output [1:0] AXI_21_RRESP; + output AXI_21_RVALID; + output AXI_21_WREADY; + output AXI_22_ARREADY; + output AXI_22_AWREADY; + output [5:0] AXI_22_BID; + output [1:0] AXI_22_BRESP; + output AXI_22_BVALID; + output [1:0] AXI_22_DFI_AW_AERR_N; + output AXI_22_DFI_CLK_BUF; + output [7:0] AXI_22_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_22_DFI_DW_RDDATA_DBI; + output [7:0] AXI_22_DFI_DW_RDDATA_DERR; + output [1:0] AXI_22_DFI_DW_RDDATA_VALID; + output AXI_22_DFI_INIT_COMPLETE; + output AXI_22_DFI_PHYUPD_REQ; + output AXI_22_DFI_PHY_LP_STATE; + output AXI_22_DFI_RST_N_BUF; + output [5:0] AXI_22_MC_STATUS; + output [7:0] AXI_22_PHY_STATUS; + output [255:0] AXI_22_RDATA; + output [31:0] AXI_22_RDATA_PARITY; + output [5:0] AXI_22_RID; + output AXI_22_RLAST; + output [1:0] AXI_22_RRESP; + output AXI_22_RVALID; + output AXI_22_WREADY; + output AXI_23_ARREADY; + output AXI_23_AWREADY; + output [5:0] AXI_23_BID; + output [1:0] AXI_23_BRESP; + output AXI_23_BVALID; + output [1:0] AXI_23_DFI_AW_AERR_N; + output AXI_23_DFI_CLK_BUF; + output [7:0] AXI_23_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_23_DFI_DW_RDDATA_DBI; + output [7:0] AXI_23_DFI_DW_RDDATA_DERR; + output [1:0] AXI_23_DFI_DW_RDDATA_VALID; + output AXI_23_DFI_INIT_COMPLETE; + output AXI_23_DFI_PHYUPD_REQ; + output AXI_23_DFI_PHY_LP_STATE; + output AXI_23_DFI_RST_N_BUF; + output [255:0] AXI_23_RDATA; + output [31:0] AXI_23_RDATA_PARITY; + output [5:0] AXI_23_RID; + output AXI_23_RLAST; + output [1:0] AXI_23_RRESP; + output AXI_23_RVALID; + output AXI_23_WREADY; + output AXI_24_ARREADY; + output AXI_24_AWREADY; + output [5:0] AXI_24_BID; + output [1:0] AXI_24_BRESP; + output AXI_24_BVALID; + output [1:0] AXI_24_DFI_AW_AERR_N; + output AXI_24_DFI_CLK_BUF; + output [7:0] AXI_24_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_24_DFI_DW_RDDATA_DBI; + output [7:0] AXI_24_DFI_DW_RDDATA_DERR; + output [1:0] AXI_24_DFI_DW_RDDATA_VALID; + output AXI_24_DFI_INIT_COMPLETE; + output AXI_24_DFI_PHYUPD_REQ; + output AXI_24_DFI_PHY_LP_STATE; + output AXI_24_DFI_RST_N_BUF; + output [5:0] AXI_24_MC_STATUS; + output [7:0] AXI_24_PHY_STATUS; + output [255:0] AXI_24_RDATA; + output [31:0] AXI_24_RDATA_PARITY; + output [5:0] AXI_24_RID; + output AXI_24_RLAST; + output [1:0] AXI_24_RRESP; + output AXI_24_RVALID; + output AXI_24_WREADY; + output AXI_25_ARREADY; + output AXI_25_AWREADY; + output [5:0] AXI_25_BID; + output [1:0] AXI_25_BRESP; + output AXI_25_BVALID; + output [1:0] AXI_25_DFI_AW_AERR_N; + output AXI_25_DFI_CLK_BUF; + output [7:0] AXI_25_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_25_DFI_DW_RDDATA_DBI; + output [7:0] AXI_25_DFI_DW_RDDATA_DERR; + output [1:0] AXI_25_DFI_DW_RDDATA_VALID; + output AXI_25_DFI_INIT_COMPLETE; + output AXI_25_DFI_PHYUPD_REQ; + output AXI_25_DFI_PHY_LP_STATE; + output AXI_25_DFI_RST_N_BUF; + output [255:0] AXI_25_RDATA; + output [31:0] AXI_25_RDATA_PARITY; + output [5:0] AXI_25_RID; + output AXI_25_RLAST; + output [1:0] AXI_25_RRESP; + output AXI_25_RVALID; + output AXI_25_WREADY; + output AXI_26_ARREADY; + output AXI_26_AWREADY; + output [5:0] AXI_26_BID; + output [1:0] AXI_26_BRESP; + output AXI_26_BVALID; + output [1:0] AXI_26_DFI_AW_AERR_N; + output AXI_26_DFI_CLK_BUF; + output [7:0] AXI_26_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_26_DFI_DW_RDDATA_DBI; + output [7:0] AXI_26_DFI_DW_RDDATA_DERR; + output [1:0] AXI_26_DFI_DW_RDDATA_VALID; + output AXI_26_DFI_INIT_COMPLETE; + output AXI_26_DFI_PHYUPD_REQ; + output AXI_26_DFI_PHY_LP_STATE; + output AXI_26_DFI_RST_N_BUF; + output [5:0] AXI_26_MC_STATUS; + output [7:0] AXI_26_PHY_STATUS; + output [255:0] AXI_26_RDATA; + output [31:0] AXI_26_RDATA_PARITY; + output [5:0] AXI_26_RID; + output AXI_26_RLAST; + output [1:0] AXI_26_RRESP; + output AXI_26_RVALID; + output AXI_26_WREADY; + output AXI_27_ARREADY; + output AXI_27_AWREADY; + output [5:0] AXI_27_BID; + output [1:0] AXI_27_BRESP; + output AXI_27_BVALID; + output [1:0] AXI_27_DFI_AW_AERR_N; + output AXI_27_DFI_CLK_BUF; + output [7:0] AXI_27_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_27_DFI_DW_RDDATA_DBI; + output [7:0] AXI_27_DFI_DW_RDDATA_DERR; + output [1:0] AXI_27_DFI_DW_RDDATA_VALID; + output AXI_27_DFI_INIT_COMPLETE; + output AXI_27_DFI_PHYUPD_REQ; + output AXI_27_DFI_PHY_LP_STATE; + output AXI_27_DFI_RST_N_BUF; + output [255:0] AXI_27_RDATA; + output [31:0] AXI_27_RDATA_PARITY; + output [5:0] AXI_27_RID; + output AXI_27_RLAST; + output [1:0] AXI_27_RRESP; + output AXI_27_RVALID; + output AXI_27_WREADY; + output AXI_28_ARREADY; + output AXI_28_AWREADY; + output [5:0] AXI_28_BID; + output [1:0] AXI_28_BRESP; + output AXI_28_BVALID; + output [1:0] AXI_28_DFI_AW_AERR_N; + output AXI_28_DFI_CLK_BUF; + output [7:0] AXI_28_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_28_DFI_DW_RDDATA_DBI; + output [7:0] AXI_28_DFI_DW_RDDATA_DERR; + output [1:0] AXI_28_DFI_DW_RDDATA_VALID; + output AXI_28_DFI_INIT_COMPLETE; + output AXI_28_DFI_PHYUPD_REQ; + output AXI_28_DFI_PHY_LP_STATE; + output AXI_28_DFI_RST_N_BUF; + output [5:0] AXI_28_MC_STATUS; + output [7:0] AXI_28_PHY_STATUS; + output [255:0] AXI_28_RDATA; + output [31:0] AXI_28_RDATA_PARITY; + output [5:0] AXI_28_RID; + output AXI_28_RLAST; + output [1:0] AXI_28_RRESP; + output AXI_28_RVALID; + output AXI_28_WREADY; + output AXI_29_ARREADY; + output AXI_29_AWREADY; + output [5:0] AXI_29_BID; + output [1:0] AXI_29_BRESP; + output AXI_29_BVALID; + output [1:0] AXI_29_DFI_AW_AERR_N; + output AXI_29_DFI_CLK_BUF; + output [7:0] AXI_29_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_29_DFI_DW_RDDATA_DBI; + output [7:0] AXI_29_DFI_DW_RDDATA_DERR; + output [1:0] AXI_29_DFI_DW_RDDATA_VALID; + output AXI_29_DFI_INIT_COMPLETE; + output AXI_29_DFI_PHYUPD_REQ; + output AXI_29_DFI_PHY_LP_STATE; + output AXI_29_DFI_RST_N_BUF; + output [255:0] AXI_29_RDATA; + output [31:0] AXI_29_RDATA_PARITY; + output [5:0] AXI_29_RID; + output AXI_29_RLAST; + output [1:0] AXI_29_RRESP; + output AXI_29_RVALID; + output AXI_29_WREADY; + output AXI_30_ARREADY; + output AXI_30_AWREADY; + output [5:0] AXI_30_BID; + output [1:0] AXI_30_BRESP; + output AXI_30_BVALID; + output [1:0] AXI_30_DFI_AW_AERR_N; + output AXI_30_DFI_CLK_BUF; + output [7:0] AXI_30_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_30_DFI_DW_RDDATA_DBI; + output [7:0] AXI_30_DFI_DW_RDDATA_DERR; + output [1:0] AXI_30_DFI_DW_RDDATA_VALID; + output AXI_30_DFI_INIT_COMPLETE; + output AXI_30_DFI_PHYUPD_REQ; + output AXI_30_DFI_PHY_LP_STATE; + output AXI_30_DFI_RST_N_BUF; + output [5:0] AXI_30_MC_STATUS; + output [7:0] AXI_30_PHY_STATUS; + output [255:0] AXI_30_RDATA; + output [31:0] AXI_30_RDATA_PARITY; + output [5:0] AXI_30_RID; + output AXI_30_RLAST; + output [1:0] AXI_30_RRESP; + output AXI_30_RVALID; + output AXI_30_WREADY; + output AXI_31_ARREADY; + output AXI_31_AWREADY; + output [5:0] AXI_31_BID; + output [1:0] AXI_31_BRESP; + output AXI_31_BVALID; + output [1:0] AXI_31_DFI_AW_AERR_N; + output AXI_31_DFI_CLK_BUF; + output [7:0] AXI_31_DFI_DBI_BYTE_DISABLE; + output [20:0] AXI_31_DFI_DW_RDDATA_DBI; + output [7:0] AXI_31_DFI_DW_RDDATA_DERR; + output [1:0] AXI_31_DFI_DW_RDDATA_VALID; + output AXI_31_DFI_INIT_COMPLETE; + output AXI_31_DFI_PHYUPD_REQ; + output AXI_31_DFI_PHY_LP_STATE; + output AXI_31_DFI_RST_N_BUF; + output [255:0] AXI_31_RDATA; + output [31:0] AXI_31_RDATA_PARITY; + output [5:0] AXI_31_RID; + output AXI_31_RLAST; + output [1:0] AXI_31_RRESP; + output AXI_31_RVALID; + output AXI_31_WREADY; + output DRAM_0_STAT_CATTRIP; + output [2:0] DRAM_0_STAT_TEMP; + output DRAM_1_STAT_CATTRIP; + output [2:0] DRAM_1_STAT_TEMP; + input [21:0] APB_0_PADDR; + (* invertible_pin = "IS_APB_0_PCLK_INVERTED" *) + input APB_0_PCLK; + input APB_0_PENABLE; + (* invertible_pin = "IS_APB_0_PRESET_N_INVERTED" *) + input APB_0_PRESET_N; + input APB_0_PSEL; + input [31:0] APB_0_PWDATA; + input APB_0_PWRITE; + input [21:0] APB_1_PADDR; + (* invertible_pin = "IS_APB_1_PCLK_INVERTED" *) + input APB_1_PCLK; + input APB_1_PENABLE; + (* invertible_pin = "IS_APB_1_PRESET_N_INVERTED" *) + input APB_1_PRESET_N; + input APB_1_PSEL; + input [31:0] APB_1_PWDATA; + input APB_1_PWRITE; + (* invertible_pin = "IS_AXI_00_ACLK_INVERTED" *) + input AXI_00_ACLK; + input [36:0] AXI_00_ARADDR; + input [1:0] AXI_00_ARBURST; + (* invertible_pin = "IS_AXI_00_ARESET_N_INVERTED" *) + input AXI_00_ARESET_N; + input [5:0] AXI_00_ARID; + input [3:0] AXI_00_ARLEN; + input [2:0] AXI_00_ARSIZE; + input AXI_00_ARVALID; + input [36:0] AXI_00_AWADDR; + input [1:0] AXI_00_AWBURST; + input [5:0] AXI_00_AWID; + input [3:0] AXI_00_AWLEN; + input [2:0] AXI_00_AWSIZE; + input AXI_00_AWVALID; + input AXI_00_BREADY; + input AXI_00_DFI_LP_PWR_X_REQ; + input AXI_00_RREADY; + input [255:0] AXI_00_WDATA; + input [31:0] AXI_00_WDATA_PARITY; + input AXI_00_WLAST; + input [31:0] AXI_00_WSTRB; + input AXI_00_WVALID; + (* invertible_pin = "IS_AXI_01_ACLK_INVERTED" *) + input AXI_01_ACLK; + input [36:0] AXI_01_ARADDR; + input [1:0] AXI_01_ARBURST; + (* invertible_pin = "IS_AXI_01_ARESET_N_INVERTED" *) + input AXI_01_ARESET_N; + input [5:0] AXI_01_ARID; + input [3:0] AXI_01_ARLEN; + input [2:0] AXI_01_ARSIZE; + input AXI_01_ARVALID; + input [36:0] AXI_01_AWADDR; + input [1:0] AXI_01_AWBURST; + input [5:0] AXI_01_AWID; + input [3:0] AXI_01_AWLEN; + input [2:0] AXI_01_AWSIZE; + input AXI_01_AWVALID; + input AXI_01_BREADY; + input AXI_01_DFI_LP_PWR_X_REQ; + input AXI_01_RREADY; + input [255:0] AXI_01_WDATA; + input [31:0] AXI_01_WDATA_PARITY; + input AXI_01_WLAST; + input [31:0] AXI_01_WSTRB; + input AXI_01_WVALID; + (* invertible_pin = "IS_AXI_02_ACLK_INVERTED" *) + input AXI_02_ACLK; + input [36:0] AXI_02_ARADDR; + input [1:0] AXI_02_ARBURST; + (* invertible_pin = "IS_AXI_02_ARESET_N_INVERTED" *) + input AXI_02_ARESET_N; + input [5:0] AXI_02_ARID; + input [3:0] AXI_02_ARLEN; + input [2:0] AXI_02_ARSIZE; + input AXI_02_ARVALID; + input [36:0] AXI_02_AWADDR; + input [1:0] AXI_02_AWBURST; + input [5:0] AXI_02_AWID; + input [3:0] AXI_02_AWLEN; + input [2:0] AXI_02_AWSIZE; + input AXI_02_AWVALID; + input AXI_02_BREADY; + input AXI_02_DFI_LP_PWR_X_REQ; + input AXI_02_RREADY; + input [255:0] AXI_02_WDATA; + input [31:0] AXI_02_WDATA_PARITY; + input AXI_02_WLAST; + input [31:0] AXI_02_WSTRB; + input AXI_02_WVALID; + (* invertible_pin = "IS_AXI_03_ACLK_INVERTED" *) + input AXI_03_ACLK; + input [36:0] AXI_03_ARADDR; + input [1:0] AXI_03_ARBURST; + (* invertible_pin = "IS_AXI_03_ARESET_N_INVERTED" *) + input AXI_03_ARESET_N; + input [5:0] AXI_03_ARID; + input [3:0] AXI_03_ARLEN; + input [2:0] AXI_03_ARSIZE; + input AXI_03_ARVALID; + input [36:0] AXI_03_AWADDR; + input [1:0] AXI_03_AWBURST; + input [5:0] AXI_03_AWID; + input [3:0] AXI_03_AWLEN; + input [2:0] AXI_03_AWSIZE; + input AXI_03_AWVALID; + input AXI_03_BREADY; + input AXI_03_DFI_LP_PWR_X_REQ; + input AXI_03_RREADY; + input [255:0] AXI_03_WDATA; + input [31:0] AXI_03_WDATA_PARITY; + input AXI_03_WLAST; + input [31:0] AXI_03_WSTRB; + input AXI_03_WVALID; + (* invertible_pin = "IS_AXI_04_ACLK_INVERTED" *) + input AXI_04_ACLK; + input [36:0] AXI_04_ARADDR; + input [1:0] AXI_04_ARBURST; + (* invertible_pin = "IS_AXI_04_ARESET_N_INVERTED" *) + input AXI_04_ARESET_N; + input [5:0] AXI_04_ARID; + input [3:0] AXI_04_ARLEN; + input [2:0] AXI_04_ARSIZE; + input AXI_04_ARVALID; + input [36:0] AXI_04_AWADDR; + input [1:0] AXI_04_AWBURST; + input [5:0] AXI_04_AWID; + input [3:0] AXI_04_AWLEN; + input [2:0] AXI_04_AWSIZE; + input AXI_04_AWVALID; + input AXI_04_BREADY; + input AXI_04_DFI_LP_PWR_X_REQ; + input AXI_04_RREADY; + input [255:0] AXI_04_WDATA; + input [31:0] AXI_04_WDATA_PARITY; + input AXI_04_WLAST; + input [31:0] AXI_04_WSTRB; + input AXI_04_WVALID; + (* invertible_pin = "IS_AXI_05_ACLK_INVERTED" *) + input AXI_05_ACLK; + input [36:0] AXI_05_ARADDR; + input [1:0] AXI_05_ARBURST; + (* invertible_pin = "IS_AXI_05_ARESET_N_INVERTED" *) + input AXI_05_ARESET_N; + input [5:0] AXI_05_ARID; + input [3:0] AXI_05_ARLEN; + input [2:0] AXI_05_ARSIZE; + input AXI_05_ARVALID; + input [36:0] AXI_05_AWADDR; + input [1:0] AXI_05_AWBURST; + input [5:0] AXI_05_AWID; + input [3:0] AXI_05_AWLEN; + input [2:0] AXI_05_AWSIZE; + input AXI_05_AWVALID; + input AXI_05_BREADY; + input AXI_05_DFI_LP_PWR_X_REQ; + input AXI_05_RREADY; + input [255:0] AXI_05_WDATA; + input [31:0] AXI_05_WDATA_PARITY; + input AXI_05_WLAST; + input [31:0] AXI_05_WSTRB; + input AXI_05_WVALID; + (* invertible_pin = "IS_AXI_06_ACLK_INVERTED" *) + input AXI_06_ACLK; + input [36:0] AXI_06_ARADDR; + input [1:0] AXI_06_ARBURST; + (* invertible_pin = "IS_AXI_06_ARESET_N_INVERTED" *) + input AXI_06_ARESET_N; + input [5:0] AXI_06_ARID; + input [3:0] AXI_06_ARLEN; + input [2:0] AXI_06_ARSIZE; + input AXI_06_ARVALID; + input [36:0] AXI_06_AWADDR; + input [1:0] AXI_06_AWBURST; + input [5:0] AXI_06_AWID; + input [3:0] AXI_06_AWLEN; + input [2:0] AXI_06_AWSIZE; + input AXI_06_AWVALID; + input AXI_06_BREADY; + input AXI_06_DFI_LP_PWR_X_REQ; + input AXI_06_RREADY; + input [255:0] AXI_06_WDATA; + input [31:0] AXI_06_WDATA_PARITY; + input AXI_06_WLAST; + input [31:0] AXI_06_WSTRB; + input AXI_06_WVALID; + (* invertible_pin = "IS_AXI_07_ACLK_INVERTED" *) + input AXI_07_ACLK; + input [36:0] AXI_07_ARADDR; + input [1:0] AXI_07_ARBURST; + (* invertible_pin = "IS_AXI_07_ARESET_N_INVERTED" *) + input AXI_07_ARESET_N; + input [5:0] AXI_07_ARID; + input [3:0] AXI_07_ARLEN; + input [2:0] AXI_07_ARSIZE; + input AXI_07_ARVALID; + input [36:0] AXI_07_AWADDR; + input [1:0] AXI_07_AWBURST; + input [5:0] AXI_07_AWID; + input [3:0] AXI_07_AWLEN; + input [2:0] AXI_07_AWSIZE; + input AXI_07_AWVALID; + input AXI_07_BREADY; + input AXI_07_DFI_LP_PWR_X_REQ; + input AXI_07_RREADY; + input [255:0] AXI_07_WDATA; + input [31:0] AXI_07_WDATA_PARITY; + input AXI_07_WLAST; + input [31:0] AXI_07_WSTRB; + input AXI_07_WVALID; + (* invertible_pin = "IS_AXI_08_ACLK_INVERTED" *) + input AXI_08_ACLK; + input [36:0] AXI_08_ARADDR; + input [1:0] AXI_08_ARBURST; + (* invertible_pin = "IS_AXI_08_ARESET_N_INVERTED" *) + input AXI_08_ARESET_N; + input [5:0] AXI_08_ARID; + input [3:0] AXI_08_ARLEN; + input [2:0] AXI_08_ARSIZE; + input AXI_08_ARVALID; + input [36:0] AXI_08_AWADDR; + input [1:0] AXI_08_AWBURST; + input [5:0] AXI_08_AWID; + input [3:0] AXI_08_AWLEN; + input [2:0] AXI_08_AWSIZE; + input AXI_08_AWVALID; + input AXI_08_BREADY; + input AXI_08_DFI_LP_PWR_X_REQ; + input AXI_08_RREADY; + input [255:0] AXI_08_WDATA; + input [31:0] AXI_08_WDATA_PARITY; + input AXI_08_WLAST; + input [31:0] AXI_08_WSTRB; + input AXI_08_WVALID; + (* invertible_pin = "IS_AXI_09_ACLK_INVERTED" *) + input AXI_09_ACLK; + input [36:0] AXI_09_ARADDR; + input [1:0] AXI_09_ARBURST; + (* invertible_pin = "IS_AXI_09_ARESET_N_INVERTED" *) + input AXI_09_ARESET_N; + input [5:0] AXI_09_ARID; + input [3:0] AXI_09_ARLEN; + input [2:0] AXI_09_ARSIZE; + input AXI_09_ARVALID; + input [36:0] AXI_09_AWADDR; + input [1:0] AXI_09_AWBURST; + input [5:0] AXI_09_AWID; + input [3:0] AXI_09_AWLEN; + input [2:0] AXI_09_AWSIZE; + input AXI_09_AWVALID; + input AXI_09_BREADY; + input AXI_09_DFI_LP_PWR_X_REQ; + input AXI_09_RREADY; + input [255:0] AXI_09_WDATA; + input [31:0] AXI_09_WDATA_PARITY; + input AXI_09_WLAST; + input [31:0] AXI_09_WSTRB; + input AXI_09_WVALID; + (* invertible_pin = "IS_AXI_10_ACLK_INVERTED" *) + input AXI_10_ACLK; + input [36:0] AXI_10_ARADDR; + input [1:0] AXI_10_ARBURST; + (* invertible_pin = "IS_AXI_10_ARESET_N_INVERTED" *) + input AXI_10_ARESET_N; + input [5:0] AXI_10_ARID; + input [3:0] AXI_10_ARLEN; + input [2:0] AXI_10_ARSIZE; + input AXI_10_ARVALID; + input [36:0] AXI_10_AWADDR; + input [1:0] AXI_10_AWBURST; + input [5:0] AXI_10_AWID; + input [3:0] AXI_10_AWLEN; + input [2:0] AXI_10_AWSIZE; + input AXI_10_AWVALID; + input AXI_10_BREADY; + input AXI_10_DFI_LP_PWR_X_REQ; + input AXI_10_RREADY; + input [255:0] AXI_10_WDATA; + input [31:0] AXI_10_WDATA_PARITY; + input AXI_10_WLAST; + input [31:0] AXI_10_WSTRB; + input AXI_10_WVALID; + (* invertible_pin = "IS_AXI_11_ACLK_INVERTED" *) + input AXI_11_ACLK; + input [36:0] AXI_11_ARADDR; + input [1:0] AXI_11_ARBURST; + (* invertible_pin = "IS_AXI_11_ARESET_N_INVERTED" *) + input AXI_11_ARESET_N; + input [5:0] AXI_11_ARID; + input [3:0] AXI_11_ARLEN; + input [2:0] AXI_11_ARSIZE; + input AXI_11_ARVALID; + input [36:0] AXI_11_AWADDR; + input [1:0] AXI_11_AWBURST; + input [5:0] AXI_11_AWID; + input [3:0] AXI_11_AWLEN; + input [2:0] AXI_11_AWSIZE; + input AXI_11_AWVALID; + input AXI_11_BREADY; + input AXI_11_DFI_LP_PWR_X_REQ; + input AXI_11_RREADY; + input [255:0] AXI_11_WDATA; + input [31:0] AXI_11_WDATA_PARITY; + input AXI_11_WLAST; + input [31:0] AXI_11_WSTRB; + input AXI_11_WVALID; + (* invertible_pin = "IS_AXI_12_ACLK_INVERTED" *) + input AXI_12_ACLK; + input [36:0] AXI_12_ARADDR; + input [1:0] AXI_12_ARBURST; + (* invertible_pin = "IS_AXI_12_ARESET_N_INVERTED" *) + input AXI_12_ARESET_N; + input [5:0] AXI_12_ARID; + input [3:0] AXI_12_ARLEN; + input [2:0] AXI_12_ARSIZE; + input AXI_12_ARVALID; + input [36:0] AXI_12_AWADDR; + input [1:0] AXI_12_AWBURST; + input [5:0] AXI_12_AWID; + input [3:0] AXI_12_AWLEN; + input [2:0] AXI_12_AWSIZE; + input AXI_12_AWVALID; + input AXI_12_BREADY; + input AXI_12_DFI_LP_PWR_X_REQ; + input AXI_12_RREADY; + input [255:0] AXI_12_WDATA; + input [31:0] AXI_12_WDATA_PARITY; + input AXI_12_WLAST; + input [31:0] AXI_12_WSTRB; + input AXI_12_WVALID; + (* invertible_pin = "IS_AXI_13_ACLK_INVERTED" *) + input AXI_13_ACLK; + input [36:0] AXI_13_ARADDR; + input [1:0] AXI_13_ARBURST; + (* invertible_pin = "IS_AXI_13_ARESET_N_INVERTED" *) + input AXI_13_ARESET_N; + input [5:0] AXI_13_ARID; + input [3:0] AXI_13_ARLEN; + input [2:0] AXI_13_ARSIZE; + input AXI_13_ARVALID; + input [36:0] AXI_13_AWADDR; + input [1:0] AXI_13_AWBURST; + input [5:0] AXI_13_AWID; + input [3:0] AXI_13_AWLEN; + input [2:0] AXI_13_AWSIZE; + input AXI_13_AWVALID; + input AXI_13_BREADY; + input AXI_13_DFI_LP_PWR_X_REQ; + input AXI_13_RREADY; + input [255:0] AXI_13_WDATA; + input [31:0] AXI_13_WDATA_PARITY; + input AXI_13_WLAST; + input [31:0] AXI_13_WSTRB; + input AXI_13_WVALID; + (* invertible_pin = "IS_AXI_14_ACLK_INVERTED" *) + input AXI_14_ACLK; + input [36:0] AXI_14_ARADDR; + input [1:0] AXI_14_ARBURST; + (* invertible_pin = "IS_AXI_14_ARESET_N_INVERTED" *) + input AXI_14_ARESET_N; + input [5:0] AXI_14_ARID; + input [3:0] AXI_14_ARLEN; + input [2:0] AXI_14_ARSIZE; + input AXI_14_ARVALID; + input [36:0] AXI_14_AWADDR; + input [1:0] AXI_14_AWBURST; + input [5:0] AXI_14_AWID; + input [3:0] AXI_14_AWLEN; + input [2:0] AXI_14_AWSIZE; + input AXI_14_AWVALID; + input AXI_14_BREADY; + input AXI_14_DFI_LP_PWR_X_REQ; + input AXI_14_RREADY; + input [255:0] AXI_14_WDATA; + input [31:0] AXI_14_WDATA_PARITY; + input AXI_14_WLAST; + input [31:0] AXI_14_WSTRB; + input AXI_14_WVALID; + (* invertible_pin = "IS_AXI_15_ACLK_INVERTED" *) + input AXI_15_ACLK; + input [36:0] AXI_15_ARADDR; + input [1:0] AXI_15_ARBURST; + (* invertible_pin = "IS_AXI_15_ARESET_N_INVERTED" *) + input AXI_15_ARESET_N; + input [5:0] AXI_15_ARID; + input [3:0] AXI_15_ARLEN; + input [2:0] AXI_15_ARSIZE; + input AXI_15_ARVALID; + input [36:0] AXI_15_AWADDR; + input [1:0] AXI_15_AWBURST; + input [5:0] AXI_15_AWID; + input [3:0] AXI_15_AWLEN; + input [2:0] AXI_15_AWSIZE; + input AXI_15_AWVALID; + input AXI_15_BREADY; + input AXI_15_DFI_LP_PWR_X_REQ; + input AXI_15_RREADY; + input [255:0] AXI_15_WDATA; + input [31:0] AXI_15_WDATA_PARITY; + input AXI_15_WLAST; + input [31:0] AXI_15_WSTRB; + input AXI_15_WVALID; + (* invertible_pin = "IS_AXI_16_ACLK_INVERTED" *) + input AXI_16_ACLK; + input [36:0] AXI_16_ARADDR; + input [1:0] AXI_16_ARBURST; + (* invertible_pin = "IS_AXI_16_ARESET_N_INVERTED" *) + input AXI_16_ARESET_N; + input [5:0] AXI_16_ARID; + input [3:0] AXI_16_ARLEN; + input [2:0] AXI_16_ARSIZE; + input AXI_16_ARVALID; + input [36:0] AXI_16_AWADDR; + input [1:0] AXI_16_AWBURST; + input [5:0] AXI_16_AWID; + input [3:0] AXI_16_AWLEN; + input [2:0] AXI_16_AWSIZE; + input AXI_16_AWVALID; + input AXI_16_BREADY; + input AXI_16_DFI_LP_PWR_X_REQ; + input AXI_16_RREADY; + input [255:0] AXI_16_WDATA; + input [31:0] AXI_16_WDATA_PARITY; + input AXI_16_WLAST; + input [31:0] AXI_16_WSTRB; + input AXI_16_WVALID; + (* invertible_pin = "IS_AXI_17_ACLK_INVERTED" *) + input AXI_17_ACLK; + input [36:0] AXI_17_ARADDR; + input [1:0] AXI_17_ARBURST; + (* invertible_pin = "IS_AXI_17_ARESET_N_INVERTED" *) + input AXI_17_ARESET_N; + input [5:0] AXI_17_ARID; + input [3:0] AXI_17_ARLEN; + input [2:0] AXI_17_ARSIZE; + input AXI_17_ARVALID; + input [36:0] AXI_17_AWADDR; + input [1:0] AXI_17_AWBURST; + input [5:0] AXI_17_AWID; + input [3:0] AXI_17_AWLEN; + input [2:0] AXI_17_AWSIZE; + input AXI_17_AWVALID; + input AXI_17_BREADY; + input AXI_17_DFI_LP_PWR_X_REQ; + input AXI_17_RREADY; + input [255:0] AXI_17_WDATA; + input [31:0] AXI_17_WDATA_PARITY; + input AXI_17_WLAST; + input [31:0] AXI_17_WSTRB; + input AXI_17_WVALID; + (* invertible_pin = "IS_AXI_18_ACLK_INVERTED" *) + input AXI_18_ACLK; + input [36:0] AXI_18_ARADDR; + input [1:0] AXI_18_ARBURST; + (* invertible_pin = "IS_AXI_18_ARESET_N_INVERTED" *) + input AXI_18_ARESET_N; + input [5:0] AXI_18_ARID; + input [3:0] AXI_18_ARLEN; + input [2:0] AXI_18_ARSIZE; + input AXI_18_ARVALID; + input [36:0] AXI_18_AWADDR; + input [1:0] AXI_18_AWBURST; + input [5:0] AXI_18_AWID; + input [3:0] AXI_18_AWLEN; + input [2:0] AXI_18_AWSIZE; + input AXI_18_AWVALID; + input AXI_18_BREADY; + input AXI_18_DFI_LP_PWR_X_REQ; + input AXI_18_RREADY; + input [255:0] AXI_18_WDATA; + input [31:0] AXI_18_WDATA_PARITY; + input AXI_18_WLAST; + input [31:0] AXI_18_WSTRB; + input AXI_18_WVALID; + (* invertible_pin = "IS_AXI_19_ACLK_INVERTED" *) + input AXI_19_ACLK; + input [36:0] AXI_19_ARADDR; + input [1:0] AXI_19_ARBURST; + (* invertible_pin = "IS_AXI_19_ARESET_N_INVERTED" *) + input AXI_19_ARESET_N; + input [5:0] AXI_19_ARID; + input [3:0] AXI_19_ARLEN; + input [2:0] AXI_19_ARSIZE; + input AXI_19_ARVALID; + input [36:0] AXI_19_AWADDR; + input [1:0] AXI_19_AWBURST; + input [5:0] AXI_19_AWID; + input [3:0] AXI_19_AWLEN; + input [2:0] AXI_19_AWSIZE; + input AXI_19_AWVALID; + input AXI_19_BREADY; + input AXI_19_DFI_LP_PWR_X_REQ; + input AXI_19_RREADY; + input [255:0] AXI_19_WDATA; + input [31:0] AXI_19_WDATA_PARITY; + input AXI_19_WLAST; + input [31:0] AXI_19_WSTRB; + input AXI_19_WVALID; + (* invertible_pin = "IS_AXI_20_ACLK_INVERTED" *) + input AXI_20_ACLK; + input [36:0] AXI_20_ARADDR; + input [1:0] AXI_20_ARBURST; + (* invertible_pin = "IS_AXI_20_ARESET_N_INVERTED" *) + input AXI_20_ARESET_N; + input [5:0] AXI_20_ARID; + input [3:0] AXI_20_ARLEN; + input [2:0] AXI_20_ARSIZE; + input AXI_20_ARVALID; + input [36:0] AXI_20_AWADDR; + input [1:0] AXI_20_AWBURST; + input [5:0] AXI_20_AWID; + input [3:0] AXI_20_AWLEN; + input [2:0] AXI_20_AWSIZE; + input AXI_20_AWVALID; + input AXI_20_BREADY; + input AXI_20_DFI_LP_PWR_X_REQ; + input AXI_20_RREADY; + input [255:0] AXI_20_WDATA; + input [31:0] AXI_20_WDATA_PARITY; + input AXI_20_WLAST; + input [31:0] AXI_20_WSTRB; + input AXI_20_WVALID; + (* invertible_pin = "IS_AXI_21_ACLK_INVERTED" *) + input AXI_21_ACLK; + input [36:0] AXI_21_ARADDR; + input [1:0] AXI_21_ARBURST; + (* invertible_pin = "IS_AXI_21_ARESET_N_INVERTED" *) + input AXI_21_ARESET_N; + input [5:0] AXI_21_ARID; + input [3:0] AXI_21_ARLEN; + input [2:0] AXI_21_ARSIZE; + input AXI_21_ARVALID; + input [36:0] AXI_21_AWADDR; + input [1:0] AXI_21_AWBURST; + input [5:0] AXI_21_AWID; + input [3:0] AXI_21_AWLEN; + input [2:0] AXI_21_AWSIZE; + input AXI_21_AWVALID; + input AXI_21_BREADY; + input AXI_21_DFI_LP_PWR_X_REQ; + input AXI_21_RREADY; + input [255:0] AXI_21_WDATA; + input [31:0] AXI_21_WDATA_PARITY; + input AXI_21_WLAST; + input [31:0] AXI_21_WSTRB; + input AXI_21_WVALID; + (* invertible_pin = "IS_AXI_22_ACLK_INVERTED" *) + input AXI_22_ACLK; + input [36:0] AXI_22_ARADDR; + input [1:0] AXI_22_ARBURST; + (* invertible_pin = "IS_AXI_22_ARESET_N_INVERTED" *) + input AXI_22_ARESET_N; + input [5:0] AXI_22_ARID; + input [3:0] AXI_22_ARLEN; + input [2:0] AXI_22_ARSIZE; + input AXI_22_ARVALID; + input [36:0] AXI_22_AWADDR; + input [1:0] AXI_22_AWBURST; + input [5:0] AXI_22_AWID; + input [3:0] AXI_22_AWLEN; + input [2:0] AXI_22_AWSIZE; + input AXI_22_AWVALID; + input AXI_22_BREADY; + input AXI_22_DFI_LP_PWR_X_REQ; + input AXI_22_RREADY; + input [255:0] AXI_22_WDATA; + input [31:0] AXI_22_WDATA_PARITY; + input AXI_22_WLAST; + input [31:0] AXI_22_WSTRB; + input AXI_22_WVALID; + (* invertible_pin = "IS_AXI_23_ACLK_INVERTED" *) + input AXI_23_ACLK; + input [36:0] AXI_23_ARADDR; + input [1:0] AXI_23_ARBURST; + (* invertible_pin = "IS_AXI_23_ARESET_N_INVERTED" *) + input AXI_23_ARESET_N; + input [5:0] AXI_23_ARID; + input [3:0] AXI_23_ARLEN; + input [2:0] AXI_23_ARSIZE; + input AXI_23_ARVALID; + input [36:0] AXI_23_AWADDR; + input [1:0] AXI_23_AWBURST; + input [5:0] AXI_23_AWID; + input [3:0] AXI_23_AWLEN; + input [2:0] AXI_23_AWSIZE; + input AXI_23_AWVALID; + input AXI_23_BREADY; + input AXI_23_DFI_LP_PWR_X_REQ; + input AXI_23_RREADY; + input [255:0] AXI_23_WDATA; + input [31:0] AXI_23_WDATA_PARITY; + input AXI_23_WLAST; + input [31:0] AXI_23_WSTRB; + input AXI_23_WVALID; + (* invertible_pin = "IS_AXI_24_ACLK_INVERTED" *) + input AXI_24_ACLK; + input [36:0] AXI_24_ARADDR; + input [1:0] AXI_24_ARBURST; + (* invertible_pin = "IS_AXI_24_ARESET_N_INVERTED" *) + input AXI_24_ARESET_N; + input [5:0] AXI_24_ARID; + input [3:0] AXI_24_ARLEN; + input [2:0] AXI_24_ARSIZE; + input AXI_24_ARVALID; + input [36:0] AXI_24_AWADDR; + input [1:0] AXI_24_AWBURST; + input [5:0] AXI_24_AWID; + input [3:0] AXI_24_AWLEN; + input [2:0] AXI_24_AWSIZE; + input AXI_24_AWVALID; + input AXI_24_BREADY; + input AXI_24_DFI_LP_PWR_X_REQ; + input AXI_24_RREADY; + input [255:0] AXI_24_WDATA; + input [31:0] AXI_24_WDATA_PARITY; + input AXI_24_WLAST; + input [31:0] AXI_24_WSTRB; + input AXI_24_WVALID; + (* invertible_pin = "IS_AXI_25_ACLK_INVERTED" *) + input AXI_25_ACLK; + input [36:0] AXI_25_ARADDR; + input [1:0] AXI_25_ARBURST; + (* invertible_pin = "IS_AXI_25_ARESET_N_INVERTED" *) + input AXI_25_ARESET_N; + input [5:0] AXI_25_ARID; + input [3:0] AXI_25_ARLEN; + input [2:0] AXI_25_ARSIZE; + input AXI_25_ARVALID; + input [36:0] AXI_25_AWADDR; + input [1:0] AXI_25_AWBURST; + input [5:0] AXI_25_AWID; + input [3:0] AXI_25_AWLEN; + input [2:0] AXI_25_AWSIZE; + input AXI_25_AWVALID; + input AXI_25_BREADY; + input AXI_25_DFI_LP_PWR_X_REQ; + input AXI_25_RREADY; + input [255:0] AXI_25_WDATA; + input [31:0] AXI_25_WDATA_PARITY; + input AXI_25_WLAST; + input [31:0] AXI_25_WSTRB; + input AXI_25_WVALID; + (* invertible_pin = "IS_AXI_26_ACLK_INVERTED" *) + input AXI_26_ACLK; + input [36:0] AXI_26_ARADDR; + input [1:0] AXI_26_ARBURST; + (* invertible_pin = "IS_AXI_26_ARESET_N_INVERTED" *) + input AXI_26_ARESET_N; + input [5:0] AXI_26_ARID; + input [3:0] AXI_26_ARLEN; + input [2:0] AXI_26_ARSIZE; + input AXI_26_ARVALID; + input [36:0] AXI_26_AWADDR; + input [1:0] AXI_26_AWBURST; + input [5:0] AXI_26_AWID; + input [3:0] AXI_26_AWLEN; + input [2:0] AXI_26_AWSIZE; + input AXI_26_AWVALID; + input AXI_26_BREADY; + input AXI_26_DFI_LP_PWR_X_REQ; + input AXI_26_RREADY; + input [255:0] AXI_26_WDATA; + input [31:0] AXI_26_WDATA_PARITY; + input AXI_26_WLAST; + input [31:0] AXI_26_WSTRB; + input AXI_26_WVALID; + (* invertible_pin = "IS_AXI_27_ACLK_INVERTED" *) + input AXI_27_ACLK; + input [36:0] AXI_27_ARADDR; + input [1:0] AXI_27_ARBURST; + (* invertible_pin = "IS_AXI_27_ARESET_N_INVERTED" *) + input AXI_27_ARESET_N; + input [5:0] AXI_27_ARID; + input [3:0] AXI_27_ARLEN; + input [2:0] AXI_27_ARSIZE; + input AXI_27_ARVALID; + input [36:0] AXI_27_AWADDR; + input [1:0] AXI_27_AWBURST; + input [5:0] AXI_27_AWID; + input [3:0] AXI_27_AWLEN; + input [2:0] AXI_27_AWSIZE; + input AXI_27_AWVALID; + input AXI_27_BREADY; + input AXI_27_DFI_LP_PWR_X_REQ; + input AXI_27_RREADY; + input [255:0] AXI_27_WDATA; + input [31:0] AXI_27_WDATA_PARITY; + input AXI_27_WLAST; + input [31:0] AXI_27_WSTRB; + input AXI_27_WVALID; + (* invertible_pin = "IS_AXI_28_ACLK_INVERTED" *) + input AXI_28_ACLK; + input [36:0] AXI_28_ARADDR; + input [1:0] AXI_28_ARBURST; + (* invertible_pin = "IS_AXI_28_ARESET_N_INVERTED" *) + input AXI_28_ARESET_N; + input [5:0] AXI_28_ARID; + input [3:0] AXI_28_ARLEN; + input [2:0] AXI_28_ARSIZE; + input AXI_28_ARVALID; + input [36:0] AXI_28_AWADDR; + input [1:0] AXI_28_AWBURST; + input [5:0] AXI_28_AWID; + input [3:0] AXI_28_AWLEN; + input [2:0] AXI_28_AWSIZE; + input AXI_28_AWVALID; + input AXI_28_BREADY; + input AXI_28_DFI_LP_PWR_X_REQ; + input AXI_28_RREADY; + input [255:0] AXI_28_WDATA; + input [31:0] AXI_28_WDATA_PARITY; + input AXI_28_WLAST; + input [31:0] AXI_28_WSTRB; + input AXI_28_WVALID; + (* invertible_pin = "IS_AXI_29_ACLK_INVERTED" *) + input AXI_29_ACLK; + input [36:0] AXI_29_ARADDR; + input [1:0] AXI_29_ARBURST; + (* invertible_pin = "IS_AXI_29_ARESET_N_INVERTED" *) + input AXI_29_ARESET_N; + input [5:0] AXI_29_ARID; + input [3:0] AXI_29_ARLEN; + input [2:0] AXI_29_ARSIZE; + input AXI_29_ARVALID; + input [36:0] AXI_29_AWADDR; + input [1:0] AXI_29_AWBURST; + input [5:0] AXI_29_AWID; + input [3:0] AXI_29_AWLEN; + input [2:0] AXI_29_AWSIZE; + input AXI_29_AWVALID; + input AXI_29_BREADY; + input AXI_29_DFI_LP_PWR_X_REQ; + input AXI_29_RREADY; + input [255:0] AXI_29_WDATA; + input [31:0] AXI_29_WDATA_PARITY; + input AXI_29_WLAST; + input [31:0] AXI_29_WSTRB; + input AXI_29_WVALID; + (* invertible_pin = "IS_AXI_30_ACLK_INVERTED" *) + input AXI_30_ACLK; + input [36:0] AXI_30_ARADDR; + input [1:0] AXI_30_ARBURST; + (* invertible_pin = "IS_AXI_30_ARESET_N_INVERTED" *) + input AXI_30_ARESET_N; + input [5:0] AXI_30_ARID; + input [3:0] AXI_30_ARLEN; + input [2:0] AXI_30_ARSIZE; + input AXI_30_ARVALID; + input [36:0] AXI_30_AWADDR; + input [1:0] AXI_30_AWBURST; + input [5:0] AXI_30_AWID; + input [3:0] AXI_30_AWLEN; + input [2:0] AXI_30_AWSIZE; + input AXI_30_AWVALID; + input AXI_30_BREADY; + input AXI_30_DFI_LP_PWR_X_REQ; + input AXI_30_RREADY; + input [255:0] AXI_30_WDATA; + input [31:0] AXI_30_WDATA_PARITY; + input AXI_30_WLAST; + input [31:0] AXI_30_WSTRB; + input AXI_30_WVALID; + (* invertible_pin = "IS_AXI_31_ACLK_INVERTED" *) + input AXI_31_ACLK; + input [36:0] AXI_31_ARADDR; + input [1:0] AXI_31_ARBURST; + (* invertible_pin = "IS_AXI_31_ARESET_N_INVERTED" *) + input AXI_31_ARESET_N; + input [5:0] AXI_31_ARID; + input [3:0] AXI_31_ARLEN; + input [2:0] AXI_31_ARSIZE; + input AXI_31_ARVALID; + input [36:0] AXI_31_AWADDR; + input [1:0] AXI_31_AWBURST; + input [5:0] AXI_31_AWID; + input [3:0] AXI_31_AWLEN; + input [2:0] AXI_31_AWSIZE; + input AXI_31_AWVALID; + input AXI_31_BREADY; + input AXI_31_DFI_LP_PWR_X_REQ; + input AXI_31_RREADY; + input [255:0] AXI_31_WDATA; + input [31:0] AXI_31_WDATA_PARITY; + input AXI_31_WLAST; + input [31:0] AXI_31_WSTRB; + input AXI_31_WVALID; + input BSCAN_DRCK_0; + input BSCAN_DRCK_1; + input BSCAN_TCK_0; + input BSCAN_TCK_1; + input HBM_REF_CLK_0; + input HBM_REF_CLK_1; + input MBIST_EN_00; + input MBIST_EN_01; + input MBIST_EN_02; + input MBIST_EN_03; + input MBIST_EN_04; + input MBIST_EN_05; + input MBIST_EN_06; + input MBIST_EN_07; + input MBIST_EN_08; + input MBIST_EN_09; + input MBIST_EN_10; + input MBIST_EN_11; + input MBIST_EN_12; + input MBIST_EN_13; + input MBIST_EN_14; + input MBIST_EN_15; +endmodule + +module PPC405_ADV (...); + parameter in_delay=100; + parameter out_delay=100; + output APUFCMDECODED; + output APUFCMDECUDIVALID; + output APUFCMENDIAN; + output APUFCMFLUSH; + output APUFCMINSTRVALID; + output APUFCMLOADDVALID; + output APUFCMOPERANDVALID; + output APUFCMWRITEBACKOK; + output APUFCMXERCA; + output C405CPMCORESLEEPREQ; + output C405CPMMSRCE; + output C405CPMMSREE; + output C405CPMTIMERIRQ; + output C405CPMTIMERRESETREQ; + output C405DBGLOADDATAONAPUDBUS; + output C405DBGMSRWE; + output C405DBGSTOPACK; + output C405DBGWBCOMPLETE; + output C405DBGWBFULL; + output C405JTGCAPTUREDR; + output C405JTGEXTEST; + output C405JTGPGMOUT; + output C405JTGSHIFTDR; + output C405JTGTDO; + output C405JTGTDOEN; + output C405JTGUPDATEDR; + output C405PLBDCUABORT; + output C405PLBDCUCACHEABLE; + output C405PLBDCUGUARDED; + output C405PLBDCUREQUEST; + output C405PLBDCURNW; + output C405PLBDCUSIZE2; + output C405PLBDCUU0ATTR; + output C405PLBDCUWRITETHRU; + output C405PLBICUABORT; + output C405PLBICUCACHEABLE; + output C405PLBICUREQUEST; + output C405PLBICUU0ATTR; + output C405RSTCHIPRESETREQ; + output C405RSTCORERESETREQ; + output C405RSTSYSRESETREQ; + output C405TRCCYCLE; + output C405TRCTRIGGEREVENTOUT; + output C405XXXMACHINECHECK; + output DCREMACCLK; + output DCREMACENABLER; + output DCREMACREAD; + output DCREMACWRITE; + output DSOCMBRAMEN; + output DSOCMBUSY; + output DSOCMRDADDRVALID; + output DSOCMWRADDRVALID; + output EXTDCRREAD; + output EXTDCRWRITE; + output ISOCMBRAMEN; + output ISOCMBRAMEVENWRITEEN; + output ISOCMBRAMODDWRITEEN; + output ISOCMDCRBRAMEVENEN; + output ISOCMDCRBRAMODDEN; + output ISOCMDCRBRAMRDSELECT; + output [0:10] C405TRCTRIGGEREVENTTYPE; + output [0:1] C405PLBDCUPRIORITY; + output [0:1] C405PLBICUPRIORITY; + output [0:1] C405TRCEVENEXECUTIONSTATUS; + output [0:1] C405TRCODDEXECUTIONSTATUS; + output [0:29] C405DBGWBIAR; + output [0:29] C405PLBICUABUS; + output [0:2] APUFCMDECUDI; + output [0:31] APUFCMINSTRUCTION; + output [0:31] APUFCMLOADDATA; + output [0:31] APUFCMRADATA; + output [0:31] APUFCMRBDATA; + output [0:31] C405PLBDCUABUS; + output [0:31] DCREMACDBUS; + output [0:31] DSOCMBRAMWRDBUS; + output [0:31] EXTDCRDBUSOUT; + output [0:31] ISOCMBRAMWRDBUS; + output [0:3] APUFCMLOADBYTEEN; + output [0:3] C405TRCTRACESTATUS; + output [0:3] DSOCMBRAMBYTEWRITE; + output [0:63] C405PLBDCUWRDBUS; + output [0:7] C405PLBDCUBE; + output [0:9] EXTDCRABUS; + output [2:3] C405PLBICUSIZE; + output [8:28] ISOCMBRAMRDABUS; + output [8:28] ISOCMBRAMWRABUS; + output [8:29] DSOCMBRAMABUS; + output [8:9] DCREMACABUS; + input BRAMDSOCMCLK; + input BRAMISOCMCLK; + input CPMC405CLOCK; + input CPMC405CORECLKINACTIVE; + input CPMC405CPUCLKEN; + input CPMC405JTAGCLKEN; + input CPMC405SYNCBYPASS; + input CPMC405TIMERCLKEN; + input CPMC405TIMERTICK; + input CPMDCRCLK; + input CPMFCMCLK; + input DBGC405DEBUGHALT; + input DBGC405EXTBUSHOLDACK; + input DBGC405UNCONDDEBUGEVENT; + input DSOCMRWCOMPLETE; + input EICC405CRITINPUTIRQ; + input EICC405EXTINPUTIRQ; + input EMACDCRACK; + input EXTDCRACK; + input FCMAPUDCDCREN; + input FCMAPUDCDFORCEALIGN; + input FCMAPUDCDFORCEBESTEERING; + input FCMAPUDCDFPUOP; + input FCMAPUDCDGPRWRITE; + input FCMAPUDCDLDSTBYTE; + input FCMAPUDCDLDSTDW; + input FCMAPUDCDLDSTHW; + input FCMAPUDCDLDSTQW; + input FCMAPUDCDLDSTWD; + input FCMAPUDCDLOAD; + input FCMAPUDCDPRIVOP; + input FCMAPUDCDRAEN; + input FCMAPUDCDRBEN; + input FCMAPUDCDSTORE; + input FCMAPUDCDTRAPBE; + input FCMAPUDCDTRAPLE; + input FCMAPUDCDUPDATE; + input FCMAPUDCDXERCAEN; + input FCMAPUDCDXEROVEN; + input FCMAPUDECODEBUSY; + input FCMAPUDONE; + input FCMAPUEXCEPTION; + input FCMAPUEXEBLOCKINGMCO; + input FCMAPUEXENONBLOCKINGMCO; + input FCMAPUINSTRACK; + input FCMAPULOADWAIT; + input FCMAPURESULTVALID; + input FCMAPUSLEEPNOTREADY; + input FCMAPUXERCA; + input FCMAPUXEROV; + input JTGC405BNDSCANTDO; + input JTGC405TCK; + input JTGC405TDI; + input JTGC405TMS; + input JTGC405TRSTNEG; + input MCBCPUCLKEN; + input MCBJTAGEN; + input MCBTIMEREN; + input MCPPCRST; + input PLBC405DCUADDRACK; + input PLBC405DCUBUSY; + input PLBC405DCUERR; + input PLBC405DCURDDACK; + input PLBC405DCUSSIZE1; + input PLBC405DCUWRDACK; + input PLBC405ICUADDRACK; + input PLBC405ICUBUSY; + input PLBC405ICUERR; + input PLBC405ICURDDACK; + input PLBC405ICUSSIZE1; + input PLBCLK; + input RSTC405RESETCHIP; + input RSTC405RESETCORE; + input RSTC405RESETSYS; + input TIEC405DETERMINISTICMULT; + input TIEC405DISOPERANDFWD; + input TIEC405MMUEN; + input TIEPVRBIT10; + input TIEPVRBIT11; + input TIEPVRBIT28; + input TIEPVRBIT29; + input TIEPVRBIT30; + input TIEPVRBIT31; + input TIEPVRBIT8; + input TIEPVRBIT9; + input TRCC405TRACEDISABLE; + input TRCC405TRIGGEREVENTIN; + input [0:15] TIEAPUCONTROL; + input [0:23] TIEAPUUDI1; + input [0:23] TIEAPUUDI2; + input [0:23] TIEAPUUDI3; + input [0:23] TIEAPUUDI4; + input [0:23] TIEAPUUDI5; + input [0:23] TIEAPUUDI6; + input [0:23] TIEAPUUDI7; + input [0:23] TIEAPUUDI8; + input [0:2] FCMAPUEXECRFIELD; + input [0:31] BRAMDSOCMRDDBUS; + input [0:31] BRAMISOCMDCRRDDBUS; + input [0:31] EMACDCRDBUS; + input [0:31] EXTDCRDBUSIN; + input [0:31] FCMAPURESULT; + input [0:3] FCMAPUCR; + input [0:5] TIEDCRADDR; + input [0:63] BRAMISOCMRDDBUS; + input [0:63] PLBC405DCURDDBUS; + input [0:63] PLBC405ICURDDBUS; + input [0:7] DSARCVALUE; + input [0:7] DSCNTLVALUE; + input [0:7] ISARCVALUE; + input [0:7] ISCNTLVALUE; + input [1:3] PLBC405DCURDWDADDR; + input [1:3] PLBC405ICURDWDADDR; +endmodule + +module PPC440 (...); + parameter CLOCK_DELAY = "FALSE"; + parameter DCR_AUTOLOCK_ENABLE = "TRUE"; + parameter PPCDM_ASYNCMODE = "FALSE"; + parameter PPCDS_ASYNCMODE = "FALSE"; + parameter PPCS0_WIDTH_128N64 = "TRUE"; + parameter PPCS1_WIDTH_128N64 = "TRUE"; + parameter [0:16] APU_CONTROL = 17'h02000; + parameter [0:23] APU_UDI0 = 24'h000000; + parameter [0:23] APU_UDI1 = 24'h000000; + parameter [0:23] APU_UDI10 = 24'h000000; + parameter [0:23] APU_UDI11 = 24'h000000; + parameter [0:23] APU_UDI12 = 24'h000000; + parameter [0:23] APU_UDI13 = 24'h000000; + parameter [0:23] APU_UDI14 = 24'h000000; + parameter [0:23] APU_UDI15 = 24'h000000; + parameter [0:23] APU_UDI2 = 24'h000000; + parameter [0:23] APU_UDI3 = 24'h000000; + parameter [0:23] APU_UDI4 = 24'h000000; + parameter [0:23] APU_UDI5 = 24'h000000; + parameter [0:23] APU_UDI6 = 24'h000000; + parameter [0:23] APU_UDI7 = 24'h000000; + parameter [0:23] APU_UDI8 = 24'h000000; + parameter [0:23] APU_UDI9 = 24'h000000; + parameter [0:31] DMA0_RXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA0_TXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA1_RXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA1_TXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA2_RXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA2_TXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA3_RXCHANNELCTRL = 32'h01010000; + parameter [0:31] DMA3_TXCHANNELCTRL = 32'h01010000; + parameter [0:31] INTERCONNECT_IMASK = 32'hFFFFFFFF; + parameter [0:31] INTERCONNECT_TMPL_SEL = 32'h3FFFFFFF; + parameter [0:31] MI_ARBCONFIG = 32'h00432010; + parameter [0:31] MI_BANKCONFLICT_MASK = 32'h00000000; + parameter [0:31] MI_CONTROL = 32'h0000008F; + parameter [0:31] MI_ROWCONFLICT_MASK = 32'h00000000; + parameter [0:31] PPCM_ARBCONFIG = 32'h00432010; + parameter [0:31] PPCM_CONTROL = 32'h8000019F; + parameter [0:31] PPCM_COUNTER = 32'h00000500; + parameter [0:31] PPCS0_ADDRMAP_TMPL0 = 32'hFFFFFFFF; + parameter [0:31] PPCS0_ADDRMAP_TMPL1 = 32'hFFFFFFFF; + parameter [0:31] PPCS0_ADDRMAP_TMPL2 = 32'hFFFFFFFF; + parameter [0:31] PPCS0_ADDRMAP_TMPL3 = 32'hFFFFFFFF; + parameter [0:31] PPCS0_CONTROL = 32'h8033336C; + parameter [0:31] PPCS1_ADDRMAP_TMPL0 = 32'hFFFFFFFF; + parameter [0:31] PPCS1_ADDRMAP_TMPL1 = 32'hFFFFFFFF; + parameter [0:31] PPCS1_ADDRMAP_TMPL2 = 32'hFFFFFFFF; + parameter [0:31] PPCS1_ADDRMAP_TMPL3 = 32'hFFFFFFFF; + parameter [0:31] PPCS1_CONTROL = 32'h8033336C; + parameter [0:31] XBAR_ADDRMAP_TMPL0 = 32'hFFFF0000; + parameter [0:31] XBAR_ADDRMAP_TMPL1 = 32'h00000000; + parameter [0:31] XBAR_ADDRMAP_TMPL2 = 32'h00000000; + parameter [0:31] XBAR_ADDRMAP_TMPL3 = 32'h00000000; + parameter [0:7] DMA0_CONTROL = 8'h00; + parameter [0:7] DMA1_CONTROL = 8'h00; + parameter [0:7] DMA2_CONTROL = 8'h00; + parameter [0:7] DMA3_CONTROL = 8'h00; + parameter [0:9] DMA0_RXIRQTIMER = 10'h3FF; + parameter [0:9] DMA0_TXIRQTIMER = 10'h3FF; + parameter [0:9] DMA1_RXIRQTIMER = 10'h3FF; + parameter [0:9] DMA1_TXIRQTIMER = 10'h3FF; + parameter [0:9] DMA2_RXIRQTIMER = 10'h3FF; + parameter [0:9] DMA2_TXIRQTIMER = 10'h3FF; + parameter [0:9] DMA3_RXIRQTIMER = 10'h3FF; + parameter [0:9] DMA3_TXIRQTIMER = 10'h3FF; + output APUFCMDECFPUOP; + output APUFCMDECLOAD; + output APUFCMDECNONAUTON; + output APUFCMDECSTORE; + output APUFCMDECUDIVALID; + output APUFCMENDIAN; + output APUFCMFLUSH; + output APUFCMINSTRVALID; + output APUFCMLOADDVALID; + output APUFCMMSRFE0; + output APUFCMMSRFE1; + output APUFCMNEXTINSTRREADY; + output APUFCMOPERANDVALID; + output APUFCMWRITEBACKOK; + output C440CPMCORESLEEPREQ; + output C440CPMDECIRPTREQ; + output C440CPMFITIRPTREQ; + output C440CPMMSRCE; + output C440CPMMSREE; + output C440CPMTIMERRESETREQ; + output C440CPMWDIRPTREQ; + output C440JTGTDO; + output C440JTGTDOEN; + output C440MACHINECHECK; + output C440RSTCHIPRESETREQ; + output C440RSTCORERESETREQ; + output C440RSTSYSTEMRESETREQ; + output C440TRCCYCLE; + output C440TRCTRIGGEREVENTOUT; + output DMA0LLRSTENGINEACK; + output DMA0LLRXDSTRDYN; + output DMA0LLTXEOFN; + output DMA0LLTXEOPN; + output DMA0LLTXSOFN; + output DMA0LLTXSOPN; + output DMA0LLTXSRCRDYN; + output DMA0RXIRQ; + output DMA0TXIRQ; + output DMA1LLRSTENGINEACK; + output DMA1LLRXDSTRDYN; + output DMA1LLTXEOFN; + output DMA1LLTXEOPN; + output DMA1LLTXSOFN; + output DMA1LLTXSOPN; + output DMA1LLTXSRCRDYN; + output DMA1RXIRQ; + output DMA1TXIRQ; + output DMA2LLRSTENGINEACK; + output DMA2LLRXDSTRDYN; + output DMA2LLTXEOFN; + output DMA2LLTXEOPN; + output DMA2LLTXSOFN; + output DMA2LLTXSOPN; + output DMA2LLTXSRCRDYN; + output DMA2RXIRQ; + output DMA2TXIRQ; + output DMA3LLRSTENGINEACK; + output DMA3LLRXDSTRDYN; + output DMA3LLTXEOFN; + output DMA3LLTXEOPN; + output DMA3LLTXSOFN; + output DMA3LLTXSOPN; + output DMA3LLTXSRCRDYN; + output DMA3RXIRQ; + output DMA3TXIRQ; + output MIMCADDRESSVALID; + output MIMCBANKCONFLICT; + output MIMCREADNOTWRITE; + output MIMCROWCONFLICT; + output MIMCWRITEDATAVALID; + output PPCCPMINTERCONNECTBUSY; + output PPCDMDCRREAD; + output PPCDMDCRWRITE; + output PPCDSDCRACK; + output PPCDSDCRTIMEOUTWAIT; + output PPCEICINTERCONNECTIRQ; + output PPCMPLBABORT; + output PPCMPLBBUSLOCK; + output PPCMPLBLOCKERR; + output PPCMPLBRDBURST; + output PPCMPLBREQUEST; + output PPCMPLBRNW; + output PPCMPLBWRBURST; + output PPCS0PLBADDRACK; + output PPCS0PLBRDBTERM; + output PPCS0PLBRDCOMP; + output PPCS0PLBRDDACK; + output PPCS0PLBREARBITRATE; + output PPCS0PLBWAIT; + output PPCS0PLBWRBTERM; + output PPCS0PLBWRCOMP; + output PPCS0PLBWRDACK; + output PPCS1PLBADDRACK; + output PPCS1PLBRDBTERM; + output PPCS1PLBRDCOMP; + output PPCS1PLBRDDACK; + output PPCS1PLBREARBITRATE; + output PPCS1PLBWAIT; + output PPCS1PLBWRBTERM; + output PPCS1PLBWRCOMP; + output PPCS1PLBWRDACK; + output [0:127] APUFCMLOADDATA; + output [0:127] MIMCWRITEDATA; + output [0:127] PPCMPLBWRDBUS; + output [0:127] PPCS0PLBRDDBUS; + output [0:127] PPCS1PLBRDDBUS; + output [0:13] C440TRCTRIGGEREVENTTYPE; + output [0:15] MIMCBYTEENABLE; + output [0:15] PPCMPLBBE; + output [0:15] PPCMPLBTATTRIBUTE; + output [0:1] PPCMPLBPRIORITY; + output [0:1] PPCS0PLBSSIZE; + output [0:1] PPCS1PLBSSIZE; + output [0:2] APUFCMDECLDSTXFERSIZE; + output [0:2] C440TRCBRANCHSTATUS; + output [0:2] PPCMPLBTYPE; + output [0:31] APUFCMINSTRUCTION; + output [0:31] APUFCMRADATA; + output [0:31] APUFCMRBDATA; + output [0:31] DMA0LLTXD; + output [0:31] DMA1LLTXD; + output [0:31] DMA2LLTXD; + output [0:31] DMA3LLTXD; + output [0:31] PPCDMDCRDBUSOUT; + output [0:31] PPCDSDCRDBUSIN; + output [0:31] PPCMPLBABUS; + output [0:35] MIMCADDRESS; + output [0:3] APUFCMDECUDI; + output [0:3] APUFCMLOADBYTEADDR; + output [0:3] DMA0LLTXREM; + output [0:3] DMA1LLTXREM; + output [0:3] DMA2LLTXREM; + output [0:3] DMA3LLTXREM; + output [0:3] PPCMPLBSIZE; + output [0:3] PPCS0PLBMBUSY; + output [0:3] PPCS0PLBMIRQ; + output [0:3] PPCS0PLBMRDERR; + output [0:3] PPCS0PLBMWRERR; + output [0:3] PPCS0PLBRDWDADDR; + output [0:3] PPCS1PLBMBUSY; + output [0:3] PPCS1PLBMIRQ; + output [0:3] PPCS1PLBMRDERR; + output [0:3] PPCS1PLBMWRERR; + output [0:3] PPCS1PLBRDWDADDR; + output [0:4] C440TRCEXECUTIONSTATUS; + output [0:6] C440TRCTRACESTATUS; + output [0:7] C440DBGSYSTEMCONTROL; + output [0:9] PPCDMDCRABUS; + output [20:21] PPCDMDCRUABUS; + output [28:31] PPCMPLBUABUS; + input CPMC440CLK; + input CPMC440CLKEN; + input CPMC440CORECLOCKINACTIVE; + input CPMC440TIMERCLOCK; + input CPMDCRCLK; + input CPMDMA0LLCLK; + input CPMDMA1LLCLK; + input CPMDMA2LLCLK; + input CPMDMA3LLCLK; + input CPMFCMCLK; + input CPMINTERCONNECTCLK; + input CPMINTERCONNECTCLKEN; + input CPMINTERCONNECTCLKNTO1; + input CPMMCCLK; + input CPMPPCMPLBCLK; + input CPMPPCS0PLBCLK; + input CPMPPCS1PLBCLK; + input DBGC440DEBUGHALT; + input DBGC440UNCONDDEBUGEVENT; + input DCRPPCDMACK; + input DCRPPCDMTIMEOUTWAIT; + input DCRPPCDSREAD; + input DCRPPCDSWRITE; + input EICC440CRITIRQ; + input EICC440EXTIRQ; + input FCMAPUCONFIRMINSTR; + input FCMAPUDONE; + input FCMAPUEXCEPTION; + input FCMAPUFPSCRFEX; + input FCMAPURESULTVALID; + input FCMAPUSLEEPNOTREADY; + input JTGC440TCK; + input JTGC440TDI; + input JTGC440TMS; + input JTGC440TRSTNEG; + input LLDMA0RSTENGINEREQ; + input LLDMA0RXEOFN; + input LLDMA0RXEOPN; + input LLDMA0RXSOFN; + input LLDMA0RXSOPN; + input LLDMA0RXSRCRDYN; + input LLDMA0TXDSTRDYN; + input LLDMA1RSTENGINEREQ; + input LLDMA1RXEOFN; + input LLDMA1RXEOPN; + input LLDMA1RXSOFN; + input LLDMA1RXSOPN; + input LLDMA1RXSRCRDYN; + input LLDMA1TXDSTRDYN; + input LLDMA2RSTENGINEREQ; + input LLDMA2RXEOFN; + input LLDMA2RXEOPN; + input LLDMA2RXSOFN; + input LLDMA2RXSOPN; + input LLDMA2RXSRCRDYN; + input LLDMA2TXDSTRDYN; + input LLDMA3RSTENGINEREQ; + input LLDMA3RXEOFN; + input LLDMA3RXEOPN; + input LLDMA3RXSOFN; + input LLDMA3RXSOPN; + input LLDMA3RXSRCRDYN; + input LLDMA3TXDSTRDYN; + input MCMIADDRREADYTOACCEPT; + input MCMIREADDATAERR; + input MCMIREADDATAVALID; + input PLBPPCMADDRACK; + input PLBPPCMMBUSY; + input PLBPPCMMIRQ; + input PLBPPCMMRDERR; + input PLBPPCMMWRERR; + input PLBPPCMRDBTERM; + input PLBPPCMRDDACK; + input PLBPPCMRDPENDREQ; + input PLBPPCMREARBITRATE; + input PLBPPCMTIMEOUT; + input PLBPPCMWRBTERM; + input PLBPPCMWRDACK; + input PLBPPCMWRPENDREQ; + input PLBPPCS0ABORT; + input PLBPPCS0BUSLOCK; + input PLBPPCS0LOCKERR; + input PLBPPCS0PAVALID; + input PLBPPCS0RDBURST; + input PLBPPCS0RDPENDREQ; + input PLBPPCS0RDPRIM; + input PLBPPCS0RNW; + input PLBPPCS0SAVALID; + input PLBPPCS0WRBURST; + input PLBPPCS0WRPENDREQ; + input PLBPPCS0WRPRIM; + input PLBPPCS1ABORT; + input PLBPPCS1BUSLOCK; + input PLBPPCS1LOCKERR; + input PLBPPCS1PAVALID; + input PLBPPCS1RDBURST; + input PLBPPCS1RDPENDREQ; + input PLBPPCS1RDPRIM; + input PLBPPCS1RNW; + input PLBPPCS1SAVALID; + input PLBPPCS1WRBURST; + input PLBPPCS1WRPENDREQ; + input PLBPPCS1WRPRIM; + input RSTC440RESETCHIP; + input RSTC440RESETCORE; + input RSTC440RESETSYSTEM; + input TIEC440ENDIANRESET; + input TRCC440TRACEDISABLE; + input TRCC440TRIGGEREVENTIN; + input [0:127] FCMAPUSTOREDATA; + input [0:127] MCMIREADDATA; + input [0:127] PLBPPCMRDDBUS; + input [0:127] PLBPPCS0WRDBUS; + input [0:127] PLBPPCS1WRDBUS; + input [0:15] PLBPPCS0BE; + input [0:15] PLBPPCS0TATTRIBUTE; + input [0:15] PLBPPCS1BE; + input [0:15] PLBPPCS1TATTRIBUTE; + input [0:1] PLBPPCMRDPENDPRI; + input [0:1] PLBPPCMREQPRI; + input [0:1] PLBPPCMSSIZE; + input [0:1] PLBPPCMWRPENDPRI; + input [0:1] PLBPPCS0MASTERID; + input [0:1] PLBPPCS0MSIZE; + input [0:1] PLBPPCS0RDPENDPRI; + input [0:1] PLBPPCS0REQPRI; + input [0:1] PLBPPCS0WRPENDPRI; + input [0:1] PLBPPCS1MASTERID; + input [0:1] PLBPPCS1MSIZE; + input [0:1] PLBPPCS1RDPENDPRI; + input [0:1] PLBPPCS1REQPRI; + input [0:1] PLBPPCS1WRPENDPRI; + input [0:1] TIEC440DCURDLDCACHEPLBPRIO; + input [0:1] TIEC440DCURDNONCACHEPLBPRIO; + input [0:1] TIEC440DCURDTOUCHPLBPRIO; + input [0:1] TIEC440DCURDURGENTPLBPRIO; + input [0:1] TIEC440DCUWRFLUSHPLBPRIO; + input [0:1] TIEC440DCUWRSTOREPLBPRIO; + input [0:1] TIEC440DCUWRURGENTPLBPRIO; + input [0:1] TIEC440ICURDFETCHPLBPRIO; + input [0:1] TIEC440ICURDSPECPLBPRIO; + input [0:1] TIEC440ICURDTOUCHPLBPRIO; + input [0:1] TIEDCRBASEADDR; + input [0:2] PLBPPCS0TYPE; + input [0:2] PLBPPCS1TYPE; + input [0:31] DCRPPCDMDBUSIN; + input [0:31] DCRPPCDSDBUSOUT; + input [0:31] FCMAPURESULT; + input [0:31] LLDMA0RXD; + input [0:31] LLDMA1RXD; + input [0:31] LLDMA2RXD; + input [0:31] LLDMA3RXD; + input [0:31] PLBPPCS0ABUS; + input [0:31] PLBPPCS1ABUS; + input [0:3] FCMAPUCR; + input [0:3] LLDMA0RXREM; + input [0:3] LLDMA1RXREM; + input [0:3] LLDMA2RXREM; + input [0:3] LLDMA3RXREM; + input [0:3] PLBPPCMRDWDADDR; + input [0:3] PLBPPCS0SIZE; + input [0:3] PLBPPCS1SIZE; + input [0:3] TIEC440ERPNRESET; + input [0:3] TIEC440USERRESET; + input [0:4] DBGC440SYSTEMSTATUS; + input [0:9] DCRPPCDSABUS; + input [28:31] PLBPPCS0UABUS; + input [28:31] PLBPPCS1UABUS; + input [28:31] TIEC440PIR; + input [28:31] TIEC440PVR; +endmodule + (* keep *) module PS7 (...); output DMA0DAVALID; @@ -28088,3 +33144,297 @@ module ILKNE4 (...); input TX_SOPIN3; endmodule +(* keep *) +module VCU (...); + parameter integer CORECLKREQ = 667; + parameter integer DECHORRESOLUTION = 3840; + parameter DECODERCHROMAFORMAT = "4_2_2"; + parameter DECODERCODING = "H.265"; + parameter integer DECODERCOLORDEPTH = 10; + parameter integer DECODERNUMCORES = 2; + parameter integer DECVERTRESOLUTION = 2160; + parameter ENABLEDECODER = "TRUE"; + parameter ENABLEENCODER = "TRUE"; + parameter integer ENCHORRESOLUTION = 3840; + parameter ENCODERCHROMAFORMAT = "4_2_2"; + parameter ENCODERCODING = "H.265"; + parameter integer ENCODERCOLORDEPTH = 10; + parameter integer ENCODERNUMCORES = 4; + parameter integer ENCVERTRESOLUTION = 2160; + output VCUPLARREADYAXILITEAPB; + output VCUPLAWREADYAXILITEAPB; + output [1:0] VCUPLBRESPAXILITEAPB; + output VCUPLBVALIDAXILITEAPB; + output VCUPLCORESTATUSCLKPLL; + output [43:0] VCUPLDECARADDR0; + output [43:0] VCUPLDECARADDR1; + output [1:0] VCUPLDECARBURST0; + output [1:0] VCUPLDECARBURST1; + output [3:0] VCUPLDECARCACHE0; + output [3:0] VCUPLDECARCACHE1; + output [3:0] VCUPLDECARID0; + output [3:0] VCUPLDECARID1; + output [7:0] VCUPLDECARLEN0; + output [7:0] VCUPLDECARLEN1; + output VCUPLDECARPROT0; + output VCUPLDECARPROT1; + output [3:0] VCUPLDECARQOS0; + output [3:0] VCUPLDECARQOS1; + output [2:0] VCUPLDECARSIZE0; + output [2:0] VCUPLDECARSIZE1; + output VCUPLDECARVALID0; + output VCUPLDECARVALID1; + output [43:0] VCUPLDECAWADDR0; + output [43:0] VCUPLDECAWADDR1; + output [1:0] VCUPLDECAWBURST0; + output [1:0] VCUPLDECAWBURST1; + output [3:0] VCUPLDECAWCACHE0; + output [3:0] VCUPLDECAWCACHE1; + output [3:0] VCUPLDECAWID0; + output [3:0] VCUPLDECAWID1; + output [7:0] VCUPLDECAWLEN0; + output [7:0] VCUPLDECAWLEN1; + output VCUPLDECAWPROT0; + output VCUPLDECAWPROT1; + output [3:0] VCUPLDECAWQOS0; + output [3:0] VCUPLDECAWQOS1; + output [2:0] VCUPLDECAWSIZE0; + output [2:0] VCUPLDECAWSIZE1; + output VCUPLDECAWVALID0; + output VCUPLDECAWVALID1; + output VCUPLDECBREADY0; + output VCUPLDECBREADY1; + output VCUPLDECRREADY0; + output VCUPLDECRREADY1; + output [127:0] VCUPLDECWDATA0; + output [127:0] VCUPLDECWDATA1; + output VCUPLDECWLAST0; + output VCUPLDECWLAST1; + output VCUPLDECWVALID0; + output VCUPLDECWVALID1; + output [16:0] VCUPLENCALL2CADDR; + output VCUPLENCALL2CRVALID; + output [319:0] VCUPLENCALL2CWDATA; + output VCUPLENCALL2CWVALID; + output [43:0] VCUPLENCARADDR0; + output [43:0] VCUPLENCARADDR1; + output [1:0] VCUPLENCARBURST0; + output [1:0] VCUPLENCARBURST1; + output [3:0] VCUPLENCARCACHE0; + output [3:0] VCUPLENCARCACHE1; + output [3:0] VCUPLENCARID0; + output [3:0] VCUPLENCARID1; + output [7:0] VCUPLENCARLEN0; + output [7:0] VCUPLENCARLEN1; + output VCUPLENCARPROT0; + output VCUPLENCARPROT1; + output [3:0] VCUPLENCARQOS0; + output [3:0] VCUPLENCARQOS1; + output [2:0] VCUPLENCARSIZE0; + output [2:0] VCUPLENCARSIZE1; + output VCUPLENCARVALID0; + output VCUPLENCARVALID1; + output [43:0] VCUPLENCAWADDR0; + output [43:0] VCUPLENCAWADDR1; + output [1:0] VCUPLENCAWBURST0; + output [1:0] VCUPLENCAWBURST1; + output [3:0] VCUPLENCAWCACHE0; + output [3:0] VCUPLENCAWCACHE1; + output [3:0] VCUPLENCAWID0; + output [3:0] VCUPLENCAWID1; + output [7:0] VCUPLENCAWLEN0; + output [7:0] VCUPLENCAWLEN1; + output VCUPLENCAWPROT0; + output VCUPLENCAWPROT1; + output [3:0] VCUPLENCAWQOS0; + output [3:0] VCUPLENCAWQOS1; + output [2:0] VCUPLENCAWSIZE0; + output [2:0] VCUPLENCAWSIZE1; + output VCUPLENCAWVALID0; + output VCUPLENCAWVALID1; + output VCUPLENCBREADY0; + output VCUPLENCBREADY1; + output VCUPLENCRREADY0; + output VCUPLENCRREADY1; + output [127:0] VCUPLENCWDATA0; + output [127:0] VCUPLENCWDATA1; + output VCUPLENCWLAST0; + output VCUPLENCWLAST1; + output VCUPLENCWVALID0; + output VCUPLENCWVALID1; + output [43:0] VCUPLMCUMAXIICDCARADDR; + output [1:0] VCUPLMCUMAXIICDCARBURST; + output [3:0] VCUPLMCUMAXIICDCARCACHE; + output [2:0] VCUPLMCUMAXIICDCARID; + output [7:0] VCUPLMCUMAXIICDCARLEN; + output VCUPLMCUMAXIICDCARLOCK; + output [2:0] VCUPLMCUMAXIICDCARPROT; + output [3:0] VCUPLMCUMAXIICDCARQOS; + output [2:0] VCUPLMCUMAXIICDCARSIZE; + output VCUPLMCUMAXIICDCARVALID; + output [43:0] VCUPLMCUMAXIICDCAWADDR; + output [1:0] VCUPLMCUMAXIICDCAWBURST; + output [3:0] VCUPLMCUMAXIICDCAWCACHE; + output [2:0] VCUPLMCUMAXIICDCAWID; + output [7:0] VCUPLMCUMAXIICDCAWLEN; + output VCUPLMCUMAXIICDCAWLOCK; + output [2:0] VCUPLMCUMAXIICDCAWPROT; + output [3:0] VCUPLMCUMAXIICDCAWQOS; + output [2:0] VCUPLMCUMAXIICDCAWSIZE; + output VCUPLMCUMAXIICDCAWVALID; + output VCUPLMCUMAXIICDCBREADY; + output VCUPLMCUMAXIICDCRREADY; + output [31:0] VCUPLMCUMAXIICDCWDATA; + output VCUPLMCUMAXIICDCWLAST; + output [3:0] VCUPLMCUMAXIICDCWSTRB; + output VCUPLMCUMAXIICDCWVALID; + output VCUPLMCUSTATUSCLKPLL; + output VCUPLPINTREQ; + output VCUPLPLLSTATUSPLLLOCK; + output VCUPLPWRSUPPLYSTATUSVCCAUX; + output VCUPLPWRSUPPLYSTATUSVCUINT; + output [31:0] VCUPLRDATAAXILITEAPB; + output [1:0] VCUPLRRESPAXILITEAPB; + output VCUPLRVALIDAXILITEAPB; + output VCUPLWREADYAXILITEAPB; + input INITPLVCUGASKETCLAMPCONTROLLVLSHVCCINTD; + input [19:0] PLVCUARADDRAXILITEAPB; + input [2:0] PLVCUARPROTAXILITEAPB; + input PLVCUARVALIDAXILITEAPB; + input [19:0] PLVCUAWADDRAXILITEAPB; + input [2:0] PLVCUAWPROTAXILITEAPB; + input PLVCUAWVALIDAXILITEAPB; + input PLVCUAXIDECCLK; + input PLVCUAXIENCCLK; + input PLVCUAXILITECLK; + input PLVCUAXIMCUCLK; + input PLVCUBREADYAXILITEAPB; + input PLVCUCORECLK; + input PLVCUDECARREADY0; + input PLVCUDECARREADY1; + input PLVCUDECAWREADY0; + input PLVCUDECAWREADY1; + input [3:0] PLVCUDECBID0; + input [3:0] PLVCUDECBID1; + input [1:0] PLVCUDECBRESP0; + input [1:0] PLVCUDECBRESP1; + input PLVCUDECBVALID0; + input PLVCUDECBVALID1; + input [127:0] PLVCUDECRDATA0; + input [127:0] PLVCUDECRDATA1; + input [3:0] PLVCUDECRID0; + input [3:0] PLVCUDECRID1; + input PLVCUDECRLAST0; + input PLVCUDECRLAST1; + input [1:0] PLVCUDECRRESP0; + input [1:0] PLVCUDECRRESP1; + input PLVCUDECRVALID0; + input PLVCUDECRVALID1; + input PLVCUDECWREADY0; + input PLVCUDECWREADY1; + input [319:0] PLVCUENCALL2CRDATA; + input PLVCUENCALL2CRREADY; + input PLVCUENCARREADY0; + input PLVCUENCARREADY1; + input PLVCUENCAWREADY0; + input PLVCUENCAWREADY1; + input [3:0] PLVCUENCBID0; + input [3:0] PLVCUENCBID1; + input [1:0] PLVCUENCBRESP0; + input [1:0] PLVCUENCBRESP1; + input PLVCUENCBVALID0; + input PLVCUENCBVALID1; + input PLVCUENCL2CCLK; + input [127:0] PLVCUENCRDATA0; + input [127:0] PLVCUENCRDATA1; + input [3:0] PLVCUENCRID0; + input [3:0] PLVCUENCRID1; + input PLVCUENCRLAST0; + input PLVCUENCRLAST1; + input [1:0] PLVCUENCRRESP0; + input [1:0] PLVCUENCRRESP1; + input PLVCUENCRVALID0; + input PLVCUENCRVALID1; + input PLVCUENCWREADY0; + input PLVCUENCWREADY1; + input PLVCUMCUCLK; + input PLVCUMCUMAXIICDCARREADY; + input PLVCUMCUMAXIICDCAWREADY; + input [2:0] PLVCUMCUMAXIICDCBID; + input [1:0] PLVCUMCUMAXIICDCBRESP; + input PLVCUMCUMAXIICDCBVALID; + input [31:0] PLVCUMCUMAXIICDCRDATA; + input [2:0] PLVCUMCUMAXIICDCRID; + input PLVCUMCUMAXIICDCRLAST; + input [1:0] PLVCUMCUMAXIICDCRRESP; + input PLVCUMCUMAXIICDCRVALID; + input PLVCUMCUMAXIICDCWREADY; + input PLVCUPLLREFCLKPL; + input PLVCURAWRSTN; + input PLVCURREADYAXILITEAPB; + input [31:0] PLVCUWDATAAXILITEAPB; + input [3:0] PLVCUWSTRBAXILITEAPB; + input PLVCUWVALIDAXILITEAPB; +endmodule + +module FE (...); + parameter MODE = "TURBO_DECODE"; + parameter real PHYSICAL_UTILIZATION = 100.00; + parameter SIM_DEVICE = "ULTRASCALE_PLUS"; + parameter STANDARD = "LTE"; + parameter real THROUGHPUT_UTILIZATION = 100.00; + output [399:0] DEBUG_DOUT; + output DEBUG_PHASE; + output INTERRUPT; + output [511:0] M_AXIS_DOUT_TDATA; + output M_AXIS_DOUT_TLAST; + output M_AXIS_DOUT_TVALID; + output [31:0] M_AXIS_STATUS_TDATA; + output M_AXIS_STATUS_TVALID; + output [15:0] SPARE_OUT; + output S_AXIS_CTRL_TREADY; + output S_AXIS_DIN_TREADY; + output S_AXIS_DIN_WORDS_TREADY; + output S_AXIS_DOUT_WORDS_TREADY; + output S_AXI_ARREADY; + output S_AXI_AWREADY; + output S_AXI_BVALID; + output [31:0] S_AXI_RDATA; + output S_AXI_RVALID; + output S_AXI_WREADY; + input CORE_CLK; + input DEBUG_CLK_EN; + input DEBUG_EN; + input [3:0] DEBUG_SEL_IN; + input M_AXIS_DOUT_ACLK; + input M_AXIS_DOUT_TREADY; + input M_AXIS_STATUS_ACLK; + input M_AXIS_STATUS_TREADY; + input RESET_N; + input [15:0] SPARE_IN; + input S_AXIS_CTRL_ACLK; + input [31:0] S_AXIS_CTRL_TDATA; + input S_AXIS_CTRL_TVALID; + input S_AXIS_DIN_ACLK; + input [511:0] S_AXIS_DIN_TDATA; + input S_AXIS_DIN_TLAST; + input S_AXIS_DIN_TVALID; + input S_AXIS_DIN_WORDS_ACLK; + input [31:0] S_AXIS_DIN_WORDS_TDATA; + input S_AXIS_DIN_WORDS_TLAST; + input S_AXIS_DIN_WORDS_TVALID; + input S_AXIS_DOUT_WORDS_ACLK; + input [31:0] S_AXIS_DOUT_WORDS_TDATA; + input S_AXIS_DOUT_WORDS_TLAST; + input S_AXIS_DOUT_WORDS_TVALID; + input S_AXI_ACLK; + input [17:0] S_AXI_ARADDR; + input S_AXI_ARVALID; + input [17:0] S_AXI_AWADDR; + input S_AXI_AWVALID; + input S_AXI_BREADY; + input S_AXI_RREADY; + input [31:0] S_AXI_WDATA; + input S_AXI_WVALID; +endmodule + From 406f866659810f67ba8a89d731b6ab80073c0941 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 07:24:26 +0000 Subject: [PATCH 0096/2410] cxxrtl: fix typo. --- backends/cxxrtl/cxxrtl_backend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 916303bfe49..dd56c59bc30 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2807,10 +2807,10 @@ struct CxxrtlBackend : public Backend { log(" no optimization.\n"); log("\n"); log(" -O1\n"); - log(" localize internal wires if possible.\n"); + log(" unbuffer internal wires if possible.\n"); log("\n"); log(" -O2\n"); - log(" like -O1, and unbuffer internal wires if possible.\n"); + log(" like -O1, and localize internal wires if possible.\n"); log("\n"); log(" -O3\n"); log(" like -O2, and inline internal wires if possible.\n"); From 6f42b26ceaa185cb7e5c243402e68cd8cd5bf2de Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 06:04:10 +0000 Subject: [PATCH 0097/2410] cxxrtl: clarify node use-def construction. NFCI. --- backends/cxxrtl/cxxrtl_backend.cc | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index dd56c59bc30..b3c443b33f6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -273,6 +273,7 @@ struct FlowGraph { std::vector nodes; dict> wire_comb_defs, wire_sync_defs, wire_uses; + dict, hash_ptr_ops> node_comb_defs, node_uses; dict wire_def_inlinable, wire_use_inlinable; dict bit_has_state; @@ -294,6 +295,7 @@ struct FlowGraph { // A comb def means that a wire doesn't hold design state. It might still be connected, // indirectly, to a flip-flop output. wire_comb_defs[chunk.wire].insert(node); + node_comb_defs[node].insert(chunk.wire); } } for (auto bit : sig.bits()) @@ -308,6 +310,7 @@ struct FlowGraph { for (auto chunk : sig.chunks()) if (chunk.wire) { wire_uses[chunk.wire].insert(node); + node_uses[node].insert(chunk.wire); // Only a single use of an entire wire in the right order can be inlined. // (But the use can include other chunks.) if (!wire_use_inlinable.count(chunk.wire)) @@ -2361,25 +2364,15 @@ struct CxxrtlWorker { inlined_wires[wire] = **flow.wire_comb_defs[wire].begin(); } - dict, hash_ptr_ops> node_defs; - for (auto wire_comb_def : flow.wire_comb_defs) - for (auto node : wire_comb_def.second) - node_defs[node].insert(wire_comb_def.first); - - dict, hash_ptr_ops> node_uses; - for (auto wire_use : flow.wire_uses) - for (auto node : wire_use.second) - node_uses[node].insert(wire_use.first); - Scheduler scheduler; - dict::Vertex*, hash_ptr_ops> node_map; + dict::Vertex*, hash_ptr_ops> node_vertex_map; for (auto node : flow.nodes) - node_map[node] = scheduler.add(node); - for (auto node_def : node_defs) { - auto vertex = node_map[node_def.first]; - for (auto wire : node_def.second) + node_vertex_map[node] = scheduler.add(node); + for (auto node_comb_def : flow.node_comb_defs) { + auto vertex = node_vertex_map[node_comb_def.first]; + for (auto wire : node_comb_def.second) for (auto succ_node : flow.wire_uses[wire]) { - auto succ_vertex = node_map[succ_node]; + auto succ_vertex = node_vertex_map[succ_node]; vertex->succs.insert(succ_vertex); succ_vertex->preds.insert(vertex); } @@ -2396,7 +2389,7 @@ struct CxxrtlWorker { // caused by a true logic loop, but usually are a benign result of dependency tracking that works // on wire, not bit, level. Nevertheless, feedback wires cannot be localized. evaluated.insert(node); - for (auto wire : node_defs[node]) + for (auto wire : flow.node_comb_defs[node]) for (auto succ_node : flow.wire_uses[wire]) if (evaluated[succ_node]) { feedback_wires.insert(wire); @@ -2470,7 +2463,7 @@ struct CxxrtlWorker { if (wire->name.isPublic() || !inlined_wires.count(wire)) debug_outlined_wires.insert(wire); // allow outlining of internal wires only for (auto node : flow.wire_comb_defs[wire]) - for (auto node_use : node_uses[node]) + for (auto node_use : flow.node_uses[node]) if (!visited.count(node_use)) worklist.insert(node_use); } From e825cf9d73a2126d518b2dc8f78114850c84ad32 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 06:05:42 +0000 Subject: [PATCH 0098/2410] cxxrtl: simplify logic choosing wire type. NFCI. --- backends/cxxrtl/cxxrtl_backend.cc | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index b3c443b33f6..458ec55565b 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2351,19 +2351,6 @@ struct CxxrtlWorker { } } - for (auto wire : module->wires()) { - if (!flow.is_inlinable(wire)) continue; - if (wire->port_id != 0) continue; - if (wire->get_bool_attribute(ID::keep)) continue; - if (wire->name.begins_with("$") && !inline_internal) continue; - if (wire->name.begins_with("\\") && !inline_public) continue; - if (edge_wires[wire]) continue; - if (flow.wire_comb_defs[wire].size() > 1) - log_cmd_error("Wire %s.%s has multiple drivers.\n", log_id(module), log_id(wire)); - log_assert(flow.wire_comb_defs[wire].size() == 1); - inlined_wires[wire] = **flow.wire_comb_defs[wire].begin(); - } - Scheduler scheduler; dict::Vertex*, hash_ptr_ops> node_vertex_map; for (auto node : flow.nodes) @@ -2391,14 +2378,9 @@ struct CxxrtlWorker { evaluated.insert(node); for (auto wire : flow.node_comb_defs[node]) for (auto succ_node : flow.wire_uses[wire]) - if (evaluated[succ_node]) { + if (evaluated[succ_node]) feedback_wires.insert(wire); - // Feedback wires may never be inlined because feedback requires state, but the point of - // inlining (and localization) is to eliminate state. - inlined_wires.erase(wire); - } } - if (!feedback_wires.empty()) { has_feedback_arcs = true; log("Module `%s' contains feedback arcs through wires:\n", log_id(module)); @@ -2419,6 +2401,13 @@ struct CxxrtlWorker { if (wire->name.begins_with("$") && !localize_internal) continue; if (wire->name.begins_with("\\") && !localize_public) continue; localized_wires.insert(wire); + if (!flow.is_inlinable(wire)) continue; + if (wire->name.begins_with("$") && !inline_internal) continue; + if (wire->name.begins_with("\\") && !inline_public) continue; + if (flow.wire_comb_defs[wire].size() > 1) + log_cmd_error("Wire %s.%s has multiple drivers.\n", log_id(module), log_id(wire)); + log_assert(flow.wire_comb_defs[wire].size() == 1); + inlined_wires[wire] = **flow.wire_comb_defs[wire].begin(); } // For maximum performance, the state of the simulation (which is the same as the set of its double buffered From b62a892b2f0b71fd6910afe68bbba9d338579f98 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 22 Dec 2020 00:10:05 +0000 Subject: [PATCH 0099/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c1c112ec9d6..9ece371c554 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3773 +YOSYS_VER := 0.9+3780 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 9396678db4f0e32192e73697c012d25432d602ca Mon Sep 17 00:00:00 2001 From: StefanBruens Date: Tue, 22 Dec 2020 03:23:42 +0100 Subject: [PATCH 0100/2410] Fix use-after-free in LUT opt pass RTLIL::Module::remove(Cell* cell) calls `delete cell`. Any subsequent accesses of `cell` then causes undefined behavior. --- passes/opt/opt_lut.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 07a91af8a11..62310101645 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -277,12 +277,13 @@ struct OptLutWorker module->connect(lut_output, value); sigmap.add(lut_output, value); - module->remove(lut); luts.erase(lut); luts_arity.erase(lut); luts_dlogics.erase(lut); luts_dlogic_inputs.erase(lut); + module->remove(lut); + eliminated_count++; if (limit > 0) limit--; @@ -493,11 +494,12 @@ struct OptLutWorker luts_arity[lutM] = lutM_arity; luts.erase(lutR); luts_arity.erase(lutR); - lutR->module->remove(lutR); worklist.insert(lutM); worklist.erase(lutR); + lutR->module->remove(lutR); + combined_count++; if (limit > 0) limit--; From b2221c1077d43a193c1a66d8017a7ed9ed1a2373 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 21:00:46 +0000 Subject: [PATCH 0101/2410] cxxrtl: completely rewrite netlist layout code. The exact shape of C++ code emitted by CXXRTL has a critical effect on performance, both compile-time and runtime. CXXRTL's performance greatly improved when it started localizing and inlining wires, not only because this assists the optimizer and register allocator, but also because inlining code into edge-triggered regions cuts the time spent in eval() by at least a factor of two. However, the logic of netlist layout has always been ad-hoc, fragile, and very hard to understand and modify. After commit ece25a45, which introduced outlining, the same logic started being applied to two distinct netlists at once instead of one, which barely worked. This commit does four major changes: * There is now a single unambiguous source of truth (per subgraph) for the layout of any emitted wire. * Netlist layout is now done entirely during analysis using well known graph algorithms; no graph operations happen when emitting. * Netlist layout now happens completely separately for eval() and debug_eval() subgraphs. * Unreachable (within subgraph scope) netlist nodes are now neither emitted nor considered for wire inlining decisions. The netlist layout code should also now closely match the described semantics. As a part of this large cleanup, it includes many miscellaneous improvements: * The "bare minimum" debug level introduced in commit dd6a761d was split into two levels; -g1 now emits debug information *only* for inputs and state wires, and -g2 now emits debug information for all public members. The old behavior matches -g2. This is done to avoid bloat on low optimization levels. * Debug aliases and inlined connections are now handled separately, and complex RHS never interferes with inlined connections. * Aliases to outlined wires now carry a pointer to the outline. * Cell sync outputs can now be emitted in debug_eval(). * Black box debug information now includes comb/sync driver flags. * The comment emitted for inlined cells is now accurate. * Debug information statistics now has less noise. * Netlist layout code is now much better documented. Due to more precise inlining decisions, unmodified (i.e. with no Yosys script being used) netlists now have much more logic inlined into edge-triggered regions. On Minerva SoC SRAM, this improves runtime by 20-25% across compilers and optimization levels. Due to more precise reachability analysis, much less C++ code is now emitted, especially at the maximum debug level. On Minerva SoC SRAM, this improves clang compile time by 30-50% depending on options. gcc is not affected. --- backends/cxxrtl/cxxrtl_backend.cc | 975 +++++++++++++++++------------- 1 file changed, 569 insertions(+), 406 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 458ec55565b..338648c899e 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -214,6 +214,11 @@ bool is_internal_cell(RTLIL::IdString type) return !type.isPublic() && !type.begins_with("$paramod"); } +bool is_effectful_cell(RTLIL::IdString type) +{ + return type == ID($memwr) || type.isPublic(); +} + bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) { RTLIL::Module *cell_module = cell->module->design->module(cell->type); @@ -227,18 +232,15 @@ enum class CxxrtlPortType { SYNC = 2, }; -CxxrtlPortType cxxrtl_port_type(const RTLIL::Cell *cell, RTLIL::IdString port) +CxxrtlPortType cxxrtl_port_type(RTLIL::Module *module, RTLIL::IdString port) { - RTLIL::Module *cell_module = cell->module->design->module(cell->type); - if (cell_module == nullptr || !cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) - return CxxrtlPortType::UNKNOWN; - RTLIL::Wire *cell_output_wire = cell_module->wire(port); - log_assert(cell_output_wire != nullptr); - bool is_comb = cell_output_wire->get_bool_attribute(ID(cxxrtl_comb)); - bool is_sync = cell_output_wire->get_bool_attribute(ID(cxxrtl_sync)); + RTLIL::Wire *output_wire = module->wire(port); + log_assert(output_wire != nullptr); + bool is_comb = output_wire->get_bool_attribute(ID(cxxrtl_comb)); + bool is_sync = output_wire->get_bool_attribute(ID(cxxrtl_sync)); if (is_comb && is_sync) log_cmd_error("Port `%s.%s' is marked as both `cxxrtl_comb` and `cxxrtl_sync`.\n", - log_id(cell_module), log_signal(cell_output_wire)); + log_id(module), log_signal(output_wire)); else if (is_comb) return CxxrtlPortType::COMB; else if (is_sync) @@ -246,6 +248,14 @@ CxxrtlPortType cxxrtl_port_type(const RTLIL::Cell *cell, RTLIL::IdString port) return CxxrtlPortType::UNKNOWN; } +CxxrtlPortType cxxrtl_port_type(const RTLIL::Cell *cell, RTLIL::IdString port) +{ + RTLIL::Module *cell_module = cell->module->design->module(cell->type); + if (cell_module == nullptr || !cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) + return CxxrtlPortType::UNKNOWN; + return cxxrtl_port_type(cell_module, port); +} + bool is_cxxrtl_comb_port(const RTLIL::Cell *cell, RTLIL::IdString port) { return cxxrtl_port_type(cell, port) == CxxrtlPortType::COMB; @@ -273,8 +283,9 @@ struct FlowGraph { std::vector nodes; dict> wire_comb_defs, wire_sync_defs, wire_uses; - dict, hash_ptr_ops> node_comb_defs, node_uses; - dict wire_def_inlinable, wire_use_inlinable; + dict, hash_ptr_ops> node_comb_defs, node_sync_defs, node_uses; + dict wire_def_inlinable; + dict> wire_use_inlinable; dict bit_has_state; ~FlowGraph() @@ -291,6 +302,7 @@ struct FlowGraph { // A sync def means that a wire holds design state because it is driven directly by // a flip-flop output. Such a wire can never be unbuffered. wire_sync_defs[chunk.wire].insert(node); + node_sync_defs[node].insert(chunk.wire); } else { // A comb def means that a wire doesn't hold design state. It might still be connected, // indirectly, to a flip-flop output. @@ -311,19 +323,33 @@ struct FlowGraph { if (chunk.wire) { wire_uses[chunk.wire].insert(node); node_uses[node].insert(chunk.wire); - // Only a single use of an entire wire in the right order can be inlined. - // (But the use can include other chunks.) - if (!wire_use_inlinable.count(chunk.wire)) - wire_use_inlinable[chunk.wire] = true; + // Only a single use of an entire wire in the right order can be inlined. (But the use can include + // other chunks.) This is tracked per-node because a wire used by multiple nodes can still be inlined + // if all but one of those nodes is dead. + if (!wire_use_inlinable[chunk.wire].count(node)) + wire_use_inlinable[chunk.wire][node] = true; else - wire_use_inlinable[chunk.wire] = false; + wire_use_inlinable[chunk.wire][node] = false; } } bool is_inlinable(const RTLIL::Wire *wire) const { - if (wire_def_inlinable.count(wire) && wire_use_inlinable.count(wire)) - return wire_def_inlinable.at(wire) && wire_use_inlinable.at(wire); + // Can the wire be inlined at all? + if (wire_def_inlinable.count(wire)) + return wire_def_inlinable.at(wire); + return false; + } + + bool is_inlinable(const RTLIL::Wire *wire, const pool &nodes) const + { + // Can the wire be inlined, knowing that the given nodes are reachable? + if (nodes.size() != 1) + return false; + Node *node = *nodes.begin(); + log_assert(node_uses.at(node).count(wire)); + if (is_inlinable(wire) && wire_use_inlinable.count(wire) && wire_use_inlinable.at(wire).count(node)) + return wire_use_inlinable.at(wire).at(node); return false; } @@ -523,6 +549,52 @@ std::string get_hdl_name(T *object) return object->name.str().substr(1); } +struct WireType { + enum Type { + // Non-referenced wire; is not a part of the design. + UNUSED, + // Double-buffered wire; is a class member, and holds design state. + BUFFERED, + // Single-buffered wire; is a class member, but holds no state. + MEMBER, + // Single-buffered wire; is a class member, and is computed on demand. + OUTLINE, + // Local wire; is a local variable in eval method. + LOCAL, + // Inline wire; is an unnamed temporary in eval method. + INLINE, + // Alias wire; is replaced with aliasee, except in debug info. + ALIAS, + // Const wire; is replaced with constant, except in debug info. + CONST, + }; + + Type type = UNUSED; + const RTLIL::Cell *cell_subst = nullptr; // for INLINE + RTLIL::SigSpec sig_subst = {}; // for INLINE, ALIAS, and CONST + + WireType() = default; + + WireType(Type type) : type(type) { + log_assert(type == UNUSED || type == BUFFERED || type == MEMBER || type == OUTLINE || type == LOCAL); + } + + WireType(Type type, const RTLIL::Cell *cell) : type(type), cell_subst(cell) { + log_assert(type == INLINE && is_inlinable_cell(cell->type)); + } + + WireType(Type type, RTLIL::SigSpec sig) : type(type), sig_subst(sig) { + log_assert(type == INLINE || (type == ALIAS && sig.is_wire()) || (type == CONST && sig.is_fully_const())); + } + + bool is_buffered() const { return type == BUFFERED; } + bool is_member() const { return type == BUFFERED || type == MEMBER || type == OUTLINE; } + bool is_outline() const { return type == OUTLINE; } + bool is_named() const { return is_member() || type == LOCAL; } + bool is_local() const { return type == LOCAL || type == INLINE; } + bool is_exact() const { return type == ALIAS || type == CONST; } +}; + struct CxxrtlWorker { bool split_intf = false; std::string intf_filename; @@ -542,6 +614,7 @@ struct CxxrtlWorker { bool inline_public = false; bool debug_info = false; + bool debug_member = false; bool debug_alias = false; bool debug_eval = false; @@ -554,13 +627,8 @@ struct CxxrtlWorker { dict edge_types; pool writable_memories; dict> transparent_for; - dict> schedule; - pool unbuffered_wires; - pool localized_wires; - dict inlined_wires; - dict debug_const_wires; - dict debug_alias_wires; - pool debug_outlined_wires; + dict> schedule, debug_schedule; + dict wire_types, debug_wire_types; dict bit_has_state; dict> blackbox_specializations; dict eval_converges; @@ -798,24 +866,31 @@ struct CxxrtlWorker { dump_const(chunk.data, chunk.width, chunk.offset); return false; } else { - if (inlined_wires.count(chunk.wire) && (!for_debug || !debug_outlined_wires[chunk.wire])) { - log_assert(!is_lhs); - const FlowGraph::Node &node = inlined_wires[chunk.wire]; - switch (node.type) { - case FlowGraph::Node::Type::CONNECT: - dump_connect_expr(node.connect, for_debug); - break; - case FlowGraph::Node::Type::CELL_EVAL: - log_assert(is_inlinable_cell(node.cell->type)); - dump_cell_expr(node.cell, for_debug); + const auto &wire_type = (for_debug ? debug_wire_types : wire_types)[chunk.wire]; + switch (wire_type.type) { + case WireType::BUFFERED: + f << mangle(chunk.wire) << (is_lhs ? ".next" : ".curr"); + break; + case WireType::MEMBER: + case WireType::LOCAL: + case WireType::OUTLINE: + f << mangle(chunk.wire); + break; + case WireType::INLINE: + log_assert(!is_lhs); + if (wire_type.cell_subst != nullptr) { + dump_cell_expr(wire_type.cell_subst, for_debug); break; - default: - log_assert(false); - } - } else if (unbuffered_wires[chunk.wire]) { - f << mangle(chunk.wire); - } else { - f << mangle(chunk.wire) << (is_lhs ? ".next" : ".curr"); + } + YS_FALLTHROUGH + case WireType::ALIAS: + case WireType::CONST: + log_assert(!is_lhs); + return dump_sigspec(wire_type.sig_subst.extract(chunk.offset, chunk.width), is_lhs, for_debug); + case WireType::UNUSED: + log_assert(is_lhs); + f << "value<" << chunk.width << ">()"; + return false; } if (chunk.width == chunk.wire->width && chunk.offset == 0) return false; @@ -876,22 +951,39 @@ struct CxxrtlWorker { f << ".val()"; } - void collect_sigspec_rhs(const RTLIL::SigSpec &sig, std::vector &cells) + void dump_inlined_cells(const std::vector &cells) + { + if (cells.empty()) { + f << indent << "// connection\n"; + } else if (cells.size() == 1) { + dump_attrs(cells.front()); + f << indent << "// cell " << cells.front()->name.str() << "\n"; + } else { + f << indent << "// cells"; + for (auto cell : cells) + f << " " << cell->name.str(); + f << "\n"; + } + } + + void collect_sigspec_rhs(const RTLIL::SigSpec &sig, bool for_debug, std::vector &cells) { for (auto chunk : sig.chunks()) { - if (!chunk.wire || !inlined_wires.count(chunk.wire)) + if (!chunk.wire) continue; - - const FlowGraph::Node &node = inlined_wires[chunk.wire]; - switch (node.type) { - case FlowGraph::Node::Type::CONNECT: - collect_connect(node.connect, cells); - break; - case FlowGraph::Node::Type::CELL_EVAL: - collect_cell_eval(node.cell, cells); + const auto &wire_type = wire_types[chunk.wire]; + switch (wire_type.type) { + case WireType::INLINE: + if (wire_type.cell_subst != nullptr) { + collect_cell_eval(wire_type.cell_subst, for_debug, cells); + break; + } + YS_FALLTHROUGH + case WireType::ALIAS: + collect_sigspec_rhs(wire_type.sig_subst, for_debug, cells); break; default: - log_assert(false); + break; } } } @@ -901,44 +993,12 @@ struct CxxrtlWorker { dump_sigspec_rhs(conn.second, for_debug); } - bool is_connect_inlined(const RTLIL::SigSig &conn) - { - return conn.first.is_wire() && inlined_wires.count(conn.first.as_wire()); - } - - bool is_connect_outlined(const RTLIL::SigSig &conn) - { - for (auto chunk : conn.first.chunks()) - if (debug_outlined_wires.count(chunk.wire)) - return true; - return false; - } - - void collect_connect(const RTLIL::SigSig &conn, std::vector &cells) - { - if (!is_connect_inlined(conn)) - return; - - collect_sigspec_rhs(conn.second, cells); - } - void dump_connect(const RTLIL::SigSig &conn, bool for_debug = false) { - if (!for_debug && is_connect_inlined(conn)) - return; - if (for_debug && !is_connect_outlined(conn)) - return; + std::vector inlined_cells; + collect_sigspec_rhs(conn.second, for_debug, inlined_cells); + dump_inlined_cells(inlined_cells); - std::vector inlined_cells; - collect_sigspec_rhs(conn.second, inlined_cells); - if (for_debug || inlined_cells.empty()) { - f << indent << "// connection\n"; - } else { - f << indent << "// cells"; - for (auto inlined_cell : inlined_cells) - f << " " << inlined_cell.str(); - f << "\n"; - } f << indent; dump_sigspec_lhs(conn.first, for_debug); f << " = "; @@ -946,7 +1006,12 @@ struct CxxrtlWorker { f << ";\n"; } - void dump_cell_sync(const RTLIL::Cell *cell) + void collect_connect(const RTLIL::SigSig &conn, bool for_debug, std::vector &cells) + { + collect_sigspec_rhs(conn.second, for_debug, cells); + } + + void dump_cell_sync(const RTLIL::Cell *cell, bool for_debug = false) { const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; f << indent << "// cell " << cell->name.str() << " syncs\n"; @@ -954,7 +1019,7 @@ struct CxxrtlWorker { if (cell->output(conn.first)) if (is_cxxrtl_sync_port(cell, conn.first)) { f << indent; - dump_sigspec_lhs(conn.second); + dump_sigspec_lhs(conn.second, for_debug); f << " = " << mangle(cell) << access << mangle_wire_name(conn.first) << ".curr;\n"; } } @@ -1023,58 +1088,11 @@ struct CxxrtlWorker { } } - bool is_cell_inlined(const RTLIL::Cell *cell) - { - return is_inlinable_cell(cell->type) && cell->hasPort(ID::Y) && cell->getPort(ID::Y).is_wire() && - inlined_wires.count(cell->getPort(ID::Y).as_wire()); - } - - bool is_cell_outlined(const RTLIL::Cell *cell) - { - if (is_internal_cell(cell->type)) - for (auto conn : cell->connections()) - if (cell->output(conn.first)) - for (auto chunk : conn.second.chunks()) - if (debug_outlined_wires.count(chunk.wire)) - return true; - return false; - } - - void collect_cell_eval(const RTLIL::Cell *cell, std::vector &cells) - { - if (!is_cell_inlined(cell)) - return; - - cells.push_back(cell->name); - for (auto port : cell->connections()) - if (port.first != ID::Y) - collect_sigspec_rhs(port.second, cells); - } - void dump_cell_eval(const RTLIL::Cell *cell, bool for_debug = false) { - if (!for_debug && is_cell_inlined(cell)) - return; - if (for_debug && !is_cell_outlined(cell)) - return; - if (cell->type == ID($meminit)) - return; // Handled elsewhere. - - std::vector inlined_cells; - if (is_inlinable_cell(cell->type)) { - for (auto port : cell->connections()) - if (port.first != ID::Y) - collect_sigspec_rhs(port.second, inlined_cells); - } - if (inlined_cells.empty()) { - dump_attrs(cell); - f << indent << "// cell " << cell->name.str() << "\n"; - } else { - f << indent << "// cells"; - for (auto inlined_cell : inlined_cells) - f << " " << inlined_cell.str(); - f << "\n"; - } + std::vector inlined_cells; + collect_cell_eval(cell, for_debug, inlined_cells); + dump_inlined_cells(inlined_cells); // Elidable cells if (is_inlinable_cell(cell->type)) { @@ -1085,6 +1103,7 @@ struct CxxrtlWorker { f << ";\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { + log_assert(!for_debug); if (cell->hasPort(ID::CLK) && cell->getPort(ID::CLK).is_wire()) { // Edge-sensitive logic RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; @@ -1185,6 +1204,7 @@ struct CxxrtlWorker { // Memory ports } else if (cell->type.in(ID($memrd), ID($memwr))) { if (cell->getParam(ID::CLK_ENABLE).as_bool()) { + log_assert(!for_debug); RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); if (clk_bit.wire) { @@ -1292,6 +1312,7 @@ struct CxxrtlWorker { log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str()); // User cells } else { + log_assert(!for_debug); log_assert(cell->known()); bool buffered_inputs = false; const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; @@ -1301,7 +1322,7 @@ struct CxxrtlWorker { log_assert(cell_module != nullptr && cell_module->wire(conn.first) && conn.second.is_wire()); RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first); f << indent << mangle(cell) << access << mangle_wire_name(conn.first); - if (!is_cxxrtl_blackbox_cell(cell) && !unbuffered_wires[cell_module_wire]) { + if (!is_cxxrtl_blackbox_cell(cell) && wire_types[cell_module_wire].is_buffered()) { buffered_inputs = true; f << ".next"; } @@ -1369,6 +1390,14 @@ struct CxxrtlWorker { } } + void collect_cell_eval(const RTLIL::Cell *cell, bool for_debug, std::vector &cells) + { + cells.push_back(cell); + for (auto port : cell->connections()) + if (cell->input(port.first)) + collect_sigspec_rhs(port.second, for_debug, cells); + } + void dump_assign(const RTLIL::SigSig &sigsig) { f << indent; @@ -1513,67 +1542,64 @@ struct CxxrtlWorker { void dump_wire(const RTLIL::Wire *wire, bool is_local) { - if (is_local && localized_wires[wire] && !inlined_wires.count(wire)) { - dump_attrs(wire); - f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; - } - if (!is_local && !localized_wires[wire]) { - std::string width; - if (wire->module->has_attribute(ID(cxxrtl_blackbox)) && wire->has_attribute(ID(cxxrtl_width))) { - width = wire->get_string_attribute(ID(cxxrtl_width)); - } else { - width = std::to_string(wire->width); - } + const auto &wire_type = wire_types[wire]; + if (!wire_type.is_named() || wire_type.is_local() != is_local) + return; - dump_attrs(wire); - f << indent; - if (wire->port_input && wire->port_output) - f << "/*inout*/ "; - else if (wire->port_input) - f << "/*input*/ "; - else if (wire->port_output) - f << "/*output*/ "; - f << (unbuffered_wires[wire] ? "value" : "wire") << "<" << width << "> " << mangle(wire); - if (wire->has_attribute(ID::init)) { - f << " "; - dump_const_init(wire->attributes.at(ID::init)); - } - f << ";\n"; - if (edge_wires[wire]) { - if (unbuffered_wires[wire]) { - f << indent << "value<" << width << "> prev_" << mangle(wire); - if (wire->has_attribute(ID::init)) { - f << " "; - dump_const_init(wire->attributes.at(ID::init)); - } - f << ";\n"; + dump_attrs(wire); + f << indent; + if (wire->port_input && wire->port_output) + f << "/*inout*/ "; + else if (wire->port_input) + f << "/*input*/ "; + else if (wire->port_output) + f << "/*output*/ "; + f << (wire_type.is_buffered() ? "wire" : "value"); + if (wire->module->has_attribute(ID(cxxrtl_blackbox)) && wire->has_attribute(ID(cxxrtl_width))) { + f << "<" << wire->get_string_attribute(ID(cxxrtl_width)) << ">"; + } else { + f << "<" << wire->width << ">"; + } + f << " " << mangle(wire); + if (wire->has_attribute(ID::init)) { + f << " "; + dump_const_init(wire->attributes.at(ID::init)); + } + f << ";\n"; + if (edge_wires[wire]) { + if (!wire_type.is_buffered()) { + f << indent << "value<" << wire->width << "> prev_" << mangle(wire); + if (wire->has_attribute(ID::init)) { + f << " "; + dump_const_init(wire->attributes.at(ID::init)); } - for (auto edge_type : edge_types) { - if (edge_type.first.wire == wire) { - std::string prev, next; - if (unbuffered_wires[wire]) { - prev = "prev_" + mangle(edge_type.first.wire); - next = mangle(edge_type.first.wire); - } else { - prev = mangle(edge_type.first.wire) + ".curr"; - next = mangle(edge_type.first.wire) + ".next"; - } - prev += ".slice<" + std::to_string(edge_type.first.offset) + ">().val()"; - next += ".slice<" + std::to_string(edge_type.first.offset) + ">().val()"; - if (edge_type.second != RTLIL::STn) { - f << indent << "bool posedge_" << mangle(edge_type.first) << "() const {\n"; - inc_indent(); - f << indent << "return !" << prev << " && " << next << ";\n"; - dec_indent(); - f << indent << "}\n"; - } - if (edge_type.second != RTLIL::STp) { - f << indent << "bool negedge_" << mangle(edge_type.first) << "() const {\n"; - inc_indent(); - f << indent << "return " << prev << " && !" << next << ";\n"; - dec_indent(); - f << indent << "}\n"; - } + f << ";\n"; + } + for (auto edge_type : edge_types) { + if (edge_type.first.wire == wire) { + std::string prev, next; + if (!wire_type.is_buffered()) { + prev = "prev_" + mangle(edge_type.first.wire); + next = mangle(edge_type.first.wire); + } else { + prev = mangle(edge_type.first.wire) + ".curr"; + next = mangle(edge_type.first.wire) + ".next"; + } + prev += ".slice<" + std::to_string(edge_type.first.offset) + ">().val()"; + next += ".slice<" + std::to_string(edge_type.first.offset) + ">().val()"; + if (edge_type.second != RTLIL::STn) { + f << indent << "bool posedge_" << mangle(edge_type.first) << "() const {\n"; + inc_indent(); + f << indent << "return !" << prev << " && " << next << ";\n"; + dec_indent(); + f << indent << "}\n"; + } + if (edge_type.second != RTLIL::STp) { + f << indent << "bool negedge_" << mangle(edge_type.first) << "() const {\n"; + inc_indent(); + f << indent << "return " << prev << " && !" << next << ";\n"; + dec_indent(); + f << indent << "}\n"; } } } @@ -1582,19 +1608,19 @@ struct CxxrtlWorker { void dump_debug_wire(const RTLIL::Wire *wire, bool is_local) { - if (!debug_outlined_wires[wire]) + const auto &wire_type = wire_types[wire]; + if (wire_type.is_member()) return; - bool is_outlined_member = wire->name.isPublic() && - !(debug_const_wires.count(wire) || debug_alias_wires.count(wire)); - if (is_local && !is_outlined_member) { - dump_attrs(wire); - f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; - } - if (!is_local && is_outlined_member) { - dump_attrs(wire); - f << indent << "/*outline*/ value<" << wire->width << "> " << mangle(wire) << ";\n"; - } + const auto &debug_wire_type = debug_wire_types[wire]; + if (!debug_wire_type.is_named() || debug_wire_type.is_local() != is_local) + return; + + dump_attrs(wire); + f << indent; + if (debug_wire_type.is_outline()) + f << "/*outline*/ "; + f << "value<" << wire->width << "> " << mangle(wire) << ";\n"; } void dump_memory(RTLIL::Module *module, const RTLIL::Memory *memory) @@ -1691,17 +1717,19 @@ struct CxxrtlWorker { inc_indent(); for (auto wire : module->wires()) dump_debug_wire(wire, /*is_local=*/true); - for (auto node : schedule[module]) { + for (auto node : debug_schedule[module]) { switch (node.type) { case FlowGraph::Node::Type::CONNECT: dump_connect(node.connect, /*for_debug=*/true); break; + case FlowGraph::Node::Type::CELL_SYNC: + dump_cell_sync(node.cell, /*for_debug=*/true); + break; case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell, /*for_debug=*/true); break; - case FlowGraph::Node::Type::CELL_SYNC: - case FlowGraph::Node::Type::PROCESS: - break; + default: + log_abort(); } } dec_indent(); @@ -1712,14 +1740,10 @@ struct CxxrtlWorker { inc_indent(); f << indent << "bool changed = false;\n"; for (auto wire : module->wires()) { - if (inlined_wires.count(wire)) - continue; - if (unbuffered_wires[wire]) { - if (edge_wires[wire]) - f << indent << "prev_" << mangle(wire) << " = " << mangle(wire) << ";\n"; - continue; - } - if (!module->get_bool_attribute(ID(cxxrtl_blackbox)) || wire->port_id != 0) + const auto &wire_type = wire_types[wire]; + if (wire_type.type == WireType::MEMBER && edge_wires[wire]) + f << indent << "prev_" << mangle(wire) << " = " << mangle(wire) << ";\n"; + if (wire_type.is_buffered()) f << indent << "if (" << mangle(wire) << ".commit()) changed = true;\n"; } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -1742,99 +1766,129 @@ struct CxxrtlWorker { void dump_debug_info_method(RTLIL::Module *module) { size_t count_public_wires = 0; - size_t count_const_wires = 0; - size_t count_alias_wires = 0; - size_t count_inline_wires = 0; size_t count_member_wires = 0; - size_t count_skipped_wires = 0; + size_t count_undriven = 0; size_t count_driven_sync = 0; size_t count_driven_comb = 0; - size_t count_undriven = 0; size_t count_mixed_driver = 0; + size_t count_alias_wires = 0; + size_t count_const_wires = 0; + size_t count_inline_wires = 0; + size_t count_skipped_wires = 0; inc_indent(); f << indent << "assert(path.empty() || path[path.size() - 1] == ' ');\n"; for (auto wire : module->wires()) { + const auto &debug_wire_type = debug_wire_types[wire]; if (!wire->name.isPublic()) continue; - if (module->get_bool_attribute(ID(cxxrtl_blackbox)) && (wire->port_id == 0)) - continue; count_public_wires++; - if (debug_const_wires.count(wire)) { - // Wire tied to a constant - f << indent << "static const value<" << wire->width << "> const_" << mangle(wire) << " = "; - dump_const(debug_const_wires[wire]); - f << ";\n"; - f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(const_" << mangle(wire) << ", "; - f << wire->start_offset << "));\n"; - count_const_wires++; - } else if (debug_alias_wires.count(wire)) { - // Alias of a member wire - f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(debug_alias(), " << mangle(debug_alias_wires[wire]) << ", "; - f << wire->start_offset << "));\n"; - count_alias_wires++; - } else if (debug_outlined_wires.count(wire)) { - // Inlined but rematerializable wire - f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(debug_eval_outline, " << mangle(wire) << ", "; - f << wire->start_offset << "));\n"; - count_inline_wires++; - } else if (!localized_wires.count(wire)) { - // Member wire - std::vector flags; - - if (wire->port_input && wire->port_output) - flags.push_back("INOUT"); - else if (wire->port_input) - flags.push_back("INPUT"); - else if (wire->port_output) - flags.push_back("OUTPUT"); - - bool has_driven_sync = false; - bool has_driven_comb = false; - bool has_undriven = false; - SigSpec sig(wire); - for (auto bit : sig.bits()) - if (!bit_has_state.count(bit)) - has_undriven = true; - else if (bit_has_state[bit]) - has_driven_sync = true; - else - has_driven_comb = true; - if (has_driven_sync) - flags.push_back("DRIVEN_SYNC"); - if (has_driven_sync && !has_driven_comb && !has_undriven) - count_driven_sync++; - if (has_driven_comb) - flags.push_back("DRIVEN_COMB"); - if (!has_driven_sync && has_driven_comb && !has_undriven) - count_driven_comb++; - if (has_undriven) - flags.push_back("UNDRIVEN"); - if (!has_driven_sync && !has_driven_comb && has_undriven) - count_undriven++; - if (has_driven_sync + has_driven_comb + has_undriven > 1) - count_mixed_driver++; - - f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(" << mangle(wire) << ", "; - f << wire->start_offset; - bool first = true; - for (auto flag : flags) { - if (first) { - first = false; - f << ", "; + switch (debug_wire_type.type) { + case WireType::BUFFERED: + case WireType::MEMBER: { + // Member wire + std::vector flags; + + if (wire->port_input && wire->port_output) + flags.push_back("INOUT"); + else if (wire->port_output) + flags.push_back("OUTPUT"); + else if (wire->port_input) + flags.push_back("INPUT"); + + bool has_driven_sync = false; + bool has_driven_comb = false; + bool has_undriven = false; + if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { + for (auto bit : SigSpec(wire)) + if (!bit_has_state.count(bit)) + has_undriven = true; + else if (bit_has_state[bit]) + has_driven_sync = true; + else + has_driven_comb = true; + } else if (wire->port_output) { + switch (cxxrtl_port_type(module, wire->name)) { + case CxxrtlPortType::SYNC: + has_driven_sync = true; + break; + case CxxrtlPortType::COMB: + has_driven_comb = true; + break; + case CxxrtlPortType::UNKNOWN: + has_driven_sync = has_driven_comb = true; + break; + } } else { - f << "|"; + has_undriven = true; } - f << "debug_item::" << flag; + if (has_undriven) + flags.push_back("UNDRIVEN"); + if (!has_driven_sync && !has_driven_comb && has_undriven) + count_undriven++; + if (has_driven_sync) + flags.push_back("DRIVEN_SYNC"); + if (has_driven_sync && !has_driven_comb && !has_undriven) + count_driven_sync++; + if (has_driven_comb) + flags.push_back("DRIVEN_COMB"); + if (!has_driven_sync && has_driven_comb && !has_undriven) + count_driven_comb++; + if (has_driven_sync + has_driven_comb + has_undriven > 1) + count_mixed_driver++; + + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(" << mangle(wire) << ", " << wire->start_offset; + bool first = true; + for (auto flag : flags) { + if (first) { + first = false; + f << ", "; + } else { + f << "|"; + } + f << "debug_item::" << flag; + } + f << "));\n"; + count_member_wires++; + break; + } + case WireType::ALIAS: { + // Alias of a member wire + const RTLIL::Wire *aliasee = debug_wire_type.sig_subst.as_wire(); + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item("; + // If the aliasee is an outline, then the alias must be an outline, too; otherwise downstream + // tooling has no way to find out about the outline. + if (debug_wire_types[aliasee].is_outline()) + f << "debug_eval_outline"; + else + f << "debug_alias()"; + f << ", " << mangle(aliasee) << ", " << wire->start_offset << "));\n"; + count_alias_wires++; + break; + } + case WireType::CONST: { + // Wire tied to a constant + f << indent << "static const value<" << wire->width << "> const_" << mangle(wire) << " = "; + dump_const(debug_wire_type.sig_subst.as_const()); + f << ";\n"; + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(const_" << mangle(wire) << ", " << wire->start_offset << "));\n"; + count_const_wires++; + break; + } + case WireType::OUTLINE: { + // Localized or inlined, but rematerializable wire + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(debug_eval_outline, " << mangle(wire) << ", " << wire->start_offset << "));\n"; + count_inline_wires++; + break; + } + default: { + // Localized or inlined wire with no debug information + count_skipped_wires++; + break; } - f << "));\n"; - count_member_wires++; - } else { - // Localized or inlined wire with no debug information - count_skipped_wires++; } } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -1858,15 +1912,17 @@ struct CxxrtlWorker { log_debug("Debug information statistics for module `%s':\n", log_id(module)); log_debug(" Public wires: %zu, of which:\n", count_public_wires); log_debug(" Member wires: %zu, of which:\n", count_member_wires); + log_debug(" Undriven: %zu (incl. inputs)\n", count_undriven); log_debug(" Driven sync: %zu\n", count_driven_sync); log_debug(" Driven comb: %zu\n", count_driven_comb); log_debug(" Mixed driver: %zu\n", count_mixed_driver); - log_debug(" Undriven: %zu\n", count_undriven); - log_debug(" Inline wires: %zu\n", count_inline_wires); - log_debug(" Alias wires: %zu\n", count_alias_wires); - log_debug(" Const wires: %zu\n", count_const_wires); - log_debug(" Other wires: %zu%s\n", count_skipped_wires, - count_skipped_wires > 0 ? " (debug information unavailable)" : ""); + if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { + log_debug(" Inline wires: %zu\n", count_inline_wires); + log_debug(" Alias wires: %zu\n", count_alias_wires); + log_debug(" Const wires: %zu\n", count_const_wires); + log_debug(" Other wires: %zu%s\n", count_skipped_wires, + count_skipped_wires > 0 ? " (debug unavailable)" : ""); + } } void dump_metadata_map(const dict &metadata_map) @@ -2031,7 +2087,7 @@ struct CxxrtlWorker { f << "\n"; f << indent << "void debug_eval();\n"; for (auto wire : module->wires()) - if (debug_outlined_wires.count(wire)) { + if (debug_wire_types[wire].is_outline()) { f << indent << "debug_outline debug_eval_outline { std::bind(&" << mangle(module) << "::debug_eval, this) };\n"; break; @@ -2221,8 +2277,11 @@ struct CxxrtlWorker { if (module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto port : module->ports) { RTLIL::Wire *wire = module->wire(port); - if (wire->port_input && !wire->port_output) - unbuffered_wires.insert(wire); + if (wire->port_input && !wire->port_output) { + wire_types[wire] = debug_wire_types[wire] = {WireType::MEMBER}; + } else if (wire->port_input || wire->port_output) { + wire_types[wire] = debug_wire_types[wire] = {WireType::BUFFERED}; + } if (wire->has_attribute(ID(cxxrtl_edge))) { RTLIL::Const edge_attr = wire->attributes[ID(cxxrtl_edge)]; if (!(edge_attr.flags & RTLIL::CONST_FLAG_STRING) || (int)edge_attr.decode_string().size() != GetSize(wire)) @@ -2252,6 +2311,8 @@ struct CxxrtlWorker { continue; } + // Construct a flow graph where each node is a basic computational operation generally corresponding + // to a fragment of the RTLIL netlist. FlowGraph flow; for (auto conn : module->connections()) @@ -2351,6 +2412,9 @@ struct CxxrtlWorker { } } + // Construct a linear order of the flow graph that minimizes the amount of feedback arcs. A flow graph + // without feedback arcs can generally be evaluated in a single pass, i.e. it always requires only + // a single delta cycle. Scheduler scheduler; dict::Vertex*, hash_ptr_ops> node_vertex_map; for (auto node : flow.nodes) @@ -2365,20 +2429,21 @@ struct CxxrtlWorker { } } - auto eval_order = scheduler.schedule(); - pool evaluated; + // Find out whether the order includes any feedback arcs. + std::vector node_order; + pool evaluated_nodes; pool feedback_wires; - for (auto vertex : eval_order) { + for (auto vertex : scheduler.schedule()) { auto node = vertex->data; - schedule[module].push_back(*node); + node_order.push_back(node); // Any wire that is an output of node vo and input of node vi where vo is scheduled later than vi // is a feedback wire. Feedback wires indicate apparent logic loops in the design, which may be // caused by a true logic loop, but usually are a benign result of dependency tracking that works - // on wire, not bit, level. Nevertheless, feedback wires cannot be localized. - evaluated.insert(node); + // on wire, not bit, level. Nevertheless, feedback wires cannot be unbuffered. + evaluated_nodes.insert(node); for (auto wire : flow.node_comb_defs[node]) for (auto succ_node : flow.wire_uses[wire]) - if (evaluated[succ_node]) + if (evaluated_nodes[succ_node]) feedback_wires.insert(wire); } if (!feedback_wires.empty()) { @@ -2388,27 +2453,85 @@ struct CxxrtlWorker { log(" %s\n", log_id(wire)); } + // Conservatively assign wire types. Assignment of types BUFFERED and MEMBER is final, but assignment + // of type LOCAL may be further refined to UNUSED or INLINE. for (auto wire : module->wires()) { + auto &wire_type = wire_types[wire]; + wire_type = {WireType::BUFFERED}; + if (feedback_wires[wire]) continue; if (wire->port_output && !module->get_bool_attribute(ID::top)) continue; - if (wire->name.begins_with("$") && !unbuffer_internal) continue; - if (wire->name.begins_with("\\") && !unbuffer_public) continue; + if (!wire->name.isPublic() && !unbuffer_internal) continue; + if (wire->name.isPublic() && !unbuffer_public) continue; if (flow.wire_sync_defs.count(wire) > 0) continue; - unbuffered_wires.insert(wire); + wire_type = {WireType::MEMBER}; + if (edge_wires[wire]) continue; if (wire->get_bool_attribute(ID::keep)) continue; if (wire->port_input || wire->port_output) continue; - if (wire->name.begins_with("$") && !localize_internal) continue; - if (wire->name.begins_with("\\") && !localize_public) continue; - localized_wires.insert(wire); - if (!flow.is_inlinable(wire)) continue; - if (wire->name.begins_with("$") && !inline_internal) continue; - if (wire->name.begins_with("\\") && !inline_public) continue; - if (flow.wire_comb_defs[wire].size() > 1) - log_cmd_error("Wire %s.%s has multiple drivers.\n", log_id(module), log_id(wire)); - log_assert(flow.wire_comb_defs[wire].size() == 1); - inlined_wires[wire] = **flow.wire_comb_defs[wire].begin(); + if (!wire->name.isPublic() && !localize_internal) continue; + if (wire->name.isPublic() && !localize_public) continue; + wire_type = {WireType::LOCAL}; + } + + // Discover nodes reachable from primary outputs (i.e. members) and collect reachable wire users. + pool worklist; + for (auto node : flow.nodes) { + if (node->type == FlowGraph::Node::Type::CELL_EVAL && is_effectful_cell(node->cell->type)) + worklist.insert(node); // node has effects + else if (flow.node_sync_defs.count(node)) + worklist.insert(node); // node is a flip-flop + else if (flow.node_comb_defs.count(node)) { + for (auto wire : flow.node_comb_defs[node]) + if (wire_types[wire].is_member()) + worklist.insert(node); // node drives public wires + } } + dict> live_wires; + pool live_nodes; + while (!worklist.empty()) { + auto node = worklist.pop(); + live_nodes.insert(node); + for (auto wire : flow.node_uses[node]) { + live_wires[wire].insert(node); + for (auto pred_node : flow.wire_comb_defs[wire]) + if (!live_nodes[pred_node]) + worklist.insert(pred_node); + } + } + + // Refine wire types taking into account the amount of uses from reachable nodes only. + for (auto wire : module->wires()) { + auto &wire_type = wire_types[wire]; + if (!wire_type.is_local()) continue; + if (!wire->name.isPublic() && !inline_internal) continue; + if (wire->name.isPublic() && !inline_public) continue; + + if (live_wires[wire].empty()) { + wire_type = {WireType::UNUSED}; // wire never used + } else if (flow.is_inlinable(wire, live_wires[wire])) { + if (flow.wire_comb_defs[wire].size() > 1) + log_cmd_error("Wire %s.%s has multiple drivers!\n", log_id(module), log_id(wire)); + log_assert(flow.wire_comb_defs[wire].size() == 1); + FlowGraph::Node *node = *flow.wire_comb_defs[wire].begin(); + switch (node->type) { + case FlowGraph::Node::Type::CELL_EVAL: + if (!is_inlinable_cell(node->cell->type)) continue; + wire_type = {WireType::INLINE, node->cell}; // wire replaced with cell + break; + case FlowGraph::Node::Type::CONNECT: + wire_type = {WireType::INLINE, node->connect.second}; // wire replaced with sig + break; + default: continue; + } + live_nodes.erase(node); + } + } + + // Emit reachable nodes in eval(). + for (auto node : node_order) + if (live_nodes[node]) + schedule[module].push_back(*node); // For maximum performance, the state of the simulation (which is the same as the set of its double buffered // wires, since using a singly buffered wire for any kind of state introduces a race condition) should contain @@ -2417,10 +2540,9 @@ struct CxxrtlWorker { // as a wire with multiple drivers where one of them is combinatorial and the other is synchronous. Such designs // also require more than one delta cycle to converge. pool buffered_comb_wires; - for (auto wire : module->wires()) { - if (flow.wire_comb_defs[wire].size() > 0 && !unbuffered_wires[wire] && !feedback_wires[wire]) + for (auto wire : module->wires()) + if (wire_types[wire].is_buffered() && !feedback_wires[wire] && flow.wire_comb_defs[wire].size() > 0) buffered_comb_wires.insert(wire); - } if (!buffered_comb_wires.empty()) { has_buffered_comb_wires = true; log("Module `%s' contains buffered combinatorial wires:\n", log_id(module)); @@ -2428,81 +2550,115 @@ struct CxxrtlWorker { log(" %s\n", log_id(wire)); } + // Record whether eval() requires only one delta cycle in this module. eval_converges[module] = feedback_wires.empty() && buffered_comb_wires.empty(); - for (auto item : flow.bit_has_state) - bit_has_state.insert(item); + if (debug_info) { + // Annotate wire bits with the type of their driver; this is exposed in the debug metadata. + for (auto item : flow.bit_has_state) + bit_has_state.insert(item); - if (debug_info && debug_eval) { - // Find wires that can be be outlined, i.e. whose values can be always recovered from - // the values of other wires. (This is the inverse of inlining--any wire that can be - // inlined can also be outlined.) Although this may seem strictly less efficient, since - // such values are computed at least twice, second-order effects make outlining useful. - pool worklist, visited; + // Assign debug information wire types to public wires according to the chosen debug level. + // Unlike with optimized wire types, all assignments here are final. for (auto wire : module->wires()) { - if (!wire->name.isPublic()) - continue; - worklist.insert(wire); + const auto &wire_type = wire_types[wire]; + auto &debug_wire_type = debug_wire_types[wire]; + if (!wire->name.isPublic()) continue; + + if (!debug_info) continue; + if (wire->port_input || wire_type.is_buffered()) + debug_wire_type = wire_type; // wire contains state + + if (!debug_member) continue; + if (wire_type.is_member()) + debug_wire_type = wire_type; // wire is a member + + if (!debug_alias) continue; + const RTLIL::Wire *it = wire; + while (flow.is_inlinable(it)) { + log_assert(flow.wire_comb_defs[it].size() == 1); + FlowGraph::Node *node = *flow.wire_comb_defs[it].begin(); + if (node->type != FlowGraph::Node::Type::CONNECT) break; // not an alias + RTLIL::SigSpec rhs = node->connect.second; + if (rhs.is_fully_const()) { + debug_wire_type = {WireType::CONST, rhs}; // wire replaced with const + } else if (rhs.is_wire()) { + if (wire_types[rhs.as_wire()].is_member()) + debug_wire_type = {WireType::ALIAS, rhs}; // wire replaced with wire + else if (debug_eval && rhs.as_wire()->name.isPublic()) + debug_wire_type = {WireType::ALIAS, rhs}; // wire replaced with outline + it = rhs.as_wire(); // and keep looking + continue; + } + break; + } + + if (!debug_eval) continue; + if (!debug_wire_type.is_exact() && !wire_type.is_member()) + debug_wire_type = {WireType::OUTLINE}; // wire is local or inlined + } + + // Discover nodes reachable from primary outputs (i.e. outlines) up until primary inputs (i.e. members) + // and collect reachable wire users. + pool worklist; + for (auto node : flow.nodes) { + if (flow.node_comb_defs.count(node)) + for (auto wire : flow.node_comb_defs[node]) + if (debug_wire_types[wire].is_outline()) + worklist.insert(node); // node drives outline } + dict> live_wires; + pool live_nodes; while (!worklist.empty()) { - const RTLIL::Wire *wire = worklist.pop(); - visited.insert(wire); - if (!localized_wires.count(wire) && !inlined_wires.count(wire)) - continue; // member wire, doesn't need outlining - if (wire->name.isPublic() || !inlined_wires.count(wire)) - debug_outlined_wires.insert(wire); // allow outlining of internal wires only - for (auto node : flow.wire_comb_defs[wire]) - for (auto node_use : flow.node_uses[node]) - if (!visited.count(node_use)) - worklist.insert(node_use); + auto node = worklist.pop(); + live_nodes.insert(node); + for (auto wire : flow.node_uses[node]) { + if (debug_wire_types[wire].is_member()) + continue; // node uses member + if (debug_wire_types[wire].is_exact()) + continue; // node uses alias or const + live_wires[wire].insert(node); + for (auto pred_node : flow.wire_comb_defs[wire]) + if (!live_nodes[pred_node]) + worklist.insert(pred_node); + } } - } - if (debug_info && debug_alias) { - // Find wires that alias other wires or are tied to a constant. Both of these cases are - // directly expressible in the debug information, improving coverage at zero cost. + + // Assign debug information wire types to internal wires used by reachable nodes. This is similar + // to refining optimized wire types with the exception that the assignments here are first and final. for (auto wire : module->wires()) { - if (!wire->name.isPublic()) - continue; - const RTLIL::Wire *cursor = wire; - RTLIL::SigSpec alias_of; - while (1) { - if (!(flow.wire_def_inlinable.count(cursor) && flow.wire_def_inlinable[cursor])) - break; // not an alias: complex def - log_assert(flow.wire_comb_defs[cursor].size() == 1); - FlowGraph::Node *node = *flow.wire_comb_defs[cursor].begin(); - if (node->type != FlowGraph::Node::Type::CONNECT) - break; // not an alias: def by cell - RTLIL::SigSpec rhs_sig = node->connect.second; - if (rhs_sig.is_fully_const()) { - alias_of = rhs_sig; // alias of const - break; - } else if (rhs_sig.is_wire()) { - RTLIL::Wire *rhs_wire = rhs_sig.as_wire(); // possible alias of wire - if (rhs_wire->port_input && !rhs_wire->port_output) { - alias_of = rhs_wire; // alias of input + const auto &wire_type = wire_types[wire]; + auto &debug_wire_type = debug_wire_types[wire]; + if (wire->name.isPublic()) continue; + + if (live_wires[wire].empty()) { + continue; // wire never used + } else if (flow.is_inlinable(wire, live_wires[wire])) { + log_assert(flow.wire_comb_defs[wire].size() == 1); + FlowGraph::Node *node = *flow.wire_comb_defs[wire].begin(); + switch (node->type) { + case FlowGraph::Node::Type::CELL_EVAL: + if (!is_inlinable_cell(node->cell->type)) continue; + debug_wire_type = {WireType::INLINE, node->cell}; // wire replaced with cell break; - } else if (!localized_wires.count(rhs_wire) && !inlined_wires.count(rhs_wire)) { - alias_of = rhs_wire; // alias of member + case FlowGraph::Node::Type::CONNECT: + debug_wire_type = {WireType::INLINE, node->connect.second}; // wire replaced with sig break; - } else { - if (rhs_wire->name.isPublic() && debug_outlined_wires.count(rhs_wire)) - alias_of = rhs_wire; // alias of either outline or another alias - cursor = rhs_wire; // keep looking - } - } else { - break; // not an alias: complex rhs + default: continue; } + live_nodes.erase(node); + } else if (wire_type.is_local()) { + debug_wire_type = {WireType::LOCAL}; // wire not inlinable + } else { + log_assert(wire_type.is_member()); + debug_wire_type = wire_type; // wire is a member } - if (alias_of.empty()) { - continue; - } else if (alias_of.is_fully_const()) { - debug_const_wires[wire] = alias_of.as_const(); - } else if (alias_of.is_wire()) { - debug_alias_wires[wire] = alias_of.as_wire(); - } else log_abort(); - if (inlined_wires.count(wire)) - debug_outlined_wires.erase(wire); } + + // Emit reachable nodes in debug_eval(). + for (auto node : node_order) + if (live_nodes[node]) + debug_schedule[module].push_back(*node); } } if (has_feedback_arcs || has_buffered_comb_wires) { @@ -2593,7 +2749,7 @@ struct CxxrtlWorker { struct CxxrtlBackend : public Backend { static const int DEFAULT_OPT_LEVEL = 6; - static const int DEFAULT_DEBUG_LEVEL = 3; + static const int DEFAULT_DEBUG_LEVEL = 4; CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { } void help() override @@ -2811,18 +2967,22 @@ struct CxxrtlBackend : public Backend { log(" more visibility and generate more code, but do not pessimize evaluation.\n"); log("\n"); log(" -g0\n"); - log(" no debug information. the C API is unavailable.\n"); + log(" no debug information. the C API is disabled.\n"); log("\n"); log(" -g1\n"); - log(" debug information for member public wires only. this is the bare minimum\n"); - log(" necessary to access all design state. enables the C API.\n"); + log(" include bare minimum of debug information necessary to access all design\n"); + log(" state. the C API is enabled.\n"); log("\n"); log(" -g2\n"); - log(" like -g1, and include debug information for public wires that are tied\n"); - log(" to a constant or another public wire.\n"); + log(" like -g1, but include debug information for all public wires that are\n"); + log(" directly accessible through the C++ interface.\n"); log("\n"); log(" -g3\n"); - log(" like -g2, and compute debug information on demand for all public wires\n"); + log(" like -g2, and include debug information for public wires that are tied\n"); + log(" to a constant or another public wire.\n"); + log("\n"); + log(" -g4\n"); + log(" like -g3, and compute debug information on demand for all public wires\n"); log(" that were optimized out.\n"); log("\n"); } @@ -2922,12 +3082,15 @@ struct CxxrtlBackend : public Backend { } switch (debug_level) { // the highest level here must match DEFAULT_DEBUG_LEVEL - case 3: + case 4: worker.debug_eval = true; YS_FALLTHROUGH - case 2: + case 3: worker.debug_alias = true; YS_FALLTHROUGH + case 2: + worker.debug_member = true; + YS_FALLTHROUGH case 1: worker.debug_info = true; YS_FALLTHROUGH From ac988cfac50050314f974dd1c7cc29ba4b46935d Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 21 Dec 2020 21:17:33 +0000 Subject: [PATCH 0102/2410] kernel: undef Tcl macros interfering with cxxrtl. --- kernel/yosys.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/yosys.h b/kernel/yosys.h index ab6eb5f8c4c..ac4436c5244 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -93,6 +93,8 @@ extern Tcl_Obj *Tcl_NewIntObj(int intValue); extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); # endif +# undef CONST +# undef INLINE #endif #ifdef _WIN32 From 7378194169e6af370ed467347d5b73d50ee22e4b Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 22 Dec 2020 00:07:45 +0000 Subject: [PATCH 0103/2410] cxxrtl: split processes into sync and case nodes. Similar to the treatment of black boxes, splitting processes into two scheduling nodes adds sufficient freedom so that netlists with well-behaved processes (e.g. those emitted by nMigen) can immediately converge. Because processes are not emitted into edge-triggered regions, this approach has comparable performance to -O5 (without -noproc), which is substantially slower than -O6. --- backends/cxxrtl/cxxrtl_backend.cc | 37 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 338648c899e..c0f02946e02 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -272,7 +272,8 @@ struct FlowGraph { CONNECT, CELL_SYNC, CELL_EVAL, - PROCESS + PROCESS_SYNC, + PROCESS_CASE, }; Type type; @@ -458,7 +459,7 @@ struct FlowGraph { } // Processes - void add_case_defs_uses(Node *node, const RTLIL::CaseRule *case_) + void add_case_rule_defs_uses(Node *node, const RTLIL::CaseRule *case_) { for (auto &action : case_->actions) { add_defs(node, action.first, /*is_ff=*/false, /*inlinable=*/false); @@ -469,14 +470,13 @@ struct FlowGraph { for (auto sub_case : sub_switch->cases) { for (auto &compare : sub_case->compare) add_uses(node, compare); - add_case_defs_uses(node, sub_case); + add_case_rule_defs_uses(node, sub_case); } } } - void add_process_defs_uses(Node *node, const RTLIL::Process *process) + void add_sync_rules_defs_uses(Node *node, const RTLIL::Process *process) { - add_case_defs_uses(node, &process->root_case); for (auto sync : process->syncs) for (auto action : sync->actions) { if (sync->type == RTLIL::STp || sync->type == RTLIL::STn || sync->type == RTLIL::STe) @@ -490,10 +490,16 @@ struct FlowGraph { Node *add_node(const RTLIL::Process *process) { Node *node = new Node; - node->type = Node::Type::PROCESS; + node->type = Node::Type::PROCESS_SYNC; node->process = process; nodes.push_back(node); - add_process_defs_uses(node, process); + add_sync_rules_defs_uses(node, process); + + node = new Node; + node->type = Node::Type::PROCESS_CASE; + node->process = process; + nodes.push_back(node); + add_case_rule_defs_uses(node, &process->root_case); return node; } }; @@ -1481,13 +1487,19 @@ struct CxxrtlWorker { f << indent << "}\n"; } - void dump_process(const RTLIL::Process *proc) + void dump_process_case(const RTLIL::Process *proc) { dump_attrs(proc); - f << indent << "// process " << proc->name.str() << "\n"; + f << indent << "// process " << proc->name.str() << " case\n"; // The case attributes (for root case) are always empty. log_assert(proc->root_case.attributes.empty()); dump_case_rule(&proc->root_case); + } + + void dump_process_syncs(const RTLIL::Process *proc) + { + dump_attrs(proc); + f << indent << "// process " << proc->name.str() << " syncs\n"; for (auto sync : proc->syncs) { RTLIL::SigBit sync_bit; if (!sync->signal.empty()) { @@ -1702,8 +1714,11 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell); break; - case FlowGraph::Node::Type::PROCESS: - dump_process(node.process); + case FlowGraph::Node::Type::PROCESS_SYNC: + dump_process_syncs(node.process); + break; + case FlowGraph::Node::Type::PROCESS_CASE: + dump_process_case(node.process); break; } } From f14074d2c2c8fa0ad4f6922e07c050c912cbfd19 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 22 Dec 2020 06:46:44 +0000 Subject: [PATCH 0104/2410] cxxrtl: don't crash generating debug information for unused wires. --- backends/cxxrtl/cxxrtl_backend.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index c0f02946e02..861b484f4eb 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2578,6 +2578,7 @@ struct CxxrtlWorker { for (auto wire : module->wires()) { const auto &wire_type = wire_types[wire]; auto &debug_wire_type = debug_wire_types[wire]; + if (wire_type.type == WireType::UNUSED) continue; if (!wire->name.isPublic()) continue; if (!debug_info) continue; @@ -2622,19 +2623,19 @@ struct CxxrtlWorker { if (debug_wire_types[wire].is_outline()) worklist.insert(node); // node drives outline } - dict> live_wires; - pool live_nodes; + dict> debug_live_wires; + pool debug_live_nodes; while (!worklist.empty()) { auto node = worklist.pop(); - live_nodes.insert(node); + debug_live_nodes.insert(node); for (auto wire : flow.node_uses[node]) { if (debug_wire_types[wire].is_member()) continue; // node uses member if (debug_wire_types[wire].is_exact()) continue; // node uses alias or const - live_wires[wire].insert(node); + debug_live_wires[wire].insert(node); for (auto pred_node : flow.wire_comb_defs[wire]) - if (!live_nodes[pred_node]) + if (!debug_live_nodes[pred_node]) worklist.insert(pred_node); } } @@ -2646,9 +2647,9 @@ struct CxxrtlWorker { auto &debug_wire_type = debug_wire_types[wire]; if (wire->name.isPublic()) continue; - if (live_wires[wire].empty()) { + if (live_wires[wire].empty() || debug_live_wires[wire].empty()) { continue; // wire never used - } else if (flow.is_inlinable(wire, live_wires[wire])) { + } else if (flow.is_inlinable(wire, debug_live_wires[wire])) { log_assert(flow.wire_comb_defs[wire].size() == 1); FlowGraph::Node *node = *flow.wire_comb_defs[wire].begin(); switch (node->type) { @@ -2661,7 +2662,7 @@ struct CxxrtlWorker { break; default: continue; } - live_nodes.erase(node); + debug_live_nodes.erase(node); } else if (wire_type.is_local()) { debug_wire_type = {WireType::LOCAL}; // wire not inlinable } else { @@ -2672,7 +2673,7 @@ struct CxxrtlWorker { // Emit reachable nodes in debug_eval(). for (auto node : node_order) - if (live_nodes[node]) + if (debug_live_nodes[node]) debug_schedule[module].push_back(*node); } } From 8206546c45d8fe74ac291a548fa372d1bd98f966 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 5 Dec 2020 18:56:18 -0700 Subject: [PATCH 0105/2410] Fix constants bound to single bit arguments (fixes #2383) --- frontends/ast/simplify.cc | 8 ++++++++ tests/various/const_arg_loop.v | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index fb6623f0238..8cd459913c2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3337,6 +3337,14 @@ skip_dynamic_range_lvalue_expansion:; wire->type = AST_LOCALPARAM; wire->attributes.erase(ID::nosync); wire->children.insert(wire->children.begin(), arg->clone()); + // args without a range implicitly have width 1 + if (wire->children.back()->type != AST_RANGE) { + AstNode* range = new AstNode(); + range->type = AST_RANGE; + wire->children.push_back(range); + range->children.push_back(mkconst_int(0, true)); + range->children.push_back(mkconst_int(0, true)); + } continue; } AstNode *wire_id = new AstNode(AST_IDENTIFIER); diff --git a/tests/various/const_arg_loop.v b/tests/various/const_arg_loop.v index 3bfff4acd8d..567bccc2542 100644 --- a/tests/various/const_arg_loop.v +++ b/tests/various/const_arg_loop.v @@ -39,6 +39,12 @@ module top; end endfunction + function automatic [16:0] operation4; + input [15:0] a; + input b; + operation4 = {a, b}; + endfunction + wire [31:0] a; assign a = 2; @@ -53,6 +59,9 @@ module top; wire [31:0] x3; assign x3 = operation3(A, a); + wire [16:0] x4; + assign x4 = operation4(a[15:0], 0); + // `define VERIFY `ifdef VERIFY assert property (a == 2); @@ -60,5 +69,6 @@ module top; assert property (x1 == 16); assert property (x2 == 4); assert property (x3 == 16); + assert property (x4 == a << 1); `endif endmodule From 832f6aa777558ccef3b06798d182372b5783c51f Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 23 Dec 2020 00:10:07 +0000 Subject: [PATCH 0106/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9ece371c554..7dee3847818 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3780 +YOSYS_VER := 0.9+3796 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 999eec561752706a8ccb085a692684c745415985 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 22 Dec 2020 17:38:51 -0700 Subject: [PATCH 0107/2410] genrtlil: fix mux2rtlil generated wire signedness --- frontends/ast/genrtlil.cc | 1 + tests/various/port_sign_extend.v | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 500ccf8c001..b8bfdf65e84 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -141,6 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size()); wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + wire->is_signed = that->is_signed; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) diff --git a/tests/various/port_sign_extend.v b/tests/various/port_sign_extend.v index 055f20ad8a0..44626826872 100644 --- a/tests/various/port_sign_extend.v +++ b/tests/various/port_sign_extend.v @@ -24,8 +24,8 @@ module PassThrough(a, b); assign b = a; endmodule -module act(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); - output wire [3:0] o1, o2, o3, o4, o5; +module act(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5, o6; // unsigned constant PassThrough pt1(1'b1, o1); @@ -48,6 +48,10 @@ module act(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); wire signed [1:0] tmp5b = 2'b01; PassThrough pt5(tmp5a ^ tmp5b, o5); + wire signed [2:0] tmp6a = 3'b100; + wire signed [2:0] tmp6b = 3'b001; + PassThrough pt6(tmp6a ? tmp6a : tmp6b, o6); + output wire [2:0] yay1, nay1; GeneratorSigned1 os1(yay1); GeneratorUnsigned1 ou1(nay1); @@ -57,14 +61,15 @@ module act(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); GeneratorUnsigned2 ou2(nay2); endmodule -module ref(o1, o2, o3, o4, o5, yay1, nay1, yay2, nay2); - output wire [3:0] o1, o2, o3, o4, o5; +module ref(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5, o6; assign o1 = 4'b0001; assign o2 = 4'b0001; assign o3 = 4'b1111; assign o4 = 4'b1111; assign o5 = 4'b1110; + assign o6 = 4'b1100; output wire [2:0] yay1, nay1; assign yay1 = 3'b111; From 84c0b5c6904ebc317daee637bbf70af5c468c7aa Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 23 Dec 2020 14:38:25 -0800 Subject: [PATCH 0108/2410] passes/pmgen/pmgen.py: trivial change to remove C++ compiler warnings Verified that the result still builds and passes self-tests --- passes/pmgen/pmgen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index db827ee8272..6e2fabeebde 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -453,7 +453,7 @@ def process_pmgfile(f, filename): print(" SigSpec port(Cell *cell, IdString portname) {", file=f) print(" try {", file=f) print(" return sigmap(cell->getPort(portname));", file=f) - print(" } catch(std::out_of_range) { log_error(\"Accessing non existing port %s\\n\",portname.c_str()); }", file=f) + print(" } catch(std::out_of_range&) { log_error(\"Accessing non existing port %s\\n\",portname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" SigSpec port(Cell *cell, IdString portname, const SigSpec& defval) {", file=f) @@ -464,7 +464,7 @@ def process_pmgfile(f, filename): print(" Const param(Cell *cell, IdString paramname) {", file=f) print(" try {", file=f) print(" return cell->getParam(paramname);", file=f) - print(" } catch(std::out_of_range) { log_error(\"Accessing non existing parameter %s\\n\",paramname.c_str()); }", file=f) + print(" } catch(std::out_of_range&) { log_error(\"Accessing non existing parameter %s\\n\",paramname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" Const param(Cell *cell, IdString paramname, const Const& defval) {", file=f) From 449154803737f45406f711d965113536bc8ae818 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 24 Dec 2020 00:10:08 +0000 Subject: [PATCH 0109/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7dee3847818..8032ce2de47 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3796 +YOSYS_VER := 0.9+3803 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1419c8761cc7594f56855546a633f8bdf0e3ebca Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 26 Dec 2020 08:39:57 -0700 Subject: [PATCH 0110/2410] Fix constants bound to redeclared function args The changes in #2476 ensured that function inputs like `input x;` retained their single-bit size when instantiated with a constant argument and turned into a localparam. That change did not handle the possibility for an input to be redeclared later on with an explicit width, such as `integer x;`. --- frontends/ast/simplify.cc | 21 ++++++++++++++++----- tests/various/const_arg_loop.v | 10 ++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5fa4ac83b2e..c6d63f24712 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3344,11 +3344,22 @@ skip_dynamic_range_lvalue_expansion:; wire->children.insert(wire->children.begin(), arg->clone()); // args without a range implicitly have width 1 if (wire->children.back()->type != AST_RANGE) { - AstNode* range = new AstNode(); - range->type = AST_RANGE; - wire->children.push_back(range); - range->children.push_back(mkconst_int(0, true)); - range->children.push_back(mkconst_int(0, true)); + // check if this wire is redeclared with an explicit size + bool uses_explicit_size = false; + for (const AstNode *other_child : decl->children) + if (other_child->type == AST_WIRE && child->str == other_child->str + && !other_child->children.empty() + && other_child->children.back()->type == AST_RANGE) { + uses_explicit_size = true; + break; + } + if (!uses_explicit_size) { + AstNode* range = new AstNode(); + range->type = AST_RANGE; + wire->children.push_back(range); + range->children.push_back(mkconst_int(0, true)); + range->children.push_back(mkconst_int(0, true)); + } } continue; } diff --git a/tests/various/const_arg_loop.v b/tests/various/const_arg_loop.v index ed15aa13529..358fb439ae6 100644 --- a/tests/various/const_arg_loop.v +++ b/tests/various/const_arg_loop.v @@ -50,6 +50,12 @@ module top; operation4 = {a, b}; endfunction + function automatic integer operation5; + input x; + integer x; + operation5 = x; + endfunction + wire [31:0] a; assign a = 2; @@ -70,6 +76,9 @@ module top; wire [16:0] x4; assign x4 = operation4(a[15:0], 0); + wire [31:0] x5; + assign x5 = operation5(64); + // `define VERIFY `ifdef VERIFY assert property (a == 2); @@ -79,5 +88,6 @@ module top; assert property (x2 == 4); assert property (x3 == 16); assert property (x4 == a << 1); + assert property (x5 == 64); `endif endmodule From af457ce8d05bb57a48831c3c252c708625ae0ffd Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sun, 27 Dec 2020 00:10:10 +0000 Subject: [PATCH 0111/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8032ce2de47..d9e29b44602 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3803 +YOSYS_VER := 0.9+3806 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 750831e3e096398856053d9cbc2701e49fe0c29e Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 26 Dec 2020 21:38:13 -0700 Subject: [PATCH 0112/2410] Fix elaboration of whole memory words used as indices --- frontends/ast/simplify.cc | 9 ++++++++- tests/various/memory_word_as_index.data | 4 ++++ tests/various/memory_word_as_index.v | 21 +++++++++++++++++++++ tests/various/memory_word_as_index.ys | 23 +++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/various/memory_word_as_index.data create mode 100644 tests/various/memory_word_as_index.v create mode 100644 tests/various/memory_word_as_index.ys diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index c6d63f24712..17b4d4cdc2b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3451,7 +3451,14 @@ replace_fcall_later:; if (current_scope[str]->children[0]->isConst()) newNode = current_scope[str]->children[0]->clone(); } - else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) { + else if (at_zero && current_scope.count(str) > 0) { + AstNode *node = current_scope[str]; + if (node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY) + newNode = mkconst_int(0, sign_hint, width_hint); + } + break; + case AST_MEMRD: + if (at_zero) { newNode = mkconst_int(0, sign_hint, width_hint); } break; diff --git a/tests/various/memory_word_as_index.data b/tests/various/memory_word_as_index.data new file mode 100644 index 00000000000..d525c18eed2 --- /dev/null +++ b/tests/various/memory_word_as_index.data @@ -0,0 +1,4 @@ +00 04 08 0c +10 14 18 1c +20 24 28 2c +30 34 38 3c diff --git a/tests/various/memory_word_as_index.v b/tests/various/memory_word_as_index.v new file mode 100644 index 00000000000..a99ea95664f --- /dev/null +++ b/tests/various/memory_word_as_index.v @@ -0,0 +1,21 @@ +`define DATA 64'h492e5c4d7747e032 + +`define GATE(n, expr) \ +module gate``n(sel, out); \ + input wire [3:0] sel; \ + output wire out; \ + reg [63:0] bits; \ + reg [5:0] ptrs[15:0]; \ + initial bits = `DATA; \ + initial $readmemh("memory_word_as_index.data", ptrs); \ + assign out = expr; \ +endmodule + +`GATE(1, bits[ptrs[sel]]) +`GATE(2, bits[ptrs[sel][5:0]]) +`GATE(3, bits[ptrs[sel]+:1]) + +module gold(sel, out); + input wire [3:0] sel; + output wire out = `DATA >> (sel * 4); +endmodule diff --git a/tests/various/memory_word_as_index.ys b/tests/various/memory_word_as_index.ys new file mode 100644 index 00000000000..9a2dea40e8e --- /dev/null +++ b/tests/various/memory_word_as_index.ys @@ -0,0 +1,23 @@ +read_verilog memory_word_as_index.v + +hierarchy +proc +memory +flatten +opt -full + +equiv_make gold gate1 equiv +equiv_simple +equiv_status -assert + +delete equiv + +equiv_make gold gate2 equiv +equiv_simple +equiv_status -assert + +delete equiv + +equiv_make gold gate3 equiv +equiv_simple +equiv_status -assert From cb2283389df6fbd2f6aa8393e8d1960123ec72f4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 27 Dec 2020 05:00:04 +0000 Subject: [PATCH 0113/2410] CODEOWNERS: add @zachjs as Verilog/AST frontend owner --- CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 350a62120b5..0419e6e4410 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -25,6 +25,9 @@ passes/opt/opt_lut.cc @whitequark # These still override previous lines, so be careful not to # accidentally disable any of the above rules. +frontends/verilog/ @zachjs +frontends/ast/ @zachjs + techlibs/intel_alm/ @ZirconiumX # pyosys From f48298347cc01d538e20dd9d86b4f795780f8f1d Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Mon, 28 Dec 2020 00:10:04 +0000 Subject: [PATCH 0114/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d9e29b44602..8577479880f 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3806 +YOSYS_VER := 0.9+3809 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 16c4182c74f7898ae6e3c7cbac8a29d8cc8e5510 Mon Sep 17 00:00:00 2001 From: umarcor Date: Sat, 26 Dec 2020 23:21:30 +0100 Subject: [PATCH 0115/2410] kernel/yosys.h: undef CONST on WIN32 --- kernel/yosys.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/yosys.h b/kernel/yosys.h index ac4436c5244..43aecdbc8e5 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -121,8 +121,9 @@ extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *p # define fileno _fileno # endif -// mingw and msvc include `wingdi.h` which defines a TRANSPARENT macro -// that conflicts with X(TRANSPARENT) entry in kernel/constids.inc +// The following defines conflict with our identifiers: +# undef CONST +// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc # undef TRANSPARENT #endif From 0ebce301c1a711662faaad3c356a9ce5a59b7246 Mon Sep 17 00:00:00 2001 From: umarcor Date: Sun, 27 Dec 2020 05:37:46 +0100 Subject: [PATCH 0116/2410] makefile: rename msys2 to msys2-32, config PREFIX --- Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 8577479880f..57bf2a7268e 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ CONFIG := clang # CONFIG := emcc # CONFIG := wasi # CONFIG := mxe -# CONFIG := msys2 +# CONFIG := msys2-32 # CONFIG := msys2-64 # features (the more the better) @@ -322,7 +322,7 @@ ABCMKARGS += ARCHFLAGS="-DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w" ABCMKARGS += LIBS="lib/x86/pthreadVC2.lib -s" LDFLAGS="-Wl,--allow-multiple-definition" ABC_USE_NO_READLINE=1 CC="/usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-gcc" EXE = .exe -else ifeq ($(CONFIG),msys2) +else ifeq ($(CONFIG),msys2-32) CXX = i686-w64-mingw32-g++ LD = i686-w64-mingw32-g++ CXXFLAGS += -std=c++11 -Os -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR @@ -345,7 +345,7 @@ ABCMKARGS += LIBS="-lpthread -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gc EXE = .exe else ifneq ($(CONFIG),none) -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, gcc-4.8, emcc, mxe, msys2, msys2-64) +$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, gcc-4.8, emcc, mxe, msys2-32, msys2-64) endif ifeq ($(ENABLE_LIBYOSYS),1) @@ -989,13 +989,15 @@ config-mxe: clean echo 'CONFIG := mxe' > Makefile.conf echo 'ENABLE_PLUGINS := 0' >> Makefile.conf -config-msys2: clean - echo 'CONFIG := msys2' > Makefile.conf +config-msys2-32: clean + echo 'CONFIG := msys2-32' > Makefile.conf echo 'ENABLE_PLUGINS := 0' >> Makefile.conf + echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf config-msys2-64: clean echo 'CONFIG := msys2-64' > Makefile.conf echo 'ENABLE_PLUGINS := 0' >> Makefile.conf + echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf config-cygwin: clean echo 'CONFIG := cygwin' > Makefile.conf From a652430c711b831423bfd2a2c0c20caa2fc333c8 Mon Sep 17 00:00:00 2001 From: umarcor Date: Mon, 28 Dec 2020 02:24:41 +0100 Subject: [PATCH 0117/2410] makefile: add support for built-in ghdl-yosys-plugin Co-authored-by: Tristan Gingold Co-authored-by: whitequark --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index 57bf2a7268e..76018a01434 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ ENABLE_GLOB := 1 ENABLE_PLUGINS := 1 ENABLE_READLINE := 1 ENABLE_EDITLINE := 0 +ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 @@ -511,6 +512,14 @@ endif endif endif +ifeq ($(ENABLE_GHDL),1) +GHDL_PREFIX ?= $(PREFIX) +GHDL_INCLUDE_DIR ?= $(GHDL_DIR)/include +GHDL_LIB_DIR ?= $(GHDL_DIR)/lib +CXXFLAGS += -I$(GHDL_INCLUDE_DIR) -DYOSYS_ENABLE_GHDL +LDLIBS += $(GHDL_LIB_DIR)/libghdl.a $(file <$(GHDL_LIB_DIR)/libghdl.link) +endif + ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree From 0347b441a1ea574977f347b59895b7374da9d028 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 29 Dec 2020 00:10:04 +0000 Subject: [PATCH 0118/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 57bf2a7268e..17d3ced8ae1 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3809 +YOSYS_VER := 0.9+3814 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From e61b1070729cf247b3d0d86225f7984a04cf72a1 Mon Sep 17 00:00:00 2001 From: umarcor Date: Mon, 28 Dec 2020 04:30:57 +0100 Subject: [PATCH 0119/2410] plugin: enhance no-plugin error --- passes/cmds/plugin.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 3ed19497d5e..a94769bcd29 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -93,7 +93,11 @@ void load_plugin(std::string filename, std::vector aliases) #else void load_plugin(std::string, std::vector) { - log_error("This version of yosys is built without plugin support.\n"); + log_error( + "\n This version of Yosys cannot load plugins at runtime.\n" + " Some plugins may have been included at build time.\n" + " Use option `-H' to see the available built-in and plugin commands.\n" + ); } #endif From 48d0aeb09483283c46491448304bf04865e176f5 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 30 Dec 2020 00:10:06 +0000 Subject: [PATCH 0120/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cd9e774488f..0883ef60f64 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3814 +YOSYS_VER := 0.9+3819 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 7f28afd3accf6152a01befb955dd2f443ddfe68e Mon Sep 17 00:00:00 2001 From: umarcor Date: Wed, 30 Dec 2020 07:06:52 +0100 Subject: [PATCH 0121/2410] makefile: fix GHDL vars, replace GHDL_DIR with GHDL_PREFIX --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0883ef60f64..fd7816898a3 100644 --- a/Makefile +++ b/Makefile @@ -514,8 +514,8 @@ endif ifeq ($(ENABLE_GHDL),1) GHDL_PREFIX ?= $(PREFIX) -GHDL_INCLUDE_DIR ?= $(GHDL_DIR)/include -GHDL_LIB_DIR ?= $(GHDL_DIR)/lib +GHDL_INCLUDE_DIR ?= $(GHDL_PREFIX)/include +GHDL_LIB_DIR ?= $(GHDL_PREFIX)/lib CXXFLAGS += -I$(GHDL_INCLUDE_DIR) -DYOSYS_ENABLE_GHDL LDLIBS += $(GHDL_LIB_DIR)/libghdl.a $(file <$(GHDL_LIB_DIR)/libghdl.link) endif From 75abd908294c599c9987978175b46196146c9d1d Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 31 Dec 2020 16:14:35 -0700 Subject: [PATCH 0122/2410] sv: complete support for implied task/function port directions --- frontends/verilog/verilog_parser.y | 10 ++++++++++ tests/various/func_port_implied_dir.sv | 23 +++++++++++++++++++++++ tests/various/func_port_implied_dir.ys | 6 ++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/various/func_port_implied_dir.sv create mode 100644 tests/various/func_port_implied_dir.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 678ce6c8759..6c4b06d7feb 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -884,7 +884,11 @@ task_func_args: task_func_port: attr wire_type range { + bool prev_was_input = true; + bool prev_was_output = false; if (albuf) { + prev_was_input = astbuf1->is_input; + prev_was_output = astbuf1->is_output; delete astbuf1; if (astbuf2 != NULL) delete astbuf2; @@ -893,6 +897,12 @@ task_func_port: albuf = $1; astbuf1 = $2; astbuf2 = checkRange(astbuf1, $3); + if (!astbuf1->is_input && !astbuf1->is_output) { + if (!sv_mode) + frontend_verilog_yyerror("task/function argument direction missing"); + astbuf1->is_input = prev_was_input; + astbuf1->is_output = prev_was_output; + } } wire_name | { if (!astbuf1) { diff --git a/tests/various/func_port_implied_dir.sv b/tests/various/func_port_implied_dir.sv new file mode 100644 index 00000000000..0424f1b46e4 --- /dev/null +++ b/tests/various/func_port_implied_dir.sv @@ -0,0 +1,23 @@ +module gate(w, x, y, z); + function automatic integer bar( + integer a + ); + bar = 2 ** a; + endfunction + output integer w = bar(4); + + function automatic integer foo( + input integer a, /* implicitly input */ integer b, + output integer c, /* implicitly output */ integer d + ); + c = 42; + d = 51; + foo = a + b + 1; + endfunction + output integer x, y, z; + initial x = foo(1, 2, y, z); +endmodule + +module gold(w, x, y, z); + output integer w = 16, x = 4, y = 42, z = 51; +endmodule diff --git a/tests/various/func_port_implied_dir.ys b/tests/various/func_port_implied_dir.ys new file mode 100644 index 00000000000..b5c22a05b89 --- /dev/null +++ b/tests/various/func_port_implied_dir.ys @@ -0,0 +1,6 @@ +read_verilog -sv func_port_implied_dir.sv +hierarchy +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From 2085d9a55d38f28551739d63bede29d93edaf578 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 31 Dec 2020 17:23:36 -0700 Subject: [PATCH 0123/2410] verilog: improved support for recursive functions --- frontends/ast/ast.h | 2 ++ frontends/ast/simplify.cc | 34 +++++++++++++++----- tests/various/fib.v | 65 +++++++++++++++++++++++++++++++++++++++ tests/various/fib.ys | 6 ++++ 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 tests/various/fib.v create mode 100644 tests/various/fib.ys diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 1b8ed22ca6e..90739216679 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -250,6 +250,7 @@ namespace AST // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc. // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); + void replace_result_wire_name_in_function(const std::string &from, const std::string &to); AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init); void expand_genblock(std::string index_var, std::string prefix, std::map &name_map, bool original_scope = true); void replace_ids(const std::string &prefix, const std::map &rules); @@ -264,6 +265,7 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; bool has_const_only_constructs(bool &recommend_const_eval); + bool has_const_only_constructs(std::set& visited, bool &recommend_const_eval); void replace_variables(std::map &variables, AstNode *fcall); AstNode *eval_const_function(AstNode *fcall); bool is_simple_const_expr(); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 17b4d4cdc2b..d4242f1e708 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3175,6 +3175,8 @@ skip_dynamic_range_lvalue_expansion:; if (all_args_const) { AstNode *func_workspace = current_scope[str]->clone(); + func_workspace->str = NEW_ID.str(); + func_workspace->replace_result_wire_name_in_function(str, func_workspace->str); newNode = func_workspace->eval_const_function(this); delete func_workspace; goto apply_newNode; @@ -3714,12 +3716,12 @@ replace_fcall_later:; return did_something; } -static void replace_result_wire_name_in_function(AstNode *node, std::string &from, std::string &to) +void AstNode::replace_result_wire_name_in_function(const std::string &from, const std::string &to) { - for (auto &it : node->children) - replace_result_wire_name_in_function(it, from, to); - if (node->str == from) - node->str = to; + for (AstNode *child : children) + child->replace_result_wire_name_in_function(from, to); + if (str == from && type != AST_FCALL && type != AST_TCALL) + str = to; } // replace a readmem[bh] TCALL ast node with a block of memory assignments @@ -3912,7 +3914,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma name_map[child->str] = new_name; if (child->type == AST_FUNCTION) - replace_result_wire_name_in_function(child, child->str, new_name); + child->replace_result_wire_name_in_function(child->str, new_name); else child->str = new_name; current_scope[new_name] = child; @@ -4492,15 +4494,31 @@ bool AstNode::detect_latch(const std::string &var) bool AstNode::has_const_only_constructs(bool &recommend_const_eval) { + std::set visited; + return has_const_only_constructs(visited, recommend_const_eval); +} + +bool AstNode::has_const_only_constructs(std::set& visited, bool &recommend_const_eval) +{ + if (type == AST_FUNCTION || type == AST_TASK) + { + if (visited.count(str)) + { + recommend_const_eval = true; + return false; + } + visited.insert(str); + } + if (type == AST_FOR) recommend_const_eval = true; if (type == AST_WHILE || type == AST_REPEAT) return true; if (type == AST_FCALL && current_scope.count(str)) - if (current_scope[str]->has_const_only_constructs(recommend_const_eval)) + if (current_scope[str]->has_const_only_constructs(visited, recommend_const_eval)) return true; for (auto child : children) - if (child->AstNode::has_const_only_constructs(recommend_const_eval)) + if (child->AstNode::has_const_only_constructs(visited, recommend_const_eval)) return true; return false; } diff --git a/tests/various/fib.v b/tests/various/fib.v new file mode 100644 index 00000000000..98674962643 --- /dev/null +++ b/tests/various/fib.v @@ -0,0 +1,65 @@ +module gate( + off, fib0, fib1, fib2, fib3, fib4, fib5, fib6, fib7, fib8, fib9 +); + input wire signed [31:0] off; + + function automatic integer fib( + input integer k + ); + if (k == 0) + fib = 0; + else if (k == 1) + fib = 1; + else + fib = fib(k - 1) + fib(k - 2); + endfunction + + function automatic integer fib_wrap( + input integer k, + output integer o + ); + o = off + fib(k); + endfunction + + output integer fib0; + output integer fib1; + output integer fib2; + output integer fib3; + output integer fib4; + output integer fib5; + output integer fib6; + output integer fib7; + output integer fib8; + output integer fib9; + + initial begin : blk + integer unused; + unused = fib_wrap(0, fib0); + unused = fib_wrap(1, fib1); + unused = fib_wrap(2, fib2); + unused = fib_wrap(3, fib3); + unused = fib_wrap(4, fib4); + unused = fib_wrap(5, fib5); + unused = fib_wrap(6, fib6); + unused = fib_wrap(7, fib7); + unused = fib_wrap(8, fib8); + unused = fib_wrap(9, fib9); + end +endmodule + +module gold( + off, fib0, fib1, fib2, fib3, fib4, fib5, fib6, fib7, fib8, fib9 +); + input wire signed [31:0] off; + + output integer fib0 = off + 0; + output integer fib1 = off + 1; + output integer fib2 = off + 1; + output integer fib3 = off + 2; + output integer fib4 = off + 3; + output integer fib5 = off + 5; + output integer fib6 = off + 8; + output integer fib7 = off + 13; + output integer fib8 = off + 21; + output integer fib9 = off + 34; +endmodule diff --git a/tests/various/fib.ys b/tests/various/fib.ys new file mode 100644 index 00000000000..946e0738a81 --- /dev/null +++ b/tests/various/fib.ys @@ -0,0 +1,6 @@ +read_verilog fib.v +hierarchy +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From b72c29465392c8d260ddf55def169438f7fb64b2 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sat, 2 Jan 2021 00:10:04 +0000 Subject: [PATCH 0124/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd7816898a3..57ef0b65ea5 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3819 +YOSYS_VER := 0.9+3830 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 87637e835922884fed301fb3580bb049c2b4d7bb Mon Sep 17 00:00:00 2001 From: Tom Verbeure Date: Sun, 3 Jan 2021 23:52:59 -0800 Subject: [PATCH 0125/2410] Fix some trivial typos. --- techlibs/common/simlib.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index e9488402561..5c9efad2751 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -237,7 +237,7 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- -//- $reduce_and (A, B, Y) +//- $reduce_and (A, Y) //- //- An AND reduction. This corresponds to the Verilog unary prefix '&' operator. //- @@ -264,7 +264,7 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- -//- $reduce_or (A, B, Y) +//- $reduce_or (A, Y) //- //- An OR reduction. This corresponds to the Verilog unary prefix '|' operator. //- @@ -291,7 +291,7 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- -//- $reduce_xor (A, B, Y) +//- $reduce_xor (A, Y) //- //- A XOR reduction. This corresponds to the Verilog unary prefix '^' operator. //- @@ -318,7 +318,7 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- -//- $reduce_xnor (A, B, Y) +//- $reduce_xnor (A, Y) //- //- A XNOR reduction. This corresponds to the Verilog unary prefix '~^' operator. //- @@ -345,7 +345,7 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- -//- $reduce_bool (A, B, Y) +//- $reduce_bool (A, Y) //- //- An OR reduction. This cell type is used instead of $reduce_or when a signal is //- implicitly converted to a boolean signal, e.g. for operands of '&&' and '||'. From bb3439562e122d3a0d8d0e8cd1179d1e478807ea Mon Sep 17 00:00:00 2001 From: Tom Verbeure Date: Mon, 4 Jan 2021 00:11:01 -0800 Subject: [PATCH 0126/2410] Add -nosynthesis flag for read_verilog command. --- frontends/verilog/verilog_frontend.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 5319a45ad16..7f7d7747734 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -84,6 +84,9 @@ struct VerilogFrontend : public Frontend { log(" enable support for SystemVerilog assertions and some Yosys extensions\n"); log(" replace the implicit -D SYNTHESIS with -D FORMAL\n"); log("\n"); + log(" -nosynthesis\n"); + log(" don't add implicit -D SYNTHESIS\n"); + log("\n"); log(" -noassert\n"); log(" ignore assert() statements\n"); log("\n"); @@ -225,8 +228,8 @@ struct VerilogFrontend : public Frontend { log("the syntax of the code, rather than to rely on read_verilog for that.\n"); log("\n"); log("Depending on if read_verilog is run in -formal mode, either the macro\n"); - log("SYNTHESIS or FORMAL is defined automatically. In addition, read_verilog\n"); - log("always defines the macro YOSYS.\n"); + log("SYNTHESIS or FORMAL is defined automatically, unless -nosynthesis is used.\n"); + log("In addition, read_verilog always defines the macro YOSYS.\n"); log("\n"); log("See the Yosys README file for a list of non-standard Verilog features\n"); log("supported by the Yosys Verilog front-end.\n"); @@ -255,6 +258,7 @@ struct VerilogFrontend : public Frontend { bool flag_defer = false; bool flag_noblackbox = false; bool flag_nowb = false; + bool flag_nosynthesis = false; define_map_t defines_map; std::list include_dirs; @@ -282,6 +286,10 @@ struct VerilogFrontend : public Frontend { formal_mode = true; continue; } + if (arg == "-nosynthesis") { + flag_nosynthesis = true; + continue; + } if (arg == "-noassert") { noassert_mode = true; continue; @@ -447,7 +455,8 @@ struct VerilogFrontend : public Frontend { break; } - defines_map.add(formal_mode ? "FORMAL" : "SYNTHESIS", "1"); + if (formal_mode || !flag_nosynthesis) + defines_map.add(formal_mode ? "FORMAL" : "SYNTHESIS", "1"); extra_args(f, filename, args, argidx); From 3a8eecebbad01f2a73ddf4efd0949b9ba5684506 Mon Sep 17 00:00:00 2001 From: Tom Verbeure Date: Mon, 4 Jan 2021 00:17:16 -0800 Subject: [PATCH 0127/2410] Fix indents. --- frontends/verilog/verilog_frontend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 7f7d7747734..e2aecd99bac 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -229,7 +229,7 @@ struct VerilogFrontend : public Frontend { log("\n"); log("Depending on if read_verilog is run in -formal mode, either the macro\n"); log("SYNTHESIS or FORMAL is defined automatically, unless -nosynthesis is used.\n"); - log("In addition, read_verilog always defines the macro YOSYS.\n"); + log("In addition, read_verilog always defines the macro YOSYS.\n"); log("\n"); log("See the Yosys README file for a list of non-standard Verilog features\n"); log("supported by the Yosys Verilog front-end.\n"); @@ -258,7 +258,7 @@ struct VerilogFrontend : public Frontend { bool flag_defer = false; bool flag_noblackbox = false; bool flag_nowb = false; - bool flag_nosynthesis = false; + bool flag_nosynthesis = false; define_map_t defines_map; std::list include_dirs; From c4e23aab55d5a1fedf73483e71cb36585f3e22b2 Mon Sep 17 00:00:00 2001 From: Xiangyu Xu Date: Mon, 4 Jan 2021 03:23:09 -0600 Subject: [PATCH 0128/2410] Add boost-python3 If enable python-api, do need boost-python3. --- Brewfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Brewfile b/Brewfile index 2a985f09e65..b50c70a4b0e 100644 --- a/Brewfile +++ b/Brewfile @@ -9,3 +9,4 @@ brew "python3" brew "tcl-tk" brew "xdot" brew "bash" +brew 'boost-python3' From b0004911ca15ec41db56c76c83461061fedc742e Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 5 Jan 2021 00:10:05 +0000 Subject: [PATCH 0129/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 57ef0b65ea5..8602a3f3c1c 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3830 +YOSYS_VER := 0.9+3833 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 760a2c1343f21b5d3e1a09fdf48c0fac88c8fc7a Mon Sep 17 00:00:00 2001 From: Tobias Faller Date: Tue, 12 Jan 2021 16:17:51 +0100 Subject: [PATCH 0130/2410] Fixed missing goto statement in passes/techmap/abc.cc --- passes/techmap/abc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 192e39372f6..cf51d7f4bdb 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1794,6 +1794,7 @@ struct AbcPass : public Pass { gate_list.push_back("OAI4"); gate_list.push_back("MUX"); gate_list.push_back("NMUX"); + goto ok_alias; } if (g_arg_from_cmd) cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); From e789a005572f7b75b53ad71bc74f8e663a83370c Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Wed, 13 Jan 2021 17:24:28 +0100 Subject: [PATCH 0131/2410] add buffer option to spice backend --- backends/spice/spice.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index aa20f106aee..ca5c680c9b8 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -64,7 +64,7 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg, } } -static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian, bool use_inames) +static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &buf, std::string &ncpf, bool big_endian, bool use_inames) { SigMap sigmap(module); idict inums; @@ -121,10 +121,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De for (auto &conn : module->connections()) for (int i = 0; i < conn.first.size(); i++) { - f << stringf("V%d", conn_counter++); - print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums); + f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++)); print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums); - f << stringf(" DC 0\n"); + print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums); + f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str())); } } @@ -148,6 +148,10 @@ struct SpiceBackend : public Backend { log(" -pos net_name\n"); log(" set the net name for constant 1 (default: Vdd)\n"); log("\n"); + log(" -buf DC|subckt_name\n"); + log(" set the name for jumper element (default: DC)\n"); + log(" (used to connect different nets)\n"); + log("\n"); log(" -nc_prefix\n"); log(" prefix for not-connected nets (default: _NC)\n"); log("\n"); @@ -164,7 +168,7 @@ struct SpiceBackend : public Backend { std::string top_module_name; RTLIL::Module *top_module = NULL; bool big_endian = false, use_inames = false; - std::string neg = "Vss", pos = "Vdd", ncpf = "_NC"; + std::string neg = "Vss", pos = "Vdd", ncpf = "_NC", buf = "DC"; log_header(design, "Executing SPICE backend.\n"); @@ -187,6 +191,10 @@ struct SpiceBackend : public Backend { pos = args[++argidx]; continue; } + if (args[argidx] == "-buf" && argidx+1 < args.size()) { + buf = args[++argidx]; + continue; + } if (args[argidx] == "-nc_prefix" && argidx+1 < args.size()) { ncpf = args[++argidx]; continue; @@ -241,14 +249,14 @@ struct SpiceBackend : public Backend { *f << stringf(" %s", spice_id2str(wire->name).c_str()); } *f << stringf("\n"); - print_spice_module(*f, module, design, neg, pos, ncpf, big_endian, use_inames); + print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames); *f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str()); } if (!top_module_name.empty()) { if (top_module == NULL) log_error("Can't find top module `%s'!\n", top_module_name.c_str()); - print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian, use_inames); + print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames); *f << stringf("\n"); } From 7cd044bbc4cc4b63302363f77d913403957fdcd3 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 14 Jan 2021 00:10:05 +0000 Subject: [PATCH 0132/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8602a3f3c1c..e00f5007554 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3833 +YOSYS_VER := 0.9+3836 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 01626e6746e85832d5b75785b9e45f39ff8eb299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 14 Jan 2021 09:58:33 +0100 Subject: [PATCH 0133/2410] opt_share: Fix X and CO signal width for shifted $alu in opt_share. These need to be the same length as actual Y, not visible part of Y. Fixes #2538. --- passes/opt/opt_share.cc | 4 ++-- tests/opt/opt_share_bug2538.ys | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/opt/opt_share_bug2538.ys diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 53296699c93..62a478673cb 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -244,8 +244,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< } if (shared_op->type.in(ID($alu))) { - shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out))); - shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out))); + shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_out))); + shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_out))); } bool is_fine = shared_op->type.in(FINE_BITWISE_OPS); diff --git a/tests/opt/opt_share_bug2538.ys b/tests/opt/opt_share_bug2538.ys new file mode 100644 index 00000000000..7261c6695df --- /dev/null +++ b/tests/opt/opt_share_bug2538.ys @@ -0,0 +1,20 @@ +read_verilog < Date: Thu, 14 Jan 2021 16:26:20 -0600 Subject: [PATCH 0134/2410] Handle sliced bits as clock inputs (fixes #2542) --- backends/cxxrtl/cxxrtl_backend.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 861b484f4eb..3906ed23552 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -601,6 +601,13 @@ struct WireType { bool is_exact() const { return type == ALIAS || type == CONST; } }; +// Tests for a SigSpec that is backed by a specific slice of a wire, this is used +// instead of .is_wire() on clocks because they can be only a portion of an underlying +// wire +bool is_wire_slice(const RTLIL::SigSpec& sig) { + return sig.is_chunk() && sig.chunks()[0].wire; +} + struct CxxrtlWorker { bool split_intf = false; std::string intf_filename; @@ -1110,7 +1117,8 @@ struct CxxrtlWorker { // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); - if (cell->hasPort(ID::CLK) && cell->getPort(ID::CLK).is_wire()) { + // Clocks might be slices of larger signals but should only ever be single bit + if (cell->hasPort(ID::CLK) && is_wire_slice(cell->getPort(ID::CLK))) { // Edge-sensitive logic RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); @@ -2372,7 +2380,7 @@ struct CxxrtlWorker { if (cell->type == ID($memwr)) writable_memories.insert(module->memories[cell->getParam(ID::MEMID).decode_string()]); // Collect groups of memory write ports in the same domain. - if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire()) { + if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_wire_slice(cell->getPort(ID::CLK))) { RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; memwr_per_domain[{clk_bit, memory}].insert(cell); @@ -2384,7 +2392,7 @@ struct CxxrtlWorker { } for (auto cell : module->cells()) { // Collect groups of memory write ports read by every transparent read port. - if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire() && + if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_wire_slice(cell->getPort(ID::CLK)) && cell->getParam(ID::TRANSPARENT).as_bool()) { RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; From 339848b954491e6bb63a3062c60f840730123436 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 15 Jan 2021 00:10:05 +0000 Subject: [PATCH 0135/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e00f5007554..2953af2e7f6 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3836 +YOSYS_VER := 0.9+3838 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From c8415884d1c2bc66479dcbce491383e1a077c5ef Mon Sep 17 00:00:00 2001 From: Iris Johnson Date: Fri, 15 Jan 2021 13:59:20 -0600 Subject: [PATCH 0136/2410] Improves the previous commit with a more complete coverage of the cases --- backends/cxxrtl/cxxrtl_backend.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 3906ed23552..39046bd782f 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -601,11 +601,10 @@ struct WireType { bool is_exact() const { return type == ALIAS || type == CONST; } }; -// Tests for a SigSpec that is backed by a specific slice of a wire, this is used -// instead of .is_wire() on clocks because they can be only a portion of an underlying -// wire -bool is_wire_slice(const RTLIL::SigSpec& sig) { - return sig.is_chunk() && sig.chunks()[0].wire; +// Tests for a SigSpec that is a valid clock input, clocks have to have a backing wire and be a single bit +// using this instead of sig.is_wire() solves issues when the clock is a slice instead of a full wire +bool is_valid_clock(const RTLIL::SigSpec& sig) { + return sig.is_chunk() && sig.is_bit() && sig[0].wire; } struct CxxrtlWorker { @@ -1118,7 +1117,7 @@ struct CxxrtlWorker { } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); // Clocks might be slices of larger signals but should only ever be single bit - if (cell->hasPort(ID::CLK) && is_wire_slice(cell->getPort(ID::CLK))) { + if (cell->hasPort(ID::CLK) && is_valid_clock(cell->getPort(ID::CLK))) { // Edge-sensitive logic RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); @@ -2274,7 +2273,7 @@ struct CxxrtlWorker { void register_edge_signal(SigMap &sigmap, RTLIL::SigSpec signal, RTLIL::SyncType type) { signal = sigmap(signal); - log_assert(signal.is_wire() && signal.is_bit()); + log_assert(is_valid_clock(signal)); log_assert(type == RTLIL::STp || type == RTLIL::STn || type == RTLIL::STe); RTLIL::SigBit sigbit = signal[0]; @@ -2282,7 +2281,8 @@ struct CxxrtlWorker { edge_types[sigbit] = type; else if (edge_types[sigbit] != type) edge_types[sigbit] = RTLIL::STe; - edge_wires.insert(signal.as_wire()); + // Cannot use as_wire because signal might not be a full wire, instead extract the wire from the sigbit + edge_wires.insert(sigbit.wire); } void analyze_design(RTLIL::Design *design) @@ -2363,14 +2363,14 @@ struct CxxrtlWorker { // Various DFF cells are treated like posedge/negedge processes, see above for details. if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { - if (sigmap(cell->getPort(ID::CLK)).is_wire()) + if (is_valid_clock(cell->getPort(ID::CLK))) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } // Similar for memory port cells. if (cell->type.in(ID($memrd), ID($memwr))) { if (cell->getParam(ID::CLK_ENABLE).as_bool()) { - if (sigmap(cell->getPort(ID::CLK)).is_wire()) + if (is_valid_clock(cell->getPort(ID::CLK))) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } @@ -2380,7 +2380,7 @@ struct CxxrtlWorker { if (cell->type == ID($memwr)) writable_memories.insert(module->memories[cell->getParam(ID::MEMID).decode_string()]); // Collect groups of memory write ports in the same domain. - if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_wire_slice(cell->getPort(ID::CLK))) { + if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK))) { RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; memwr_per_domain[{clk_bit, memory}].insert(cell); @@ -2392,7 +2392,7 @@ struct CxxrtlWorker { } for (auto cell : module->cells()) { // Collect groups of memory write ports read by every transparent read port. - if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_wire_slice(cell->getPort(ID::CLK)) && + if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK)) && cell->getParam(ID::TRANSPARENT).as_bool()) { RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; From 09071afe15bee8d764062e9175b8f03e20ea9cb5 Mon Sep 17 00:00:00 2001 From: Lukasz Dalek Date: Tue, 19 May 2020 17:13:04 +0200 Subject: [PATCH 0137/2410] Parse package user type in module port list Signed-off-by: Lukasz Dalek Signed-off-by: Kamil Rakoczy --- frontends/verilog/verilog_parser.y | 62 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 6c4b06d7feb..0f7f2a57adb 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN %type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int -%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type %type opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type type_name %type opt_enum_init enum_type struct_type non_wire_data_type @@ -619,26 +619,19 @@ non_opt_delay: delay: non_opt_delay | %empty; -wire_type: - { - astbuf3 = new AstNode(AST_WIRE); - current_wire_rand = false; - current_wire_const = false; - } wire_type_token_list { - $$ = astbuf3; - SET_RULE_LOC(@$, @2, @$); - }; +io_wire_type: + { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; } + wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness + { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); }; -wire_type_token_list: - wire_type_token | - wire_type_token_list wire_type_token | - wire_type_token_io | - hierarchical_type_id { - astbuf3->is_custom_type = true; - astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); - astbuf3->children.back()->str = *$1; - delete $1; - }; +non_io_wire_type: + { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; } + wire_type_const_rand wire_type_token wire_type_signedness + { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); }; + +wire_type: + io_wire_type | + non_io_wire_type; wire_type_token_io: TOK_INPUT { @@ -652,7 +645,25 @@ wire_type_token_io: astbuf3->is_output = true; }; +wire_type_signedness: + TOK_SIGNED { astbuf3->is_signed = true; } | + TOK_UNSIGNED { astbuf3->is_signed = false; } | + %empty; + +wire_type_const_rand: + TOK_CONST { current_wire_const = true; } | + TOK_RAND { current_wire_rand = true; } | + %empty; + +opt_wire_type_token: + wire_type_token | %empty; + wire_type_token: + hierarchical_type_id { + astbuf3->is_custom_type = true; + astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); + astbuf3->children.back()->str = *$1; + } | TOK_WIRE { } | TOK_WOR { @@ -682,15 +693,6 @@ wire_type_token: astbuf3->is_signed = true; astbuf3->range_left = 31; astbuf3->range_right = 0; - } | - TOK_SIGNED { - astbuf3->is_signed = true; - } | - TOK_RAND { - current_wire_rand = true; - } | - TOK_CONST { - current_wire_const = true; }; non_opt_range: @@ -1803,7 +1805,7 @@ type_name: TOK_ID // first time seen ; typedef_decl: - TOK_TYPEDEF wire_type range type_name range_or_multirange ';' { + TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' { astbuf1 = $2; astbuf2 = checkRange(astbuf1, $3); if (astbuf2) From 61501e3266238f6c4cffafb08ed85ff86f912cf4 Mon Sep 17 00:00:00 2001 From: Kamil Rakoczy Date: Tue, 9 Jun 2020 09:53:00 +0200 Subject: [PATCH 0138/2410] Fix input/output attributes when resolving typedef of wire Signed-off-by: Kamil Rakoczy --- frontends/ast/simplify.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d4242f1e708..fc2976c83e8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1330,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { // replace with wire representing the packed structure newNode = make_packed_struct(template_node, str); + // add original input/output attribute to resolved wire + newNode->is_input = this->is_input; + newNode->is_output = this->is_output; current_scope[str] = this; goto apply_newNode; } From d69ddf19da47242a5fde4d0beca65fa95c453884 Mon Sep 17 00:00:00 2001 From: Kamil Rakoczy Date: Wed, 8 Jul 2020 13:44:03 +0200 Subject: [PATCH 0139/2410] Add typedef input/output test Signed-off-by: Kamil Rakoczy --- tests/svtypes/typedef_struct_port.sv | 111 +++++++++++++++++++++++++++ tests/svtypes/typedef_struct_port.ys | 6 ++ 2 files changed, 117 insertions(+) create mode 100644 tests/svtypes/typedef_struct_port.sv create mode 100644 tests/svtypes/typedef_struct_port.ys diff --git a/tests/svtypes/typedef_struct_port.sv b/tests/svtypes/typedef_struct_port.sv new file mode 100644 index 00000000000..ecc03bee851 --- /dev/null +++ b/tests/svtypes/typedef_struct_port.sv @@ -0,0 +1,111 @@ +package p; + +typedef struct packed { + byte a; + byte b; +} p_t; + +typedef logic [31:0] l_t; + +endpackage + +module foo1( + input p::p_t p, + output p::p_t o +); + assign o = p; +endmodule + +module foo2(p, o); + input p::p_t p; + output p::p_t o; + assign o = p; +endmodule + +module foo3(input p::l_t p, input p::l_t o); + assign o = p; +endmodule + +module foo4(input logic [15:0] p, input logic [15:0] o); + assign o = p; +endmodule + +module test_parser(a,b,c,d,e,f,g,h,i); +input [7:0] a; // no explicit net declaration - net is unsigned +input [7:0] b; +input signed [7:0] c; +input signed [7:0] d; // no explicit net declaration - net is signed +output [7:0] e; // no explicit net declaration - net is unsigned +output [7:0] f; +output signed [7:0] g; +output signed [7:0] h; // no explicit net declaration - net is signed +output unsigned [7:0] i; +wire signed [7:0] b; // port b inherits signed attribute from net decl. +wire [7:0] c; // net c inherits signed attribute from port +logic signed [7:0] f;// port f inherits signed attribute from logic decl. +logic [7:0] g; // logic g inherits signed attribute from port + + assign a = 8'b10001111; + assign b = 8'b10001111; + assign c = 8'b10001111; + assign d = 8'b10001111; + assign e = 8'b10001111; + assign f = 8'b10001111; + assign g = 8'b10001111; + assign h = 8'b10001111; + assign i = 8'b10001111; + always_comb begin + assert($unsigned(143) == a); + assert($signed(-113) == b); + assert($signed(-113) == c); + assert($signed(-113) == d); + assert($unsigned(143) == e); + assert($unsigned(143) == f); + assert($signed(-113) == g); + assert($signed(-113) == h); + assert($unsigned(143) == i); + end +endmodule + +module top; + p::p_t ps; + assign ps.a = 8'hAA; + assign ps.b = 8'h55; + foo1 foo(.p(ps)); + + p::p_t body; + assign body.a = 8'hBB; + assign body.b = 8'h66; + foo2 foo_b(.p(body)); + + typedef p::l_t local_alias; + + local_alias l_s; + assign l_s = 32'hAAAAAAAA; + foo3 foo_l(.p(l_s)); + + typedef logic [15:0] sl_t; + + sl_t sl_s; + assign sl_s = 16'hBBBB; + foo4 foo_sl(.p(sl_s)); + + typedef sl_t local_alias_st; + + local_alias_st lsl_s; + assign lsl_s = 16'hCCCC; + foo4 foo_lsl(.p(lsl_s)); + + const logic j = 1'b1; + + always_comb begin + assert(8'hAA == ps.a); + assert(8'h55 == ps.b); + assert(8'hBB == body.a); + assert(8'h66 == body.b); + assert(32'hAAAAAAAA == l_s); + assert(16'hBBBB == sl_s); + assert(16'hCCCC == lsl_s); + assert(1'b1 == j); + end +endmodule diff --git a/tests/svtypes/typedef_struct_port.ys b/tests/svtypes/typedef_struct_port.ys new file mode 100644 index 00000000000..5b75c310551 --- /dev/null +++ b/tests/svtypes/typedef_struct_port.ys @@ -0,0 +1,6 @@ +read_verilog -sv typedef_struct_port.sv +hierarchy; proc; opt +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all +select -module test_parser +sat -verify -seq 1 -tempinduct -prove-asserts -show-all From 4c108b441930016c38bb13767da7461614409375 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 18 Jan 2021 11:13:21 -0700 Subject: [PATCH 0140/2410] Add plugin.so.dSYM to .gitignore This artifact is automatically generated by the builtin clang on macOS when -g is used. --- tests/various/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/various/.gitignore b/tests/various/.gitignore index 12d4e504856..2bb6c71793c 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -4,3 +4,4 @@ /write_gzip.v.gz /run-test.mk /plugin.so +/plugin.so.dSYM From 169234d6e9ee7468ead4f211210f6ea44dae1467 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Mon, 18 Jan 2021 16:47:49 -0500 Subject: [PATCH 0141/2410] adding support for passing multiple liberty files to abc --- passes/techmap/abc.cc | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 192e39372f6..73f0b86fe72 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -54,6 +54,7 @@ #include #include #include +#include #ifndef _WIN32 # include @@ -654,7 +655,7 @@ struct abc_output_filter }; void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - std::string liberty_file, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, + std::vector &liberty_files, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode, const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress) { @@ -709,8 +710,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::string abc_script = stringf("read_blif %s/input.blif; ", tempdir_name.c_str()); - if (!liberty_file.empty()) { - abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); + if (!liberty_files.empty()) { + for (std::string liberty_file : liberty_files) abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); if (!constr_file.empty()) abc_script += stringf("read_constr -v %s; ", constr_file.c_str()); } else @@ -738,7 +739,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; if (all_luts_cost_same && !fast_mode) abc_script += "; lutpack {S}"; - } else if (!liberty_file.empty()) + } else if (!liberty_files.empty()) abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); else if (sop_mode) abc_script += fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; @@ -1019,7 +1020,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - bool builtin_lib = liberty_file.empty(); + bool builtin_lib = liberty_files.empty(); RTLIL::Design *mapped_design = new RTLIL::Design; parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode); @@ -1471,7 +1472,8 @@ struct AbcPass : public Pass { po_map.clear(); std::string exe_file = yosys_abc_executable; - std::string script_file, liberty_file, constr_file, clk_str; + std::string script_file, default_liberty_file, constr_file, clk_str; + std::vector liberty_files; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false, sop_mode = false; @@ -1489,7 +1491,7 @@ struct AbcPass : public Pass { std::string lut_arg, luts_arg, g_arg; exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); script_file = design->scratchpad_get_string("abc.script", script_file); - liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file); + default_liberty_file = design->scratchpad_get_string("abc.liberty", default_liberty_file); constr_file = design->scratchpad_get_string("abc.constr", constr_file); if (design->scratchpad.count("abc.D")) { delay_target = "-D " + design->scratchpad_get_string("abc.D"); @@ -1551,7 +1553,7 @@ struct AbcPass : public Pass { continue; } if (arg == "-liberty" && argidx+1 < args.size()) { - liberty_file = args[++argidx]; + liberty_files.push_back(args[++argidx]); continue; } if (arg == "-constr" && argidx+1 < args.size()) { @@ -1643,12 +1645,16 @@ struct AbcPass : public Pass { } extra_args(args, argidx, design); + if (liberty_files.empty() && !default_liberty_file.empty()) liberty_files.push_back(default_liberty_file); + rewrite_filename(script_file); if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') script_file = std::string(pwd) + "/" + script_file; - rewrite_filename(liberty_file); - if (!liberty_file.empty() && !is_absolute_path(liberty_file)) - liberty_file = std::string(pwd) + "/" + liberty_file; + for (int i = 0; i < GetSize(liberty_files); i++) { + rewrite_filename(liberty_files[i]); + if (!liberty_files[i].empty() && !is_absolute_path(liberty_files[i])) + liberty_files[i] = std::string(pwd) + "/" + liberty_files[i]; + } rewrite_filename(constr_file); if (!constr_file.empty() && !is_absolute_path(constr_file)) constr_file = std::string(pwd) + "/" + constr_file; @@ -1811,9 +1817,9 @@ struct AbcPass : public Pass { } } - if (!lut_costs.empty() && !liberty_file.empty()) + if (!lut_costs.empty() && !liberty_files.empty()) log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); - if (!constr_file.empty() && liberty_file.empty()) + if (!constr_file.empty() && liberty_files.empty()) log_cmd_error("Got -constr but no -liberty!\n"); if (enabled_gates.empty()) { @@ -1844,7 +1850,7 @@ struct AbcPass : public Pass { initvals.set(&assign_map, mod); if (!dff_mode || !clk_str.empty()) { - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, + abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress); continue; } @@ -1989,7 +1995,7 @@ struct AbcPass : public Pass { clk_sig = assign_map(std::get<1>(it.first)); en_polarity = std::get<2>(it.first); en_sig = assign_map(std::get<3>(it.first)); - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", + abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress); assign_map.set(mod); } From 4762cc06c6b7cd36dda2e6eddf15b9782334ccd4 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 19 Jan 2021 00:10:05 +0000 Subject: [PATCH 0142/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2953af2e7f6..a6e7f07fcab 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3838 +YOSYS_VER := 0.9+3845 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4fadcc8f25d5ef1e494aa7d5e49d893afdaa1705 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 20 Jan 2021 08:49:32 -0700 Subject: [PATCH 0143/2410] verilog: allow spaces in macro arguments --- frontends/verilog/preproc.cc | 1 - tests/simple/macro_arg_spaces.sv | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/simple/macro_arg_spaces.sv diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 752f7a7a8c0..5a2804a4176 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -392,7 +392,6 @@ static bool read_argument(std::string &dest) { std::vector openers; for (;;) { - skip_spaces(); std::string tok = next_token(true); if (tok == ")") { if (openers.empty()) diff --git a/tests/simple/macro_arg_spaces.sv b/tests/simple/macro_arg_spaces.sv new file mode 100644 index 00000000000..75c4cd1369f --- /dev/null +++ b/tests/simple/macro_arg_spaces.sv @@ -0,0 +1,28 @@ +module top( + input wire [31:0] i, + output wire [31:0] x, y, z +); + +`define BAR(a) a +`define FOO(a = function automatic [31:0] f) a + +`BAR(function automatic [31:0] a); + input [31:0] i; + a = i * 2; +endfunction + +`FOO(); + input [31:0] i; + f = i * 3; +endfunction + +`FOO(function automatic [31:0] b); + input [31:0] i; + b = i * 5; +endfunction + +assign x = a(i); +assign y = f(i); +assign z = b(i); + +endmodule From 006c18fc112a686a20b2b138ddc3bf773ee2f2f5 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 20 Jan 2021 09:15:48 -0700 Subject: [PATCH 0144/2410] sv: fix support wire and var data type modifiers --- frontends/verilog/verilog_parser.y | 32 +++++++++++++++++++++-------- tests/verilog/wire_and_var.sv | 33 ++++++++++++++++++++++++++++++ tests/verilog/wire_and_var.ys | 9 ++++++++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 tests/verilog/wire_and_var.sv create mode 100644 tests/verilog/wire_and_var.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 0f7f2a57adb..2886db0e56a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -664,28 +664,33 @@ wire_type_token: astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); astbuf3->children.back()->str = *$1; } | - TOK_WIRE { - } | TOK_WOR { astbuf3->is_wor = true; } | TOK_WAND { astbuf3->is_wand = true; } | + // wires + TOK_WIRE { + } | + TOK_WIRE logic_type { + } | + // regs TOK_REG { astbuf3->is_reg = true; } | - TOK_LOGIC { - astbuf3->is_logic = true; + TOK_VAR TOK_REG { + astbuf3->is_reg = true; } | + // logics TOK_VAR { astbuf3->is_logic = true; } | - TOK_INTEGER { - astbuf3->is_reg = true; - astbuf3->range_left = 31; - astbuf3->range_right = 0; - astbuf3->is_signed = true; + TOK_VAR logic_type { + astbuf3->is_logic = true; + } | + logic_type { + astbuf3->is_logic = true; } | TOK_GENVAR { astbuf3->type = AST_GENVAR; @@ -695,6 +700,15 @@ wire_type_token: astbuf3->range_right = 0; }; +logic_type: + TOK_LOGIC { + } | + TOK_INTEGER { + astbuf3->range_left = 31; + astbuf3->range_right = 0; + astbuf3->is_signed = true; + }; + non_opt_range: '[' expr ':' expr ']' { $$ = new AstNode(AST_RANGE); diff --git a/tests/verilog/wire_and_var.sv b/tests/verilog/wire_and_var.sv new file mode 100644 index 00000000000..79c7c04c617 --- /dev/null +++ b/tests/verilog/wire_and_var.sv @@ -0,0 +1,33 @@ +`define TEST(kwd) \ + kwd kwd``_1; \ + kwd kwd``_2; \ + initial kwd``_1 = 1; \ + assign kwd``_2 = 1; + +`define TEST_VAR(kwd) \ + var kwd var_``kwd``_1; \ + var kwd var_``kwd``_2; \ + initial var_``kwd``_1 = 1; \ + assign var_``kwd``_2 = 1; + +`define TEST_WIRE(kwd) \ + wire kwd wire_``kwd``_1; \ + wire kwd wire_``kwd``_2; \ + initial wire_``kwd``_1 = 1; \ + assign wire_``kwd``_2 = 1; + +module top; + +`TEST(wire) // wire assigned in a block +`TEST(reg) // reg assigned in a continuous assignment +`TEST(logic) +`TEST(integer) + +`TEST_VAR(reg) // reg assigned in a continuous assignment +`TEST_VAR(logic) +`TEST_VAR(integer) + +`TEST_WIRE(logic) // wire assigned in a block +`TEST_WIRE(integer) // wire assigned in a block + +endmodule diff --git a/tests/verilog/wire_and_var.ys b/tests/verilog/wire_and_var.ys new file mode 100644 index 00000000000..9359a9d5556 --- /dev/null +++ b/tests/verilog/wire_and_var.ys @@ -0,0 +1,9 @@ +logger -expect warning "wire '\\wire_1' is assigned in a block" 1 +logger -expect warning "reg '\\reg_2' is assigned in a continuous assignment" 1 + +logger -expect warning "reg '\\var_reg_2' is assigned in a continuous assignment" 1 + +logger -expect warning "wire '\\wire_logic_1' is assigned in a block" 1 +logger -expect warning "wire '\\wire_integer_1' is assigned in a block" 1 + +read_verilog -sv wire_and_var.sv From acad7a6e4031a37745bf05b84d9bd65d2e31627b Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 20 Jan 2021 20:48:10 +0100 Subject: [PATCH 0145/2410] Switch verific bindings from Symbiotic EDA flavored Verific to YosysHQ flavored Verific Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cf3bf10704d..614124a296c 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -51,12 +51,12 @@ USING_YOSYS_NAMESPACE #include "VeriLibrary.h" #include "VeriExtensions.h" -#ifndef SYMBIOTIC_VERIFIC_API_VERSION -# error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific." +#ifndef YOSYSHQ_VERIFIC_API_VERSION +# error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if SYMBIOTIC_VERIFIC_API_VERSION < 20201101 -# error "Please update your version of Symbiotic EDA flavored Verific." +#if YOSYSHQ_VERIFIC_API_VERSION < 20201201 +# error "Please update your version of YosysHQ flavored Verific." #endif #ifdef __clang__ @@ -1471,7 +1471,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se continue; } - if (inst->Type() == PRIM_SEDA_INITSTATE) + if (inst->Type() == PRIM_YOSYSHQ_INITSTATE) { SigBit initstate = module->Initstate(new_verific_id(inst)); SigBit sig_o = net_map_at(inst->GetOutput()); @@ -2199,7 +2199,7 @@ struct VerificPass : public Pass { log("\n"); log(" verific -app ..\n"); log("\n"); - log("Execute SEDA formal application on loaded Verilog files.\n"); + log("Execute YosysHQ formal application on loaded Verilog files.\n"); log("\n"); log("Application options:\n"); log("\n"); @@ -2250,11 +2250,11 @@ struct VerificPass : public Pass { log(" WARNING: Templates only available in commercial build.\n"); log("\n"); #endif - log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"); - log("https://www.symbioticeda.com/seda-suite\n"); + log("Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"); + log("https://www.yosyshq.com/\n"); log("\n"); - log("Contact office@symbioticeda.com for free evaluation\n"); - log("binaries of Symbiotic EDA Suite.\n"); + log("Contact office@yosyshq.com for free evaluation\n"); + log("binaries of YosysHQ Tabby CAD Suite.\n"); log("\n"); } #ifdef YOSYS_ENABLE_VERIFIC @@ -2265,11 +2265,11 @@ struct VerificPass : public Pass { if (check_noverific_env()) log_cmd_error("This version of Yosys is built without Verific support.\n" "\n" - "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n" - "https://www.symbioticeda.com/seda-suite\n" + "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n" + "https://www.yosyshq.com/\n" "\n" - "Contact office@symbioticeda.com for free evaluation\n" - "binaries of Symbiotic EDA Suite.\n"); + "Contact office@yosyshq.com for free evaluation\n" + "binaries of YosysHQ Tabby CAD Suite.\n"); log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n"); @@ -2926,11 +2926,11 @@ struct VerificPass : public Pass { void execute(std::vector, RTLIL::Design *) override { log_cmd_error("This version of Yosys is built without Verific support.\n" "\n" - "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n" - "https://www.symbioticeda.com/seda-suite\n" + "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n" + "https://www.yosyshq.com/\n" "\n" - "Contact office@symbioticeda.com for free evaluation\n" - "binaries of Symbiotic EDA Suite.\n"); + "Contact office@yosyshq.com for free evaluation\n" + "binaries of YosysHQ Tabby CAD Suite.\n"); } #endif } VerificPass; From 699a98b265a41b0565637323f929e6cb1f8837e0 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 21 Jan 2021 00:10:05 +0000 Subject: [PATCH 0146/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a6e7f07fcab..728647a3f08 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3845 +YOSYS_VER := 0.9+3852 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1096b969efb24dc28b501585f23ceb242d781745 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 21 Jan 2021 08:30:55 -0700 Subject: [PATCH 0147/2410] Allow combination of rand and const modifiers --- frontends/verilog/verilog_parser.y | 12 ++++++++++-- tests/various/rand_const.sv | 8 ++++++++ tests/various/rand_const.ys | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tests/various/rand_const.sv create mode 100644 tests/various/rand_const.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 2886db0e56a..8bd58d24c8c 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -651,8 +651,16 @@ wire_type_signedness: %empty; wire_type_const_rand: - TOK_CONST { current_wire_const = true; } | - TOK_RAND { current_wire_rand = true; } | + TOK_RAND TOK_CONST { + current_wire_rand = true; + current_wire_const = true; + } | + TOK_CONST { + current_wire_const = true; + } | + TOK_RAND { + current_wire_rand = true; + } | %empty; opt_wire_type_token: diff --git a/tests/various/rand_const.sv b/tests/various/rand_const.sv new file mode 100644 index 00000000000..be00812c0ec --- /dev/null +++ b/tests/various/rand_const.sv @@ -0,0 +1,8 @@ +module top; + rand const reg rx; + const reg ry; + rand reg rz; + rand const integer ix; + const integer iy; + rand integer iz; +endmodule diff --git a/tests/various/rand_const.ys b/tests/various/rand_const.ys new file mode 100644 index 00000000000..74e43c7ccea --- /dev/null +++ b/tests/various/rand_const.ys @@ -0,0 +1 @@ +read_verilog -sv rand_const.sv From 7d014902ec579eccd04446131fea4772dd715daf Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Thu, 21 Jan 2021 12:20:53 -0800 Subject: [PATCH 0148/2410] Fix digit-formatting calculation for small numbers. Calling log10() on zero causes a non-sensical value to be calculated. On some compile options, I've observed yosys crashing with an illegal instruction (SIGILL). To make it safe, fix the calculation to do a range check; wrap it a decimal_digits() function, and use it where the previous ceil(log10(n)) call was used. As a side, it also improves readability. Signed-off-by: Henner Zeller --- frontends/aiger/aigerparse.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 07e3cd6e0aa..2d7c2187e2f 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -55,6 +55,10 @@ inline int32_t from_big_endian(int32_t i32) { #define log_debug2(...) ; //#define log_debug2(...) log_debug(__VA_ARGS__) +static int decimal_digits(unsigned n) { + return n > 1 ? ceil(log10(n)) : 1; +} + struct ConstEvalAig { RTLIL::Module *module; @@ -515,7 +519,7 @@ void AigerReader::parse_aiger_ascii() unsigned l1, l2, l3; // Parse inputs - int digits = ceil(log10(I)); + int digits = decimal_digits(I); for (unsigned i = 1; i <= I; ++i, ++line_count) { if (!(f >> l1)) log_error("Line %u cannot be interpreted as an input!\n", line_count); @@ -537,7 +541,7 @@ void AigerReader::parse_aiger_ascii() clk_wire->port_input = true; clk_wire->port_output = false; } - digits = ceil(log10(L)); + digits = decimal_digits(L); for (unsigned i = 0; i < L; ++i, ++line_count) { if (!(f >> l1 >> l2)) log_error("Line %u cannot be interpreted as a latch!\n", line_count); @@ -575,7 +579,7 @@ void AigerReader::parse_aiger_ascii() } // Parse outputs - digits = ceil(log10(O)); + digits = decimal_digits(O); for (unsigned i = 0; i < O; ++i, ++line_count) { if (!(f >> l1)) log_error("Line %u cannot be interpreted as an output!\n", line_count); @@ -643,7 +647,7 @@ void AigerReader::parse_aiger_binary() std::string line; // Parse inputs - int digits = ceil(log10(I)); + int digits = decimal_digits(I); for (unsigned i = 1; i <= I; ++i) { log_debug2("%d is an input\n", i); RTLIL::Wire *wire = module->addWire(stringf("$i%0*d", digits, i)); @@ -662,7 +666,7 @@ void AigerReader::parse_aiger_binary() clk_wire->port_input = true; clk_wire->port_output = false; } - digits = ceil(log10(L)); + digits = decimal_digits(L); l1 = (I+1) * 2; for (unsigned i = 0; i < L; ++i, ++line_count, l1 += 2) { if (!(f >> l2)) @@ -700,7 +704,7 @@ void AigerReader::parse_aiger_binary() } // Parse outputs - digits = ceil(log10(O)); + digits = decimal_digits(O); for (unsigned i = 0; i < O; ++i, ++line_count) { if (!(f >> l1)) log_error("Line %u cannot be interpreted as an output!\n", line_count); From 54294957ed15d954c69c2722028209077cf91cfe Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 22 Jan 2021 00:10:05 +0000 Subject: [PATCH 0149/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 728647a3f08..eccfd3c8251 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3852 +YOSYS_VER := 0.9+3855 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 09311b6581e5f1b4282b20b987919d1514e62073 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sat, 23 Jan 2021 22:24:31 +0000 Subject: [PATCH 0150/2410] dpi: Support for chandle type Signed-off-by: David Shah --- frontends/ast/dpicall.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index e241142d352..948c9083c61 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -67,7 +67,7 @@ static ffi_fptr resolve_fn (std::string symbol_name) AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args) { AST::AstNode *newNode = nullptr; - union { double f64; float f32; int32_t i32; } value_store [args.size() + 1]; + union { double f64; float f32; int32_t i32; void *ptr; } value_store [args.size() + 1]; ffi_type *types [args.size() + 1]; void *values [args.size() + 1]; ffi_cif cif; @@ -92,6 +92,11 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, value_store[i].i32 = args[i]->asInt(args[i]->is_signed); values[i] = &value_store[i].i32; types[i] = &ffi_type_sint32; + } else if (argtypes[i] == "chandle") { + log(" arg %d (%s): %llx\n", i, argtypes[i].c_str(), (unsigned long long)args[i]->asInt(false)); + value_store[i].ptr = (void *)args[i]->asInt(args[i]->is_signed); + values[i] = &value_store[i].ptr; + types[i] = &ffi_type_pointer; } else { log_error("invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i); } @@ -106,6 +111,9 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, } else if (rtype == "real") { types[args.size()] = &ffi_type_double; values[args.size()] = &value_store[args.size()].f64; + } else if (rtype == "chandle") { + types[args.size()] = &ffi_type_pointer; + values[args.size()] = &value_store[args.size()].ptr; } else { log_error("invalid rtype '%s'.\n", rtype.c_str()); } @@ -123,6 +131,13 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, newNode = new AstNode(AST_REALVALUE); newNode->realvalue = value_store[args.size()].f32; log(" return realvalue: %g\n", newNode->asReal(true)); + } else if (rtype == "chandle") { + uint64_t rawval = (uint64_t)value_store[args.size()].ptr; + std::vector bits(64); + for (int i = 0; i < 64; i++) + bits.at(i) = (rawval & (1ULL << i)) ? RTLIL::State::S1 : RTLIL::State::S0; + newNode = AstNode::mkconst_bits(bits, false); + log(" return chandle: %llx\n", (unsigned long long)newNode->asInt(false)); } else { newNode = AstNode::mkconst_int(value_store[args.size()].i32, false); log(" return integer: %lld\n", (long long)newNode->asInt(true)); From 410ea422429aa31e5b5af7628d6126a3d3884512 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Mon, 25 Jan 2021 00:10:07 +0000 Subject: [PATCH 0151/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eccfd3c8251..da1ffdda5c8 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3855 +YOSYS_VER := 0.9+3858 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 8eaeaa8434681403d12ac5d6a9761d3720b4ef98 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 26 Jan 2021 00:10:05 +0000 Subject: [PATCH 0152/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index da1ffdda5c8..a6a542f0c0a 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3858 +YOSYS_VER := 0.9+3863 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 74dad5afe72ff1afa777352e9ca078cd80878a52 Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Mon, 11 Jan 2021 18:37:27 +0000 Subject: [PATCH 0153/2410] scc: Add -specify option to find loops in boxes --- passes/cmds/scc.cc | 77 ++++++++++++++++++++++++++++++++---------- passes/techmap/abc9.cc | 2 +- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 8e7f3f9909c..7aa9a484f32 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -37,7 +37,7 @@ struct SccWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; - CellTypes ct; + CellTypes ct, specifyCells; std::set workQueue; std::map> cellToNextCell; @@ -100,7 +100,7 @@ struct SccWorker } } - SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) : + SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, bool specifyMode, int maxDepth) : design(design), module(module), sigmap(module) { if (module->processes.size() > 0) { @@ -115,6 +115,18 @@ struct SccWorker ct.setup_stdcells(); } + // Discover boxes with specify rules in them, for special handling. + if (specifyMode) { + for (auto mod : design->modules()) + if (mod->get_blackbox_attribute(false)) + for (auto cell : mod->cells()) + if (cell->type == ID($specify2)) + { + specifyCells.setup_module(mod); + break; + } + } + SigPool selectedSignals; SigSet sigToNextCells; @@ -129,29 +141,52 @@ struct SccWorker if (!design->selected(module, cell)) continue; - if (!allCellTypes && !ct.cell_known(cell->type)) + if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type)) continue; workQueue.insert(cell); RTLIL::SigSpec inputSignals, outputSignals; - for (auto &conn : cell->connections()) - { - bool isInput = true, isOutput = true; + if (specifyCells.cell_known(cell->type)) { + // Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes. + for (auto subcell : design->module(cell->type)->cells()) + { + if (subcell->type != ID($specify2)) + continue; - if (ct.cell_known(cell->type)) { - isInput = ct.cell_input(cell->type, conn.first); - isOutput = ct.cell_output(cell->type, conn.first); + for (auto bit : subcell->getPort(ID::SRC)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + inputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } + + for (auto bit : subcell->getPort(ID::DST)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + outputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } } + } else { + for (auto &conn : cell->connections()) + { + bool isInput = true, isOutput = true; + + if (ct.cell_known(cell->type)) { + isInput = ct.cell_input(cell->type, conn.first); + isOutput = ct.cell_output(cell->type, conn.first); + } - RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); - sig.sort_and_unify(); + RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); + sig.sort_and_unify(); - if (isInput) - inputSignals.append(sig); - if (isOutput) - outputSignals.append(sig); + if (isInput) + inputSignals.append(sig); + if (isOutput) + outputSignals.append(sig); + } } inputSignals.sort_and_unify(); @@ -228,7 +263,7 @@ struct SccPass : public Pass { log("design.\n"); log("\n"); log(" -expect \n"); - log(" expect to find exactly SSCs. A different number of SSCs will\n"); + log(" expect to find exactly SCCs. A different number of SCCs will\n"); log(" produce an error.\n"); log("\n"); log(" -max_depth \n"); @@ -254,6 +289,9 @@ struct SccPass : public Pass { log(" replace the current selection with a selection of all cells and wires\n"); log(" that are part of a found logic loop\n"); log("\n"); + log(" -specify\n"); + log(" examine specify rules to detect logic loops in whitebox/blackbox cells\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -261,6 +299,7 @@ struct SccPass : public Pass { bool allCellTypes = false; bool selectMode = false; bool nofeedbackMode = false; + bool specifyMode = false; int maxDepth = -1; int expect = -1; @@ -293,6 +332,10 @@ struct SccPass : public Pass { selectMode = true; continue; } + if (args[argidx] == "-specify") { + specifyMode = true; + continue; + } break; } int origSelectPos = design->selection_stack.size() - 1; @@ -303,7 +346,7 @@ struct SccPass : public Pass { for (auto mod : design->selected_modules()) { - SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); + SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth); if (!setAttr.empty()) { diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7d017ac4033..56bb1549578 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("read_verilog -icells -lib -specify +/abc9_model.v"); - run("scc -set_attr abc9_scc_id {}"); + run("scc -specify -set_attr abc9_scc_id {}"); if (help_mode) run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); else From 4b6e764c462047561ddc32b0638c21d773a4fbe4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 26 Jan 2021 17:42:23 +0000 Subject: [PATCH 0154/2410] cxxrtl: do not use `->template` for non-dependent names. This breaks build on MSVC but not GCC/Clang. --- backends/cxxrtl/cxxrtl.h | 16 ++++++++-------- backends/cxxrtl/cxxrtl_vcd.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 0a6bcb84940..0e55c46c223 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1217,49 +1217,49 @@ value xnor_ss(const value &a, const value &b) { template CXXRTL_ALWAYS_INLINE value shl_uu(const value &a, const value &b) { - return a.template zcast().template shl(b); + return a.template zcast().shl(b); } template CXXRTL_ALWAYS_INLINE value shl_su(const value &a, const value &b) { - return a.template scast().template shl(b); + return a.template scast().shl(b); } template CXXRTL_ALWAYS_INLINE value sshl_uu(const value &a, const value &b) { - return a.template zcast().template shl(b); + return a.template zcast().shl(b); } template CXXRTL_ALWAYS_INLINE value sshl_su(const value &a, const value &b) { - return a.template scast().template shl(b); + return a.template scast().shl(b); } template CXXRTL_ALWAYS_INLINE value shr_uu(const value &a, const value &b) { - return a.template shr(b).template zcast(); + return a.shr(b).template zcast(); } template CXXRTL_ALWAYS_INLINE value shr_su(const value &a, const value &b) { - return a.template shr(b).template scast(); + return a.shr(b).template scast(); } template CXXRTL_ALWAYS_INLINE value sshr_uu(const value &a, const value &b) { - return a.template shr(b).template zcast(); + return a.shr(b).template zcast(); } template CXXRTL_ALWAYS_INLINE value sshr_su(const value &a, const value &b) { - return a.template sshr(b).template scast(); + return a.sshr(b).template scast(); } template diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index 6ee98b4284d..3f40a8d122d 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -228,13 +228,13 @@ class vcd_writer { } void add(const debug_items &items) { - this->template add(items, [](const std::string &, const debug_item &) { + this->add(items, [](const std::string &, const debug_item &) { return true; }); } void add_without_memories(const debug_items &items) { - this->template add(items, [](const std::string &, const debug_item &item) { + this->add(items, [](const std::string &, const debug_item &item) { return item.type != debug_item::MEMORY; }); } From 2364820f504beef06d0d94d6b2e82eddffeb57c1 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 26 Jan 2021 18:29:16 +0000 Subject: [PATCH 0155/2410] flatten: clarify confusing error message. --- passes/techmap/flatten.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index ec5f83fb03f..f35b7ff6050 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -211,7 +211,7 @@ struct FlattenWorker log_assert(new_conn.first.size() == new_conn.second.size()); if (sigmap(new_conn.first).has_const()) - log_error("Mismatch in directionality for cell port %s.%s.%s: %s <= %s\n", + log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n", log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second)); module->connect(new_conn); From cd6f0732f3b342938a915951bdcd5299576f1843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 25 Jan 2021 13:01:24 +0100 Subject: [PATCH 0156/2410] xilinx: Add FDRSE_1, FDCPE_1. --- techlibs/xilinx/cells_sim.v | 80 +++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index adaf7aee1e8..a079f1c95f2 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -633,6 +633,41 @@ module FDRSE ( Q <= d; endmodule +module FDRSE_1 ( + output reg Q, + (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) + input C, + (* invertible_pin = "IS_CE_INVERTED" *) + input CE, + (* invertible_pin = "IS_D_INVERTED" *) + input D, + (* invertible_pin = "IS_R_INVERTED" *) + input R, + (* invertible_pin = "IS_S_INVERTED" *) + input S +); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_CE_INVERTED = 1'b0; + parameter [0:0] IS_D_INVERTED = 1'b0; + parameter [0:0] IS_R_INVERTED = 1'b0; + parameter [0:0] IS_S_INVERTED = 1'b0; + initial Q <= INIT; + wire c = C ^ IS_C_INVERTED; + wire ce = CE ^ IS_CE_INVERTED; + wire d = D ^ IS_D_INVERTED; + wire r = R ^ IS_R_INVERTED; + wire s = S ^ IS_S_INVERTED; + always @(negedge c) + if (r) + Q <= 0; + else if (s) + Q <= 1; + else if (ce) + Q <= d; +endmodule + (* abc9_box, lib_whitebox *) module FDCE ( output reg Q, @@ -837,6 +872,51 @@ module FDCPE ( assign Q = qs ? qp : qc; endmodule +module FDCPE_1 ( + output wire Q, + (* clkbuf_sink *) + (* invertible_pin = "IS_C_INVERTED" *) + input C, + input CE, + (* invertible_pin = "IS_CLR_INVERTED" *) + input CLR, + input D, + (* invertible_pin = "IS_PRE_INVERTED" *) + input PRE +); + parameter [0:0] INIT = 1'b0; + parameter [0:0] IS_C_INVERTED = 1'b0; + parameter [0:0] IS_CLR_INVERTED = 1'b0; + parameter [0:0] IS_PRE_INVERTED = 1'b0; + wire c = C ^ IS_C_INVERTED; + wire clr = CLR ^ IS_CLR_INVERTED; + wire pre = PRE ^ IS_PRE_INVERTED; + // Hacky model to avoid simulation-synthesis mismatches. + reg qc, qp, qs; + initial qc = INIT; + initial qp = INIT; + initial qs = 0; + always @(negedge c, posedge clr) begin + if (clr) + qc <= 0; + else if (CE) + qc <= D; + end + always @(negedge c, posedge pre) begin + if (pre) + qp <= 1; + else if (CE) + qp <= D; + end + always @* begin + if (clr) + qs <= 0; + else if (pre) + qs <= 1; + end + assign Q = qs ? qp : qc; +endmodule + module LDCE ( output reg Q, (* invertible_pin = "IS_CLR_INVERTED" *) From ea79e16bab7abf374f371626297e65c81e00a068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 25 Jan 2021 13:01:18 +0100 Subject: [PATCH 0157/2410] xilinx_dffopt: Don't crash on missing IS_*_INVERTED. The presence of IS_*_INVERTED on FD* cells follows Vivado, which apparently has been decided by a dice roll. Just assume false if the parameter doesn't exist. Fixes #2559. --- techlibs/xilinx/xilinx_dffopt.cc | 6 ++-- tests/arch/xilinx/mux.ys | 3 +- tests/arch/xilinx/xilinx_dffopt.ys | 46 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index 365f505fb34..598f1b216a1 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -209,7 +209,7 @@ struct XilinxDffOptPass : public Pass { continue; LutData lut_d = it_D->second.first; Cell *cell_d = it_D->second.second; - if (cell->getParam(ID(IS_D_INVERTED)).as_bool()) { + if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) { // Flip all bits in the LUT. for (int i = 0; i < GetSize(lut_d.first); i++) lut_d.first.bits[i] = (lut_d.first.bits[i] == State::S1) ? State::S0 : State::S1; @@ -249,7 +249,7 @@ struct XilinxDffOptPass : public Pass { if (has_s) { SigBit sig_S = sigmap(cell->getPort(ID::S)); LutData lut_s = LutData(Const(2, 2), {sig_S}); - bool inv_s = cell->getParam(ID(IS_S_INVERTED)).as_bool(); + bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool(); auto it_S = bit_to_lut.find(sig_S); if (it_S != bit_to_lut.end()) lut_s = it_S->second.first; @@ -271,7 +271,7 @@ struct XilinxDffOptPass : public Pass { if (has_r) { SigBit sig_R = sigmap(cell->getPort(ID::R)); LutData lut_r = LutData(Const(2, 2), {sig_R}); - bool inv_r = cell->getParam(ID(IS_R_INVERTED)).as_bool(); + bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool(); auto it_R = bit_to_lut.find(sig_R); if (it_R != bit_to_lut.end()) lut_r = it_R->second.first; diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys index 1b27884488b..c2a23de6d96 100644 --- a/tests/arch/xilinx/mux.ys +++ b/tests/arch/xilinx/mux.ys @@ -40,10 +40,11 @@ proc equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module +select -assert-max 2 t:LUT3 select -assert-max 2 t:LUT4 select -assert-min 4 t:LUT6 select -assert-max 7 t:LUT6 select -assert-max 2 t:MUXF7 dump -select -assert-none t:LUT6 t:LUT4 t:MUXF7 %% t:* %D +select -assert-none t:LUT6 t:LUT4 t:LUT3 t:MUXF7 %% t:* %D diff --git a/tests/arch/xilinx/xilinx_dffopt.ys b/tests/arch/xilinx/xilinx_dffopt.ys index 2c729832ed0..c096994114b 100644 --- a/tests/arch/xilinx/xilinx_dffopt.ys +++ b/tests/arch/xilinx/xilinx_dffopt.ys @@ -223,3 +223,49 @@ select -assert-count 1 t:LUT2 select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D design -reset + + +read_verilog << EOT + +// FDSE_1, mergeable CE and S, but CE only not worth it. + +module t0 (...); +input wire clk; +input wire [7:0] i; +output wire [7:0] o; + +wire [7:0] tmp ; + +LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0])); +LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1])); + +FDSE_1 ff (.D(tmp[0]), .CE(i[7]), .S(tmp[1]), .Q(o[0])); + +endmodule + +EOT + +read_verilog -lib +/xilinx/cells_sim.v +design -save t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt +design -load postopt +clean + +cd t0 +select -assert-count 1 t:FDSE_1 +select -assert-count 1 t:LUT5 +select -assert-none t:FDSE_1 t:LUT5 %% t:* %D + +design -load t0 + +equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4 +design -load postopt +clean + +cd t0 +select -assert-count 1 t:FDSE_1 +select -assert-count 2 t:LUT2 +select -assert-none t:FDSE_1 t:LUT2 %% t:* %D + +design -reset From 98afe2b7589181c39281a6c58540f6756395e1d9 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Wed, 27 Jan 2021 00:10:04 +0000 Subject: [PATCH 0158/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a6a542f0c0a..e4a228b8193 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3863 +YOSYS_VER := 0.9+3871 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 27257a419fe94e10f24eea916c56821e22e43cc5 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 28 Jan 2021 11:26:21 -0500 Subject: [PATCH 0159/2410] verilog: strip leading and trailing spaces in macro args --- frontends/verilog/preproc.cc | 6 +++++- tests/simple/macro_arg_surrounding_spaces.v | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/simple/macro_arg_surrounding_spaces.v diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 5a2804a4176..c451c4c2013 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -390,12 +390,16 @@ static void input_file(std::istream &f, std::string filename) // the argument list); false if we finished with ','. static bool read_argument(std::string &dest) { + skip_spaces(); std::vector openers; for (;;) { std::string tok = next_token(true); if (tok == ")") { - if (openers.empty()) + if (openers.empty()) { + while (dest.size() && (dest.back() == ' ' || dest.back() == '\t')) + dest = dest.substr(0, dest.size() - 1); return true; + } if (openers.back() != '(') log_error("Mismatched brackets in macro argument: %c and %c.\n", openers.back(), tok[0]); diff --git a/tests/simple/macro_arg_surrounding_spaces.v b/tests/simple/macro_arg_surrounding_spaces.v new file mode 100644 index 00000000000..3dbb5ea015d --- /dev/null +++ b/tests/simple/macro_arg_surrounding_spaces.v @@ -0,0 +1,20 @@ +module top( + IDENT_V_, + IDENT_W_, + IDENT_X_, + IDENT_Y_, + IDENT_Z_, + IDENT_A_, + IDENT_B_, + IDENT_C_ +); + `define MACRO(dummy, x) IDENT_``x``_ + output wire IDENT_V_; + output wire `MACRO(_,W); + output wire `MACRO(_, X); + output wire `MACRO(_,Y ); + output wire `MACRO(_, Z ); + output wire `MACRO(_, A); + output wire `MACRO(_,B ); + output wire `MACRO(_, C ); +endmodule From ffa1cb836be07b2bfec46da76ef7c7ab5fda6995 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 29 Jan 2021 00:10:05 +0000 Subject: [PATCH 0160/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e4a228b8193..7755df5019b 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3871 +YOSYS_VER := 0.9+3876 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From a4c04d1b909285789cbb3b7f9d39e9020701f741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 28 Jan 2021 00:31:50 +0100 Subject: [PATCH 0161/2410] ast: fix dump_vlog display of casex/casez The first child of AST_CASE is the case expression, it's subsequent childrean that are AST_COND* and can be used to discriminate the type of the case. --- frontends/ast/ast.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 1c0a8b34df4..dc47420af05 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -548,9 +548,9 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const break; case AST_CASE: - if (!children.empty() && children[0]->type == AST_CONDX) + if (children.size() > 1 && children[1]->type == AST_CONDX) fprintf(f, "%s" "casex (", indent.c_str()); - else if (!children.empty() && children[0]->type == AST_CONDZ) + else if (children.size() > 1 && children[1]->type == AST_CONDZ) fprintf(f, "%s" "casez (", indent.c_str()); else fprintf(f, "%s" "case (", indent.c_str()); From 1057273852ce1e25bffc2def67312eb34be48b00 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sat, 30 Jan 2021 00:10:05 +0000 Subject: [PATCH 0162/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7755df5019b..2df8e89152b 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3876 +YOSYS_VER := 0.9+3880 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From d99c032c278f3732c95a368c7e6d9573d99ae2e4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 30 Jan 2021 09:23:46 +0100 Subject: [PATCH 0163/2410] Require latest Verific build --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 614124a296c..81e14ac4145 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,7 +55,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20201201 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210101 # error "Please update your version of YosysHQ flavored Verific." #endif From beeaad19045f017acb27e38eb452457726932a8f Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sun, 31 Jan 2021 00:10:05 +0000 Subject: [PATCH 0164/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2df8e89152b..beeb6a8f9f8 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3880 +YOSYS_VER := 0.9+3882 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From fe74b0cd95267bc78953236311382653a6db7f60 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 27 Jan 2021 13:30:22 -0500 Subject: [PATCH 0165/2410] verilog: significant block scoping improvements This change set contains a number of bug fixes and improvements related to scoping and resolution in generate and procedural blocks. While many of the frontend changes are interdependent, it may be possible bring the techmap changes in under a separate PR. Declarations within unnamed generate blocks previously encountered issues because the data declarations were left un-prefixed, breaking proper scoping. The LRM outlines behavior for generating names for unnamed generate blocks. The original goal was to add this implicit labelling, but doing so exposed a number of issues downstream. Additional testing highlighted other closely related scope resolution issues, which have been fixed. This change also adds support for block item declarations within unnamed blocks in SystemVerilog mode. 1. Unlabled generate blocks are now implicitly named according to the LRM in `label_genblks`, which is invoked at the beginning of module elaboration 2. The Verilog parser no longer wraps explicitly named generate blocks in a synthetic unnamed generate block to avoid creating extra hierarchy levels where they should not exist 3. The techmap phase now allows special control identifiers to be used outside of the topmost scope, which is necessary because such wires and cells often appear in unlabeled generate blocks, which now prefix the declarations within 4. Some techlibs required modifications because they relied on the previous invalid scope resolution behavior 5. `expand_genblock` has been simplified, now only expanding the outermost scope, completely deferring the inspection and elaboration of nested scopes; names are now resolved by looking in the innermost scope and stepping outward 6. Loop variables now always become localparams during unrolling, allowing them to be resolved and shadowed like any other identifier 7. Identifiers in synthetic function call scopes are now prefixed and resolved in largely the same manner as other blocks before: `$func$\func_01$tests/simple/scopes.blk.v:60$5$\blk\x` after: `\func_01$func$tests/simple/scopes.v:60$5.blk.x` 8. Support identifiers referencing a local generate scope nested more than 1 level deep, i.e. `B.C.x` while within generate scope `A`, or using a prefix of a current or parent scope, i.e. `B.C.D.x` while in `A.B`, `A.B.C`, or `A.B.C.D` 9. Variables can now be declared within unnamed blocks in SystemVerilog mode Addresses the following issues: 656, 2423, 2493 --- frontends/ast/ast.h | 4 +- frontends/ast/simplify.cc | 268 ++++++++++++++------------- frontends/verilog/verilog_parser.y | 45 +++-- kernel/rtlil.h | 4 + passes/techmap/techmap.cc | 45 +++-- techlibs/common/cmp2lcu.v | 29 ++- techlibs/common/cmp2lut.v | 14 +- techlibs/common/mul2dsp.v | 48 ++--- techlibs/ice40/brams_map.v | 73 ++++---- techlibs/xilinx/arith_map.v | 6 +- tests/simple/func_block.v | 33 ++++ tests/simple/func_recurse.v | 25 +++ tests/simple/func_width_scope.v | 41 ++++ tests/simple/genblk_collide.v | 27 +++ tests/simple/genblk_dive.v | 21 +++ tests/simple/genblk_order.v | 18 ++ tests/simple/generate.v | 63 +++++++ tests/simple/local_loop_var.sv | 11 ++ tests/simple/loop_var_shadow.v | 15 ++ tests/simple/named_genblk.v | 27 +++ tests/simple/nested_genblk_resolve.v | 14 ++ tests/simple/unnamed_block_decl.sv | 17 ++ tests/various/gen_if_null.v | 12 +- tests/various/gen_if_null.ys | 4 +- tests/verilog/bug2493.ys | 12 ++ tests/verilog/bug656.v | 21 +++ tests/verilog/bug656.ys | 13 ++ tests/verilog/genblk_case.v | 26 +++ tests/verilog/genblk_case.ys | 15 ++ tests/verilog/hidden_decl.ys | 11 ++ tests/verilog/unnamed_block.ys | 28 +++ tests/verilog/unnamed_genblk.sv | 39 ++++ tests/verilog/unnamed_genblk.ys | 8 + 33 files changed, 779 insertions(+), 258 deletions(-) create mode 100644 tests/simple/func_block.v create mode 100644 tests/simple/func_recurse.v create mode 100644 tests/simple/func_width_scope.v create mode 100644 tests/simple/genblk_collide.v create mode 100644 tests/simple/genblk_dive.v create mode 100644 tests/simple/genblk_order.v create mode 100644 tests/simple/local_loop_var.sv create mode 100644 tests/simple/loop_var_shadow.v create mode 100644 tests/simple/named_genblk.v create mode 100644 tests/simple/nested_genblk_resolve.v create mode 100644 tests/simple/unnamed_block_decl.sv create mode 100644 tests/verilog/bug2493.ys create mode 100644 tests/verilog/bug656.v create mode 100644 tests/verilog/bug656.ys create mode 100644 tests/verilog/genblk_case.v create mode 100644 tests/verilog/genblk_case.ys create mode 100644 tests/verilog/hidden_decl.ys create mode 100644 tests/verilog/unnamed_block.ys create mode 100644 tests/verilog/unnamed_genblk.sv create mode 100644 tests/verilog/unnamed_genblk.ys diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 90739216679..6f173ca22f2 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -252,8 +252,8 @@ namespace AST bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void replace_result_wire_name_in_function(const std::string &from, const std::string &to); AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init); - void expand_genblock(std::string index_var, std::string prefix, std::map &name_map, bool original_scope = true); - void replace_ids(const std::string &prefix, const std::map &rules); + void expand_genblock(const std::string &prefix); + void label_genblks(std::set& existing, int &counter); void mem2reg_as_needed_pass1(dict> &mem2reg_places, dict &mem2reg_flags, dict &proc_flags, uint32_t &status_flags); bool mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index fc2976c83e8..77911e96620 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -549,6 +549,16 @@ static bool node_contains_assignment_to(const AstNode* node, const AstNode* var) return true; } +static std::string prefix_id(const std::string &prefix, const std::string &str) +{ + log_assert(!prefix.empty() && (prefix.front() == '$' || prefix.front() == '\\')); + log_assert(!str.empty() && (str.front() == '$' || str.front() == '\\')); + log_assert(prefix.back() == '.'); + if (str.front() == '\\') + return prefix + str.substr(1); + return prefix + str; +} + // convert the AST into a simpler AST that has all parameters substituted by their // values, unrolled for-loops, expanded generate blocks, etc. when this function // is done with an AST it can be converted into RTLIL using genRTLIL(). @@ -748,6 +758,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;") if (type == AST_MODULE) { current_scope.clear(); + std::set existing; + int counter = 0; + label_genblks(existing, counter); std::map this_wire_scope; for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; @@ -1855,19 +1868,24 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // expand body int index = varbuf->children[0]->integer; - if (body_ast->type == AST_GENBLOCK) - buf = body_ast->clone(); - else - buf = new AstNode(AST_GENBLOCK, body_ast->clone()); - if (buf->str.empty()) { - std::stringstream sstr; - sstr << "$genblock$" << filename << ":" << location.first_line << "$" << (autoidx++); - buf->str = sstr.str(); - } - std::map name_map; + log_assert(body_ast->type == AST_GENBLOCK || body_ast->type == AST_BLOCK); + log_assert(!body_ast->str.empty()); + buf = body_ast->clone(); + std::stringstream sstr; sstr << buf->str << "[" << index << "]."; - buf->expand_genblock(varbuf->str, sstr.str(), name_map); + std::string prefix = sstr.str(); + + // create a scoped localparam for the current value of the loop variable + AstNode *local_index = varbuf->clone(); + size_t pos = local_index->str.rfind('.'); + if (pos != std::string::npos) // remove outer prefix + local_index->str = "\\" + local_index->str.substr(pos + 1); + local_index->str = prefix_id(prefix, local_index->str); + current_scope[local_index->str] = local_index; + current_ast_mod->children.push_back(local_index); + + buf->expand_genblock(prefix); if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { @@ -1915,14 +1933,16 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { for (size_t i = 0; i < children.size(); i++) if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) - log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); + { + log_assert(!VERILOG_FRONTEND::sv_mode); + log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is only supported in SystemVerilog mode!\n"); + } } // transform block with name if (type == AST_BLOCK && !str.empty()) { - std::map name_map; - expand_genblock(std::string(), str + ".", name_map); + expand_genblock(str + "."); std::vector new_children; for (size_t i = 0; i < children.size(); i++) @@ -1942,8 +1962,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENBLOCK && children.size() != 0) { if (!str.empty()) { - std::map name_map; - expand_genblock(std::string(), str + ".", name_map); + expand_genblock(str + "."); } for (size_t i = 0; i < children.size(); i++) { @@ -1979,8 +1998,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, buf = new AstNode(AST_GENBLOCK, buf); if (!buf->str.empty()) { - std::map name_map; - buf->expand_genblock(std::string(), buf->str + ".", name_map); + buf->expand_genblock(buf->str + "."); } for (size_t i = 0; i < buf->children.size(); i++) { @@ -2058,8 +2076,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, buf = selected_case->clone(); if (!buf->str.empty()) { - std::map name_map; - buf->expand_genblock(std::string(), buf->str + ".", name_map); + buf->expand_genblock(buf->str + "."); } for (size_t i = 0; i < buf->children.size(); i++) { @@ -3159,12 +3176,16 @@ skip_dynamic_range_lvalue_expansion:; log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str()); } - AstNode *decl = current_scope[str]; std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++) << "$"; + sstr << str << "$func$" << filename << ":" << location.first_line << "$" << (autoidx++) << '.'; std::string prefix = sstr.str(); + AstNode *decl = current_scope[str]; + decl = decl->clone(); + decl->replace_result_wire_name_in_function(str, "$result"); // enables recursion + decl->expand_genblock(prefix); + bool recommend_const_eval = false; bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count(ID::via_celltype)) @@ -3177,11 +3198,11 @@ skip_dynamic_range_lvalue_expansion:; } if (all_args_const) { - AstNode *func_workspace = current_scope[str]->clone(); - func_workspace->str = NEW_ID.str(); - func_workspace->replace_result_wire_name_in_function(str, func_workspace->str); + AstNode *func_workspace = decl->clone(); + func_workspace->str = prefix_id(prefix, "$result"); newNode = func_workspace->eval_const_function(this); delete func_workspace; + delete decl; goto apply_newNode; } @@ -3192,8 +3213,6 @@ skip_dynamic_range_lvalue_expansion:; } size_t arg_count = 0; - std::map replace_rules; - vector added_mod_children; dict wire_cache; vector new_stmts; vector output_assignments; @@ -3203,16 +3222,17 @@ skip_dynamic_range_lvalue_expansion:; log_assert(type == AST_FCALL); AstNode *wire = NULL; + std::string res_name = prefix_id(prefix, "$result"); for (auto child : decl->children) - if (child->type == AST_WIRE && child->str == str) + if (child->type == AST_WIRE && child->str == res_name) wire = child->clone(); log_assert(wire != NULL); - wire->str = prefix + str; wire->port_id = 0; wire->is_input = false; wire->is_output = false; + current_scope[wire->str] = wire; current_ast_mod->children.push_back(wire); while (wire->simplify(true, false, false, 1, -1, false, false)) { } @@ -3256,7 +3276,6 @@ skip_dynamic_range_lvalue_expansion:; if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str))) { AstNode *wire = child->clone(); - wire->str = prefix + wire->str; wire->port_id = 0; wire->is_input = false; wire->is_output = false; @@ -3318,7 +3337,6 @@ skip_dynamic_range_lvalue_expansion:; else { wire = child->clone(); - wire->str = prefix + wire->str; wire->port_id = 0; wire->is_input = false; wire->is_output = false; @@ -3329,15 +3347,11 @@ skip_dynamic_range_lvalue_expansion:; wire_cache[child->str] = wire; + current_scope[wire->str] = wire; current_ast_mod->children.push_back(wire); - added_mod_children.push_back(wire); } - if (child->type == AST_WIRE) - while (wire->simplify(true, false, false, 1, -1, false, false)) { } - - replace_rules[child->str] = wire->str; - current_scope[wire->str] = wire; + while (wire->simplify(true, false, false, 1, -1, false, false)) { } if ((child->is_input || child->is_output) && arg_count < children.size()) { @@ -3381,18 +3395,9 @@ skip_dynamic_range_lvalue_expansion:; } } - for (auto child : added_mod_children) { - child->replace_ids(prefix, replace_rules); - while (child->simplify(true, false, false, 1, -1, false, false)) { } - } - for (auto child : decl->children) if (child->type != AST_WIRE && child->type != AST_MEMORY && child->type != AST_PARAMETER && child->type != AST_LOCALPARAM) - { - AstNode *stmt = child->clone(); - stmt->replace_ids(prefix, replace_rules); - new_stmts.push_back(stmt); - } + new_stmts.push_back(child->clone()); new_stmts.insert(new_stmts.end(), output_assignments.begin(), output_assignments.end()); @@ -3405,10 +3410,11 @@ skip_dynamic_range_lvalue_expansion:; } replace_fcall_with_id: + delete decl; if (type == AST_FCALL) { delete_children(); type = AST_IDENTIFIER; - str = prefix + str; + str = prefix_id(prefix, "$result"); } if (type == AST_TCALL) str = ""; @@ -3859,63 +3865,52 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m return block; } -// annotate the names of all wires and other named objects in a generate block -void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map &name_map, bool original_scope) +// annotate the names of all wires and other named objects in a named generate +// or procedural block; nested blocks are themselves annotated such that the +// prefix is carried forward, but resolution of their children is deferred +void AstNode::expand_genblock(const std::string &prefix) { - // `original_scope` defaults to false, and is used to prevent the premature - // prefixing of items in named sub-blocks - - if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) { - if (children.empty()) { - current_scope[index_var]->children[0]->cloneInto(this); - } else { - AstNode *p = new AstNode(AST_LOCALPARAM, current_scope[index_var]->children[0]->clone()); - p->str = stringf("$genval$%d", autoidx++); - current_ast_mod->children.push_back(p); - str = p->str; - id2ast = p; - } - } - if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) { - if (name_map.count(str) > 0) { - str = name_map[str]; - } else { - // remap the prefix of this ident if it is a local generate scope - size_t pos = str.rfind('.'); - if (pos != std::string::npos) { - std::string existing_prefix = str.substr(0, pos); - if (name_map.count(existing_prefix) > 0) { - str = name_map[existing_prefix] + str.substr(pos); - } + log_assert(!str.empty()); + + // search starting in the innermost scope and then stepping outward + for (size_t ppos = prefix.size() - 1; ppos; --ppos) { + if (prefix.at(ppos) != '.') continue; + + std::string new_prefix = prefix.substr(0, ppos + 1); + auto attempt_resolve = [&new_prefix](const std::string &ident) -> std::string { + std::string new_name = prefix_id(new_prefix, ident); + if (current_scope.count(new_name)) + return new_name; + return {}; + }; + + // attempt to resolve the full identifier + std::string resolved = attempt_resolve(str); + if (!resolved.empty()) { + str = resolved; + break; } - } - } - std::map backup_name_map; - - auto prefix_node = [&](AstNode* child) { - if (backup_name_map.size() == 0) - backup_name_map = name_map; + // attempt to resolve hierarchical prefixes within the identifier, + // as the prefix could refer to a local scope which exists but + // hasn't yet been elaborated + for (size_t spos = str.size() - 1; spos; --spos) { + if (str.at(spos) != '.') continue; + resolved = attempt_resolve(str.substr(0, spos)); + if (!resolved.empty()) { + str = resolved + str.substr(spos); + ppos = 1; // break outer loop + break; + } + } - // if within a nested scope - if (!original_scope) { - // this declaration shadows anything in the parent scope(s) - name_map[child->str] = child->str; - return; } + } - std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix; - size_t pos = child->str.rfind('.'); - if (pos == std::string::npos) - pos = child->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0; - else - pos = pos + 1; - new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos); - if (new_name[0] != '$' && new_name[0] != '\\') - new_name = prefix[0] + new_name; - - name_map[child->str] = new_name; + auto prefix_node = [&prefix](AstNode* child) { + if (child->str.empty()) return; + std::string new_name = prefix_id(prefix, child->str); if (child->type == AST_FUNCTION) child->replace_result_wire_name_in_function(child->str, new_name); else @@ -3967,43 +3962,55 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma continue; // functions/tasks may reference wires, constants, etc. in this scope if (child->type == AST_FUNCTION || child->type == AST_TASK) - child->expand_genblock(index_var, prefix, name_map, false); - // continue prefixing if this child block is anonymous - else if (child->type == AST_GENBLOCK || child->type == AST_BLOCK) - child->expand_genblock(index_var, prefix, name_map, original_scope && child->str.empty()); - else - child->expand_genblock(index_var, prefix, name_map, original_scope); - } - + continue; + // named blocks pick up the current prefix and will expanded later + if ((child->type == AST_GENBLOCK || child->type == AST_BLOCK) && !child->str.empty()) + continue; - if (backup_name_map.size() > 0) - name_map.swap(backup_name_map); + child->expand_genblock(prefix); + } } -// rename stuff (used when tasks of functions are instantiated) -void AstNode::replace_ids(const std::string &prefix, const std::map &rules) +// add implicit AST_GENBLOCK names according to IEEE 1364-2005 Section 12.4.3 or +// IEEE 1800-2017 Section 27.6 +void AstNode::label_genblks(std::set& existing, int &counter) { - if (type == AST_BLOCK) - { - std::map new_rules = rules; - std::string new_prefix = prefix + str; - - for (auto child : children) - if (child->type == AST_WIRE) { - new_rules[child->str] = new_prefix + child->str; - child->str = new_prefix + child->str; - } + switch (type) { + case AST_GENIF: + case AST_GENFOR: + case AST_GENCASE: + // seeing a proper generate control flow construct increments the + // counter once + ++counter; + for (AstNode *child : children) + child->label_genblks(existing, counter); + break; - for (auto child : children) - if (child->type != AST_WIRE) - child->replace_ids(new_prefix, new_rules); + case AST_GENBLOCK: { + // if this block is unlabeled, generate its corresponding unique name + for (int padding = 0; str.empty(); ++padding) { + std::string candidate = "\\genblk"; + for (int i = 0; i < padding; ++i) + candidate += '0'; + candidate += std::to_string(counter); + if (!existing.count(candidate)) + str = candidate; + } + // within a genblk, the counter starts fresh + std::set existing_local = existing; + int counter_local = 0; + for (AstNode *child : children) + child->label_genblks(existing_local, counter_local); + break; } - else - { - if (type == AST_IDENTIFIER && rules.count(str) > 0) - str = rules.at(str); - for (auto child : children) - child->replace_ids(prefix, rules); + + default: + // track names which could conflict with implicit genblk names + if (str.rfind("\\genblk", 0) == 0) + existing.insert(str); + for (AstNode *child : children) + child->label_genblks(existing, counter); + break; } } @@ -4773,6 +4780,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) if (stmt->type == AST_BLOCK) { + if (!stmt->str.empty()) + stmt->expand_genblock(stmt->str + "."); + block->children.erase(block->children.begin()); block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end()); stmt->children.clear(); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 8bd58d24c8c..6255a4204d0 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -770,6 +770,7 @@ module_body: module_body module_body_stmt | /* the following line makes the generate..endgenrate keywords optional */ module_body gen_stmt | + module_body gen_block | module_body ';' | %empty; @@ -2459,6 +2460,16 @@ behavioral_stmt: exitTypeScope(); if ($4 != NULL && $8 != NULL && *$4 != *$8) frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1); + AstNode *node = ast_stack.back(); + // In SystemVerilog, unnamed blocks with block item declarations + // create an implicit hierarchy scope + if (sv_mode && node->str.empty()) + for (const AstNode* child : node->children) + if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER + || child->type == AST_LOCALPARAM || child->type == AST_TYPEDEF) { + node->str = "$unnamed_block$" + std::to_string(autoidx++); + break; + } SET_AST_NODE_LOC(ast_stack.back(), @2, @8); delete $4; delete $8; @@ -2473,6 +2484,7 @@ behavioral_stmt: ast_stack.back()->children.push_back($7); } ';' simple_behavioral_stmt ')' { AstNode *block = new AstNode(AST_BLOCK); + block->str = "$for_loop$" + std::to_string(autoidx++); ast_stack.back()->children.push_back(block); ast_stack.push_back(block); } behavioral_stmt { @@ -2722,6 +2734,7 @@ single_arg: module_gen_body: module_gen_body gen_stmt_or_module_body_stmt | + module_gen_body gen_block | %empty; gen_stmt_or_module_body_stmt: @@ -2747,12 +2760,7 @@ gen_stmt: ast_stack.back()->children.push_back(node); ast_stack.push_back(node); ast_stack.back()->children.push_back($3); - AstNode *block = new AstNode(AST_GENBLOCK); - ast_stack.back()->children.push_back(block); - ast_stack.push_back(block); - } gen_stmt_block { - ast_stack.pop_back(); - } opt_gen_else { + } gen_stmt_block opt_gen_else { SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); } | @@ -2765,6 +2773,18 @@ gen_stmt: SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); } | + TOK_MSG_TASKS { + AstNode *node = new AstNode(AST_TECALL); + node->str = *$1; + delete $1; + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @1, @3); + ast_stack.pop_back(); + }; + +gen_block: TOK_BEGIN { enterTypeScope(); } opt_label { @@ -2778,18 +2798,9 @@ gen_stmt: delete $7; SET_AST_NODE_LOC(ast_stack.back(), @1, @7); ast_stack.pop_back(); - } | - TOK_MSG_TASKS { - AstNode *node = new AstNode(AST_TECALL); - node->str = *$1; - delete $1; - ast_stack.back()->children.push_back(node); - ast_stack.push_back(node); - } opt_arg_list ';'{ - SET_AST_NODE_LOC(ast_stack.back(), @1, @3); - ast_stack.pop_back(); }; +// result is wrapped in a genblock only if necessary gen_stmt_block: { AstNode *node = new AstNode(AST_GENBLOCK); @@ -2798,7 +2809,7 @@ gen_stmt_block: } gen_stmt_or_module_body_stmt { SET_AST_NODE_LOC(ast_stack.back(), @2, @2); ast_stack.pop_back(); - }; + } | gen_block; opt_gen_else: TOK_ELSE gen_stmt_block | %empty %prec FAKE_THEN; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index cd966b81522..4dad3c42873 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -334,6 +334,10 @@ namespace RTLIL return compare(size()-len, len, suffix) == 0; } + bool contains(const char* str) const { + return strstr(c_str(), str); + } + size_t size() const { return strlen(c_str()); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index d43737c8dc0..96843d7108d 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -118,19 +118,14 @@ struct TechmapWorker return result; for (auto w : module->wires()) { - const char *p = w->name.c_str(); - if (*p == '$') + if (*w->name.c_str() == '$') continue; - const char *q = strrchr(p+1, '.'); - if (q) - p = q; - - if (!strncmp(p, "\\_TECHMAP_", 10)) { + if (w->name.contains("_TECHMAP_") && !w->name.contains("_TECHMAP_REPLACE_")) { TechmapWireData record; record.wire = w; record.value = w; - result[p].push_back(record); + result[w->name].push_back(record); w->set_bool_attribute(ID::keep); w->set_bool_attribute(ID::_techmap_special_); } @@ -165,7 +160,7 @@ struct TechmapWorker orig_cell_name = cell->name.str(); for (auto tpl_cell : tpl->cells()) - if (tpl_cell->name == ID::_TECHMAP_REPLACE_) { + if (tpl_cell->name.ends_with("_TECHMAP_REPLACE_")) { module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); break; } @@ -226,8 +221,8 @@ struct TechmapWorker } design->select(module, w); - if (tpl_w->name.begins_with("\\_TECHMAP_REPLACE_.")) { - IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), tpl_w->name.c_str() + strlen("\\_TECHMAP_REPLACE_")); + if (const char *p = strstr(tpl_w->name.c_str(), "_TECHMAP_REPLACE_.")) { + IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), p + strlen("_TECHMAP_REPLACE_")); Wire *replace_w = module->addWire(replace_name, tpl_w); module->connect(replace_w, w); } @@ -327,12 +322,12 @@ struct TechmapWorker for (auto tpl_cell : tpl->cells()) { IdString c_name = tpl_cell->name; - bool techmap_replace_cell = (c_name == ID::_TECHMAP_REPLACE_); + bool techmap_replace_cell = c_name.ends_with("_TECHMAP_REPLACE_"); if (techmap_replace_cell) c_name = orig_cell_name; - else if (tpl_cell->name.begins_with("\\_TECHMAP_REPLACE_.")) - c_name = stringf("%s%s", orig_cell_name.c_str(), c_name.c_str() + strlen("\\_TECHMAP_REPLACE_")); + else if (const char *p = strstr(tpl_cell->name.c_str(), "_TECHMAP_REPLACE_.")) + c_name = stringf("%s%s", orig_cell_name.c_str(), p + strlen("_TECHMAP_REPLACE_")); else apply_prefix(cell->name, c_name); @@ -730,12 +725,16 @@ struct TechmapWorker for (auto &it : twd) techmap_wire_names.insert(it.first); - for (auto &it : twd[ID::_TECHMAP_FAIL_]) { - RTLIL::SigSpec value = it.value; - if (value.is_fully_const() && value.as_bool()) { - log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", - derived_name.c_str(), log_id(it.wire->name), log_signal(value)); - techmap_do_cache[tpl] = false; + for (auto &it : twd) { + if (!it.first.ends_with("_TECHMAP_FAIL_")) + continue; + for (const TechmapWireData &elem : it.second) { + RTLIL::SigSpec value = elem.value; + if (value.is_fully_const() && value.as_bool()) { + log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", + derived_name.c_str(), log_id(elem.wire->name), log_signal(value)); + techmap_do_cache[tpl] = false; + } } } @@ -744,7 +743,7 @@ struct TechmapWorker for (auto &it : twd) { - if (!it.first.begins_with("\\_TECHMAP_DO_") || it.second.empty()) + if (!it.first.contains("_TECHMAP_DO_") || it.second.empty()) continue; auto &data = it.second.front(); @@ -756,7 +755,7 @@ struct TechmapWorker const char *p = data.wire->name.c_str(); const char *q = strrchr(p+1, '.'); - q = q ? q : p+1; + q = q ? q+1 : p+1; std::string cmd_string = data.value.as_const().decode_string(); @@ -873,7 +872,7 @@ struct TechmapWorker TechmapWires twd = techmap_find_special_wires(tpl); for (auto &it : twd) { - if (it.first != ID::_TECHMAP_FAIL_ && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.begins_with("\\_TECHMAP_DO_") && !it.first.begins_with("\\_TECHMAP_DONE_")) + if (!it.first.ends_with("_TECHMAP_FAIL_") && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.contains("_TECHMAP_DO_") && !it.first.contains("_TECHMAP_DONE_")) log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first)); if (techmap_do_cache[tpl]) for (auto &it2 : it.second) diff --git a/techlibs/common/cmp2lcu.v b/techlibs/common/cmp2lcu.v index a221727e774..4e62039e9d4 100644 --- a/techlibs/common/cmp2lcu.v +++ b/techlibs/common/cmp2lcu.v @@ -41,10 +41,7 @@ generate wire [WIDTH-1:0] BB = {{(WIDTH-B_WIDTH){B_SIGNED ? B[B_WIDTH-1] : 1'b0}}, B}; // For $ge operation, start with the assumption that A and B are // equal (propagating this equality if A and B turn out to be so) - if (_TECHMAP_CELLTYPE_ == "$ge") - localparam CI = 1'b1; - else - localparam CI = 1'b0; + localparam CI = _TECHMAP_CELLTYPE_ == "$ge"; $__CMP2LCU #(.AB_WIDTH(WIDTH), .AB_SIGNED(A_SIGNED && B_SIGNED), .LCU_WIDTH(1), .BUDGET(`LUT_WIDTH), .CI(CI)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .P(1'b1), .G(1'b0), .Y(Y)); end @@ -81,12 +78,12 @@ generate assign Y = CO[LCU_WIDTH-1]; end else begin - if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] && _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0]) - localparam COST = 0; - else if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] || _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0]) - localparam COST = 1; - else - localparam COST = 2; + localparam COST = + _TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] && _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0] + ? 0 + : (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] || _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0] + ? 1 + : 2); if (BUDGET < COST) $__CMP2LCU #(.AB_WIDTH(AB_WIDTH), .AB_SIGNED(AB_SIGNED), .LCU_WIDTH(LCU_WIDTH+1), .BUDGET(`LUT_WIDTH), .CI(CI)) @@ -104,21 +101,21 @@ generate // from MSB down, deferring to less significant bits if the // MSBs are equal assign GG = P[0] & (A[AB_WIDTH-1] & ~B[AB_WIDTH-1]); + (* force_downto *) + wire [LCU_WIDTH-1:0] P_, G_; if (LCU_WIDTH == 1) begin // Propagate only if all pairs are equal // (inconclusive evidence to say A >= B) - wire P_ = P[0] & PP; + assign P_ = P[0] & PP; // Generate if any comparisons call for it - wire G_ = G[0] | GG; + assign G_ = G[0] | GG; end else begin // Propagate only if all pairs are equal // (inconclusive evidence to say A >= B) - (* force_downto *) - wire [LCU_WIDTH-1:0] P_ = {P[LCU_WIDTH-1:1], P[0] & PP}; + assign P_ = {P[LCU_WIDTH-1:1], P[0] & PP}; // Generate if any comparisons call for it - (* force_downto *) - wire [LCU_WIDTH-1:0] G_ = {G[LCU_WIDTH-1:1], G[0] | GG}; + assign G_ = {G[LCU_WIDTH-1:1], G[0] | GG}; end if (AB_WIDTH == 1) $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI)) diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v index ec8f98e8d75..c753bd2f1b7 100644 --- a/techlibs/common/cmp2lut.v +++ b/techlibs/common/cmp2lut.v @@ -66,14 +66,12 @@ function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut; endfunction generate - if (_TECHMAP_CELLTYPE_ == "$lt") - localparam operation = 0; - if (_TECHMAP_CELLTYPE_ == "$le") - localparam operation = 1; - if (_TECHMAP_CELLTYPE_ == "$gt") - localparam operation = 2; - if (_TECHMAP_CELLTYPE_ == "$ge") - localparam operation = 3; + localparam operation = + _TECHMAP_CELLTYPE_ == "$lt" ? 0 : + _TECHMAP_CELLTYPE_ == "$le" ? 1 : + _TECHMAP_CELLTYPE_ == "$gt" ? 2 : + _TECHMAP_CELLTYPE_ == "$ge" ? 3 : + -1; if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1) wire _TECHMAP_FAIL_ = 1; diff --git a/techlibs/common/mul2dsp.v b/techlibs/common/mul2dsp.v index bec47d01f9c..f22f47b4a54 100644 --- a/techlibs/common/mul2dsp.v +++ b/techlibs/common/mul2dsp.v @@ -121,7 +121,7 @@ module _80_mul (A, B, Y); localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH_PARTIAL); localparam last_A_WIDTH = A_WIDTH-n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom); localparam last_Y_WIDTH = B_WIDTH+last_A_WIDTH; - if (A_SIGNED && B_SIGNED) begin + if (A_SIGNED && B_SIGNED) begin : blk (* force_downto *) wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; (* force_downto *) @@ -129,7 +129,7 @@ module _80_mul (A, B, Y); (* force_downto *) wire signed [Y_WIDTH-1:0] partial_sum [n:0]; end - else begin + else begin : blk (* force_downto *) wire [partial_Y_WIDTH-1:0] partial [n-1:0]; (* force_downto *) @@ -148,15 +148,15 @@ module _80_mul (A, B, Y); ) mul ( .A({{sign_headroom{1'b0}}, A[i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_A_MAXWIDTH_PARTIAL-sign_headroom]}), .B(B), - .Y(partial[i]) + .Y(blk.partial[i]) ); // TODO: Currently a 'cascade' approach to summing the partial // products is taken here, but a more efficient 'binary // reduction' approach also exists... if (i == 0) - assign partial_sum[i] = partial[i]; + assign blk.partial_sum[i] = blk.partial[i]; else - assign partial_sum[i] = (partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[i-1]; + assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; end \$__mul #( @@ -168,17 +168,17 @@ module _80_mul (A, B, Y); ) sliceA.last ( .A(A[A_WIDTH-1 -: last_A_WIDTH]), .B(B), - .Y(last_partial) + .Y(blk.last_partial) ); - assign partial_sum[n] = (last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[n-1]; - assign Y = partial_sum[n]; + assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; + assign Y = blk.partial_sum[n]; end else if (B_WIDTH > `DSP_B_MAXWIDTH) begin localparam n = (B_WIDTH-`DSP_B_MAXWIDTH+`DSP_B_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH_PARTIAL); localparam last_B_WIDTH = B_WIDTH-n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); localparam last_Y_WIDTH = A_WIDTH+last_B_WIDTH; - if (A_SIGNED && B_SIGNED) begin + if (A_SIGNED && B_SIGNED) begin : blk (* force_downto *) wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; (* force_downto *) @@ -186,7 +186,7 @@ module _80_mul (A, B, Y); (* force_downto *) wire signed [Y_WIDTH-1:0] partial_sum [n:0]; end - else begin + else begin : blk (* force_downto *) wire [partial_Y_WIDTH-1:0] partial [n-1:0]; (* force_downto *) @@ -205,15 +205,15 @@ module _80_mul (A, B, Y); ) mul ( .A(A), .B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_B_MAXWIDTH_PARTIAL-sign_headroom]}), - .Y(partial[i]) + .Y(blk.partial[i]) ); // TODO: Currently a 'cascade' approach to summing the partial // products is taken here, but a more efficient 'binary // reduction' approach also exists... if (i == 0) - assign partial_sum[i] = partial[i]; + assign blk.partial_sum[i] = blk.partial[i]; else - assign partial_sum[i] = (partial[i] << (* mul2dsp *) i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[i-1]; + assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; end \$__mul #( @@ -225,20 +225,24 @@ module _80_mul (A, B, Y); ) mul_sliceB_last ( .A(A), .B(B[B_WIDTH-1 -: last_B_WIDTH]), - .Y(last_partial) + .Y(blk.last_partial) ); - assign partial_sum[n] = (last_partial << (* mul2dsp *) n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[n-1]; - assign Y = partial_sum[n]; + assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; + assign Y = blk.partial_sum[n]; end else begin - if (A_SIGNED) + if (A_SIGNED) begin : blkA wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A); - else + end + else begin : blkA wire [`DSP_A_MAXWIDTH-1:0] Aext = A; - if (B_SIGNED) + end + if (B_SIGNED) begin : blkB wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B); - else + end + else begin : blkB wire [`DSP_B_MAXWIDTH-1:0] Bext = B; + end `DSP_NAME #( .A_SIGNED(A_SIGNED), @@ -247,8 +251,8 @@ module _80_mul (A, B, Y); .B_WIDTH(`DSP_B_MAXWIDTH), .Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)), ) _TECHMAP_REPLACE_ ( - .A(Aext), - .B(Bext), + .A(blkA.Aext), + .B(blkB.Bext), .Y(Y) ); end diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v index ad3bccd21f4..db9f5d8ce59 100644 --- a/techlibs/ice40/brams_map.v +++ b/techlibs/ice40/brams_map.v @@ -254,6 +254,41 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B wire [15:0] A1DATA_16, B1DATA_16; +`define INSTANCE \ + \$__ICE40_RAM4K #( \ + .READ_MODE(MODE), \ + .WRITE_MODE(MODE), \ + .NEGCLK_R(!CLKPOL2), \ + .NEGCLK_W(!CLKPOL3), \ + .INIT_0(INIT_0), \ + .INIT_1(INIT_1), \ + .INIT_2(INIT_2), \ + .INIT_3(INIT_3), \ + .INIT_4(INIT_4), \ + .INIT_5(INIT_5), \ + .INIT_6(INIT_6), \ + .INIT_7(INIT_7), \ + .INIT_8(INIT_8), \ + .INIT_9(INIT_9), \ + .INIT_A(INIT_A), \ + .INIT_B(INIT_B), \ + .INIT_C(INIT_C), \ + .INIT_D(INIT_D), \ + .INIT_E(INIT_E), \ + .INIT_F(INIT_F) \ + ) _TECHMAP_REPLACE_ ( \ + .RDATA(A1DATA_16), \ + .RADDR(A1ADDR_11), \ + .RCLK(CLK2), \ + .RCLKE(A1EN), \ + .RE(1'b1), \ + .WDATA(B1DATA_16), \ + .WADDR(B1ADDR_11), \ + .WCLK(CLK3), \ + .WCLKE(|B1EN), \ + .WE(1'b1) \ + ); + generate if (MODE == 1) begin assign A1DATA = {A1DATA_16[14], A1DATA_16[12], A1DATA_16[10], A1DATA_16[ 8], @@ -261,51 +296,23 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B assign {B1DATA_16[14], B1DATA_16[12], B1DATA_16[10], B1DATA_16[ 8], B1DATA_16[ 6], B1DATA_16[ 4], B1DATA_16[ 2], B1DATA_16[ 0]} = B1DATA; `include "brams_init1.vh" + `INSTANCE end if (MODE == 2) begin assign A1DATA = {A1DATA_16[13], A1DATA_16[9], A1DATA_16[5], A1DATA_16[1]}; assign {B1DATA_16[13], B1DATA_16[9], B1DATA_16[5], B1DATA_16[1]} = B1DATA; `include "brams_init2.vh" + `INSTANCE end if (MODE == 3) begin assign A1DATA = {A1DATA_16[11], A1DATA_16[3]}; assign {B1DATA_16[11], B1DATA_16[3]} = B1DATA; `include "brams_init3.vh" + `INSTANCE end endgenerate - \$__ICE40_RAM4K #( - .READ_MODE(MODE), - .WRITE_MODE(MODE), - .NEGCLK_R(!CLKPOL2), - .NEGCLK_W(!CLKPOL3), - .INIT_0(INIT_0), - .INIT_1(INIT_1), - .INIT_2(INIT_2), - .INIT_3(INIT_3), - .INIT_4(INIT_4), - .INIT_5(INIT_5), - .INIT_6(INIT_6), - .INIT_7(INIT_7), - .INIT_8(INIT_8), - .INIT_9(INIT_9), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .INIT_C(INIT_C), - .INIT_D(INIT_D), - .INIT_E(INIT_E), - .INIT_F(INIT_F) - ) _TECHMAP_REPLACE_ ( - .RDATA(A1DATA_16), - .RADDR(A1ADDR_11), - .RCLK(CLK2), - .RCLKE(A1EN), - .RE(1'b1), - .WDATA(B1DATA_16), - .WADDR(B1ADDR_11), - .WCLK(CLK3), - .WCLKE(|B1EN), - .WE(1'b1) - ); +`undef INSTANCE + endmodule diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index eb8a04bded0..63be7563e8e 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -151,6 +151,8 @@ generate if (`LUT_SIZE == 4) begin ); end endgenerate + assign X = S; + end else begin localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; @@ -193,8 +195,8 @@ end else begin end end endgenerate -end endgenerate - assign X = S; + +end endgenerate endmodule diff --git a/tests/simple/func_block.v b/tests/simple/func_block.v new file mode 100644 index 00000000000..be759d1a95e --- /dev/null +++ b/tests/simple/func_block.v @@ -0,0 +1,33 @@ +`default_nettype none + +module top(inp, out1, out2, out3); + input wire [31:0] inp; + + function automatic [31:0] func1; + input [31:0] inp; + reg [31:0] idx; + for (idx = 0; idx < 32; idx = idx + 1) begin : blk + func1[idx] = (idx & 1'b1) ^ inp[idx]; + end + endfunction + + function automatic [31:0] func2; + input [31:0] inp; + reg [31:0] idx; + for (idx = 0; idx < 32; idx = idx + 1) begin : blk + func2[idx] = (idx & 1'b1) ^ inp[idx]; + end + endfunction + + function automatic [31:0] func3; + localparam A = 32 - 1; + parameter B = 1 - 0; + input [31:0] inp; + func3[A:B] = inp[A:B]; + endfunction + + output wire [31:0] out1, out2, out3; + assign out1 = func1(inp); + assign out2 = func2(inp); + assign out3 = func3(inp); +endmodule diff --git a/tests/simple/func_recurse.v b/tests/simple/func_recurse.v new file mode 100644 index 00000000000..d61c8cc06fc --- /dev/null +++ b/tests/simple/func_recurse.v @@ -0,0 +1,25 @@ +module top( + input wire [3:0] inp, + output wire [3:0] out1, out2 +); + function automatic [3:0] pow_a; + input [3:0] base, exp; + begin + pow_a = 1; + if (exp > 0) + pow_a = base * pow_a(base, exp - 1); + end + endfunction + + function automatic [3:0] pow_b; + input [3:0] base, exp; + begin + pow_b = 1; + if (exp > 0) + pow_b = base * pow_b(base, exp - 1); + end + endfunction + + assign out1 = pow_a(inp, 3); + assign out2 = pow_b(2, 2); +endmodule diff --git a/tests/simple/func_width_scope.v b/tests/simple/func_width_scope.v new file mode 100644 index 00000000000..ce81e894e96 --- /dev/null +++ b/tests/simple/func_width_scope.v @@ -0,0 +1,41 @@ +module top(inp, out1, out2); + input wire signed inp; + + localparam WIDTH_A = 5; + function automatic [WIDTH_A-1:0] func1; + input reg [WIDTH_A-1:0] inp; + func1 = ~inp; + endfunction + wire [func1(0)-1:0] xc; + assign xc = 1'sb1; + wire [WIDTH_A-1:0] xn; + assign xn = func1(inp); + + generate + if (1) begin : blk + localparam WIDTH_A = 6; + function automatic [WIDTH_A-1:0] func2; + input reg [WIDTH_A-1:0] inp; + func2 = ~inp; + endfunction + wire [func2(0)-1:0] yc; + assign yc = 1'sb1; + wire [WIDTH_A-1:0] yn; + assign yn = func2(inp); + + localparam WIDTH_B = 7; + function automatic [WIDTH_B-1:0] func3; + input reg [WIDTH_B-1:0] inp; + func3 = ~inp; + endfunction + wire [func3(0)-1:0] zc; + assign zc = 1'sb1; + wire [WIDTH_B-1:0] zn; + assign zn = func3(inp); + end + endgenerate + + output wire [1023:0] out1, out2; + assign out1 = {xc, 1'b0, blk.yc, 1'b0, blk.zc}; + assign out2 = {xn, 1'b0, blk.yn, 1'b0, blk.zn}; +endmodule diff --git a/tests/simple/genblk_collide.v b/tests/simple/genblk_collide.v new file mode 100644 index 00000000000..f42dd2cfc7b --- /dev/null +++ b/tests/simple/genblk_collide.v @@ -0,0 +1,27 @@ +`default_nettype none + +module top1; + generate + if (1) begin : foo + if (1) begin : bar + wire x; + end + assign bar.x = 1; + wire y; + end + endgenerate +endmodule + +module top2; + genvar i; + generate + if (1) begin : foo + wire x; + for (i = 0; i < 1; i = i + 1) begin : foo + if (1) begin : foo + assign x = 1; + end + end + end + endgenerate +endmodule diff --git a/tests/simple/genblk_dive.v b/tests/simple/genblk_dive.v new file mode 100644 index 00000000000..98d0e1f4bf6 --- /dev/null +++ b/tests/simple/genblk_dive.v @@ -0,0 +1,21 @@ +`default_nettype none +module top(output wire x); + generate + if (1) begin : Z + if (1) begin : A + wire x; + if (1) begin : B + wire x; + if (1) begin : C + wire x; + assign B.x = 0; + wire z = A.B.C.x; + end + assign A.x = A.B.C.x; + end + assign B.C.x = B.x; + end + end + endgenerate + assign x = Z.A.x; +endmodule diff --git a/tests/simple/genblk_order.v b/tests/simple/genblk_order.v new file mode 100644 index 00000000000..7c3a7a756fe --- /dev/null +++ b/tests/simple/genblk_order.v @@ -0,0 +1,18 @@ +`default_nettype none +module top( + output wire out1, + output wire out2 +); + generate + if (1) begin : outer + if (1) begin : foo + wire x = 0; + if (1) begin : foo + wire x = 1; + assign out1 = foo.x; + end + assign out2 = foo.x; + end + end + endgenerate +endmodule diff --git a/tests/simple/generate.v b/tests/simple/generate.v index 12327b36eb8..ac4dd81a8b6 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -260,3 +260,66 @@ module gen_test8; `ASSERT(gen_test8.A.C.x == 1) `ASSERT(gen_test8.A.B.x == 0) endmodule + +// ------------------------------------------ + +module gen_test9; + +// `define VERIFY +`ifdef VERIFY + `define ASSERT(expr) assert property (expr); +`else + `define ASSERT(expr) +`endif + + wire [1:0] w = 2'b11; + generate + begin : A + wire [1:0] x; + begin : B + wire [1:0] y = 2'b00; + `ASSERT(w == 3) + `ASSERT(x == 2) + `ASSERT(y == 0) + `ASSERT(A.x == 2) + `ASSERT(A.C.z == 1) + `ASSERT(A.B.y == 0) + `ASSERT(gen_test9.w == 3) + `ASSERT(gen_test9.A.x == 2) + `ASSERT(gen_test9.A.C.z == 1) + `ASSERT(gen_test9.A.B.y == 0) + end + begin : C + wire [1:0] z = 2'b01; + `ASSERT(w == 3) + `ASSERT(x == 2) + `ASSERT(z == 1) + `ASSERT(A.x == 2) + `ASSERT(A.C.z == 1) + `ASSERT(A.B.y == 0) + `ASSERT(gen_test9.w == 3) + `ASSERT(gen_test9.A.x == 2) + `ASSERT(gen_test9.A.C.z == 1) + `ASSERT(gen_test9.A.B.y == 0) + end + assign x = B.y ^ 2'b11 ^ C.z; + `ASSERT(x == 2) + `ASSERT(A.x == 2) + `ASSERT(A.C.z == 1) + `ASSERT(A.B.y == 0) + `ASSERT(gen_test9.w == 3) + `ASSERT(gen_test9.A.x == 2) + `ASSERT(gen_test9.A.C.z == 1) + `ASSERT(gen_test9.A.B.y == 0) + end + endgenerate + + `ASSERT(w == 3) + `ASSERT(A.x == 2) + `ASSERT(A.C.z == 1) + `ASSERT(A.B.y == 0) + `ASSERT(gen_test9.w == 3) + `ASSERT(gen_test9.A.x == 2) + `ASSERT(gen_test9.A.C.z == 1) + `ASSERT(gen_test9.A.B.y == 0) +endmodule diff --git a/tests/simple/local_loop_var.sv b/tests/simple/local_loop_var.sv new file mode 100644 index 00000000000..46b4e5c229f --- /dev/null +++ b/tests/simple/local_loop_var.sv @@ -0,0 +1,11 @@ +module top(out); + output integer out; + initial begin + integer i; + for (i = 0; i < 5; i = i + 1) + if (i == 0) + out = 1; + else + out += 2 ** i; + end +endmodule diff --git a/tests/simple/loop_var_shadow.v b/tests/simple/loop_var_shadow.v new file mode 100644 index 00000000000..0222a4493d4 --- /dev/null +++ b/tests/simple/loop_var_shadow.v @@ -0,0 +1,15 @@ +module top(out); + genvar i; + generate + for (i = 0; i < 2; i = i + 1) begin : loop + localparam j = i + 1; + if (1) begin : blk + localparam i = j + 1; + wire [i:0] x; + assign x = 1'sb1; + end + end + endgenerate + output wire [63:0] out; + assign out = {loop[0].blk.x, loop[1].blk.x}; +endmodule diff --git a/tests/simple/named_genblk.v b/tests/simple/named_genblk.v new file mode 100644 index 00000000000..b8300fc4dc5 --- /dev/null +++ b/tests/simple/named_genblk.v @@ -0,0 +1,27 @@ +`default_nettype none +module top; + generate + if (1) begin + wire t; + begin : foo + wire x; + end + wire u; + end + begin : bar + wire x; + wire y; + begin : baz + wire x; + wire z; + end + end + endgenerate + assign genblk1.t = 1; + assign genblk1.foo.x = 1; + assign genblk1.u = 1; + assign bar.x = 1; + assign bar.y = 1; + assign bar.baz.x = 1; + assign bar.baz.z = 1; +endmodule diff --git a/tests/simple/nested_genblk_resolve.v b/tests/simple/nested_genblk_resolve.v new file mode 100644 index 00000000000..da5593f8a79 --- /dev/null +++ b/tests/simple/nested_genblk_resolve.v @@ -0,0 +1,14 @@ +`default_nettype none +module top; + generate + if (1) begin + wire x; + genvar i; + for (i = 0; i < 1; i = i + 1) begin + if (1) begin + assign x = 1; + end + end + end + endgenerate +endmodule diff --git a/tests/simple/unnamed_block_decl.sv b/tests/simple/unnamed_block_decl.sv new file mode 100644 index 00000000000..e81b457a88a --- /dev/null +++ b/tests/simple/unnamed_block_decl.sv @@ -0,0 +1,17 @@ +module top(z); + output integer z; + initial begin + integer x; + x = 1; + begin + integer y; + y = x + 1; + begin + integer z; + z = y + 1; + y = z + 1; + end + z = y + 1; + end + end +endmodule diff --git a/tests/various/gen_if_null.v b/tests/various/gen_if_null.v index a12ac628868..992bc68b3df 100644 --- a/tests/various/gen_if_null.v +++ b/tests/various/gen_if_null.v @@ -1,13 +1,17 @@ -module test(x, y, z); +`default_nettype none +module test; localparam OFF = 0; generate if (OFF) ; - else input x; - if (!OFF) input y; + else wire x; + if (!OFF) wire y; else ; if (OFF) ; else ; if (OFF) ; - input z; + wire z; endgenerate + assign genblk1.x = 0; + assign genblk2.y = 0; + assign z = 0; endmodule diff --git a/tests/various/gen_if_null.ys b/tests/various/gen_if_null.ys index 31dfc444b6f..0733e3a945d 100644 --- a/tests/various/gen_if_null.ys +++ b/tests/various/gen_if_null.ys @@ -1,4 +1,4 @@ read_verilog gen_if_null.v -select -assert-count 1 test/x -select -assert-count 1 test/y +select -assert-count 1 test/genblk1.x +select -assert-count 1 test/genblk2.y select -assert-count 1 test/z diff --git a/tests/verilog/bug2493.ys b/tests/verilog/bug2493.ys new file mode 100644 index 00000000000..380d2a82317 --- /dev/null +++ b/tests/verilog/bug2493.ys @@ -0,0 +1,12 @@ +logger -expect error "Failed to detect width for identifier \\genblk1\.y!" 1 +read_verilog < 2) begin + wire tmp; + assign tmp = a_i[g] || b_i[g]; + assign z_o[g] = tmp; + end + else begin + assign z_o[g] = a_i[g] && b_i[g]; + end + end + endgenerate +endmodule diff --git a/tests/verilog/bug656.ys b/tests/verilog/bug656.ys new file mode 100644 index 00000000000..7f367341aac --- /dev/null +++ b/tests/verilog/bug656.ys @@ -0,0 +1,13 @@ +read_verilog bug656.v + +select -assert-count 1 top/a_i +select -assert-count 1 top/b_i +select -assert-count 1 top/z_o + +select -assert-none top/genblk1[0].genblk1.tmp +select -assert-none top/genblk1[1].genblk1.tmp +select -assert-none top/genblk1[2].genblk1.tmp + +select -assert-count 1 top/genblk1[3].genblk1.tmp +select -assert-count 1 top/genblk1[4].genblk1.tmp +select -assert-count 1 top/genblk1[5].genblk1.tmp diff --git a/tests/verilog/genblk_case.v b/tests/verilog/genblk_case.v new file mode 100644 index 00000000000..081fb09d33e --- /dev/null +++ b/tests/verilog/genblk_case.v @@ -0,0 +1,26 @@ +module top; + parameter YES = 1; + generate + if (YES) wire y; + else wire n; + + if (!YES) wire n; + else wire y; + + case (YES) + 1: wire y; + 0: wire n; + endcase + + case (!YES) + 0: wire y; + 1: wire n; + endcase + + if (YES) wire y; + else wire n; + + if (!YES) wire n; + else wire y; + endgenerate +endmodule diff --git a/tests/verilog/genblk_case.ys b/tests/verilog/genblk_case.ys new file mode 100644 index 00000000000..3c1bb51f958 --- /dev/null +++ b/tests/verilog/genblk_case.ys @@ -0,0 +1,15 @@ +read_verilog genblk_case.v + +select -assert-count 0 top/genblk1.n +select -assert-count 0 top/genblk2.n +select -assert-count 0 top/genblk3.n +select -assert-count 0 top/genblk4.n +select -assert-count 0 top/genblk5.n +select -assert-count 0 top/genblk6.n + +select -assert-count 1 top/genblk1.y +select -assert-count 1 top/genblk2.y +select -assert-count 1 top/genblk3.y +select -assert-count 1 top/genblk4.y +select -assert-count 1 top/genblk5.y +select -assert-count 1 top/genblk6.y diff --git a/tests/verilog/hidden_decl.ys b/tests/verilog/hidden_decl.ys new file mode 100644 index 00000000000..aed7847dc43 --- /dev/null +++ b/tests/verilog/hidden_decl.ys @@ -0,0 +1,11 @@ +logger -expect error "Identifier `\\y' is implicitly declared and `default_nettype is set to none" 1 +read_verilog < Date: Mon, 1 Feb 2021 11:23:44 -0800 Subject: [PATCH 0166/2410] Provide an integer implementation of decimal_digits(). Signed-off-by: Henner Zeller --- frontends/aiger/aigerparse.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 2d7c2187e2f..463c5965b94 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -55,8 +55,15 @@ inline int32_t from_big_endian(int32_t i32) { #define log_debug2(...) ; //#define log_debug2(...) log_debug(__VA_ARGS__) -static int decimal_digits(unsigned n) { - return n > 1 ? ceil(log10(n)) : 1; +static int decimal_digits(uint32_t n) { + static uint32_t digit_cutoff[9] = { + 10, 100, 1000, 10000, 100000, + 1000000, 10000000, 100000000, 1000000000 + }; + for (int i = 0; i < 9; ++i) { + if (n < digit_cutoff[i]) return i + 1; + } + return 10; } struct ConstEvalAig From afcc31ceba35d33fc11f9e1592956bb4112ca0e3 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 4 Feb 2021 00:10:05 +0000 Subject: [PATCH 0167/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index beeb6a8f9f8..843ced93592 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3882 +YOSYS_VER := 0.9+3885 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From b93b6f4285243ebbb43ad95769dc2890b6e1e7ab Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 27 Jan 2021 13:21:13 -0500 Subject: [PATCH 0168/2410] verilog: refactored constant function evaluation Elaboration now attempts constant evaluation of any function call with only constant arguments, regardless of the context or contents of the function. This removes the concept of "recommended constant evaluation" which previously applied to functions with `for` loops or which were (sometimes erroneously) identified as recursive. Any function call in a constant context (e.g., `localparam`) or which contains a constant-only procedural construct (`while` or `repeat`) in its body will fail as before if constant evaluation does not succeed. --- frontends/ast/ast.h | 7 +- frontends/ast/simplify.cc | 147 +++++++++++++++++-------------- tests/simple/const_fold_func.v | 61 +++++++++++++ tests/simple/const_func_shadow.v | 33 +++++++ 4 files changed, 176 insertions(+), 72 deletions(-) create mode 100644 tests/simple/const_fold_func.v create mode 100644 tests/simple/const_func_shadow.v diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6f173ca22f2..d8818df31b0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -264,10 +264,9 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; - bool has_const_only_constructs(bool &recommend_const_eval); - bool has_const_only_constructs(std::set& visited, bool &recommend_const_eval); - void replace_variables(std::map &variables, AstNode *fcall); - AstNode *eval_const_function(AstNode *fcall); + bool has_const_only_constructs(); + bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); + AstNode *eval_const_function(AstNode *fcall, bool must_succeed); bool is_simple_const_expr(); std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 77911e96620..402b7257b61 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1218,11 +1218,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_block = this; current_block_child = children[i]; } - if (!in_param_here && type == AST_FCALL) { - bool recommend_const_eval = false; - bool require_const_eval = has_const_only_constructs(recommend_const_eval); - in_param_here = recommend_const_eval || require_const_eval; - } if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK) current_top_block = children[i]; if (i == 0 && child_0_is_self_determined) @@ -3186,10 +3181,9 @@ skip_dynamic_range_lvalue_expansion:; decl->replace_result_wire_name_in_function(str, "$result"); // enables recursion decl->expand_genblock(prefix); - bool recommend_const_eval = false; - bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); - if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count(ID::via_celltype)) + if (decl->type == AST_FUNCTION && !decl->attributes.count(ID::via_celltype)) { + bool require_const_eval = decl->has_const_only_constructs(); bool all_args_const = true; for (auto child : children) { while (child->simplify(true, false, false, 1, -1, false, true)) { } @@ -3200,10 +3194,12 @@ skip_dynamic_range_lvalue_expansion:; if (all_args_const) { AstNode *func_workspace = decl->clone(); func_workspace->str = prefix_id(prefix, "$result"); - newNode = func_workspace->eval_const_function(this); + newNode = func_workspace->eval_const_function(this, in_param || require_const_eval); delete func_workspace; - delete decl; - goto apply_newNode; + if (newNode) { + delete decl; + goto apply_newNode; + } } if (in_param) @@ -4502,33 +4498,12 @@ bool AstNode::detect_latch(const std::string &var) } } -bool AstNode::has_const_only_constructs(bool &recommend_const_eval) +bool AstNode::has_const_only_constructs() { - std::set visited; - return has_const_only_constructs(visited, recommend_const_eval); -} - -bool AstNode::has_const_only_constructs(std::set& visited, bool &recommend_const_eval) -{ - if (type == AST_FUNCTION || type == AST_TASK) - { - if (visited.count(str)) - { - recommend_const_eval = true; - return false; - } - visited.insert(str); - } - - if (type == AST_FOR) - recommend_const_eval = true; if (type == AST_WHILE || type == AST_REPEAT) return true; - if (type == AST_FCALL && current_scope.count(str)) - if (current_scope[str]->has_const_only_constructs(visited, recommend_const_eval)) - return true; for (auto child : children) - if (child->AstNode::has_const_only_constructs(visited, recommend_const_eval)) + if (child->has_const_only_constructs()) return true; return false; } @@ -4544,19 +4519,26 @@ bool AstNode::is_simple_const_expr() } // helper function for AstNode::eval_const_function() -void AstNode::replace_variables(std::map &variables, AstNode *fcall) +bool AstNode::replace_variables(std::map &variables, AstNode *fcall, bool must_succeed) { if (type == AST_IDENTIFIER && variables.count(str)) { int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); if (!children.empty()) { - if (children.size() != 1 || children.at(0)->type != AST_RANGE) + if (children.size() != 1 || children.at(0)->type != AST_RANGE) { + if (!must_succeed) + return false; log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s:%d.%d-%d.%d: ...called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); - children.at(0)->replace_variables(variables, fcall); + } + if (!children.at(0)->replace_variables(variables, fcall, must_succeed)) + return false; while (simplify(true, false, false, 1, -1, false, true)) { } - if (!children.at(0)->range_valid) + if (!children.at(0)->range_valid) { + if (!must_succeed) + return false; log_file_error(filename, location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } offset = min(children.at(0)->range_left, children.at(0)->range_right); width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width); } @@ -4566,19 +4548,22 @@ void AstNode::replace_variables(std::map &varia AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed); newNode->cloneInto(this); delete newNode; - return; + return true; } for (auto &child : children) - child->replace_variables(variables, fcall); + if (!child->replace_variables(variables, fcall, must_succeed)) + return false; + return true; } -// evaluate functions with all-const arguments -AstNode *AstNode::eval_const_function(AstNode *fcall) +// attempt to statically evaluate a functions with all-const arguments +AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) { - std::map backup_scope; + std::map backup_scope = current_scope; std::map variables; AstNode *block = new AstNode(AST_BLOCK); + AstNode *result = nullptr; size_t argidx = 0; for (auto child : children) @@ -4600,9 +4585,12 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) if (stmt->type == AST_WIRE) { while (stmt->simplify(true, false, false, 1, -1, false, true)) { } - if (!stmt->range_valid) + if (!stmt->range_valid) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", stmt->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } variables[stmt->str].val = RTLIL::Const(RTLIL::State::Sx, abs(stmt->range_left - stmt->range_right)+1); variables[stmt->str].offset = min(stmt->range_left, stmt->range_right); variables[stmt->str].is_signed = stmt->is_signed; @@ -4616,8 +4604,6 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) variables[stmt->str].val = arg_node->realAsConst(width); } } - if (!backup_scope.count(stmt->str)) - backup_scope[stmt->str] = current_scope[stmt->str]; current_scope[stmt->str] = stmt; block->children.erase(block->children.begin()); @@ -4630,8 +4616,6 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { while (stmt->simplify(true, false, false, 1, -1, false, true)) { } - if (!backup_scope.count(stmt->str)) - backup_scope[stmt->str] = current_scope[stmt->str]; current_scope[stmt->str] = stmt; block->children.erase(block->children.begin()); @@ -4642,32 +4626,46 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 && stmt->children.at(0)->children.at(0)->type == AST_RANGE) - stmt->children.at(0)->children.at(0)->replace_variables(variables, fcall); - stmt->children.at(1)->replace_variables(variables, fcall); + if (!stmt->children.at(0)->children.at(0)->replace_variables(variables, fcall, must_succeed)) + goto finished; + if (!stmt->children.at(1)->replace_variables(variables, fcall, must_succeed)) + goto finished; while (stmt->simplify(true, false, false, 1, -1, false, true)) { } if (stmt->type != AST_ASSIGN_EQ) continue; - if (stmt->children.at(1)->type != AST_CONSTANT) + if (stmt->children.at(1)->type != AST_CONSTANT) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here. X\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } - if (stmt->children.at(0)->type != AST_IDENTIFIER) + if (stmt->children.at(0)->type != AST_IDENTIFIER) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } - if (!variables.count(stmt->children.at(0)->str)) + if (!variables.count(stmt->children.at(0)->str)) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } if (stmt->children.at(0)->children.empty()) { variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); } else { AstNode *range = stmt->children.at(0)->children.at(0); - if (!range->range_valid) + if (!range->range_valid) { + if (!must_succeed) + goto finished; log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } int offset = min(range->range_left, range->range_right); int width = std::abs(range->range_left - range->range_right) + 1; varinfo_t &v = variables[stmt->children.at(0)->str]; @@ -4694,12 +4692,16 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) if (stmt->type == AST_WHILE) { AstNode *cond = stmt->children.at(0)->clone(); - cond->replace_variables(variables, fcall); + if (!cond->replace_variables(variables, fcall, must_succeed)) + goto finished; while (cond->simplify(true, false, false, 1, -1, false, true)) { } - if (cond->type != AST_CONSTANT) + if (cond->type != AST_CONSTANT) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } if (cond->asBool()) { block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); @@ -4715,12 +4717,16 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) if (stmt->type == AST_REPEAT) { AstNode *num = stmt->children.at(0)->clone(); - num->replace_variables(variables, fcall); + if (!num->replace_variables(variables, fcall, must_succeed)) + goto finished; while (num->simplify(true, false, false, 1, -1, false, true)) { } - if (num->type != AST_CONSTANT) + if (num->type != AST_CONSTANT) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } block->children.erase(block->children.begin()); for (int i = 0; i < num->bitsAsConst().as_int(); i++) @@ -4734,7 +4740,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) if (stmt->type == AST_CASE) { AstNode *expr = stmt->children.at(0)->clone(); - expr->replace_variables(variables, fcall); + if (!expr->replace_variables(variables, fcall, must_succeed)) + goto finished; while (expr->simplify(true, false, false, 1, -1, false, true)) { } AstNode *sel_case = NULL; @@ -4751,14 +4758,18 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++) { AstNode *cond = stmt->children.at(i)->children.at(j)->clone(); - cond->replace_variables(variables, fcall); + if (!cond->replace_variables(variables, fcall, must_succeed)) + goto finished; cond = new AstNode(AST_EQ, expr->clone(), cond); while (cond->simplify(true, false, false, 1, -1, false, true)) { } - if (cond->type != AST_CONSTANT) + if (cond->type != AST_CONSTANT) { + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + } found_match = cond->asBool(); delete cond; @@ -4790,20 +4801,20 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (!must_succeed) + goto finished; log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); log_abort(); } - delete block; + result = AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); - for (auto &it : backup_scope) - if (it.second == NULL) - current_scope.erase(it.first); - else - current_scope[it.first] = it.second; +finished: + delete block; + current_scope = backup_scope; - return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); + return result; } void AstNode::allocateDefaultEnumValues() diff --git a/tests/simple/const_fold_func.v b/tests/simple/const_fold_func.v new file mode 100644 index 00000000000..ee2f12e0689 --- /dev/null +++ b/tests/simple/const_fold_func.v @@ -0,0 +1,61 @@ +module top( + input wire [3:0] inp, + output wire [3:0] out1, out2, out3, out4, out5, + output reg [3:0] out6 +); + function automatic [3:0] flip; + input [3:0] inp; + flip = ~inp; + endfunction + + function automatic [3:0] help; + input [3:0] inp; + help = flip(inp); + endfunction + + // while loops are const-eval-only + function automatic [3:0] loop; + input [3:0] inp; + reg [3:0] val; + begin + val = inp; + loop = 1; + while (val != inp) begin + loop = loop * 2; + val = val + 1; + end + end + endfunction + + // not const-eval-only, despite calling a const-eval-only function + function automatic [3:0] help_mul; + input [3:0] inp; + help_mul = inp * loop(2); + endfunction + + // can be elaborated so long as exp is a constant + function automatic [3:0] pow_flip_a; + input [3:0] base, exp; + begin + pow_flip_a = 1; + if (exp > 0) + pow_flip_a = base * pow_flip_a(flip(base), exp - 1); + end + endfunction + + function automatic [3:0] pow_flip_b; + input [3:0] base, exp; + begin + out6[exp] = base & 1; + pow_flip_b = 1; + if (exp > 0) + pow_flip_b = base * pow_flip_b(flip(base), exp - 1); + end + endfunction + + assign out1 = flip(flip(inp)); + assign out2 = help(flip(inp)); + assign out3 = help_mul(inp); + assign out4 = pow_flip_a(flip(inp), 3); + assign out5 = pow_flip_b(2, 2); +endmodule diff --git a/tests/simple/const_func_shadow.v b/tests/simple/const_func_shadow.v new file mode 100644 index 00000000000..ca63606d95d --- /dev/null +++ b/tests/simple/const_func_shadow.v @@ -0,0 +1,33 @@ +module top(w, x, y, z); + function [11:0] func; + input reg [2:0] x; + input reg [2:0] y; + begin + x = x * (y + 1); + begin : foo + reg [2:0] y; + y = x + 1; + begin : bar + reg [2:0] x; + x = y + 1; + begin : blah + reg [2:0] y; + y = x + 1; + func[2:0] = y; + end + func[5:3] = x; + end + func[8:6] = y; + end + func[11:9] = x; + end + endfunction + output wire [func(2, 3) - 1:0] w; + output wire [func(1, 3) - 1:0] x; + output wire [func(3, 1) - 1:0] y; + output wire [func(5, 2) - 1:0] z; + assign w = 1'sb1; + assign x = 1'sb1; + assign y = 1'sb1; + assign z = 1'sb1; +endmodule From 98c4feb72ff52f12aadd34b0deccb819d701ff2c Mon Sep 17 00:00:00 2001 From: Kamil Rakoczy Date: Thu, 4 Feb 2021 12:12:59 +0100 Subject: [PATCH 0169/2410] Add check of begin/end labels for genblock Signed-off-by: Kamil Rakoczy --- frontends/verilog/verilog_parser.y | 2 ++ tests/verilog/block_labels.ys | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/verilog/block_labels.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 6255a4204d0..fb5846f7b58 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2794,6 +2794,8 @@ gen_block: ast_stack.push_back(node); } module_gen_body TOK_END opt_label { exitTypeScope(); + if ($3 != NULL && $7 != NULL && *$3 != *$7) + frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1); delete $3; delete $7; SET_AST_NODE_LOC(ast_stack.back(), @1, @7); diff --git a/tests/verilog/block_labels.ys b/tests/verilog/block_labels.ys new file mode 100644 index 00000000000..e76bcf771a8 --- /dev/null +++ b/tests/verilog/block_labels.ys @@ -0,0 +1,26 @@ +read_verilog < Date: Thu, 4 Feb 2021 15:35:35 -0600 Subject: [PATCH 0170/2410] Accept disable case for SVA liveness properties. --- frontends/verific/verificsva.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 632043b6f09..1f5da1b1d95 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1759,6 +1759,11 @@ struct VerificSvaImporter clocking.addDff(NEW_ID, sig_en, sig_en_q, State::S0); } + // accept in disable case + + if (clocking.disable_sig != State::S0) + sig_a_q = module->Or(NEW_ID, sig_a_q, clocking.disable_sig); + // generate fair/live cell RTLIL::Cell *c = nullptr; From 7c6bf42db8cf8e269b04591a80d8e085e072059a Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Fri, 5 Feb 2021 00:10:05 +0000 Subject: [PATCH 0171/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 843ced93592..af76bca37a3 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3885 +YOSYS_VER := 0.9+3888 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 2f64f96129e09b2efb02d741839549c472fd350a Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sat, 6 Feb 2021 00:10:05 +0000 Subject: [PATCH 0172/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index af76bca37a3..f0a8dc43843 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3888 +YOSYS_VER := 0.9+3891 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4b2f97733104c4e68dfdb0d89c1b03da137010c4 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 5 Feb 2021 19:38:10 -0500 Subject: [PATCH 0173/2410] genrtlil: fix signed port connection codegen failures This fixes binding signed memory reads, signed unary expressions, and signed complex SigSpecs to ports. This also sets `is_signed` for wires generated from signed params when -pwires is used. Though not necessary for any of the current usages, `is_signed` is now appropriately set when the `extendWidth` helper is used. --- frontends/ast/genrtlil.cc | 6 +++++- tests/various/port_sign_extend.v | 22 ++++++++++++++++++---- tests/various/port_sign_extend.ys | 13 ++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b8bfdf65e84..24f5e1bef90 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -49,6 +49,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + wire->is_signed = that->is_signed; if (gen_attributes) for (auto &attr : that->attributes) { @@ -80,6 +81,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + wire->is_signed = that->is_signed; if (that != NULL) for (auto &attr : that->attributes) { @@ -1050,6 +1052,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Const val = children[0]->bitsAsConst(); RTLIL::Wire *wire = current_module->addWire(str, GetSize(val)); current_module->connect(wire, val); + wire->is_signed = children[0]->is_signed; wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); wire->attributes[type == AST_PARAMETER ? ID::parameter : ID::localparam] = 1; @@ -1551,6 +1554,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int mem_width, mem_size, addr_bits; is_signed = id2ast->is_signed; + wire->is_signed = is_signed; id2ast->meminfo(mem_width, mem_size, addr_bits); RTLIL::SigSpec addr_sig = children[0]->genRTLIL(); @@ -1740,7 +1744,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // non-trivial signed nodes are indirected through // signed wires to enable sign extension RTLIL::IdString wire_name = NEW_ID; - RTLIL::Wire *wire = current_module->addWire(wire_name, arg->bits.size()); + RTLIL::Wire *wire = current_module->addWire(wire_name, GetSize(sig)); wire->is_signed = true; current_module->connect(wire, sig); sig = wire; diff --git a/tests/various/port_sign_extend.v b/tests/various/port_sign_extend.v index 44626826872..813ceb50312 100644 --- a/tests/various/port_sign_extend.v +++ b/tests/various/port_sign_extend.v @@ -24,8 +24,8 @@ module PassThrough(a, b); assign b = a; endmodule -module act(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); - output wire [3:0] o1, o2, o3, o4, o5, o6; +module act(o1, o2, o3, o4, o5, o6, o7, o8, o9, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5, o6, o7, o8, o9; // unsigned constant PassThrough pt1(1'b1, o1); @@ -52,6 +52,17 @@ module act(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); wire signed [2:0] tmp6b = 3'b001; PassThrough pt6(tmp6a ? tmp6a : tmp6b, o6); + wire signed [2:0] tmp7 = 3'b011; + PassThrough pt7(~tmp7, o7); + + reg signed [2:0] tmp8 [0:0]; + initial tmp8[0] = 3'b101; + PassThrough pt8(tmp8[0], o8); + + wire signed [2:0] tmp9a = 3'b100; + wire signed [1:0] tmp9b = 2'b11; + PassThrough pt9(0 ? tmp9a : tmp9b, o9); + output wire [2:0] yay1, nay1; GeneratorSigned1 os1(yay1); GeneratorUnsigned1 ou1(nay1); @@ -61,8 +72,8 @@ module act(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); GeneratorUnsigned2 ou2(nay2); endmodule -module ref(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); - output wire [3:0] o1, o2, o3, o4, o5, o6; +module ref(o1, o2, o3, o4, o5, o6, o7, o8, o9, yay1, nay1, yay2, nay2); + output wire [3:0] o1, o2, o3, o4, o5, o6, o7, o8, o9; assign o1 = 4'b0001; assign o2 = 4'b0001; @@ -70,6 +81,9 @@ module ref(o1, o2, o3, o4, o5, o6, yay1, nay1, yay2, nay2); assign o4 = 4'b1111; assign o5 = 4'b1110; assign o6 = 4'b1100; + assign o7 = 4'b1100; + assign o8 = 4'b1101; + assign o9 = 4'b1111; output wire [2:0] yay1, nay1; assign yay1 = 3'b111; diff --git a/tests/various/port_sign_extend.ys b/tests/various/port_sign_extend.ys index 0a6a9381038..6d1adf7f350 100644 --- a/tests/various/port_sign_extend.ys +++ b/tests/various/port_sign_extend.ys @@ -1,22 +1,29 @@ -read_verilog port_sign_extend.v +read_verilog -nomem2reg port_sign_extend.v hierarchy flatten +proc +memory equiv_make ref act equiv equiv_simple equiv_status -assert delete -read_verilog port_sign_extend.v +read_verilog -nomem2reg port_sign_extend.v flatten +proc +memory equiv_make ref act equiv equiv_simple equiv_status -assert delete -read_verilog port_sign_extend.v +read_verilog -nomem2reg port_sign_extend.v hierarchy +proc +memory equiv_make ref act equiv prep -flatten -top equiv +equiv_induct equiv_status -assert From eff18a2b1519428b11400979f116342086c13e13 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sun, 7 Feb 2021 00:10:04 +0000 Subject: [PATCH 0174/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f0a8dc43843..794965655b0 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3891 +YOSYS_VER := 0.9+3894 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1d5f3fe5064146955dafdabafe7180ff79c95d08 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 6 Feb 2021 23:54:17 -0500 Subject: [PATCH 0175/2410] verlog: allow shadowing module ports within generate blocks This is a somewhat obscure edge case I encountered while working on test cases for earlier changes. Declarations in generate blocks should not be checked against the list of ports. This change also adds a check forbidding declarations within generate blocks being tagged as inputs or outputs. --- frontends/verilog/verilog_parser.y | 11 +++++++---- tests/simple/genblk_port_shadow.v | 10 ++++++++++ tests/verilog/genblk_port_decl.ys | 12 ++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 tests/simple/genblk_port_shadow.v create mode 100644 tests/verilog/genblk_port_decl.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index fb5846f7b58..0aae253533a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1784,7 +1784,13 @@ wire_name: } rewriteAsMemoryNode(node, $2); } - if (current_function_or_task == NULL) { + if (current_function_or_task) { + if (node->is_input || node->is_output) + node->port_id = current_function_or_task_port_id++; + } else if (ast_stack.back()->type == AST_GENBLOCK) { + if (node->is_input || node->is_output) + frontend_verilog_yyerror("Cannot declare module port `%s' within a generate block.", $1->c_str()); + } else { if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) { port_stubs[*$1] = ++port_counter; } @@ -1799,9 +1805,6 @@ wire_name: if (node->is_input || node->is_output) frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str()); } - } else { - if (node->is_input || node->is_output) - node->port_id = current_function_or_task_port_id++; } //FIXME: for some reason, TOK_ID has a location which always points to one column *after* the real last column... SET_AST_NODE_LOC(node, @1, @1); diff --git a/tests/simple/genblk_port_shadow.v b/tests/simple/genblk_port_shadow.v new file mode 100644 index 00000000000..a04631a209f --- /dev/null +++ b/tests/simple/genblk_port_shadow.v @@ -0,0 +1,10 @@ +module top(x); + generate + if (1) begin : blk + wire x; + assign x = 0; + end + endgenerate + output wire x; + assign x = blk.x; +endmodule diff --git a/tests/verilog/genblk_port_decl.ys b/tests/verilog/genblk_port_decl.ys new file mode 100644 index 00000000000..589d3d2e107 --- /dev/null +++ b/tests/verilog/genblk_port_decl.ys @@ -0,0 +1,12 @@ +logger -expect error "Cannot declare module port `\\x' within a generate block\." 1 +read_verilog < Date: Thu, 11 Feb 2021 12:53:07 +0100 Subject: [PATCH 0176/2410] Add missing is_signed to type_atom Signed-off-by: Kamil Rakoczy --- frontends/verilog/verilog_parser.y | 8 ++++---- tests/verilog/atom_type_signedness.ys | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 tests/verilog/atom_type_signedness.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index fb5846f7b58..69fd66cba18 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1491,10 +1491,10 @@ enum_base_type: type_atom type_signing | %empty { astbuf1->is_reg = true; addRange(astbuf1); } ; -type_atom: TOK_INTEGER { astbuf1->is_reg = true; addRange(astbuf1); } // 4-state signed - | TOK_INT { astbuf1->is_reg = true; addRange(astbuf1); } // 2-state signed - | TOK_SHORTINT { astbuf1->is_reg = true; addRange(astbuf1, 15, 0); } // 2-state signed - | TOK_BYTE { astbuf1->is_reg = true; addRange(astbuf1, 7, 0); } // 2-state signed +type_atom: TOK_INTEGER { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 4-state signed + | TOK_INT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 2-state signed + | TOK_SHORTINT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 15, 0); } // 2-state signed + | TOK_BYTE { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 7, 0); } // 2-state signed ; type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned diff --git a/tests/verilog/atom_type_signedness.ys b/tests/verilog/atom_type_signedness.ys new file mode 100644 index 00000000000..22bbe6efc2f --- /dev/null +++ b/tests/verilog/atom_type_signedness.ys @@ -0,0 +1,19 @@ +read_verilog -dump_ast1 -dump_ast2 -sv < Date: Fri, 12 Feb 2021 00:10:05 +0000 Subject: [PATCH 0177/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 794965655b0..94f7a217d11 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3894 +YOSYS_VER := 0.9+3901 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 13c2fd7137df6c69851452bdf3e459036e555fe4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 12 Feb 2021 10:08:43 +0100 Subject: [PATCH 0178/2410] Ganulate Verific support --- frontends/verific/verific.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 81e14ac4145..7aa3ebcbb81 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -49,13 +49,16 @@ USING_YOSYS_NAMESPACE #include "VeriWrite.h" #include "VhdlUnits.h" #include "VeriLibrary.h" + +#if defined(YOSYSHQ_VERIFIC_INITSTATE) || defined(YOSYSHQ_VERIFIC_TEMPLATES) || defined(YOSYSHQ_VERIFIC_FORMALAPPS) #include "VeriExtensions.h" +#endif #ifndef YOSYSHQ_VERIFIC_API_VERSION # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210101 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210103 # error "Please update your version of YosysHQ flavored Verific." #endif @@ -1471,6 +1474,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se continue; } +#ifdef YOSYSHQ_VERIFIC_INITSTATE if (inst->Type() == PRIM_YOSYSHQ_INITSTATE) { SigBit initstate = module->Initstate(new_verific_id(inst)); @@ -1480,7 +1484,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se if (!mode_keep) continue; } - +#endif if (!mode_keep && verific_sva_prims.count(inst->Type())) { if (verific_verbose) log(" skipping SVA cell in non k-mode\n"); @@ -1958,9 +1962,10 @@ void verific_import(Design *design, const std::map &par for (const auto &i : parameters) verific_params.Insert(i.first.c_str(), i.second.c_str()); +#ifdef YOSYSHQ_VERIFIC_INITSTATE InitialAssertionRewriter rw; rw.RegisterCallBack(); - +#endif if (top.empty()) { netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, &verific_params); } @@ -2217,7 +2222,7 @@ struct VerificPass : public Pass { log("\n"); log("Applications:\n"); log("\n"); -#ifdef YOSYS_ENABLE_VERIFIC +#if defined(YOSYS_ENABLE_VERIFIC) && defined(YOSYSHQ_VERIFIC_FORMALAPPS) VerificFormalApplications vfa; log("%s\n",vfa.GetHelp().c_str()); #else @@ -2243,7 +2248,7 @@ struct VerificPass : public Pass { log("\n"); log("Templates:\n"); log("\n"); -#ifdef YOSYS_ENABLE_VERIFIC +#if defined(YOSYS_ENABLE_VERIFIC) && defined(YOSYSHQ_VERIFIC_TEMPLATES) VerificTemplateGenerator vfg; log("%s\n",vfg.GetHelp().c_str()); #else @@ -2494,6 +2499,7 @@ struct VerificPass : public Pass { goto check_error; } +#ifdef YOSYSHQ_VERIFIC_FORMALAPPS if (argidx < GetSize(args) && args[argidx] == "-app") { if (!(argidx+1 < GetSize(args))) @@ -2587,7 +2593,7 @@ struct VerificPass : public Pass { } goto check_error; } - +#endif if (argidx < GetSize(args) && args[argidx] == "-pp") { const char* filename = nullptr; @@ -2630,6 +2636,7 @@ struct VerificPass : public Pass { goto check_error; } +#ifdef YOSYSHQ_VERIFIC_TEMPLATES if (argidx < GetSize(args) && args[argidx] == "-template") { if (!(argidx+1 < GetSize(args))) @@ -2713,7 +2720,7 @@ struct VerificPass : public Pass { fclose(of); goto check_error; } - +#endif if (GetSize(args) > argidx && args[argidx] == "-import") { std::set nl_todo, nl_done; @@ -2798,9 +2805,10 @@ struct VerificPass : public Pass { std::set top_mod_names; +#ifdef YOSYSHQ_VERIFIC_INITSTATE InitialAssertionRewriter rw; rw.RegisterCallBack(); - +#endif if (mode_all) { log("Running hier_tree::ElaborateAll().\n"); From 8de2e863af4233aca0a0ca0eef4477d216f7a227 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 12 Feb 2021 14:25:34 -0500 Subject: [PATCH 0179/2410] verilog: support recursive functions using ternary expressions This adds a mechanism for marking certain portions of elaboration as occurring within unevaluated ternary branches. To enable elaboration of the overall ternary, this also adds width detection for these unelaborated function calls. --- frontends/ast/ast.h | 3 ++ frontends/ast/genrtlil.cc | 35 +++++++++++++ frontends/ast/simplify.cc | 100 ++++++++++++++++++++++++++++++-------- tests/various/fib_tern.v | 70 ++++++++++++++++++++++++++ tests/various/fib_tern.ys | 6 +++ 5 files changed, 195 insertions(+), 19 deletions(-) create mode 100644 tests/various/fib_tern.v create mode 100644 tests/various/fib_tern.ys diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index d8818df31b0..8cc7b474f89 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -270,6 +270,9 @@ namespace AST bool is_simple_const_expr(); std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint); + bool is_recursive_function() const; + std::pair get_tern_choice(); + // create a human-readable text representation of the AST (for debugging) void dumpAst(FILE *f, std::string indent) const; void dumpVlog(FILE *f, std::string indent) const; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 24f5e1bef90..713e34eb1b4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -944,6 +944,41 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun } break; } + if (current_scope.count(str)) + { + // This width detection is needed for function calls which are + // unelaborated, which currently only applies to calls to recursive + // functions reached by unevaluated ternary branches. + const AstNode *func = current_scope.at(str); + if (func->type != AST_FUNCTION) + log_file_error(filename, location.first_line, "Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str()); + const AstNode *wire = nullptr; + for (const AstNode *child : func->children) + if (child->str == func->str) { + wire = child; + break; + } + log_assert(wire && wire->type == AST_WIRE); + sign_hint = wire->is_signed; + width_hint = 1; + if (!wire->children.empty()) + { + log_assert(wire->children.size() == 1); + const AstNode *range = wire->children.at(0); + log_assert(range->type == AST_RANGE && range->children.size() == 2); + AstNode *left = range->children.at(0)->clone(); + AstNode *right = range->children.at(1)->clone(); + while (left->simplify(true, false, false, 1, -1, false, true)) { } + while (right->simplify(true, false, false, 1, -1, false, true)) { } + if (left->type != AST_CONSTANT || right->type != AST_CONSTANT) + log_file_error(filename, location.first_line, "Function %s has non-constant width!", + RTLIL::unescape_id(str).c_str()); + width_hint = abs(int(left->asInt(true) - right->asInt(true))); + delete left; + delete right; + } + break; + } YS_FALLTHROUGH // everything should have been handled above -> print error if not. diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 402b7257b61..3c315f7ff42 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -575,6 +575,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, deep_recursion_warning = false; } + static bool unevaluated_tern_branch = false; + AstNode *newNode = NULL; bool did_something = false; @@ -1091,7 +1093,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, break; case AST_TERNARY: - detect_width_simple = true; child_0_is_self_determined = true; break; @@ -1124,6 +1125,24 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, detectSignWidth(width_hint, sign_hint); if (type == AST_TERNARY) { + if (width_hint < 0) { + while (!children[0]->basic_prep && children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param)) + did_something = true; + + bool backup_unevaluated_tern_branch = unevaluated_tern_branch; + AstNode *chosen = get_tern_choice().first; + + unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[2]; + while (!children[1]->basic_prep && children[1]->simplify(false, false, in_lvalue, stage, -1, false, in_param)) + did_something = true; + + unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[1]; + while (!children[2]->basic_prep && children[2]->simplify(false, false, in_lvalue, stage, -1, false, in_param)) + did_something = true; + + unevaluated_tern_branch = backup_unevaluated_tern_branch; + detectSignWidth(width_hint, sign_hint); + } int width_hint_left, width_hint_right; bool sign_hint_left, sign_hint_right; bool found_real_left, found_real_right; @@ -1187,6 +1206,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { bool did_something_here = true; bool backup_flag_autowire = flag_autowire; + bool backup_unevaluated_tern_branch = unevaluated_tern_branch; if ((type == AST_GENFOR || type == AST_FOR) && i >= 3) break; if ((type == AST_GENIF || type == AST_GENCASE) && i >= 1) @@ -1199,6 +1219,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, break; if (type == AST_DEFPARAM && i == 0) flag_autowire = true; + if (type == AST_TERNARY && i > 0 && !unevaluated_tern_branch) { + AstNode *chosen = get_tern_choice().first; + unevaluated_tern_branch = chosen && chosen != children[i]; + } while (did_something_here && i < children.size()) { bool const_fold_here = const_fold, in_lvalue_here = in_lvalue; int width_hint_here = width_hint; @@ -1238,6 +1262,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; } flag_autowire = backup_flag_autowire; + unevaluated_tern_branch = backup_unevaluated_tern_branch; } for (auto &attr : attributes) { while (attr.second->simplify(true, false, false, stage, -1, false, true)) @@ -3177,6 +3202,8 @@ skip_dynamic_range_lvalue_expansion:; std::string prefix = sstr.str(); AstNode *decl = current_scope[str]; + if (unevaluated_tern_branch && decl->is_recursive_function()) + goto replace_fcall_later; decl = decl->clone(); decl->replace_result_wire_name_in_function(str, "$result"); // enables recursion decl->expand_genblock(prefix); @@ -3610,24 +3637,9 @@ replace_fcall_later:; case AST_TERNARY: if (children[0]->isConst()) { - bool found_sure_true = false; - bool found_maybe_true = false; - - if (children[0]->type == AST_CONSTANT) - for (auto &bit : children[0]->bits) { - if (bit == RTLIL::State::S1) - found_sure_true = true; - if (bit > RTLIL::State::S1) - found_maybe_true = true; - } - else - found_sure_true = children[0]->asReal(sign_hint) != 0; - - AstNode *choice = NULL, *not_choice = NULL; - if (found_sure_true) - choice = children[1], not_choice = children[2]; - else if (!found_maybe_true) - choice = children[2], not_choice = children[1]; + auto pair = get_tern_choice(); + AstNode *choice = pair.first; + AstNode *not_choice = pair.second; if (choice != NULL) { if (choice->type == AST_CONSTANT) { @@ -4845,4 +4857,54 @@ void AstNode::allocateDefaultEnumValues() } } +bool AstNode::is_recursive_function() const +{ + std::set visited; + std::function visit = [&](const AstNode *node) { + if (visited.count(node)) + return node == this; + visited.insert(node); + if (node->type == AST_FCALL) { + auto it = current_scope.find(node->str); + if (it != current_scope.end() && visit(it->second)) + return true; + } + for (const AstNode *child : node->children) { + if (visit(child)) + return true; + } + return false; + }; + + log_assert(type == AST_FUNCTION); + return visit(this); +} + +std::pair AstNode::get_tern_choice() +{ + if (!children[0]->isConst()) + return {}; + + bool found_sure_true = false; + bool found_maybe_true = false; + + if (children[0]->type == AST_CONSTANT) + for (auto &bit : children[0]->bits) { + if (bit == RTLIL::State::S1) + found_sure_true = true; + if (bit > RTLIL::State::S1) + found_maybe_true = true; + } + else + found_sure_true = children[0]->asReal(true) != 0; + + AstNode *choice = nullptr, *not_choice = nullptr; + if (found_sure_true) + choice = children[1], not_choice = children[2]; + else if (!found_maybe_true) + choice = children[2], not_choice = children[1]; + + return {choice, not_choice}; +} + YOSYS_NAMESPACE_END diff --git a/tests/various/fib_tern.v b/tests/various/fib_tern.v new file mode 100644 index 00000000000..fefde74cebd --- /dev/null +++ b/tests/various/fib_tern.v @@ -0,0 +1,70 @@ +module gate( + off, fib0, fib1, fib2, fib3, fib4, fib5, fib6, fib7, fib8, fib9 +); + input wire signed [31:0] off; + + function automatic blah( + input x + ); + blah = x; + endfunction + + function automatic integer fib( + input integer k + ); + fib = k == 0 + ? 0 + : k == 1 + ? 1 + : fib(k - 1) + fib(k - 2); + endfunction + + function automatic integer fib_wrap( + input integer k, + output integer o + ); + o = off + fib(k); + endfunction + + output integer fib0; + output integer fib1; + output integer fib2; + output integer fib3; + output integer fib4; + output integer fib5; + output integer fib6; + output integer fib7; + output integer fib8; + output integer fib9; + + initial begin : blk + integer unused; + unused = fib_wrap(0, fib0); + unused = fib_wrap(1, fib1); + unused = fib_wrap(2, fib2); + unused = fib_wrap(3, fib3); + unused = fib_wrap(4, fib4); + unused = fib_wrap(5, fib5); + unused = fib_wrap(6, fib6); + unused = fib_wrap(7, fib7); + unused = fib_wrap(8, fib8); + unused = fib_wrap(9, fib9); + end +endmodule + +module gold( + off, fib0, fib1, fib2, fib3, fib4, fib5, fib6, fib7, fib8, fib9 +); + input wire signed [31:0] off; + + output integer fib0 = off + 0; + output integer fib1 = off + 1; + output integer fib2 = off + 1; + output integer fib3 = off + 2; + output integer fib4 = off + 3; + output integer fib5 = off + 5; + output integer fib6 = off + 8; + output integer fib7 = off + 13; + output integer fib8 = off + 21; + output integer fib9 = off + 34; +endmodule diff --git a/tests/various/fib_tern.ys b/tests/various/fib_tern.ys new file mode 100644 index 00000000000..e5bf186e1aa --- /dev/null +++ b/tests/various/fib_tern.ys @@ -0,0 +1,6 @@ +read_verilog fib_tern.v +hierarchy +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From 4e741adda976260f620e5787d6db3cb28e0e35e7 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Sat, 13 Feb 2021 00:10:04 +0000 Subject: [PATCH 0180/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 94f7a217d11..809251be30c 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3901 +YOSYS_VER := 0.9+3905 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 78684596dcd6e5c62d020d13480ed6d081c865bd Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Tue, 16 Feb 2021 00:10:06 +0000 Subject: [PATCH 0181/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 809251be30c..baffc53eaab 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3905 +YOSYS_VER := 0.9+3908 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1d79222af48399051b038ca8ec3052977e933d4a Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Tue, 16 Feb 2021 16:34:09 -0800 Subject: [PATCH 0182/2410] Fixes command line for abc pass in -fast -sop mode --- passes/techmap/abc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 1169e3da020..d5286f4e9ab 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -38,7 +38,7 @@ #define ABC_FAST_COMMAND_LIB "strash; dretime; map {D}" #define ABC_FAST_COMMAND_CTR "strash; dretime; map {D}; buffer; upsize {D}; dnsize {D}; stime -p" #define ABC_FAST_COMMAND_LUT "strash; dretime; if" -#define ABC_FAST_COMMAND_SOP "strash; dretime; cover -I {I} -P {P}" +#define ABC_FAST_COMMAND_SOP "strash; dretime; cover {I} {P}" #define ABC_FAST_COMMAND_DFL "strash; dretime; map" #include "kernel/register.h" From 127484e675538fbaeca1f6e53ba264a1f02e9cf6 Mon Sep 17 00:00:00 2001 From: Yosys Bot Date: Thu, 18 Feb 2021 00:10:06 +0000 Subject: [PATCH 0183/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index baffc53eaab..1f255a5eaee 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3908 +YOSYS_VER := 0.9+3911 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 220cb1f7bbf6405117b953526c50a21a5ef5788f Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 18 Feb 2021 12:04:02 -0500 Subject: [PATCH 0184/2410] verilog: error on macro invocations with missing argument lists This would previously complain about an undefined internal macro if the unapplied macro had not already been used. If it had, it would incorrectly use the arguments from the previous invocation. --- frontends/verilog/preproc.cc | 11 ++++++++++- tests/verilog/macro_unapplied.ys | 17 +++++++++++++++++ tests/verilog/macro_unapplied_newline.ys | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/macro_unapplied.ys create mode 100644 tests/verilog/macro_unapplied_newline.ys diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index c451c4c2013..de707593f9b 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -477,7 +477,16 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok) std::string name = tok.substr(1); std::string skipped_spaces = skip_spaces(); tok = next_token(false); - if (tok == "(" && body->has_args) { + if (body->has_args) { + if (tok != "(") { + if (tok.size() == 1 && iscntrl(tok[0])) { + char buf[5]; + snprintf(buf, sizeof(buf), "\\x%02x", tok[0]); + tok = buf; + } + log_error("Expected to find '(' to begin macro arguments for '%s', but instead found '%s'\n", + name.c_str(), tok.c_str()); + } std::vector args; bool done = false; while (!done) { diff --git a/tests/verilog/macro_unapplied.ys b/tests/verilog/macro_unapplied.ys new file mode 100644 index 00000000000..81eb10b8b30 --- /dev/null +++ b/tests/verilog/macro_unapplied.ys @@ -0,0 +1,17 @@ +logger -expect-no-warnings +read_verilog -sv < Date: Sun, 21 Feb 2021 14:45:21 -0500 Subject: [PATCH 0185/2410] verilog: fix sizing of constant args for tasks/functions - Simplify synthetic localparams for normal calls to update their width - This step was inadvertently removed alongside `added_mod_children` - Support redeclaration of constant function arguments - `eval_const_function` never correctly handled this, but the issue was not exposed in the existing tests until the recent change to always attempt constant function evaluation when all-const args are used - Check asserts in const_arg_loop and const_func tests - Add coverage for width mismatch error cases --- frontends/ast/ast.h | 8 +++- frontends/ast/simplify.cc | 32 +++++++++++---- .../{const_arg_loop.v => const_arg_loop.sv} | 27 ++++++------ tests/various/const_arg_loop.ys | 7 +++- tests/various/{const_func.v => const_func.sv} | 41 +++++++++---------- tests/various/const_func.ys | 8 +++- tests/verilog/func_arg_mismatch_1.ys | 12 ++++++ tests/verilog/func_arg_mismatch_2.ys | 12 ++++++ tests/verilog/func_arg_mismatch_3.ys | 12 ++++++ tests/verilog/func_arg_mismatch_4.ys | 12 ++++++ 10 files changed, 124 insertions(+), 47 deletions(-) rename tests/various/{const_arg_loop.v => const_arg_loop.sv} (78%) rename tests/various/{const_func.v => const_func.sv} (74%) create mode 100644 tests/verilog/func_arg_mismatch_1.ys create mode 100644 tests/verilog/func_arg_mismatch_2.ys create mode 100644 tests/verilog/func_arg_mismatch_3.ys create mode 100644 tests/verilog/func_arg_mismatch_4.ys diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index d8818df31b0..b793c6c2d04 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -263,7 +263,13 @@ namespace AST bool detect_latch(const std::string &var); // additional functionality for evaluating constant functions - struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; + struct varinfo_t { + RTLIL::Const val; + int offset; + bool is_signed; + AstNode *arg = nullptr; + bool explicitly_sized; + }; bool has_const_only_constructs(); bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); AstNode *eval_const_function(AstNode *fcall, bool must_succeed); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 402b7257b61..df7c9282ceb 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3376,6 +3376,8 @@ skip_dynamic_range_lvalue_expansion:; range->children.push_back(mkconst_int(0, true)); } } + // updates the sizing + while (wire->simplify(true, false, false, 1, -1, false, false)) { } continue; } AstNode *wire_id = new AstNode(AST_IDENTIFIER); @@ -4591,17 +4593,29 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", stmt->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); } - variables[stmt->str].val = RTLIL::Const(RTLIL::State::Sx, abs(stmt->range_left - stmt->range_right)+1); - variables[stmt->str].offset = min(stmt->range_left, stmt->range_right); - variables[stmt->str].is_signed = stmt->is_signed; + AstNode::varinfo_t &variable = variables[stmt->str]; + int width = abs(stmt->range_left - stmt->range_right) + 1; + // if this variable has already been declared as an input, check the + // sizes match if it already had an explicit size + if (variable.arg && variable.explicitly_sized && variable.val.size() != width) { + log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str()); + } + variable.val = RTLIL::Const(RTLIL::State::Sx, width); + variable.offset = min(stmt->range_left, stmt->range_right); + variable.is_signed = stmt->is_signed; + variable.explicitly_sized = stmt->children.size() && + stmt->children.back()->type == AST_RANGE; + // identify the argument corresponding to this wire, if applicable if (stmt->is_input && argidx < fcall->children.size()) { - int width = variables[stmt->str].val.bits.size(); - auto* arg_node = fcall->children.at(argidx++); - if (arg_node->type == AST_CONSTANT) { - variables[stmt->str].val = arg_node->bitsAsConst(width); + variable.arg = fcall->children.at(argidx++); + } + // load the constant arg's value into this variable + if (variable.arg) { + if (variable.arg->type == AST_CONSTANT) { + variable.val = variable.arg->bitsAsConst(width); } else { - log_assert(arg_node->type == AST_REALVALUE); - variables[stmt->str].val = arg_node->realAsConst(width); + log_assert(variable.arg->type == AST_REALVALUE); + variable.val = variable.arg->realAsConst(width); } } current_scope[stmt->str] = stmt; diff --git a/tests/various/const_arg_loop.v b/tests/various/const_arg_loop.sv similarity index 78% rename from tests/various/const_arg_loop.v rename to tests/various/const_arg_loop.sv index 358fb439ae6..f28d06e68d1 100644 --- a/tests/various/const_arg_loop.v +++ b/tests/various/const_arg_loop.sv @@ -20,11 +20,11 @@ module top; endfunction function automatic [31:0] operation2; - input [4:0] var; + input [4:0] inp; input integer num; begin - var[0] = var[0] ^ 1; - operation2 = num * var; + inp[0] = inp[0] ^ 1; + operation2 = num * inp; end endfunction @@ -79,15 +79,14 @@ module top; wire [31:0] x5; assign x5 = operation5(64); -// `define VERIFY -`ifdef VERIFY - assert property (a == 2); - assert property (A == 3); - assert property (x1 == 16); - assert property (x1b == 16); - assert property (x2 == 4); - assert property (x3 == 16); - assert property (x4 == a << 1); - assert property (x5 == 64); -`endif + always_comb begin + assert(a == 2); + assert(A == 3); + assert(x1 == 16); + assert(x1b == 16); + assert(x2 == 4); + assert(x3 == 16); + assert(x4 == a << 1); + assert(x5 == 64); + end endmodule diff --git a/tests/various/const_arg_loop.ys b/tests/various/const_arg_loop.ys index b039bda1053..392532213b4 100644 --- a/tests/various/const_arg_loop.ys +++ b/tests/various/const_arg_loop.ys @@ -1 +1,6 @@ -read_verilog const_arg_loop.v +read_verilog -sv const_arg_loop.sv +hierarchy +proc +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all diff --git a/tests/various/const_func.v b/tests/various/const_func.sv similarity index 74% rename from tests/various/const_func.v rename to tests/various/const_func.sv index 541e63b1924..af65f5c73f7 100644 --- a/tests/various/const_func.v +++ b/tests/various/const_func.sv @@ -62,26 +62,25 @@ module top(out); localparam signed Y = $floor(W / X); localparam signed Z = negate($floor(W / X)); -// `define VERIFY -`ifdef VERIFY - assert property (a1 == 0); - assert property (a2 == 0); - assert property (a3 == "BAR"); - assert property (a4 == 0); - assert property (b1 == "FOO"); - assert property (b2 == "FOO"); - assert property (b3 == 0); - assert property (b4 == "HI"); - assert property (c1 == 1); - assert property (c2 == 1); - assert property (c3 == 0); - assert property (c4 == 0); - assert property (d1 == 0); - assert property (d2 == 0); - assert property (d3 == 1); - assert property (d4 == 1); + always_comb begin + assert(a1 == 0); + assert(a2 == 0); + assert(a3 == "BAR"); + assert(a4 == 0); + assert(b1 == "FOO"); + assert(b2 == "FOO"); + assert(b3 == 0); + assert(b4 == "HI"); + assert(c1 == 1); + assert(c2 == 1); + assert(c3 == 0); + assert(c4 == 0); + assert(d1 == 0); + assert(d2 == 0); + assert(d3 == 1); + assert(d4 == 1); - assert property (Y == 3); - assert property (Z == ~3); -`endif + assert(Y == 3); + assert(Z == ~3); + end endmodule diff --git a/tests/various/const_func.ys b/tests/various/const_func.ys index 5e3c0410522..2f60acfe670 100644 --- a/tests/various/const_func.ys +++ b/tests/various/const_func.ys @@ -1 +1,7 @@ -read_verilog const_func.v +read_verilog -sv const_func.sv +hierarchy +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all diff --git a/tests/verilog/func_arg_mismatch_1.ys b/tests/verilog/func_arg_mismatch_1.ys new file mode 100644 index 00000000000..a0e82db0c72 --- /dev/null +++ b/tests/verilog/func_arg_mismatch_1.ys @@ -0,0 +1,12 @@ +logger -expect error "Incompatible re-declaration of wire" 1 +read_verilog -sv < Date: Mon, 22 Feb 2021 22:02:48 +0100 Subject: [PATCH 0186/2410] assertpmux: Fix crash on unused $pmux output. Fixes #2595. --- passes/sat/assertpmux.cc | 2 +- tests/sat/bug2595.ys | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/sat/bug2595.ys diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index e9a10465ea6..f31b7880487 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -88,7 +88,7 @@ struct AssertpmuxWorker { SigSpec output; - for (auto muxuser : sigbit_muxusers.at(bit)) + for (auto muxuser : sigbit_muxusers[bit]) { Cell *cell = std::get<0>(muxuser); int portidx = std::get<1>(muxuser); diff --git a/tests/sat/bug2595.ys b/tests/sat/bug2595.ys new file mode 100644 index 00000000000..f668fd7472e --- /dev/null +++ b/tests/sat/bug2595.ys @@ -0,0 +1,18 @@ +read_ilang < Date: Wed, 27 Jan 2021 20:34:00 +0100 Subject: [PATCH 0187/2410] frontend: json: parse negative values Signed-off-by: Karol Gugala --- frontends/json/jsonparse.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 1b34aaf3af7..312f6d3be50 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -72,10 +72,17 @@ struct JsonNode break; } - if ('0' <= ch && ch <= '9') + if (('0' <= ch && ch <= '9') || ch == '-') { + bool negative = false; type = 'N'; - data_number = ch - '0'; + if (ch == '-') { + data_number = 0; + negative = true; + } else { + data_number = ch - '0'; + } + data_string += ch; while (1) @@ -97,6 +104,7 @@ struct JsonNode data_string += ch; } + data_number = negative ? -data_number : data_number; data_string = ""; break; From 88c8f812602c25ef0a062002bede8fe737b6ac77 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 16 Nov 2020 15:07:32 -0500 Subject: [PATCH 0188/2410] machxo2: Create basic techlibs and synth_machxo2 pass. --- techlibs/machxo2/Makefile.inc | 5 + techlibs/machxo2/cells_map.v | 23 +++ techlibs/machxo2/cells_sim.v | 62 ++++++++ techlibs/machxo2/synth_machxo2.cc | 230 ++++++++++++++++++++++++++++++ 4 files changed, 320 insertions(+) create mode 100644 techlibs/machxo2/Makefile.inc create mode 100644 techlibs/machxo2/cells_map.v create mode 100644 techlibs/machxo2/cells_sim.v create mode 100644 techlibs/machxo2/synth_machxo2.cc diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc new file mode 100644 index 00000000000..6f6f6ce9458 --- /dev/null +++ b/techlibs/machxo2/Makefile.inc @@ -0,0 +1,5 @@ + +OBJS += techlibs/machxo2/synth_machxo2.o + +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v new file mode 100644 index 00000000000..0f21fc32b86 --- /dev/null +++ b/techlibs/machxo2/cells_map.v @@ -0,0 +1,23 @@ +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + input [WIDTH-1:0] A; + output Y; + + localparam rep = 1<<(4-WIDTH); + wire [3:0] I; + + generate + if(WIDTH == 2) begin + assign I = {1'b0, 1'b0, A[1], A[0]}; + end else if(WIDTH == 3) begin + assign I = {1'b0, A[2], A[1], A[0]}; + end else if(WIDTH == 4) begin + assign I = {A[3], A[2], A[1], A[0]}; + end + endgenerate + + LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .F(Y)); +endmodule + +module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .D(D), .Q(Q)); endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v new file mode 100644 index 00000000000..06fbe20234a --- /dev/null +++ b/techlibs/machxo2/cells_sim.v @@ -0,0 +1,62 @@ +module LUT4 #( + parameter [15:0] INIT = 0 +) ( + input A, B, C, D, + output F +); + wire [3:0] I; + wire [3:0] I_pd; + + genvar ii; + generate + for (ii = 0; ii < 4; ii = ii + 1'b1) + assign I_pd[ii] = (I[ii] === 1'bz) ? 1'b0 : I[ii]; + endgenerate + + assign I = {D, C, B, A}; + assign F = INIT[I_pd]; +endmodule + +module FACADE_FF #( + parameter GSR = "ENABLED", + parameter CEMUX = "1", + parameter CLKMUX = "0", + parameter LSRMUX = "LSR", + parameter LSRONMUX = "LSRMUX", + parameter SRMODE = "LSR_OVER_CE", + parameter REGSET = "SET" +) ( + input CLK, D, LSR, CE, + output reg Q +); + + wire muxce; + generate + case (CEMUX) + "1": assign muxce = 1'b1; + "0": assign muxce = 1'b0; + "INV": assign muxce = ~CE; + default: assign muxce = CE; + endcase + endgenerate + + wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; + wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; + assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; + + generate + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, posedge muxlsr) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end + endgenerate +endmodule diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc new file mode 100644 index 00000000000..625d708cc2a --- /dev/null +++ b/techlibs/machxo2/synth_machxo2.cc @@ -0,0 +1,230 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 William D. Jones + * + * 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/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthMachXO2Pass : public ScriptPass +{ + SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs") { } + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_machxo2 [options]\n"); + log("\n"); + log("This command runs synthesis for ECP5 FPGAs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified EDIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -json \n"); + log(" write the design to the specified JSON file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -vpr\n"); + log(" generate an output netlist (and BLIF file) suitable for VPR\n"); + log(" (this feature is experimental and incomplete)\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, blif_file, edif_file, json_file; + bool flatten, vpr; + + void clear_flags() override + { + top_opt = "-auto-top"; + blif_file = ""; + edif_file = ""; + json_file = ""; + flatten = true; + vpr = false; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-vpr") { + vpr = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + log_header(design, "Executing SYNTH_MACHXO2 pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + if (check_label("begin")) + { + run("read_verilog -lib +/machxo2/cells_sim.v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (check_label("flatten", "(unless -noflatten)")) + { + if (flatten) { + run("proc"); + run("flatten"); + run("tribuf -logic"); + run("deminout"); + } + } + + if (check_label("coarse")) + { + run("synth -run coarse"); + } + + if (check_label("fine")) + { + run("memory_map"); + run("opt -full"); + run("techmap -map +/techmap.v"); + run("opt -fast"); + } + + if (check_label("map_ffs")) + { + run("dfflegalize -cell $_DFF_P_ 0"); + } + + if (check_label("map_luts")) + { + run("abc -lut 4 -dress"); + run("clean"); + } + + if (check_label("map_cells")) + { + run("techmap -map +/machxo2/cells_map.v"); + run("clean"); + } + + if (check_label("check")) + { + run("hierarchy -check"); + run("stat"); + } + + if (check_label("blif")) + { + if (!blif_file.empty() || help_mode) { + if (vpr || help_mode) { + run(stringf("opt_clean -purge"), + " (vpr mode)"); + run(stringf("write_blif -attr -cname -conn -param %s", + help_mode ? "" : blif_file.c_str()), + " (vpr mode)"); + } + if (!vpr) + run(stringf("write_blif -gates -attr -param %s", + help_mode ? "" : blif_file.c_str()), + " (non-vpr mode)"); + } + } + + if (check_label("edif")) + { + if (!edif_file.empty() || help_mode) + run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); + } + + if (check_label("json")) + { + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); + } + } +} SynthMachXO2Pass; + +PRIVATE_NAMESPACE_END From b87f6a09069eb2b1dce3ff197691e5f2e76dff38 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 17 Nov 2020 12:49:15 -0500 Subject: [PATCH 0189/2410] machxo2: Fix typos. test/arch/run-test.sh passes. --- techlibs/machxo2/cells_sim.v | 2 +- techlibs/machxo2/synth_machxo2.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 06fbe20234a..22b4fcf3c5a 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -26,7 +26,7 @@ module FACADE_FF #( parameter SRMODE = "LSR_OVER_CE", parameter REGSET = "SET" ) ( - input CLK, D, LSR, CE, + input CLK, DI, LSR, CE, output reg Q ); diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 625d708cc2a..f126f9c32db 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -35,7 +35,7 @@ struct SynthMachXO2Pass : public ScriptPass log("\n"); log(" synth_machxo2 [options]\n"); log("\n"); - log("This command runs synthesis for ECP5 FPGAs.\n"); + log("This command runs synthesis for MachXO2 FPGAs.\n"); log("\n"); log(" -top \n"); log(" use the specified module as top module\n"); From 9cb0bae1b27928202fa9ce6d494f7f6aaa36563a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 17 Nov 2020 13:01:57 -0500 Subject: [PATCH 0190/2410] machxo2: Add test/arch/machxo2 directory (test does not pass). --- Makefile | 1 + tests/arch/machxo2/.gitignore | 2 ++ tests/arch/machxo2/logic.ys | 8 ++++++++ tests/arch/machxo2/run-test.sh | 4 ++++ 4 files changed, 15 insertions(+) create mode 100644 tests/arch/machxo2/.gitignore create mode 100644 tests/arch/machxo2/logic.ys create mode 100644 tests/arch/machxo2/run-test.sh diff --git a/Makefile b/Makefile index 1f255a5eaee..50f4f52b7e6 100644 --- a/Makefile +++ b/Makefile @@ -810,6 +810,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/arch/ice40 && bash run-test.sh $(SEEDOPT) +cd tests/arch/xilinx && bash run-test.sh $(SEEDOPT) +cd tests/arch/ecp5 && bash run-test.sh $(SEEDOPT) + +cd tests/arch/machxo2 && bash run-test.sh $(SEEDOPT) +cd tests/arch/efinix && bash run-test.sh $(SEEDOPT) +cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT) +cd tests/arch/gowin && bash run-test.sh $(SEEDOPT) diff --git a/tests/arch/machxo2/.gitignore b/tests/arch/machxo2/.gitignore new file mode 100644 index 00000000000..1d329c9331d --- /dev/null +++ b/tests/arch/machxo2/.gitignore @@ -0,0 +1,2 @@ +*.log +/run-test.mk diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys new file mode 100644 index 00000000000..c5d2fb08ef5 --- /dev/null +++ b/tests/arch/machxo2/logic.ys @@ -0,0 +1,8 @@ +read_verilog ../common/logic.v +hierarchy -top top +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 9 t:LUT4 +select -assert-none t:LUT4 %% t:* %D diff --git a/tests/arch/machxo2/run-test.sh b/tests/arch/machxo2/run-test.sh new file mode 100644 index 00000000000..4be4b70ae17 --- /dev/null +++ b/tests/arch/machxo2/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" From 044393b990316d997df3a5cc57e9d065c3a5e9d8 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 17 Nov 2020 14:22:44 -0500 Subject: [PATCH 0191/2410] machxo2: Fix more oversights in machxo2 models. logic.ys test passes. --- techlibs/machxo2/cells_map.v | 6 +++++- techlibs/machxo2/cells_sim.v | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 0f21fc32b86..345675db9aa 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -8,12 +8,16 @@ module \$lut (A, Y); wire [3:0] I; generate - if(WIDTH == 2) begin + if(WIDTH == 1) begin + assign I = {1'b0, 1'b0, 1'b0, A[0]}; + end else if(WIDTH == 2) begin assign I = {1'b0, 1'b0, A[1], A[0]}; end else if(WIDTH == 3) begin assign I = {1'b0, A[2], A[1], A[0]}; end else if(WIDTH == 4) begin assign I = {A[3], A[2], A[1], A[0]}; + end else begin + INVALID_LUT_WIDTH error(); end endgenerate diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 22b4fcf3c5a..8db73c50c77 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -42,7 +42,7 @@ module FACADE_FF #( wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; - assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; + wire srval = (REGSET == "SET") ? 1'b1 : 1'b0; generate if (SRMODE == "ASYNC") begin From 84937e9689c6fddfc613356f9a629d7628939668 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 17 Nov 2020 14:35:17 -0500 Subject: [PATCH 0192/2410] machxo2: Add dff.ys test, fix another cells_map.v typo. --- techlibs/machxo2/cells_map.v | 2 +- tests/arch/machxo2/dffs.ys | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/arch/machxo2/dffs.ys diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 345675db9aa..054b678b34c 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -24,4 +24,4 @@ module \$lut (A, Y); LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .F(Y)); endmodule -module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .D(D), .Q(Q)); endmodule +module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys new file mode 100644 index 00000000000..3e9f87fec2e --- /dev/null +++ b/tests/arch/machxo2/dffs.ys @@ -0,0 +1,10 @@ +read_verilog ../common/dffs.v +design -save read + +hierarchy -top dff +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dff # Constrain all select calls below inside the top module +select -assert-count 1 t:FACADE_FF +select -assert-none t:FACADE_FF %% t:* %D From 19b043344c67a0ce5a8a14ef2960f366980c9873 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 20 Nov 2020 18:16:45 -0500 Subject: [PATCH 0193/2410] machxo2: Add dffe test. --- tests/arch/machxo2/dffs.ys | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 3e9f87fec2e..83a07cfeee6 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -8,3 +8,12 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:FACADE_FF select -assert-none t:FACADE_FF %% t:* %D + +design -load read +hierarchy -top dffe +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffe # Constrain all select calls below inside the top module +select -assert-count 2 t:FACADE_FF t:LUT4 +select -assert-none t:FACADE_FF t:LUT4 %% t:* %D From 427fed23eec2f09eb93bf08a5ac1a4cd41d0a2c2 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 20 Nov 2020 18:53:09 -0500 Subject: [PATCH 0194/2410] machxo2: Improve LUT4 techmap. Use same output port name for LUT4 as Lattice. --- techlibs/machxo2/cells_map.v | 4 ++-- techlibs/machxo2/cells_sim.v | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 054b678b34c..924df6f2555 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -17,11 +17,11 @@ module \$lut (A, Y); end else if(WIDTH == 4) begin assign I = {A[3], A[2], A[1], A[0]}; end else begin - INVALID_LUT_WIDTH error(); + wire _TECHMAP_FAIL_ = 1; end endgenerate - LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .F(Y)); + LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .Z(Y)); endmodule module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 8db73c50c77..2c4d2f46273 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -2,7 +2,7 @@ module LUT4 #( parameter [15:0] INIT = 0 ) ( input A, B, C, D, - output F + output Z ); wire [3:0] I; wire [3:0] I_pd; @@ -14,7 +14,7 @@ module LUT4 #( endgenerate assign I = {D, C, B, A}; - assign F = INIT[I_pd]; + assign Z = INIT[I_pd]; endmodule module FACADE_FF #( From cc52eb53cde6863ae209343c234c33e1092e94b6 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 20 Nov 2020 21:24:39 -0500 Subject: [PATCH 0195/2410] machxo2: Improve FACADE_FF simulation model. --- techlibs/machxo2/cells_sim.v | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 2c4d2f46273..8d93a4a33e1 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -24,7 +24,8 @@ module FACADE_FF #( parameter LSRMUX = "LSR", parameter LSRONMUX = "LSRMUX", parameter SRMODE = "LSR_OVER_CE", - parameter REGSET = "SET" + parameter REGSET = "SET", + parameter REGMODE = "FF" ) ( input CLK, DI, LSR, CE, output reg Q @@ -41,22 +42,29 @@ module FACADE_FF #( endgenerate wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; + wire muxlsron = (LSRONMUX == "LSRMUX") ? muxlsr : 1'b0; wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; wire srval = (REGSET == "SET") ? 1'b1 : 1'b0; generate - if (SRMODE == "ASYNC") begin - always @(posedge muxclk, posedge muxlsr) - if (muxlsr) - Q <= srval; - else if (muxce) - Q <= DI; + if (REGMODE == "FF") begin + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, posedge muxlsron) + if (muxlsron) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk) + if (muxlsron) + Q <= srval; + else if (muxce) + Q <= DI; + end + end else if (REGMODE == "LATCH") begin + ERROR_UNSUPPORTED_FF_MODE error(); end else begin - always @(posedge muxclk) - if (muxlsr) - Q <= srval; - else if (muxce) - Q <= DI; + ERROR_UNKNOWN_FF_MODE error(); end endgenerate endmodule From 1b703d3f03eaaf55d2475ee803d546ad4cfc6663 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 21 Nov 2020 11:53:30 -0500 Subject: [PATCH 0196/2410] machxo2: Add FACADE_SLICE simulation model. --- techlibs/machxo2/cells_sim.v | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 8d93a4a33e1..89a66be7f05 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -68,3 +68,86 @@ module FACADE_FF #( end endgenerate endmodule + +module PFUMX (input ALUT, BLUT, C0, output Z); + assign Z = C0 ? ALUT : BLUT; +endmodule + +module L6MUX21 (input D0, D1, SD, output Z); + assign Z = SD ? D1 : D0; +endmodule + +/* For consistency, input order matches TRELLIS_SLICE even though the BELs in +prjtrellis were filled in clockwise order from bottom left. */ +module FACADE_SLICE #( + parameter MODE = "LOGIC", + parameter GSR = "ENABLED", + parameter SRMODE = "LSR_OVER_CE", + parameter CEMUX = "1", + parameter CLKMUX = "0", + parameter LSRMUX = "LSR", + parameter LSRONMUX = "LSRMUX", + parameter LUT0_INITVAL = 16'hFFFF, + parameter LUT1_INITVAL = 16'hFFFF, + parameter REG0_SD = "1", + parameter REG1_SD = "1", + parameter REG0_REGSET = "SET", + parameter REG1_REGSET = "SET", + parameter REG0_REGMODE = "FF", + parameter REG1_REGMODE = "FF", + parameter CCU2_INJECT1_0 = "YES", + parameter CCU2_INJECT1_1 = "YES", + parameter WREMUX = "INV" +) ( + input A0, B0, C0, D0, + input A1, B1, C1, D1, + input M0, M1, + input FCI, FXA, FXB, + + input CLK, LSR, CE, + input DI0, DI1, + + input WD0, WD1, + input WAD0, WAD1, WAD2, WAD3, + input WRE, WCK, + + output F0, Q0, + output F1, Q1, + output FCO, OFX0, OFX1, + + output WDO0, WDO1, WDO2, WDO3, + output WADO0, WADO1, WADO2, WADO3 +); + + generate + if (MODE == "LOGIC") begin + L6MUX21 FXMUX (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1)); + + wire k0; + wire k1; + PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX1)); + + LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0)); + LUT4 #(.INIT(LUT0_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); + + assign F0 = k0; + assign F1 = k1; + end else if (MODE == "CCU2") begin + ERROR_UNSUPPORTED_SLICE_MODE error(); + end else if (MODE == "DPRAM") begin + ERROR_UNSUPPORTED_SLICE_MODE error(); + end else begin + ERROR_UNKNOWN_SLICE_MODE error(); + end + endgenerate + + wire di0 = (REG0_SD == "1") ? M0 : DI0; + wire di1 = (REG0_SD == "1") ? M1 : DI1; + + FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), + .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), + .REGMODE(REG0_REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); + FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), + .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), + .REGMODE(REG1_REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); +endmodule From 0364ded385e3ba7817a9e466e165a184292c3ef2 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 21 Nov 2020 11:58:30 -0500 Subject: [PATCH 0197/2410] machxo2: Add FACADE_IO simulation model. More comments on models. --- techlibs/machxo2/cells_sim.v | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 89a66be7f05..f09837c13e1 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -69,10 +69,12 @@ module FACADE_FF #( endgenerate endmodule +/* For consistency with ECP5; represents F0/F1 => OFX0 mux in a slice. */ module PFUMX (input ALUT, BLUT, C0, output Z); assign Z = C0 ? ALUT : BLUT; endmodule +/* For consistency with ECP5; represents FXA/FXB => OFX1 mux in a slice. */ module L6MUX21 (input D0, D1, SD, output Z); assign Z = SD ? D1 : D0; endmodule @@ -141,6 +143,8 @@ module FACADE_SLICE #( end endgenerate + /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F + outputs (in other words, feeds back into FACADE_SLICE). */ wire di0 = (REG0_SD == "1") ? M0 : DI0; wire di1 = (REG0_SD == "1") ? M1 : DI1; @@ -151,3 +155,24 @@ module FACADE_SLICE #( .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), .REGMODE(REG1_REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); endmodule + +module FACADE_IO #( + parameter DIR = "INPUT" +) ( + inout PAD, + input I, EN, + output O +); + generate + if (DIR == "INPUT") begin + assign O = PAD; + end else if (DIR == "OUTPUT") begin + assign PAD = EN ? I : 1'bz; + end else if (DIR == "BIDIR") begin + assign PAD = EN ? I : 1'bz; + assign O = PAD; + end else begin + ERROR_UNKNOWN_IO_MODE error(); + end + endgenerate +endmodule From 03cbf1327d01dbb7997d2f2b241340c29ff35e00 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 21 Nov 2020 18:44:42 -0500 Subject: [PATCH 0198/2410] machxo2: Add initial value for Q in FACADE_FF. --- techlibs/machxo2/cells_sim.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index f09837c13e1..ef40f023159 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -46,6 +46,8 @@ module FACADE_FF #( wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; wire srval = (REGSET == "SET") ? 1'b1 : 1'b0; + initial Q = srval; + generate if (REGMODE == "FF") begin if (SRMODE == "ASYNC") begin From c76f361b56216aa4021c88e5d00b7d8323165967 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 13:39:40 -0500 Subject: [PATCH 0199/2410] machxo2: synth_machxo2 now maps ports to FACADE_IO. --- techlibs/machxo2/cells_map.v | 7 +++++++ techlibs/machxo2/synth_machxo2.cc | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 924df6f2555..a0263070339 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -24,4 +24,11 @@ module \$lut (A, Y); LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .Z(Y)); endmodule +// DFFs module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule + +// IO- "$__" cells for the iopadmap pass. +module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .EN(1'b1)); endmodule +module \$__FACADE_INPAD (input I, output O); FACADE_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.PAD(I), .O(O)); endmodule +module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .EN(OE)); endmodule +module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .EN(OE)); endmodule diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index f126f9c32db..794f25d0afc 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -173,6 +173,11 @@ struct SynthMachXO2Pass : public ScriptPass run("opt -fast"); } + if (check_label("map_ios")) + { + run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top"); + } + if (check_label("map_ffs")) { run("dfflegalize -cell $_DFF_P_ 0"); From f07b8eb606e9bcbf425510d938145a1e30e54b5d Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 18:47:11 -0500 Subject: [PATCH 0200/2410] machxo2: Fix cells_sim typo where OFX1 was multiply-driven. --- techlibs/machxo2/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index ef40f023159..1cb45650aec 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -129,7 +129,7 @@ module FACADE_SLICE #( wire k0; wire k1; - PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX1)); + PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX0)); LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0)); LUT4 #(.INIT(LUT0_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); From 3697f351d58a1abe200457f252c41acb37da103a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 20:18:15 -0500 Subject: [PATCH 0201/2410] machxo2: Use correct INITVAL for LUT1 in FACADE_SLICE. --- techlibs/machxo2/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 1cb45650aec..134f264533e 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -132,7 +132,7 @@ module FACADE_SLICE #( PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX0)); LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0)); - LUT4 #(.INIT(LUT0_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); + LUT4 #(.INIT(LUT1_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); assign F0 = k0; assign F1 = k1; From 597a54dbd04542dc82b0183c31da55aa73ad41a6 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 21:23:13 -0500 Subject: [PATCH 0202/2410] machxo2: Add -noiopad option to synth_machxo2. --- techlibs/machxo2/synth_machxo2.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 794f25d0afc..c9ab2342678 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -60,6 +60,9 @@ struct SynthMachXO2Pass : public ScriptPass log(" -noflatten\n"); log(" do not flatten design before synthesis\n"); log("\n"); + log(" -noiopad\n"); + log(" do not insert IO buffers\n"); + log("\n"); log(" -vpr\n"); log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); @@ -71,7 +74,7 @@ struct SynthMachXO2Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool flatten, vpr; + bool flatten, vpr, noiopad; void clear_flags() override { @@ -81,6 +84,7 @@ struct SynthMachXO2Pass : public ScriptPass json_file = ""; flatten = true; vpr = false; + noiopad = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -123,6 +127,10 @@ struct SynthMachXO2Pass : public ScriptPass flatten = false; continue; } + if (args[argidx] == "-noiopad") { + noiopad = true; + continue; + } if (args[argidx] == "-vpr") { vpr = true; continue; @@ -175,7 +183,8 @@ struct SynthMachXO2Pass : public ScriptPass if (check_label("map_ios")) { - run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top"); + if (!noiopad || help_mode) + run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top", "(skip if '-noiopad')"); } if (check_label("map_ffs")) From 453904dd0020ed8aacf8319cb90d1f0e05c9daa9 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 21:58:20 -0500 Subject: [PATCH 0203/2410] machxo2: Add add_sub test. Fix tests to include FACADE_IO primitives. --- tests/arch/machxo2/add_sub.ys | 8 ++++++++ tests/arch/machxo2/dffs.ys | 4 ++-- tests/arch/machxo2/logic.ys | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 tests/arch/machxo2/add_sub.ys diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys new file mode 100644 index 00000000000..d9497b8182b --- /dev/null +++ b/tests/arch/machxo2/add_sub.ys @@ -0,0 +1,8 @@ +read_verilog ../common/add_sub.v +hierarchy -top top +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 10 t:LUT4 +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 83a07cfeee6..83a79a9d6b3 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -7,7 +7,7 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:FACADE_FF -select -assert-none t:FACADE_FF %% t:* %D +select -assert-none t:FACADE_FF t:FACADE_IO %% t:* %D design -load read hierarchy -top dffe @@ -16,4 +16,4 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 2 t:FACADE_FF t:LUT4 -select -assert-none t:FACADE_FF t:LUT4 %% t:* %D +select -assert-none t:FACADE_FF t:LUT4 t:FACADE_IO %% t:* %D diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index c5d2fb08ef5..bf93ab128ae 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -5,4 +5,4 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 9 t:LUT4 -select -assert-none t:LUT4 %% t:* %D +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D From c7aaa88f5807c7d49346b43b830a9826c52061ee Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 22:30:48 -0500 Subject: [PATCH 0204/2410] machxo2: Add passing fsm, mux, and shifter tests. --- tests/arch/machxo2/fsm.ys | 15 +++++++++++++ tests/arch/machxo2/mux.ys | 40 +++++++++++++++++++++++++++++++++++ tests/arch/machxo2/shifter.ys | 10 +++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/arch/machxo2/fsm.ys create mode 100644 tests/arch/machxo2/mux.ys create mode 100644 tests/arch/machxo2/shifter.ys diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys new file mode 100644 index 00000000000..847a61161b0 --- /dev/null +++ b/tests/arch/machxo2/fsm.ys @@ -0,0 +1,15 @@ +read_verilog ../common/fsm.v +hierarchy -top fsm +proc +flatten + +equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 +miter -equiv -make_assert -flatten gold gate miter +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +select -assert-max 16 t:LUT4 +select -assert-count 6 t:FACADE_FF +select -assert-none t:FACADE_FF t:LUT4 t:FACADE_IO %% t:* %D diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys new file mode 100644 index 00000000000..0cfc365bd16 --- /dev/null +++ b/tests/arch/machxo2/mux.ys @@ -0,0 +1,40 @@ +read_verilog ../common/mux.v +design -save read + +hierarchy -top mux2 +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux2 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT4 +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 2 t:LUT4 + +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 5 t:LUT4 + +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D + +design -load read +hierarchy -top mux16 +proc +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux16 # Constrain all select calls below inside the top module +select -assert-count 12 t:LUT4 + +select -assert-none t:LUT4 t:FACADE_IO %% t:* %D diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys new file mode 100644 index 00000000000..87fdab0fa36 --- /dev/null +++ b/tests/arch/machxo2/shifter.ys @@ -0,0 +1,10 @@ +read_verilog ../common/shifter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 8 t:FACADE_FF +select -assert-none t:FACADE_FF t:FACADE_IO %% t:* %D From c31b17a2e28ac5f70600ee8b27f0befb3a1706be Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 26 Nov 2020 22:34:46 -0500 Subject: [PATCH 0205/2410] machxo2: Add believed-to-be-correct tribuf test. --- tests/arch/machxo2/tribuf.ys | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/arch/machxo2/tribuf.ys diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys new file mode 100644 index 00000000000..7f3cd326ec1 --- /dev/null +++ b/tests/arch/machxo2/tribuf.ys @@ -0,0 +1,9 @@ +read_verilog ../common/tribuf.v +hierarchy -top tristate +proc +flatten +equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd tristate # Constrain all select calls below inside the top module +select -assert-count 3 t:FACADE_IO +select -assert-none t:FACADE_IO %% t:* %D From 124780ecd9a74e9477313975b5e06e3fdd902573 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 7 Dec 2020 22:29:36 -0500 Subject: [PATCH 0206/2410] machxo2: Add missing OSCH oscillator primitive. --- techlibs/machxo2/cells_sim.v | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 134f264533e..76de3929979 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -178,3 +178,13 @@ module FACADE_IO #( end endgenerate endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule From 3674eb34d4e3719798a274a251150a7687064422 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 12 Dec 2020 18:09:52 -0500 Subject: [PATCH 0207/2410] machxo2: Use attrmvcp pass to move LOC and src attributes from ports/wires to IO cells. --- techlibs/machxo2/cells_sim.v | 12 ++++++++++++ techlibs/machxo2/synth_machxo2.cc | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 76de3929979..3dd41334e73 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -188,3 +188,15 @@ module OSCH #( output SEDSTDBY ); endmodule + +// IO- "$__" cells for the iopadmap pass. These are temporary cells not meant +// to be instantiated by the end user. They are required in this file for +// attrmvcp to work. +(* blackbox *) +module \$__FACADE_OUTPAD (input I, output O); endmodule +(* blackbox *) +module \$__FACADE_INPAD (input I, output O); endmodule +(* blackbox *) +module \$__FACADE_TOUTPAD (input I, OE, output O); endmodule +(* blackbox *) +module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); endmodule diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index c9ab2342678..ea9b2a0e842 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -154,7 +154,7 @@ struct SynthMachXO2Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib +/machxo2/cells_sim.v"); + run("read_verilog -lib -icells +/machxo2/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); } @@ -184,7 +184,11 @@ struct SynthMachXO2Pass : public ScriptPass if (check_label("map_ios")) { if (!noiopad || help_mode) + { run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top", "(skip if '-noiopad')"); + run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]", "(skip if '-noiopad')"); + run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]", "(skip if '-noiopad')"); + } } if (check_label("map_ffs")) From 120404bfda90578a014ba702d457eb85ae3711d7 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 13 Dec 2020 00:34:01 -0500 Subject: [PATCH 0208/2410] machxo2: Improve help_mode output in synth_machxo2. --- techlibs/machxo2/synth_machxo2.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index ea9b2a0e842..19c0ab9d00b 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -160,7 +160,7 @@ struct SynthMachXO2Pass : public ScriptPass if (check_label("flatten", "(unless -noflatten)")) { - if (flatten) { + if (flatten || help_mode) { run("proc"); run("flatten"); run("tribuf -logic"); @@ -181,13 +181,13 @@ struct SynthMachXO2Pass : public ScriptPass run("opt -fast"); } - if (check_label("map_ios")) + if (check_label("map_ios", "(unless -noiopad)")) { if (!noiopad || help_mode) { - run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top", "(skip if '-noiopad')"); - run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]", "(skip if '-noiopad')"); - run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]", "(skip if '-noiopad')"); + run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top"); + run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]"); + run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]"); } } From 8348c45e4f679b44b238c0f205e2e3815c909c38 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 29 Jan 2021 18:14:13 -0500 Subject: [PATCH 0209/2410] machxo2: Fix naming of TRELLIS_IO ports to match PIO pins in routing graph. --- techlibs/machxo2/cells_map.v | 6 +++--- techlibs/machxo2/cells_sim.v | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index a0263070339..15428d4dcd0 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -28,7 +28,7 @@ endmodule module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule // IO- "$__" cells for the iopadmap pass. -module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .EN(1'b1)); endmodule +module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(1'b1)); endmodule module \$__FACADE_INPAD (input I, output O); FACADE_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.PAD(I), .O(O)); endmodule -module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .EN(OE)); endmodule -module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .EN(OE)); endmodule +module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(OE)); endmodule +module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(OE)); endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 3dd41334e73..4e2a1bb6ca2 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -162,16 +162,16 @@ module FACADE_IO #( parameter DIR = "INPUT" ) ( inout PAD, - input I, EN, + input I, T, output O ); generate if (DIR == "INPUT") begin assign O = PAD; end else if (DIR == "OUTPUT") begin - assign PAD = EN ? I : 1'bz; + assign PAD = T ? I : 1'bz; end else if (DIR == "BIDIR") begin - assign PAD = EN ? I : 1'bz; + assign PAD = T ? I : 1'bz; assign O = PAD; end else begin ERROR_UNKNOWN_IO_MODE error(); From 8b14152506cdae1f15a33189736cbd3388f3b345 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 30 Jan 2021 23:55:00 -0500 Subject: [PATCH 0210/2410] machxo2: Fix typos in FACADE_FF sim model. --- techlibs/machxo2/cells_sim.v | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 4e2a1bb6ca2..d2267e8fdf6 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -93,12 +93,11 @@ module FACADE_SLICE #( parameter LSRONMUX = "LSRMUX", parameter LUT0_INITVAL = 16'hFFFF, parameter LUT1_INITVAL = 16'hFFFF, + parameter REGMODE = "FF", parameter REG0_SD = "1", parameter REG1_SD = "1", parameter REG0_REGSET = "SET", parameter REG1_REGSET = "SET", - parameter REG0_REGMODE = "FF", - parameter REG1_REGMODE = "FF", parameter CCU2_INJECT1_0 = "YES", parameter CCU2_INJECT1_1 = "YES", parameter WREMUX = "INV" @@ -148,14 +147,14 @@ module FACADE_SLICE #( /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F outputs (in other words, feeds back into FACADE_SLICE). */ wire di0 = (REG0_SD == "1") ? M0 : DI0; - wire di1 = (REG0_SD == "1") ? M1 : DI1; + wire di1 = (REG1_SD == "1") ? M1 : DI1; FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), - .REGMODE(REG0_REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); + .REGMODE(REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), - .REGMODE(REG1_REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); + .REGMODE(REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); endmodule module FACADE_IO #( From 4e9def23de62c4e25478cdcaaba525d8686ac90c Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 31 Jan 2021 11:33:20 -0500 Subject: [PATCH 0211/2410] machxo2: Tristate is active-low. --- techlibs/machxo2/cells_map.v | 6 +++--- techlibs/machxo2/cells_sim.v | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 15428d4dcd0..82eb10d9592 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -28,7 +28,7 @@ endmodule module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule // IO- "$__" cells for the iopadmap pass. -module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(1'b1)); endmodule +module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(1'b0)); endmodule module \$__FACADE_INPAD (input I, output O); FACADE_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.PAD(I), .O(O)); endmodule -module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(OE)); endmodule -module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(OE)); endmodule +module \$__FACADE_TOUTPAD (input I, OE, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(~OE)); endmodule +module \$__FACADE_TINOUTPAD (input I, OE, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(~OE)); endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index d2267e8fdf6..5f985d47738 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -168,9 +168,9 @@ module FACADE_IO #( if (DIR == "INPUT") begin assign O = PAD; end else if (DIR == "OUTPUT") begin - assign PAD = T ? I : 1'bz; + assign PAD = T ? 1'bz : I; end else if (DIR == "BIDIR") begin - assign PAD = T ? I : 1'bz; + assign PAD = T ? 1'bz : I; assign O = PAD; end else begin ERROR_UNKNOWN_IO_MODE error(); From a1ea1430b6ba478267d30253a79936fcb9e5faef Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 31 Jan 2021 19:05:15 -0500 Subject: [PATCH 0212/2410] machxo2: Fix reversed interpretation of REG_SD config bits. --- techlibs/machxo2/cells_sim.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 5f985d47738..e046d0c8787 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -146,8 +146,8 @@ module FACADE_SLICE #( /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F outputs (in other words, feeds back into FACADE_SLICE). */ - wire di0 = (REG0_SD == "1") ? M0 : DI0; - wire di1 = (REG1_SD == "1") ? M1 : DI1; + wire di0 = (REG0_SD == "1") ? DI0 : M0; + wire di1 = (REG1_SD == "1") ? DI1 : M1; FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), From e3974809ec55395fad4f6b407b03784f397e3f30 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 31 Jan 2021 23:57:13 -0500 Subject: [PATCH 0213/2410] machxo2: Add DCCA and DCMA blackbox primitives. --- techlibs/machxo2/cells_sim.v | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index e046d0c8787..c6d70a05505 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -188,6 +188,23 @@ module OSCH #( ); endmodule +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + // IO- "$__" cells for the iopadmap pass. These are temporary cells not meant // to be instantiated by the end user. They are required in this file for // attrmvcp to work. From 8f1a350f5ef9223f5e1de2f695a53435e03d98ac Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 8 Feb 2021 17:31:58 -0500 Subject: [PATCH 0214/2410] machxo2: Add experimental status to help. --- techlibs/machxo2/synth_machxo2.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 19c0ab9d00b..bd56fbba930 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct SynthMachXO2Pass : public ScriptPass { - SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs") { } + SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs. This work is experimental.") { } void help() override { From 353ace50345ab6a88f29dfe19c0ef813e7eb4e79 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 10 Feb 2021 18:50:17 -0500 Subject: [PATCH 0215/2410] machxo2: Update tribuf test to reflect active-low OE. --- tests/arch/machxo2/tribuf.ys | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index 7f3cd326ec1..9c00a8bcf6b 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -6,4 +6,5 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module select -assert-count 3 t:FACADE_IO -select -assert-none t:FACADE_IO %% t:* %D +select -assert-count 1 t:$not +select -assert-none t:FACADE_IO t:$not %% t:* %D From ae07298a6b26315793167d9fe0e47d33412fc033 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 21 Feb 2021 09:14:37 -0500 Subject: [PATCH 0216/2410] machxo2: Switch to LUT4 sim model which propagates less undefined/don't care values. --- techlibs/machxo2/cells_sim.v | 16 +++++----------- tests/arch/machxo2/mux.ys | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index c6d70a05505..161ddfe2ea3 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -4,17 +4,11 @@ module LUT4 #( input A, B, C, D, output Z ); - wire [3:0] I; - wire [3:0] I_pd; - - genvar ii; - generate - for (ii = 0; ii < 4; ii = ii + 1'b1) - assign I_pd[ii] = (I[ii] === 1'bz) ? 1'b0 : I[ii]; - endgenerate - - assign I = {D, C, B, A}; - assign Z = INIT[I_pd]; + // This form of LUT propagates as few x's as possible. + wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + assign Z = A ? s1[1] : s1[0]; endmodule module FACADE_FF #( diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 0cfc365bd16..6c8aa857c0f 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -35,6 +35,6 @@ proc equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module -select -assert-count 12 t:LUT4 +select -assert-count 11 t:LUT4 select -assert-none t:LUT4 t:FACADE_IO %% t:* %D From 7c50b89b244ed23d42f95c3d08efde40ec7ddd82 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sat, 20 Feb 2021 11:46:30 -0800 Subject: [PATCH 0217/2410] Adds is_wire to SigBit and SigChunk Useful for PYOSYS because Python can't easily check wire against NULL. --- kernel/rtlil.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4dad3c42873..a5f170085ce 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -735,6 +735,7 @@ struct RTLIL::SigChunk RTLIL::SigChunk extract(int offset, int length) const; inline int size() const { return width; } + inline int is_wire() const { return wire != NULL; } bool operator <(const RTLIL::SigChunk &other) const; bool operator ==(const RTLIL::SigChunk &other) const; @@ -760,6 +761,8 @@ struct RTLIL::SigBit SigBit(const RTLIL::SigBit &sigbit) = default; RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default; + inline int is_wire() const { return wire != NULL; } + bool operator <(const RTLIL::SigBit &other) const; bool operator ==(const RTLIL::SigBit &other) const; bool operator !=(const RTLIL::SigBit &other) const; From 4b31223e60f8854d50c1d1bbddca528fbf37d261 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sun, 21 Feb 2021 20:00:31 -0800 Subject: [PATCH 0218/2410] int -> bool --- kernel/rtlil.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a5f170085ce..6170ea55ea4 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -735,7 +735,7 @@ struct RTLIL::SigChunk RTLIL::SigChunk extract(int offset, int length) const; inline int size() const { return width; } - inline int is_wire() const { return wire != NULL; } + inline bool is_wire() const { return wire != NULL; } bool operator <(const RTLIL::SigChunk &other) const; bool operator ==(const RTLIL::SigChunk &other) const; @@ -761,7 +761,7 @@ struct RTLIL::SigBit SigBit(const RTLIL::SigBit &sigbit) = default; RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default; - inline int is_wire() const { return wire != NULL; } + inline bool is_wire() const { return wire != NULL; } bool operator <(const RTLIL::SigBit &other) const; bool operator ==(const RTLIL::SigBit &other) const; From f4f471f34218fb003edf3551406bfd298408094d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 19:22:53 +0100 Subject: [PATCH 0219/2410] frontend: Make helper functions for printing locations. --- frontends/ast/ast.cc | 24 ++++++++++++------- frontends/ast/ast.h | 6 +++++ frontends/ast/genrtlil.cc | 50 +++++++++++++++++++-------------------- frontends/ast/simplify.cc | 48 ++++++++++++++++++------------------- 4 files changed, 71 insertions(+), 57 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index dc47420af05..57552d86c62 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -287,8 +287,7 @@ void AstNode::dumpAst(FILE *f, std::string indent) const } std::string type_name = type2str(type); - fprintf(f, "%s%s <%s:%d.%d-%d.%d>", indent.c_str(), type_name.c_str(), filename.c_str(), location.first_line, - location.first_column, location.last_line, location.last_column); + fprintf(f, "%s%s <%s>", indent.c_str(), type_name.c_str(), loc_string().c_str()); if (!flag_no_dump_ptr) { if (id2ast) @@ -959,6 +958,16 @@ RTLIL::Const AstNode::realAsConst(int width) return result; } +std::string AstNode::loc_string() const +{ + return stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); +} + +void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast) +{ + obj->attributes[ID::src] = ast->loc_string(); +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { @@ -974,8 +983,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast current_module = new AstModule; current_module->ast = NULL; current_module->name = ast->str; - current_module->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, - ast->location.first_column, ast->location.last_line, ast->location.last_column); + set_src_attr(current_module, ast); current_module->set_bool_attribute(ID::cells_not_processed); current_ast_mod = ast; @@ -1229,13 +1237,13 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { log_file_error((*it)->filename, (*it)->location.first_line, "Re-definition of module `%s'!\n", (*it)->str.c_str()); } else if (nooverwrite) { - log("Ignoring re-definition of module `%s' at %s:%d.%d-%d.%d.\n", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); + log("Ignoring re-definition of module `%s' at %s.\n", + (*it)->str.c_str(), (*it)->loc_string().c_str()); continue; } else { - log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n", + log("Replacing existing%s module `%s' at %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); + (*it)->str.c_str(), (*it)->loc_string().c_str()); design->remove(existing_mod); } } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index df2700831d4..1c9a6ee47c6 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -323,6 +323,9 @@ namespace AST // helpers for enum void allocateDefaultEnumValues(); void annotateTypedEnums(AstNode *template_node); + + // helpers for locations + std::string loc_string() const; }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code @@ -361,6 +364,9 @@ namespace AST std::pair split_modport_from_type(std::string name_type); AstNode * find_modport(AstNode *intf, std::string name); void explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport); + + // Helper for setting the src attribute. + void set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast); } namespace AST_INTERNAL diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 713e34eb1b4..449f8c38e9d 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -45,10 +45,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width { IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, type); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(cell, that); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(wire, that); wire->is_signed = that->is_signed; if (gen_attributes) @@ -77,10 +77,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s IdString name = stringf("$extend$%s:%d$%d", that->filename.c_str(), that->location.first_line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, ID($pos)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(cell, that); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(wire, that); wire->is_signed = that->is_signed; if (that != NULL) @@ -104,10 +104,10 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width { IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++); RTLIL::Cell *cell = current_module->addCell(name, type); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(cell, that); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(wire, that); wire->is_signed = that->is_signed; for (auto &attr : that->attributes) { @@ -139,10 +139,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($mux)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(cell, that); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size()); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column); + set_src_attr(wire, that); wire->is_signed = that->is_signed; for (auto &attr : that->attributes) { @@ -320,7 +320,7 @@ struct AST_INTERNAL::ProcessGenerator // generate process and simple root case proc = new RTLIL::Process; - proc->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); + set_src_attr(proc, always); proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) @@ -356,7 +356,7 @@ struct AST_INTERNAL::ProcessGenerator if (found_anyedge_syncs) { if (found_global_syncs) log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n"); - log("Note: Assuming pure combinatorial block at %s:%d.%d-%d.%d in\n", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); + log("Note: Assuming pure combinatorial block at %s in\n", always->loc_string().c_str()); log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n"); log("use of @* instead of @(...) for better match of synthesis and simulation.\n"); } @@ -456,7 +456,7 @@ struct AST_INTERNAL::ProcessGenerator } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column); + set_src_attr(wire, always); chunk.wire = wire; chunk.offset = 0; @@ -591,7 +591,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); + set_src_attr(sw, ast); sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); @@ -625,7 +625,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; - current_case->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column); + set_src_attr(current_case, child); last_generated_case = current_case; addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); for (auto node : child->children) { @@ -1048,7 +1048,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // This is used by the hierarchy pass to know when it can replace interface connection with the individual // signals. RTLIL::Wire *wire = current_module->addWire(str, 1); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); wire->start_offset = 0; wire->port_id = port_id; wire->port_input = true; @@ -1089,7 +1089,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) current_module->connect(wire, val); wire->is_signed = children[0]->is_signed; - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); wire->attributes[type == AST_PARAMETER ? ID::parameter : ID::localparam] = 1; for (auto &attr : attributes) { @@ -1111,7 +1111,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); wire->start_offset = range_right; wire->port_id = port_id; wire->port_input = is_input; @@ -1143,7 +1143,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str()); RTLIL::Memory *memory = new RTLIL::Memory; - memory->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(memory, this); memory->name = str; memory->width = children[0]->range_left - children[0]->range_right + 1; if (children[1]->range_right < children[1]->range_left) { @@ -1200,7 +1200,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); wire->name = str; if (flag_autowire) log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str()); @@ -1582,10 +1582,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($memrd)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(cell, this); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); int mem_width, mem_size, addr_bits; is_signed = id2ast->is_signed; @@ -1621,7 +1621,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? ID($memwr) : ID($meminit)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(cell, this); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); @@ -1685,7 +1685,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cellname = str; RTLIL::Cell *cell = current_module->addCell(cellname, celltype); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(cell, this); for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -1730,7 +1730,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str()); RTLIL::Cell *cell = current_module->addCell(str, ""); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(cell, this); // Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass cell->set_bool_attribute(ID::module_not_derived); @@ -1894,7 +1894,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str()); Cell *cell = current_module->addCell(myid, str.substr(1)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(cell, this); cell->parameters[ID::WIDTH] = width; if (attributes.count(ID::reg)) { @@ -1905,7 +1905,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } Wire *wire = current_module->addWire(myid + "_wire", width); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + set_src_attr(wire, this); cell->setPort(ID::Y, wire); is_signed = sign_hint; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ae42d7ec660..6b4b9e04507 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -943,7 +943,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic) children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg) - log_warning("wire '%s' is assigned in a block at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str.c_str(), loc_string().c_str()); if (type == AST_ASSIGN && children[0]->id2ast->is_reg) { bool is_rand_reg = false; if (children[1]->type == AST_FCALL) { @@ -957,7 +957,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, is_rand_reg = true; } if (!is_rand_reg) - log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column); + log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str.c_str(), loc_string().c_str()); } children[0]->was_checked = true; } @@ -4541,8 +4541,8 @@ bool AstNode::replace_variables(std::map &varia if (children.size() != 1 || children.at(0)->type != AST_RANGE) { if (!must_succeed) return false; - log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s:%d.%d-%d.%d: ...called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s: ...called from here.\n", + fcall->loc_string().c_str()); } if (!children.at(0)->replace_variables(variables, fcall, must_succeed)) return false; @@ -4550,8 +4550,8 @@ bool AstNode::replace_variables(std::map &varia if (!children.at(0)->range_valid) { if (!must_succeed) return false; - log_file_error(filename, location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(filename, location.first_line, "Non-constant range\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } offset = min(children.at(0)->range_left, children.at(0)->range_right); width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width); @@ -4602,8 +4602,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!stmt->range_valid) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", - stmt->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s: ... called from here.\n", + stmt->str.c_str(), fcall->loc_string().c_str()); } AstNode::varinfo_t &variable = variables[stmt->str]; int width = abs(stmt->range_left - stmt->range_right) + 1; @@ -4664,22 +4664,22 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (stmt->children.at(1)->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here. X\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here. X\n", + fcall->loc_string().c_str()); } if (stmt->children.at(0)->type != AST_IDENTIFIER) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } if (!variables.count(stmt->children.at(0)->str)) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } if (stmt->children.at(0)->children.empty()) { @@ -4689,8 +4689,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!range->range_valid) { if (!must_succeed) goto finished; - log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } int offset = min(range->range_left, range->range_right); int width = std::abs(range->range_left - range->range_right) + 1; @@ -4725,8 +4725,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (cond->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } if (cond->asBool()) { @@ -4750,8 +4750,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (num->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } block->children.erase(block->children.begin()); @@ -4793,8 +4793,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (cond->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); } found_match = cond->asBool(); @@ -4829,8 +4829,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s:%d.%d-%d.%d: ... called from here.\n", - fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s: ... called from here.\n", + fcall->loc_string().c_str()); log_abort(); } From cde73428b046a1a87339f8a069f59ce732794617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 12:12:37 +0100 Subject: [PATCH 0220/2410] Fix syntax error in adff2dff.v Fixes #2600. --- techlibs/common/adff2dff.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/adff2dff.v b/techlibs/common/adff2dff.v index eca0110eb1f..2e4357b6477 100644 --- a/techlibs/common/adff2dff.v +++ b/techlibs/common/adff2dff.v @@ -11,7 +11,7 @@ module adff2dff (CLK, ARST, D, Q); (* force_downto *) output reg [WIDTH-1:0] Q; (* force_downto *) - wire reg [WIDTH-1:0] NEXT_Q; + reg [WIDTH-1:0] NEXT_Q; wire [1023:0] _TECHMAP_DO_ = "proc;;"; From b05b98521c781fef0f9d900a53310cad9e1434b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 21:23:26 +0100 Subject: [PATCH 0221/2410] Add tests for some common techmap files. --- tests/techmap/adff2dff.ys | 19 +++++++++++++++++++ tests/techmap/dff2ff.ys | 16 ++++++++++++++++ tests/techmap/pmux2mux.ys | 15 +++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 tests/techmap/adff2dff.ys create mode 100644 tests/techmap/dff2ff.ys create mode 100644 tests/techmap/pmux2mux.ys diff --git a/tests/techmap/adff2dff.ys b/tests/techmap/adff2dff.ys new file mode 100644 index 00000000000..53f7d2f0844 --- /dev/null +++ b/tests/techmap/adff2dff.ys @@ -0,0 +1,19 @@ +read_verilog -icells << EOT +module top(...); + +input [1:0] D; +input C, R; +output [1:0] Q; + +always @(posedge C, posedge R) + if (R) + Q <= 0; + else + Q <= D; + +endmodule +EOT + +proc + +equiv_opt -async2sync techmap -map +/adff2dff.v diff --git a/tests/techmap/dff2ff.ys b/tests/techmap/dff2ff.ys new file mode 100644 index 00000000000..5adf14b0719 --- /dev/null +++ b/tests/techmap/dff2ff.ys @@ -0,0 +1,16 @@ +read_verilog -icells << EOT +module top(...); + +input [1:0] D; +input C; +output [1:0] Q; + +always @(posedge C) + Q <= D; + +endmodule +EOT + +proc + +equiv_opt techmap -map +/dff2ff.v diff --git a/tests/techmap/pmux2mux.ys b/tests/techmap/pmux2mux.ys new file mode 100644 index 00000000000..1714a6b8795 --- /dev/null +++ b/tests/techmap/pmux2mux.ys @@ -0,0 +1,15 @@ +read_verilog -icells << EOT +module top(...); + +input [3:0] A; +input [3:0] B0; +input [3:0] B1; +input [1:0] S; +output [3:0] O; + +\$pmux #(.WIDTH(4), .S_WIDTH(2)) pm (.A(A), .B({B1, B0}), .S(S), .Y(O)); + +endmodule +EOT + +equiv_opt techmap -map +/pmux2mux.v From 5e439b6e3fdb498c821cccfed456547e9568f47b Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 23 Feb 2021 20:39:13 -0500 Subject: [PATCH 0222/2410] Fix double-free on unmatched logger error pattern When an expected logger error pattern is unmatched, the logger raises another (hidden) error. Because of the previous ordering of actions, `logv_error_with_prefix()` would inadvertently invoke `yosys_atexit()` twice, causing a double-free. --- kernel/log.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index c7ae873bc82..41e91119e97 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -345,9 +345,6 @@ static void logv_error_with_prefix(const char *prefix, log_make_debug = bak_log_make_debug; - if (log_error_atexit) - log_error_atexit(); - for (auto &item : log_expect_error) if (YS_REGEX_NS::regex_search(log_last_error, item.second.pattern)) item.second.current_count++; @@ -355,6 +352,9 @@ static void logv_error_with_prefix(const char *prefix, if (check_expected_logs) log_check_expected(); + if (log_error_atexit) + log_error_atexit(); + YS_DEBUGTRAP_IF_DEBUGGING; #ifdef EMSCRIPTEN From dcd9f0af23f9b580b044890452ecf1aef59bbb85 Mon Sep 17 00:00:00 2001 From: TimRudy <3942818+TimRudy@users.noreply.github.com> Date: Wed, 24 Feb 2021 15:48:15 -0500 Subject: [PATCH 0223/2410] Extend "delay" expressions to handle pair and triplet, i.e. rise, fall and turn-off (#2566) --- frontends/verilog/verilog_parser.y | 9 +- tests/verilog/delay_mintypmax.ys | 213 +++++++++++++++++++++++++++ tests/verilog/delay_risefall.ys | 225 +++++++++++++++++++++++++++++ 3 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 tests/verilog/delay_mintypmax.ys create mode 100644 tests/verilog/delay_risefall.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 7fbd2aa27f0..89e68681826 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -609,12 +609,17 @@ interface_body_stmt: param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | modport_stmt; +mintypmax_expr: + expr { delete $1; } | + expr ':' expr ':' expr { delete $1; delete $3; delete $5; }; + non_opt_delay: '#' TOK_ID { delete $2; } | '#' TOK_CONSTVAL { delete $2; } | '#' TOK_REALVAL { delete $2; } | - '#' '(' expr ')' { delete $3; } | - '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; }; + '#' '(' mintypmax_expr ')' | + '#' '(' mintypmax_expr ',' mintypmax_expr ')' | + '#' '(' mintypmax_expr ',' mintypmax_expr ',' mintypmax_expr ')'; delay: non_opt_delay | %empty; diff --git a/tests/verilog/delay_mintypmax.ys b/tests/verilog/delay_mintypmax.ys new file mode 100644 index 00000000000..74359f557f0 --- /dev/null +++ b/tests/verilog/delay_mintypmax.ys @@ -0,0 +1,213 @@ +logger -expect-no-warnings +read_verilog <> b) >>> c; +endmodule +EOT + +design -reset +logger -expect-no-warnings +read_verilog < inA[1]) out <= 1'b1; + else if (inA[0] < inA[1] - hyst) out <= 1'b0; + end +endmodule +EOT + +design -reset +logger -expect-no-warnings +read_verilog <> b) >>> c; +endmodule +EOT + +design -reset +logger -expect-no-warnings +read_verilog < inA[1]) out <= 1'b1; + else if (inA[0] < inA[1] - hyst) out <= 1'b0; + end +endmodule +EOT + +design -reset +logger -expect-no-warnings +read_verilog < inA[1]) out <= 1'b1; + else if (inA[0] < inA[1] - hyst) out <= 1'b0; + end +endmodule +EOT + +design -reset +logger -expect-no-warnings +read_verilog < Date: Mon, 22 Feb 2021 19:19:42 +0100 Subject: [PATCH 0224/2410] Fix handling of unique/unique0/priority cases in the frontend. Basically: - priority converts to (* full_case *) - unique0 converts to (* parallel_case *) - unique converts to (* parallel_case, full_case *) Fixes #2596. --- frontends/verilog/verilog_lexer.l | 2 +- frontends/verilog/verilog_parser.y | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index f2241066ff8..eeb7440f81f 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -234,7 +234,7 @@ static bool isUserType(std::string &s) "automatic" { return TOK_AUTOMATIC; } "unique" { SV_KEYWORD(TOK_UNIQUE); } -"unique0" { SV_KEYWORD(TOK_UNIQUE); } +"unique0" { SV_KEYWORD(TOK_UNIQUE0); } "priority" { SV_KEYWORD(TOK_PRIORITY); } "always_comb" { SV_KEYWORD(TOK_ALWAYS_COMB); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 89e68681826..dc7ec834873 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -277,7 +277,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY -%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY +%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY %token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_UNION %token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN @@ -286,7 +286,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %type opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type type_name %type opt_enum_init enum_type struct_type non_wire_data_type -%type opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff +%type opt_signed opt_property always_comb_or_latch always_or_always_ff %type attr case_attr %type struct_union @@ -2559,20 +2559,21 @@ behavioral_stmt: ast_stack.pop_back(); }; -unique_case_attr: - %empty { - $$ = false; +case_attr: + attr { + $$ = $1; } | - TOK_PRIORITY case_attr { - $$ = $2; + attr TOK_UNIQUE0 { + (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + $$ = $1; } | - TOK_UNIQUE case_attr { - $$ = true; - }; - -case_attr: - attr unique_case_attr { - if ($2) (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); + attr TOK_PRIORITY { + (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); + $$ = $1; + } | + attr TOK_UNIQUE { + (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); + (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false); $$ = $1; }; From 979347999f72591b5536e58110cfd491edccc937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 12:06:21 +0100 Subject: [PATCH 0225/2410] btor, smt2, smv: Add a hint on how to deal with funny FF types. --- backends/btor/btor.cc | 15 ++++++++++++++- backends/smt2/smt2.cc | 12 ++++++++++++ backends/smv/smv.cc | 18 ++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 639c6f12950..692452aad5b 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -860,7 +860,20 @@ struct BtorWorker goto okay; } - log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); + if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { + log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + log_error("Unsupported cell type %s for cell %s.%s.\n", + log_id(cell->type), log_id(module), log_id(cell)); okay: btorf_pop(log_id(cell)); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index a185fdd747d..8be9e05f11e 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -855,6 +855,18 @@ struct Smt2Worker return; } + if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { + log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } log_error("Unsupported cell type %s for cell %s.%s.\n", log_id(cell->type), log_id(module), log_id(cell)); } diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index 4e5c6050db6..e41582fea4a 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -573,8 +573,22 @@ struct SmvWorker continue; } - if (cell->type[0] == '$') - log_error("Found currently unsupported cell type %s (%s.%s).\n", log_id(cell->type), log_id(module), log_id(cell)); + if (cell->type[0] == '$') { + if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) { + log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") { + log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } + log_error("Unsupported cell type %s for cell %s.%s.\n", + log_id(cell->type), log_id(module), log_id(cell)); + } // f << stringf(" %s : %s;\n", cid(cell->name), cid(cell->type)); From 5d0cc54f5c36dea1d989438426a321b4554257c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 26 Feb 2021 00:24:33 +0100 Subject: [PATCH 0226/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 50f4f52b7e6..ced14cb486d 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3911 +YOSYS_VER := 0.9+3962 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 22bed385401a41b297790c3388b2e452cc037b54 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 25 Feb 2021 16:02:55 -0500 Subject: [PATCH 0227/2410] Extend simplify() recursion warning --- frontends/ast/simplify.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 6b4b9e04507..babd8c562f4 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -571,7 +571,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, static bool deep_recursion_warning = false; if (recursion_counter++ == 1000 && deep_recursion_warning) { - log_warning("Deep recursion in AST simplifier.\nDoes this design contain insanely long expressions?\n"); + log_warning("Deep recursion in AST simplifier.\nDoes this design contain overly long or deeply nested expressions, or excessive recursion?\n"); deep_recursion_warning = false; } From 8434ba5a3bb497f6fbf91dc4384390a4815bb98f Mon Sep 17 00:00:00 2001 From: Michael Singer Date: Tue, 23 Feb 2021 00:55:55 +0100 Subject: [PATCH 0228/2410] Implement $countbits function --- frontends/ast/simplify.cc | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index babd8c562f4..15948777116 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3089,6 +3089,65 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (str == "\\$countbits") { + if (children.size() < 2) + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected at least 2.\n", + RTLIL::unescape_id(str).c_str(), int(children.size())); + + std::vector control_bits; + + // Determine which bits to count + for (size_t i = 1; i < children.size(); i++) { + AstNode *node = children[i]; + while (node->simplify(true, false, false, stage, -1, false, false)) { } + if (node->type != AST_CONSTANT) + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str()); + if (node->bits.size() != 1) + log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str()); + control_bits.push_back(node->bits[0]); + } + + // Detect width of exp (first argument of $countbits) + int exp_width = -1; + bool exp_sign = false; + AstNode *exp = children[0]; + exp->detectSignWidth(exp_width, exp_sign, NULL); + + newNode = mkconst_int(0, false); + + for (int i = 0; i < exp_width; i++) { + // Generate nodes for: exp << i >> ($size(exp) - 1) + // ^^ ^^ + AstNode *lsh_node = new AstNode(AST_SHIFT_LEFT, exp->clone(), mkconst_int(i, false)); + AstNode *rsh_node = new AstNode(AST_SHIFT_RIGHT, lsh_node, mkconst_int(exp_width - 1, false)); + + AstNode *or_node = nullptr; + + for (RTLIL::State control_bit : control_bits) { + // Generate node for: (exp << i >> ($size(exp) - 1)) === control_bit + // ^^^ + AstNode *eq_node = new AstNode(AST_EQX, rsh_node->clone(), mkconst_bits({control_bit}, false)); + + // Or the result for each checked bit value + if (or_node) + or_node = new AstNode(AST_LOGIC_OR, or_node, eq_node); + else + or_node = eq_node; + } + + // We should have at least one element in control_bits, + // because we checked for the number of arguments above + log_assert(or_node != nullptr); + + delete rsh_node; + + // Generate node for adding with result of previous bit + newNode = new AstNode(AST_ADD, newNode, or_node); + } + + goto apply_newNode; + } + if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION) { AstNode *dpi_decl = current_scope[str]; From 04b41ed04a9fef53ab8be9d8ba1fd438a2286346 Mon Sep 17 00:00:00 2001 From: Michael Singer Date: Tue, 23 Feb 2021 01:19:06 +0100 Subject: [PATCH 0229/2410] Implement $countones, $isunknown and $onehot{,0} --- frontends/ast/simplify.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 15948777116..5c4dd290f7b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3148,6 +3148,34 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") { + if (children.size() != 1) + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + RTLIL::unescape_id(str).c_str(), int(children.size())); + + AstNode *countbits = clone(); + countbits->str = "\\$countbits"; + + if (str == "\\$countones") { + countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); + newNode = countbits; + } else if (str == "\\$isunknown") { + countbits->children.push_back(mkconst_bits({RTLIL::Sx}, false)); + countbits->children.push_back(mkconst_bits({RTLIL::Sz}, false)); + newNode = new AstNode(AST_GT, countbits, mkconst_int(0, false)); + } else if (str == "\\$onehot") { + countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); + newNode = new AstNode(AST_EQ, countbits, mkconst_int(1, false)); + } else if (str == "\\$onehot0") { + countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false)); + newNode = new AstNode(AST_LE, countbits, mkconst_int(1, false)); + } else { + log_abort(); + } + + goto apply_newNode; + } + if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION) { AstNode *dpi_decl = current_scope[str]; From d56b76bd7c79a2b77c62bf96fce6ca464244ba84 Mon Sep 17 00:00:00 2001 From: Michael Singer Date: Thu, 25 Feb 2021 01:21:36 +0100 Subject: [PATCH 0230/2410] Add tests for $countbits --- tests/various/countbits.sv | 69 ++++++++++++++++++++++++++++++++++++++ tests/various/countbits.ys | 7 ++++ 2 files changed, 76 insertions(+) create mode 100644 tests/various/countbits.sv create mode 100644 tests/various/countbits.ys diff --git a/tests/various/countbits.sv b/tests/various/countbits.sv new file mode 100644 index 00000000000..5762217bb46 --- /dev/null +++ b/tests/various/countbits.sv @@ -0,0 +1,69 @@ +module top; + + assert property ($countbits(15'b011xxxxzzzzzzzz, '0 ) == 1); + assert property ($countbits(15'b011xxxxzzzzzzzz, '1 ) == 2); + assert property ($countbits(15'b011xxxxzzzzzzzz, 'x ) == 4); + assert property ($countbits(15'b011xxxxzzzzzzzz, 'z ) == 8); + assert property ($countbits(15'b011xxxxzzzzzzzz, '0, '1 ) == 3); + assert property ($countbits(15'b011xxxxzzzzzzzz, '1, '1, '0 ) == 3); + assert property ($countbits(15'b011xxxxzzzzzzzz, '0, 'x ) == 5); + assert property ($countbits(15'b011xxxxzzzzzzzz, '0, 'z ) == 9); + assert property ($countbits(15'bz1x10xzxzzxzzzz, '0, 'z ) == 9); + assert property ($countbits(15'b011xxxxzzzzzzzz, 'x, 'z ) == 12); + assert property ($countbits(15'b011xxxxzzzzzzzz, '1, 'z ) == 10); + assert property ($countbits(15'b011xxxxzzzzzzzz, '1, 'x, 'z ) == 14); + assert property ($countbits(15'b011xxxxzzzzzzzz, '1, 'x, 'z, '0) == 15); + + assert property ($countbits(0, '0) == 32); // test integers + assert property ($countbits(0, '1) == 0); + assert property ($countbits(80'b0, '0) == 80); // test something bigger than integer + assert property ($countbits(80'bx0, 'x) == 79); + + always_comb begin + logic one; + logic [1:0] two; + logic [3:0] four; + + // Make sure that the width of the whole expression doesn't affect the width of the shift + // operations inside the function. + one = $countbits(3'b100, '1) & 1'b1; + two = $countbits(3'b111, '1) & 2'b11; + four = $countbits(3'b111, '1) & 4'b1111; + + assert (one == 1); + assert (two == 3); + assert (four == 3); + end + + assert property ($countones(8'h00) == 0); + assert property ($countones(8'hff) == 8); + assert property ($countones(8'ha5) == 4); + assert property ($countones(8'h13) == 3); + + logic test1 = 1'b1; + logic [4:0] test5 = 5'b10101; + + assert property ($countones(test1) == 1); + assert property ($countones(test5) == 3); + + assert property ($isunknown(8'h00) == 0); + assert property ($isunknown(8'hff) == 0); + assert property ($isunknown(8'hx0) == 1); + assert property ($isunknown(8'h1z) == 1); + assert property ($isunknown(8'hxz) == 1); + + assert property ($onehot(8'h00) == 0); + assert property ($onehot(8'hff) == 0); + assert property ($onehot(8'h01) == 1); + assert property ($onehot(8'h80) == 1); + assert property ($onehot(8'h81) == 0); + assert property ($onehot(8'h20) == 1); + + assert property ($onehot0(8'h00) == 1); + assert property ($onehot0(8'hff) == 0); + assert property ($onehot0(8'h01) == 1); + assert property ($onehot0(8'h80) == 1); + assert property ($onehot0(8'h81) == 0); + assert property ($onehot0(8'h20) == 1); + +endmodule diff --git a/tests/various/countbits.ys b/tests/various/countbits.ys new file mode 100644 index 00000000000..a556f7c5d83 --- /dev/null +++ b/tests/various/countbits.ys @@ -0,0 +1,7 @@ +read_verilog -sv countbits.sv +hierarchy +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all From bbff844acd15c274a6619050d1251aea4698ef56 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 26 Feb 2021 18:08:23 -0500 Subject: [PATCH 0231/2410] genrtlil: improve name conflict error messaging --- frontends/ast/genrtlil.cc | 49 ++++++++++++++++++------ tests/verilog/conflict_assert.ys | 8 ++++ tests/verilog/conflict_cell_memory.ys | 9 +++++ tests/verilog/conflict_interface_port.ys | 17 ++++++++ tests/verilog/conflict_memory_wire.ys | 7 ++++ tests/verilog/conflict_pwire.ys | 8 ++++ tests/verilog/conflict_wire_memory.ys | 7 ++++ 7 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 tests/verilog/conflict_assert.ys create mode 100644 tests/verilog/conflict_cell_memory.ys create mode 100644 tests/verilog/conflict_interface_port.ys create mode 100644 tests/verilog/conflict_memory_wire.ys create mode 100644 tests/verilog/conflict_pwire.ys create mode 100644 tests/verilog/conflict_wire_memory.ys diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 449f8c38e9d..d4299bf69c6 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1002,6 +1002,29 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real detectSignWidthWorker(width_hint, sign_hint, found_real); } +static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id, + const AstNode *node, const char *to_add_kind) +{ + auto already_exists = [&](const RTLIL::AttrObject *existing, const char *existing_kind) { + std::string src = existing->get_string_attribute(ID::src); + std::string location_str = "earlier"; + if (!src.empty()) + location_str = "at " + src; + log_file_error(node->filename, node->location.first_line, + "Cannot add %s `%s' because a %s with the same name was already created %s!\n", + to_add_kind, id.c_str(), existing_kind, location_str.c_str()); + }; + + if (const RTLIL::Wire *wire = module->wire(id)) + already_exists(wire, "signal"); + if (const RTLIL::Cell *cell = module->cell(id)) + already_exists(cell, "cell"); + if (module->processes.count(id)) + already_exists(module->processes.at(id), "process"); + if (module->memories.count(id)) + already_exists(module->memories.at(id), "memory"); +} + // create RTLIL from an AST node // all generated cells, wires and processes are added to the module pointed to by 'current_module' // when the AST node is an expression (AST_ADD, AST_BIT_XOR, etc.), the result signal is returned. @@ -1047,7 +1070,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // If a port in a module with unknown type is found, mark it with the attribute 'is_interface' // This is used by the hierarchy pass to know when it can replace interface connection with the individual // signals. - RTLIL::Wire *wire = current_module->addWire(str, 1); + RTLIL::IdString id = str; + check_unique_id(current_module, id, this, "interface port"); + RTLIL::Wire *wire = current_module->addWire(id, 1); set_src_attr(wire, this); wire->start_offset = 0; wire->port_id = port_id; @@ -1085,7 +1110,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str()); RTLIL::Const val = children[0]->bitsAsConst(); - RTLIL::Wire *wire = current_module->addWire(str, GetSize(val)); + RTLIL::IdString id = str; + check_unique_id(current_module, id, this, "pwire"); + RTLIL::Wire *wire = current_module->addWire(id, GetSize(val)); current_module->connect(wire, val); wire->is_signed = children[0]->is_signed; @@ -1102,15 +1129,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Wire for an AST_WIRE node case AST_WIRE: { - if (current_module->wires_.count(str) != 0) - log_file_error(filename, location.first_line, "Re-definition of signal `%s'!\n", str.c_str()); if (!range_valid) log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str()); if (!(range_left + 1 >= range_right)) log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); - RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); + RTLIL::IdString id = str; + check_unique_id(current_module, id, this, "signal"); + RTLIL::Wire *wire = current_module->addWire(id, range_left - range_right + 1); set_src_attr(wire, this); wire->start_offset = range_right; wire->port_id = port_id; @@ -1132,9 +1159,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Memory for an AST_MEMORY node case AST_MEMORY: { - if (current_module->memories.count(str) != 0) - log_file_error(filename, location.first_line, "Re-definition of memory `%s'!\n", str.c_str()); - log_assert(children.size() >= 2); log_assert(children[0]->type == AST_RANGE); log_assert(children[1]->type == AST_RANGE); @@ -1153,6 +1177,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) memory->start_offset = children[1]->range_left; memory->size = children[1]->range_right - children[1]->range_left + 1; } + check_unique_id(current_module, memory->name, this, "memory"); current_module->memories[memory->name] = memory; for (auto &attr : attributes) { @@ -1684,6 +1709,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) else cellname = str; + check_unique_id(current_module, cellname, this, "procedural assertion"); RTLIL::Cell *cell = current_module->addCell(cellname, celltype); set_src_attr(cell, this); @@ -1726,10 +1752,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { int port_counter = 0, para_counter = 0; - if (current_module->count_id(str) != 0) - log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str()); - - RTLIL::Cell *cell = current_module->addCell(str, ""); + RTLIL::IdString id = str; + check_unique_id(current_module, id, this, "cell"); + RTLIL::Cell *cell = current_module->addCell(id, ""); set_src_attr(cell, this); // Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass cell->set_bool_attribute(ID::module_not_derived); diff --git a/tests/verilog/conflict_assert.ys b/tests/verilog/conflict_assert.ys new file mode 100644 index 00000000000..121a0cf519c --- /dev/null +++ b/tests/verilog/conflict_assert.ys @@ -0,0 +1,8 @@ +logger -expect error "Cannot add procedural assertion `\\x' because a signal with the same name was already created" 1 +read_verilog -sv < Date: Sat, 27 Feb 2021 16:52:30 +0100 Subject: [PATCH 0232/2410] Update issue_template.md --- .github/issue_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index 5a0723c3e0a..c72daae3ec7 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -13,7 +13,7 @@ create a Minimal, Complete, and Verifiable example (MCVE). Please do not waste our time with issues that lack sufficient information to reproduce the issue easily. We will simply close those issues. -Contact https://www.symbioticeda.com/ if you need commercial support for Yosys. +Contact https://www.yosyshq.com/ if you need commercial support for Yosys. ## Expected behavior From ca4b1afcb687c03837c66b657fe73363cacf1e70 Mon Sep 17 00:00:00 2001 From: Robert Baruch Date: Sat, 27 Feb 2021 09:58:03 -0800 Subject: [PATCH 0233/2410] RTLIL Documentation: switch in process is optional --- manual/CHAPTER_TextRtlil.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/CHAPTER_TextRtlil.tex b/manual/CHAPTER_TextRtlil.tex index 243b56a87a4..5615a87079a 100644 --- a/manual/CHAPTER_TextRtlil.tex +++ b/manual/CHAPTER_TextRtlil.tex @@ -241,7 +241,7 @@ \subsection{Processes} ::= "process" - ::= $*$ $*$ $*$ + ::= $*$ $?$ $*$ $*$ ::= "assign" From 0f5b646ab8cd918821ce2924cc5dda01dbcba40f Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 28 Feb 2021 15:49:16 -0500 Subject: [PATCH 0234/2410] sv: extended support for integer types - Standard data declarations can now use any integer type - Parameters and localparams can now use any integer type - Function returns types can now use any integer type - Fix `parameter logic`, `localparam reg`, etc. to be 1 bit (previously 32 bits) - Added longint type (64 bits) - Unified parser source for integer type widths --- frontends/verilog/verilog_lexer.l | 1 + frontends/verilog/verilog_parser.y | 108 ++++++++++++++++++----------- tests/verilog/int_types.sv | 47 +++++++++++++ tests/verilog/int_types.ys | 7 ++ tests/verilog/param_int_types.sv | 19 +++++ tests/verilog/param_int_types.ys | 5 ++ 6 files changed, 148 insertions(+), 39 deletions(-) create mode 100644 tests/verilog/int_types.sv create mode 100644 tests/verilog/int_types.ys create mode 100644 tests/verilog/param_int_types.sv create mode 100644 tests/verilog/param_int_types.ys diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index eeb7440f81f..66772a09758 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -267,6 +267,7 @@ static bool isUserType(std::string &s) "int" { SV_KEYWORD(TOK_INT); } "byte" { SV_KEYWORD(TOK_BYTE); } "shortint" { SV_KEYWORD(TOK_SHORTINT); } +"longint" { SV_KEYWORD(TOK_LONGINT); } "eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); } "s_eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index dc7ec834873..476ee68ad1e 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -253,6 +253,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) struct specify_rise_fall *specify_rise_fall_ptr; bool boolean; char ch; + int integer; } %token TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE @@ -278,15 +279,17 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY -%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_UNION +%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_UNION %token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN -%type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int +%type range range_or_multirange non_opt_range non_opt_multirange %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type %type opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type type_name -%type opt_enum_init enum_type struct_type non_wire_data_type -%type opt_signed opt_property always_comb_or_latch always_or_always_ff +%type opt_enum_init enum_type struct_type non_wire_data_type func_return_type +%type opt_property always_comb_or_latch always_or_always_ff +%type opt_signedness_default_signed opt_signedness_default_unsigned +%type integer_atom_type %type attr case_attr %type struct_union @@ -716,12 +719,19 @@ wire_type_token: logic_type: TOK_LOGIC { } | - TOK_INTEGER { - astbuf3->range_left = 31; + integer_atom_type { + astbuf3->range_left = $1 - 1; astbuf3->range_right = 0; astbuf3->is_signed = true; }; +integer_atom_type: + TOK_INTEGER { $$ = 32; } | + TOK_INT { $$ = 32; } | + TOK_SHORTINT { $$ = 16; } | + TOK_LONGINT { $$ = 64; } | + TOK_BYTE { $$ = 8; } ; + non_opt_range: '[' expr ':' expr ']' { $$ = new AstNode(AST_RANGE); @@ -766,11 +776,6 @@ range_or_multirange: range { $$ = $1; } | non_opt_multirange { $$ = $1; }; -range_or_signed_int: - range { $$ = $1; } - | TOK_INTEGER { $$ = makeRange(); } - ; - module_body: module_body module_body_stmt | /* the following line makes the generate..endgenrate keywords optional */ @@ -841,29 +846,58 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - attr TOK_FUNCTION opt_automatic opt_signed range_or_signed_int TOK_ID { + attr TOK_FUNCTION opt_automatic func_return_type TOK_ID { current_function_or_task = new AstNode(AST_FUNCTION); - current_function_or_task->str = *$6; + current_function_or_task->str = *$5; append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - outreg->str = *$6; - outreg->is_signed = $4; + outreg->str = *$5; + outreg->is_signed = false; outreg->is_reg = true; - if ($5 != NULL) { - outreg->children.push_back($5); - outreg->is_signed = $4 || $5->is_signed; - $5->is_signed = false; + if ($4 != NULL) { + outreg->children.push_back($4); + outreg->is_signed = $4->is_signed; + $4->is_signed = false; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; - delete $6; + delete $5; } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); }; +func_return_type: + opt_type_vec opt_signedness_default_unsigned { + $$ = makeRange(0, 0, $2); + } | + opt_type_vec opt_signedness_default_unsigned non_opt_range { + $$ = $3; + $$->is_signed = $2; + } | + integer_atom_type opt_signedness_default_signed { + $$ = makeRange($1 - 1, 0, $2); + }; + +opt_type_vec: + %empty + | TOK_REG + | TOK_LOGIC + ; + +opt_signedness_default_signed: + %empty { $$ = true; } + | TOK_SIGNED { $$ = true; } + | TOK_UNSIGNED { $$ = false; } + ; +opt_signedness_default_unsigned: + %empty { $$ = false; } + | TOK_SIGNED { $$ = true; } + | TOK_UNSIGNED { $$ = false; } + ; + dpi_function_arg: TOK_ID TOK_ID { current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); @@ -889,14 +923,6 @@ opt_automatic: TOK_AUTOMATIC | %empty; -opt_signed: - TOK_SIGNED { - $$ = true; - } | - %empty { - $$ = false; - }; - task_func_args_opt: '(' ')' | %empty | '(' { albuf = nullptr; @@ -1379,11 +1405,8 @@ param_signed: } | %empty; param_integer: - TOK_INTEGER { - astbuf1->children.push_back(new AstNode(AST_RANGE)); - astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); - astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); - astbuf1->is_signed = true; + type_atom { + astbuf1->is_reg = false; }; param_real: @@ -1399,7 +1422,13 @@ param_range: }; param_integer_type: param_integer param_signed; -param_range_type: type_vec param_signed param_range; +param_range_type: + type_vec param_signed { + addRange(astbuf1, 0, 0); + } | + type_vec param_signed non_opt_range { + astbuf1->children.push_back($3); + }; param_implicit_type: param_signed param_range; param_type: @@ -1496,11 +1525,12 @@ enum_base_type: type_atom type_signing | %empty { astbuf1->is_reg = true; addRange(astbuf1); } ; -type_atom: TOK_INTEGER { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 4-state signed - | TOK_INT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 2-state signed - | TOK_SHORTINT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 15, 0); } // 2-state signed - | TOK_BYTE { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 7, 0); } // 2-state signed - ; +type_atom: + integer_atom_type { + astbuf1->is_reg = true; + astbuf1->is_signed = true; + addRange(astbuf1, $1 - 1, 0); + }; type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned | TOK_LOGIC { astbuf1->is_logic = true; } // unsigned diff --git a/tests/verilog/int_types.sv b/tests/verilog/int_types.sv new file mode 100644 index 00000000000..8133f8218b8 --- /dev/null +++ b/tests/verilog/int_types.sv @@ -0,0 +1,47 @@ +`define TEST(typ, width, is_signed) \ + if (1) begin \ + typ x = -1; \ + localparam typ y = -1; \ + logic [127:0] a = x; \ + logic [127:0] b = y; \ + if ($bits(x) != width) \ + $error(`"typ doesn't have expected size width`"); \ + if ($bits(x) != $bits(y)) \ + $error(`"localparam typ doesn't match size of typ`"); \ + function automatic typ f; \ + input integer x; \ + f = x; \ + endfunction \ + logic [127:0] c = f(-1); \ + always @* begin \ + assert (x == y); \ + assert (a == b); \ + assert (a == c); \ + assert ((a == -1) == is_signed); \ + end \ + end + +`define TEST_INTEGER_ATOM(typ, width) \ + `TEST(typ, width, 1) \ + `TEST(typ signed, width, 1) \ + `TEST(typ unsigned, width, 0) + +`define TEST_INTEGER_VECTOR(typ) \ + `TEST(typ, 1, 0) \ + `TEST(typ signed, 1, 1) \ + `TEST(typ unsigned, 1, 0) \ + `TEST(typ [1:0], 2, 0) \ + `TEST(typ signed [1:0], 2, 1) \ + `TEST(typ unsigned [1:0], 2, 0) + +module top; + `TEST_INTEGER_ATOM(integer, 32) + `TEST_INTEGER_ATOM(int, 32) + `TEST_INTEGER_ATOM(shortint, 16) + `TEST_INTEGER_ATOM(longint, 64) + `TEST_INTEGER_ATOM(byte, 8) + + `TEST_INTEGER_VECTOR(reg) + `TEST_INTEGER_VECTOR(logic) + `TEST_INTEGER_VECTOR(bit) +endmodule diff --git a/tests/verilog/int_types.ys b/tests/verilog/int_types.ys new file mode 100644 index 00000000000..c17c44b4ce0 --- /dev/null +++ b/tests/verilog/int_types.ys @@ -0,0 +1,7 @@ +read_verilog -sv int_types.sv +hierarchy +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all diff --git a/tests/verilog/param_int_types.sv b/tests/verilog/param_int_types.sv new file mode 100644 index 00000000000..3228369b8d2 --- /dev/null +++ b/tests/verilog/param_int_types.sv @@ -0,0 +1,19 @@ +module gate(out); + parameter integer a = -1; + parameter int b = -2; + parameter shortint c = -3; + parameter longint d = -4; + parameter byte e = -5; + output wire [1023:0] out; + assign out = {a, b, c, d, e}; +endmodule + +module gold(out); + integer a = -1; + int b = -2; + shortint c = -3; + longint d = -4; + byte e = -5; + output wire [1023:0] out; + assign out = {a, b, c, d, e}; +endmodule diff --git a/tests/verilog/param_int_types.ys b/tests/verilog/param_int_types.ys new file mode 100644 index 00000000000..7727801cf61 --- /dev/null +++ b/tests/verilog/param_int_types.ys @@ -0,0 +1,5 @@ +read_verilog -sv param_int_types.sv +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From b6904a8e5344fcd01c1a0feea281cd7d7bf0f210 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 9 Feb 2021 19:58:15 -0500 Subject: [PATCH 0235/2410] Set aside extraneous tests in simple_abc9 test suite New test cases on one branch may be automatically copied from simple/ to simple_abc9/, causing failures when switching to another branch. This updates the simple_abc9 script to set aside extraneous tests in a non-destructive way. --- tests/simple_abc9/.gitignore | 1 + tests/simple_abc9/run-test.sh | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/tests/simple_abc9/.gitignore b/tests/simple_abc9/.gitignore index 2355aea2953..fda60e57785 100644 --- a/tests/simple_abc9/.gitignore +++ b/tests/simple_abc9/.gitignore @@ -2,3 +2,4 @@ *.sv *.log *.out +*.bak diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index 650e42fcab8..b48505e29ad 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -17,6 +17,24 @@ if ! command -v iverilog > /dev/null ; then exit 1 fi +for file in `ls *.v *.sv`; do + if [ ! -f "../simple/$file" -a "$file" != "abc9.v" ]; then + echo "Warning: $file is in simple_abc9/, but not in simple/" + backup="$file.bak" + if [ -f "$backup" ]; then + if cmp "$file" "$backup" > /dev/null; then + echo " => $backup already exists and matches; removing $file" + rm "$file" + else + echo " => $backup already exists but differs; leaving $file in place" + fi + else + echo " => moving $file to $backup" + mv -i "$file" "$backup" + fi + fi +done + cp ../simple/*.v . cp ../simple/*.sv . DOLLAR='?' From 1ec5994100510d6fb9e18ff7234ede496f831a51 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 25 Feb 2021 15:53:55 -0500 Subject: [PATCH 0236/2410] verilog: fix handling of nested ifdef directives - track depth so we know whether to consider higher-level elsifs - error on unmatched endif/elsif/else --- frontends/verilog/preproc.cc | 49 ++++++++++++++---- tests/simple/ifdef_1.v | 88 ++++++++++++++++++++++++++++++++ tests/simple/ifdef_2.v | 21 ++++++++ tests/verilog/include_self.v | 30 +++++++++++ tests/verilog/include_self.ys | 2 + tests/verilog/unmatched_else.ys | 6 +++ tests/verilog/unmatched_elsif.ys | 6 +++ tests/verilog/unmatched_endif.ys | 6 +++ 8 files changed, 197 insertions(+), 11 deletions(-) create mode 100644 tests/simple/ifdef_1.v create mode 100644 tests/simple/ifdef_2.v create mode 100644 tests/verilog/include_self.v create mode 100644 tests/verilog/include_self.ys create mode 100644 tests/verilog/unmatched_else.ys create mode 100644 tests/verilog/unmatched_elsif.ys create mode 100644 tests/verilog/unmatched_endif.ys diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index de707593f9b..84966e50190 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -727,7 +727,8 @@ frontend_verilog_preproc(std::istream &f, std::vector filename_stack; int ifdef_fail_level = 0; - bool in_elseif = false; + int ifdef_pass_level = 0; + bool ifdef_already_satisfied = false; output_code.clear(); input_buffer.clear(); @@ -743,42 +744,68 @@ frontend_verilog_preproc(std::istream &f, if (tok == "`endif") { if (ifdef_fail_level > 0) ifdef_fail_level--; - if (ifdef_fail_level == 0) - in_elseif = false; + else if (ifdef_pass_level > 0) + ifdef_already_satisfied = --ifdef_pass_level; + else + log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); continue; } if (tok == "`else") { - if (ifdef_fail_level == 0) + if (ifdef_fail_level == 0) { + if (ifdef_pass_level == 0) + log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); + log_assert(ifdef_already_satisfied); ifdef_fail_level = 1; - else if (ifdef_fail_level == 1 && !in_elseif) + } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied) { ifdef_fail_level = 0; + ifdef_pass_level++; + ifdef_already_satisfied = true; + } continue; } if (tok == "`elsif") { skip_spaces(); std::string name = next_token(true); - if (ifdef_fail_level == 0) - ifdef_fail_level = 1, in_elseif = true; - else if (ifdef_fail_level == 1 && defines.find(name)) - ifdef_fail_level = 0, in_elseif = true; + if (ifdef_fail_level == 0) { + if (ifdef_pass_level == 0) + log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); + log_assert(ifdef_already_satisfied); + ifdef_fail_level = 1; + } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied && defines.find(name)) { + ifdef_fail_level = 0; + ifdef_pass_level++; + ifdef_already_satisfied = true; + } continue; } if (tok == "`ifdef") { skip_spaces(); std::string name = next_token(true); - if (ifdef_fail_level > 0 || !defines.find(name)) + if (ifdef_fail_level > 0 || !defines.find(name)) { ifdef_fail_level++; + } else { + ifdef_pass_level++; + ifdef_already_satisfied = true; + } + if (ifdef_fail_level == 1) + ifdef_already_satisfied = false; continue; } if (tok == "`ifndef") { skip_spaces(); std::string name = next_token(true); - if (ifdef_fail_level > 0 || defines.find(name)) + if (ifdef_fail_level > 0 || defines.find(name)) { ifdef_fail_level++; + } else { + ifdef_pass_level++; + ifdef_already_satisfied = true; + } + if (ifdef_fail_level == 1) + ifdef_already_satisfied = false; continue; } diff --git a/tests/simple/ifdef_1.v b/tests/simple/ifdef_1.v new file mode 100644 index 00000000000..fa962355cb9 --- /dev/null +++ b/tests/simple/ifdef_1.v @@ -0,0 +1,88 @@ +module top(o1, o2, o3, o4); + +`define FAIL input wire not_a_port; + +`ifdef COND_1 + `FAIL +`elsif COND_2 + `FAIL +`elsif COND_3 + `FAIL +`elsif COND_4 + `FAIL +`else + + `define COND_4 + output wire o4; + + `ifdef COND_1 + `FAIL + `elsif COND_2 + `FAIL + `elsif COND_3 + `FAIL + `elsif COND_4 + + `define COND_3 + output wire o3; + + `ifdef COND_1 + `FAIL + `elsif COND_2 + `FAIL + `elsif COND_3 + + `define COND_2 + output wire o2; + + `ifdef COND_1 + `FAIL + `elsif COND_2 + + `define COND_1 + output wire o1; + + `ifdef COND_1 + + `ifdef COND_1 + `elsif COND_2 + `FAIL + `elsif COND_3 + `FAIL + `elsif COND_4 + `FAIL + `else + `FAIL + `endif + + `elsif COND_2 + `FAIL + `elsif COND_3 + `FAIL + `elsif COND_4 + `FAIL + `else + `FAIL + `endif + + `elsif COND_3 + `FAIL + `elsif COND_4 + `FAIL + `else + `FAIL + `endif + + `elsif COND_4 + `FAIL + `else + `FAIL + `endif + + `else + `FAIL + `endif + +`endif + +endmodule diff --git a/tests/simple/ifdef_2.v b/tests/simple/ifdef_2.v new file mode 100644 index 00000000000..6dd89efed76 --- /dev/null +++ b/tests/simple/ifdef_2.v @@ -0,0 +1,21 @@ +module top(o1, o2, o3); + +output wire o1; + +`define COND_1 +`define COND_2 +`define COND_3 + +`ifdef COND_1 + output wire o2; +`elsif COND_2 + input wire dne1; +`elsif COND_3 + input wire dne2; +`else + input wire dne3; +`endif + +output wire o3; + +endmodule diff --git a/tests/verilog/include_self.v b/tests/verilog/include_self.v new file mode 100644 index 00000000000..23ffc710411 --- /dev/null +++ b/tests/verilog/include_self.v @@ -0,0 +1,30 @@ +`ifdef GUARD_5 +module top; + wire x; +endmodule + +`elsif GUARD_4 +`define GUARD_5 +`include "include_self.v" + +`elsif GUARD_3 +`define GUARD_4 +`include "include_self.v" + +`elsif GUARD_2 +`define GUARD_3 +`include "include_self.v" + +`elsif GUARD_1 +`define GUARD_2 +`include "include_self.v" + +`elsif GUARD_0 +`define GUARD_1 +`include "include_self.v" + +`else +`define GUARD_0 +`include "include_self.v" + +`endif diff --git a/tests/verilog/include_self.ys b/tests/verilog/include_self.ys new file mode 100644 index 00000000000..07d840d6886 --- /dev/null +++ b/tests/verilog/include_self.ys @@ -0,0 +1,2 @@ +read_verilog include_self.v +select -assert-count 1 top/x diff --git a/tests/verilog/unmatched_else.ys b/tests/verilog/unmatched_else.ys new file mode 100644 index 00000000000..413f413c3f2 --- /dev/null +++ b/tests/verilog/unmatched_else.ys @@ -0,0 +1,6 @@ +logger -expect error "Found `else outside of macro conditional branch!" 1 +read_verilog < Date: Mon, 1 Mar 2021 19:33:05 +0100 Subject: [PATCH 0237/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ced14cb486d..1fed7ae0e74 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3962 +YOSYS_VER := 0.9+3981 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 10a6bc9b81d1c2236e80a608778c904aebe54c28 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 1 Mar 2021 13:31:25 -0500 Subject: [PATCH 0238/2410] verilog: fix sizing of ports with int types in module headers Declaring the ports as standard module items already worked as expected. This adds a missing usage of `checkRange()` so that headers such as `module m(output integer x);` now work correctly. --- frontends/verilog/verilog_parser.y | 5 +-- tests/verilog/port_int_types.sv | 50 ++++++++++++++++++++++++++++++ tests/verilog/port_int_types.ys | 11 +++++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 tests/verilog/port_int_types.sv create mode 100644 tests/verilog/port_int_types.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 476ee68ad1e..bcba9b76a94 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -546,8 +546,9 @@ module_arg: node->str = *$4; SET_AST_NODE_LOC(node, @4, @4); node->port_id = ++port_counter; - if ($3 != NULL) - node->children.push_back($3); + AstNode *range = checkRange(node, $3); + if (range != NULL) + node->children.push_back(range); if (!node->is_input && !node->is_output) frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $4->c_str()); if (node->is_reg && node->is_input && !node->is_output && !sv_mode) diff --git a/tests/verilog/port_int_types.sv b/tests/verilog/port_int_types.sv new file mode 100644 index 00000000000..40e2cf14add --- /dev/null +++ b/tests/verilog/port_int_types.sv @@ -0,0 +1,50 @@ +`define INITS \ + assign a = -1; \ + assign b = -2; \ + assign c = -3; \ + assign d = -4; \ + assign a_ext = a; \ + assign b_ext = b; \ + assign c_ext = c; \ + assign d_ext = d; + +module gate_a( + output byte a, + output byte unsigned b, + output shortint c, + output shortint unsigned d, + output [31:0] a_ext, + output [31:0] b_ext, + output [31:0] c_ext, + output [31:0] d_ext +); + `INITS +endmodule + +module gate_b( + a, b, c, d, + a_ext, b_ext, c_ext, d_ext +); + output byte a; + output byte unsigned b; + output shortint c; + output shortint unsigned d; + output [31:0] a_ext; + output [31:0] b_ext; + output [31:0] c_ext; + output [31:0] d_ext; + `INITS +endmodule + +module gold( + output signed [7:0] a, + output unsigned [7:0] b, + output signed [15:0] c, + output unsigned [15:0] d, + output [31:0] a_ext, + output [31:0] b_ext, + output [31:0] c_ext, + output [31:0] d_ext +); + `INITS +endmodule diff --git a/tests/verilog/port_int_types.ys b/tests/verilog/port_int_types.ys new file mode 100644 index 00000000000..75888e1a8b7 --- /dev/null +++ b/tests/verilog/port_int_types.ys @@ -0,0 +1,11 @@ +read_verilog -sv port_int_types.sv +equiv_make gold gate_a equiv +equiv_simple +equiv_status -assert + +design -reset + +read_verilog -sv port_int_types.sv +equiv_make gold gate_b equiv +equiv_simple +equiv_status -assert From d738b2c1272b02d8799e9feda83b1eae8ba10c07 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 2 Mar 2021 10:43:53 -0500 Subject: [PATCH 0239/2410] sv: support for parameters without default values - Modules with a parameter without a default value will be automatically deferred until the hierarchy pass - Allows for parameters without defaults as module items, rather than just int the `parameter_port_list`, despite being forbidden in the LRM - Check for parameters without defaults that haven't been overriden - Add location info to parameter/localparam declarations --- frontends/ast/ast.cc | 29 ++++++++++- frontends/verilog/verilog_parser.y | 24 +++++++-- tests/verilog/localparam_no_default_1.ys | 17 +++++++ tests/verilog/localparam_no_default_2.ys | 15 ++++++ tests/verilog/param_no_default.sv | 52 ++++++++++++++++++++ tests/verilog/param_no_default.ys | 7 +++ tests/verilog/param_no_default_not_svmode.ys | 26 ++++++++++ tests/verilog/param_no_default_unbound_1.ys | 12 +++++ tests/verilog/param_no_default_unbound_2.ys | 12 +++++ tests/verilog/param_no_default_unbound_3.ys | 12 +++++ tests/verilog/param_no_default_unbound_4.ys | 12 +++++ tests/verilog/param_no_default_unbound_5.ys | 12 +++++ 12 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 tests/verilog/localparam_no_default_1.ys create mode 100644 tests/verilog/localparam_no_default_2.ys create mode 100644 tests/verilog/param_no_default.sv create mode 100644 tests/verilog/param_no_default.ys create mode 100644 tests/verilog/param_no_default_not_svmode.ys create mode 100644 tests/verilog/param_no_default_unbound_1.ys create mode 100644 tests/verilog/param_no_default_unbound_2.ys create mode 100644 tests/verilog/param_no_default_unbound_3.ys create mode 100644 tests/verilog/param_no_default_unbound_4.ys create mode 100644 tests/verilog/param_no_default_unbound_5.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 57552d86c62..7fb61bb34ed 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -968,6 +968,14 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast) obj->attributes[ID::src] = ast->loc_string(); } +static bool param_has_no_default(const AstNode *param) { + const auto &children = param->children; + log_assert(param->type == AST_PARAMETER); + log_assert(children.size() <= 2); + return children.empty() || + (children.size() == 1 && children[0]->type == AST_RANGE); +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { @@ -1006,6 +1014,10 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast if (!defer) { + for (const AstNode *node : ast->children) + if (node->type == AST_PARAMETER && param_has_no_default(node)) + log_file_error(node->filename, node->location.first_line, "Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str()); + bool blackbox_module = flag_lib; if (!blackbox_module && !flag_noblackbox) { @@ -1229,7 +1241,18 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (flag_icells && (*it)->str.compare(0, 2, "\\$") == 0) (*it)->str = (*it)->str.substr(1); - if (defer) + bool defer_local = defer; + if (!defer_local) + for (const AstNode *node : (*it)->children) + if (node->type == AST_PARAMETER && param_has_no_default(node)) + { + log("Deferring `%s' because it contains parameter(s) without defaults.\n", ast->str.c_str()); + defer_local = true; + break; + } + + + if (defer_local) (*it)->str = "$abstract" + (*it)->str; if (design->has((*it)->str)) { @@ -1248,7 +1271,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } } - design->add(process_module(*it, defer)); + design->add(process_module(*it, defer_local)); current_ast_mod = nullptr; } else if ((*it)->type == AST_PACKAGE) { @@ -1619,6 +1642,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictchildren.insert(child->children.begin(), nullptr); delete child->children.at(0); if ((it->second.flags & RTLIL::CONST_FLAG_REAL) != 0) { child->children[0] = new AstNode(AST_REALVALUE); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index bcba9b76a94..ea8cc0765d0 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1462,7 +1462,26 @@ param_decl_list: single_param_decl | param_decl_list ',' single_param_decl; single_param_decl: - TOK_ID '=' expr { + single_param_decl_ident '=' expr { + AstNode *decl = ast_stack.back()->children.back(); + log_assert(decl->type == AST_PARAMETER || decl->type == AST_LOCALPARAM); + delete decl->children[0]; + decl->children[0] = $3; + } | + single_param_decl_ident { + AstNode *decl = ast_stack.back()->children.back(); + if (decl->type != AST_PARAMETER) { + log_assert(decl->type == AST_LOCALPARAM); + frontend_verilog_yyerror("localparam initialization is missing!"); + } + if (!sv_mode) + frontend_verilog_yyerror("Parameter defaults can only be omitted in SystemVerilog mode!"); + delete decl->children[0]; + decl->children.erase(decl->children.begin()); + }; + +single_param_decl_ident: + TOK_ID { AstNode *node; if (astbuf1 == nullptr) { if (!sv_mode) @@ -1473,10 +1492,9 @@ single_param_decl: node = astbuf1->clone(); } node->str = *$1; - delete node->children[0]; - node->children[0] = $3; ast_stack.back()->children.push_back(node); delete $1; + SET_AST_NODE_LOC(node, @1, @1); }; defparam_decl: diff --git a/tests/verilog/localparam_no_default_1.ys b/tests/verilog/localparam_no_default_1.ys new file mode 100644 index 00000000000..426a48a1c92 --- /dev/null +++ b/tests/verilog/localparam_no_default_1.ys @@ -0,0 +1,17 @@ +logger -expect-no-warnings +read_verilog -sv < Date: Tue, 2 Mar 2021 18:28:56 -0500 Subject: [PATCH 0240/2410] clk2fflogic: nice names for autogenerated signals --- kernel/yosys.cc | 17 +++++++++++++++++ kernel/yosys.h | 3 +++ passes/sat/clk2fflogic.cc | 28 +++++++++++++++++++--------- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index dcaf364e929..1caf80c1128 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -616,6 +616,23 @@ RTLIL::IdString new_id(std::string file, int line, std::string func) return stringf("$auto$%s:%d:%s$%d", file.c_str(), line, func.c_str(), autoidx++); } +RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix) +{ +#ifdef _WIN32 + size_t pos = file.find_last_of("/\\"); +#else + size_t pos = file.find_last_of('/'); +#endif + if (pos != std::string::npos) + file = file.substr(pos+1); + + pos = func.find_last_of(':'); + if (pos != std::string::npos) + func = func.substr(pos+1); + + return stringf("$auto$%s:%d:%s$%s$%d", file.c_str(), line, func.c_str(), suffix.c_str(), autoidx++); +} + RTLIL::Design *yosys_get_design() { return yosys_design; diff --git a/kernel/yosys.h b/kernel/yosys.h index 43aecdbc8e5..5df7e2df047 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -321,9 +321,12 @@ Tcl_Interp *yosys_get_tcl_interp(); extern RTLIL::Design *yosys_design; RTLIL::IdString new_id(std::string file, int line, std::string func); +RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix); #define NEW_ID \ YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) +#define NEW_ID_SUFFIX(suffix) \ + YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) // Create a statically allocated IdString object, using for example ID::A or ID($add). // diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index cbf7c5435e9..b9ba5ee3c5c 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -40,7 +40,10 @@ struct Clk2fflogicPass : public Pass { log("\n"); } SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity) { - Wire *past_sig = module->addWire(NEW_ID, GetSize(sig)); + return wrap_async_control(module, sig, polarity, NEW_ID); + } + SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity, IdString past_sig_id) { + Wire *past_sig = module->addWire(past_sig_id, GetSize(sig)); module->addFf(NEW_ID, sig, past_sig); if (polarity) sig = module->Or(NEW_ID, sig, past_sig); @@ -105,7 +108,7 @@ struct Clk2fflogicPass : public Pass { i, log_id(module), log_id(mem.memid), log_signal(port.clk), log_signal(port.addr), log_signal(port.data)); - Wire *past_clk = module->addWire(NEW_ID); + Wire *past_clk = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#past_clk#%s", log_id(mem.memid), i, log_signal(port.clk)))); past_clk->attributes[ID::init] = port.clk_polarity ? State::S1 : State::S0; module->addFf(NEW_ID, port.clk, past_clk); @@ -121,13 +124,13 @@ struct Clk2fflogicPass : public Pass { SigSpec clock_edge = module->Eqx(NEW_ID, {port.clk, SigSpec(past_clk)}, clock_edge_pattern); - SigSpec en_q = module->addWire(NEW_ID, GetSize(port.en)); + SigSpec en_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#en_q", log_id(mem.memid), i)), GetSize(port.en)); module->addFf(NEW_ID, port.en, en_q); - SigSpec addr_q = module->addWire(NEW_ID, GetSize(port.addr)); + SigSpec addr_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#addr_q", log_id(mem.memid), i)), GetSize(port.addr)); module->addFf(NEW_ID, port.addr, addr_q); - SigSpec data_q = module->addWire(NEW_ID, GetSize(port.data)); + SigSpec data_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#%d#data_q", log_id(mem.memid), i)), GetSize(port.data)); module->addFf(NEW_ID, port.data, data_q); port.clk = State::S0; @@ -153,7 +156,13 @@ struct Clk2fflogicPass : public Pass { continue; } - Wire *past_q = module->addWire(NEW_ID, ff.width); + // Strip spaces from signal name, since Yosys IDs can't contain spaces + // Spaces only occur when have a signal that's a slice of a larger bus, + // e.g. "\myreg [5:0]", so removing spaces shouldn't result in loss of uniqueness + std::string sig_q_str = log_signal(ff.sig_q); + sig_q_str.erase(std::remove(sig_q_str.begin(), sig_q_str.end(), ' '), sig_q_str.end()); + + Wire *past_q = module->addWire(NEW_ID_SUFFIX(stringf("%s#past_q_wire", sig_q_str.c_str())), ff.width); if (!ff.is_fine) { module->addFf(NEW_ID, ff.sig_q, past_q); } else { @@ -165,7 +174,7 @@ struct Clk2fflogicPass : public Pass { if (ff.has_clk) { ff.unmap_ce_srst(module); - Wire *past_clk = module->addWire(NEW_ID); + Wire *past_clk = module->addWire(NEW_ID_SUFFIX(stringf("%s#past_clk#%s", sig_q_str.c_str(), log_signal(ff.sig_clk)))); initvals.set_init(past_clk, ff.pol_clk ? State::S1 : State::S0); if (!ff.is_fine) @@ -189,7 +198,7 @@ struct Clk2fflogicPass : public Pass { SigSpec clock_edge = module->Eqx(NEW_ID, {ff.sig_clk, SigSpec(past_clk)}, clock_edge_pattern); - Wire *past_d = module->addWire(NEW_ID, ff.width); + Wire *past_d = module->addWire(NEW_ID_SUFFIX(stringf("%s#past_d_wire", sig_q_str.c_str())), ff.width); if (!ff.is_fine) module->addFf(NEW_ID, ff.sig_d, past_d); else @@ -236,7 +245,8 @@ struct Clk2fflogicPass : public Pass { module->addAndGate(NEW_ID, qval, clrval, ff.sig_q); } } else if (ff.has_arst) { - SigSpec arst = wrap_async_control(module, ff.sig_arst, ff.pol_arst); + IdString id = NEW_ID_SUFFIX(stringf("%s#past_arst#%s", sig_q_str.c_str(), log_signal(ff.sig_arst))); + SigSpec arst = wrap_async_control(module, ff.sig_arst, ff.pol_arst, id); if (!ff.is_fine) module->addMux(NEW_ID, qval, ff.val_arst, arst, ff.sig_q); else From 6c56c083f8c55d28a3dc0dc8e17a611fd31a2261 Mon Sep 17 00:00:00 2001 From: Claire Xen Date: Thu, 4 Mar 2021 16:43:30 +0100 Subject: [PATCH 0241/2410] Update README --- frontends/verific/README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontends/verific/README b/frontends/verific/README index c37d7634346..952fb1e0cce 100644 --- a/frontends/verific/README +++ b/frontends/verific/README @@ -1,11 +1,11 @@ This directory contains Verific bindings for Yosys. -Use Symbiotic EDA Suite if you need Yosys+Verifc. -https://www.symbioticeda.com/seda-suite +Use Tabby CAD Suite from YosysHQ if you need Yosys+Verifc. +https://www.yosyshq.com/ -Contact office@symbioticeda.com for free evaluation -binaries of Symbiotic EDA Suite. +Contact YosysHQ at contact@yosyshq.com for free evaluation +binaries of Tabby CAD Suite. Verific Features that should be enabled in your Verific library From 7d2097b00538fa366cc433b23c2c307db0e3a4be Mon Sep 17 00:00:00 2001 From: Claire Xen Date: Thu, 4 Mar 2021 16:45:21 +0100 Subject: [PATCH 0242/2410] Update command-reference-manual.tex --- manual/command-reference-manual.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index 988f034b4bc..e2d54cb03c5 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -6652,11 +6652,11 @@ \section{verific -- load Verilog and VHDL designs using Verific} Dump the Verific netlist as a verilog file. -Use Symbiotic EDA Suite if you need Yosys+Verifc. -https://www.symbioticeda.com/seda-suite +Use YosysHQ Tabby CAD Suite if you need Yosys+Verific. +https://www.yosyshq.com/\n"); -Contact office@symbioticeda.com for free evaluation -binaries of Symbiotic EDA Suite. +Contact office@yosyshq.com for free evaluation +binaries of YosysHQ Tabby CAD Suite. \end{lstlisting} \section{verilog\_defaults -- set default options for read\_verilog} From c18ddbcd822410095d28c4be1c3ac3c6358622d2 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 4 Mar 2021 15:08:16 -0500 Subject: [PATCH 0243/2410] verilog: impose limit on maximum expression width Designs with unreasonably wide expressions would previously get stuck allocating memory forever. --- frontends/ast/genrtlil.cc | 6 ++++++ tests/verilog/absurd_width.ys | 17 +++++++++++++++++ tests/verilog/absurd_width_const.ys | 16 ++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/verilog/absurd_width.ys create mode 100644 tests/verilog/absurd_width_const.ys diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d4299bf69c6..e0a52243054 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1000,6 +1000,12 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real if (found_real) *found_real = false; detectSignWidthWorker(width_hint, sign_hint, found_real); + + constexpr int kWidthLimit = 1 << 24; + if (width_hint >= kWidthLimit) + log_file_error(filename, location.first_line, + "Expression width %d exceeds implementation limit of %d!\n", + width_hint, kWidthLimit); } static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id, diff --git a/tests/verilog/absurd_width.ys b/tests/verilog/absurd_width.ys new file mode 100644 index 00000000000..c0d2af4c28e --- /dev/null +++ b/tests/verilog/absurd_width.ys @@ -0,0 +1,17 @@ +logger -expect error "Expression width 1073741824 exceeds implementation limit of 16777216!" 1 +read_verilog < Date: Fri, 5 Mar 2021 11:05:19 +0000 Subject: [PATCH 0244/2410] cxxrtl: don't crash on empty designs. --- backends/cxxrtl/cxxrtl_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 39046bd782f..a312c1e21dc 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2763,7 +2763,7 @@ struct CxxrtlWorker { // Recheck the design if it was modified. if (did_anything) check_design(design, has_top, has_sync_init, has_packed_mem); - log_assert(has_top && !has_sync_init && !has_packed_mem); + log_assert(!has_sync_init && !has_packed_mem); log_pop(); if (did_anything) log_spacer(); From 8471808834bd15a51f1f41fdbf4a3cbffb0b4b02 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 5 Mar 2021 11:44:39 +0000 Subject: [PATCH 0245/2410] cxxrtl: add pass debug flag to show assigned wire types. Refs #2543. --- backends/cxxrtl/cxxrtl_backend.cc | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 39046bd782f..8c86cf75dc3 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -614,6 +614,8 @@ struct CxxrtlWorker { std::ostream *impl_f = nullptr; std::ostream *intf_f = nullptr; + bool print_wire_types = false; + bool print_debug_wire_types = false; bool run_hierarchy = false; bool run_flatten = false; bool run_proc = false; @@ -2684,6 +2686,35 @@ struct CxxrtlWorker { if (debug_live_nodes[node]) debug_schedule[module].push_back(*node); } + + auto show_wire_type = [&](const RTLIL::Wire* wire, const WireType &wire_type) { + const char *type_str; + switch (wire_type.type) { + case WireType::UNUSED: type_str = "UNUSED"; break; + case WireType::BUFFERED: type_str = "BUFFERED"; break; + case WireType::MEMBER: type_str = "MEMBER"; break; + case WireType::OUTLINE: type_str = "OUTLINE"; break; + case WireType::LOCAL: type_str = "LOCAL"; break; + case WireType::INLINE: type_str = "INLINE"; break; + case WireType::ALIAS: type_str = "ALIAS"; break; + case WireType::CONST: type_str = "CONST"; break; + default: type_str = "(invalid)"; + } + if (wire_type.sig_subst.empty()) + log_debug(" %s: %s\n", log_signal((RTLIL::Wire*)wire), type_str); + else + log_debug(" %s: %s = %s\n", log_signal((RTLIL::Wire*)wire), type_str, log_signal(wire_type.sig_subst)); + }; + if (print_wire_types && !wire_types.empty()) { + log_debug("Wire types:\n"); + for (auto wire_type : wire_types) + show_wire_type(wire_type.first, wire_type.second); + } + if (print_debug_wire_types && !debug_wire_types.empty()) { + log_debug("Debug wire types:\n"); + for (auto debug_wire_type : debug_wire_types) + show_wire_type(debug_wire_type.first, debug_wire_type.second); + } } if (has_feedback_arcs || has_buffered_comb_wires) { // Although both non-feedback buffered combinatorial wires and apparent feedback wires may be eliminated @@ -2934,6 +2965,9 @@ struct CxxrtlBackend : public Backend { log("\n"); log("The following options are supported by this backend:\n"); log("\n"); + log(" -print-wire-types, -print-debug-wire-types\n"); + log(" enable additional debug logging, for pass developers.\n"); + log("\n"); log(" -header\n"); log(" generate separate interface (.h) and implementation (.cc) files.\n"); log(" if specified, the backend must be called with a filename, and filename\n"); @@ -3013,6 +3047,8 @@ struct CxxrtlBackend : public Backend { void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override { + bool print_wire_types = false; + bool print_debug_wire_types = false; bool nohierarchy = false; bool noflatten = false; bool noproc = false; @@ -3025,6 +3061,14 @@ struct CxxrtlBackend : public Backend { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-print-wire-types") { + print_wire_types = true; + continue; + } + if (args[argidx] == "-print-debug-wire-types") { + print_debug_wire_types = true; + continue; + } if (args[argidx] == "-nohierarchy") { nohierarchy = true; continue; @@ -3076,6 +3120,8 @@ struct CxxrtlBackend : public Backend { } extra_args(f, filename, args, argidx); + worker.print_wire_types = print_wire_types; + worker.print_debug_wire_types = print_debug_wire_types; worker.run_hierarchy = !nohierarchy; worker.run_flatten = !noflatten; worker.run_proc = !noproc; From 14ce8bdaa6a1120c48a934697488c463ffb15b48 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 5 Mar 2021 12:08:48 +0000 Subject: [PATCH 0246/2410] cxxrtl: follow aliases to outlines when emitting $memrd.ADDR. --- backends/cxxrtl/cxxrtl_backend.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 39046bd782f..f2ff8a46832 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1231,7 +1231,9 @@ struct CxxrtlWorker { RTLIL::Memory *memory = cell->module->memories[cell->getParam(ID::MEMID).decode_string()]; std::string valid_index_temp = fresh_temporary(); f << indent << "auto " << valid_index_temp << " = memory_index("; - dump_sigspec_rhs(cell->getPort(ID::ADDR)); + // Almost all non-elidable cells cannot appear in debug_eval(), but $memrd is an exception; asynchronous + // memory read ports can. + dump_sigspec_rhs(cell->getPort(ID::ADDR), for_debug); f << ", " << memory->start_offset << ", " << memory->size << ");\n"; if (cell->type == ID($memrd)) { bool has_enable = cell->getParam(ID::CLK_ENABLE).as_bool() && !cell->getPort(ID::EN).is_fully_ones(); From 55e5bd4213c8065994fb916e72105d822bd4175a Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Fri, 5 Mar 2021 21:45:11 +0000 Subject: [PATCH 0247/2410] Replace assert in addModule with more useful error message --- kernel/rtlil.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1faf376e7fd..40079ffc5f8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -613,7 +613,8 @@ void RTLIL::Design::add(RTLIL::Module *module) RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) { - log_assert(modules_.count(name) == 0); + if (modules_.count(name) != 0) + log_error("Attempted to add new module named '%s', but a module by that name already exists\n", name.c_str()); log_assert(refcount_modules_ == 0); RTLIL::Module *module = new RTLIL::Module; From 3d2aef0bde5ee35d283da4b230430ffcb73ec176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 6 Mar 2021 01:18:24 +0100 Subject: [PATCH 0248/2410] Remove a few functions that, in fact, did not exist in the first place. --- kernel/rtlil.h | 2 -- misc/py_wrap_generator.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6170ea55ea4..f03f27617ec 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1339,7 +1339,6 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); - RTLIL::SigSpec Bu0 (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = ""); RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = ""); @@ -1520,7 +1519,6 @@ struct RTLIL::CaseRule : public RTLIL::AttrObject std::vector switches; ~CaseRule(); - void optimize(); bool empty() const; diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 38bd6129eea..2de3c1f99f8 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -997,7 +997,7 @@ def contains_default_constr(self): Source("kernel/cost",[]) ] -blacklist_methods = ["YOSYS_NAMESPACE::Pass::run_register", "YOSYS_NAMESPACE::Module::Pow", "YOSYS_NAMESPACE::Module::Bu0", "YOSYS_NAMESPACE::CaseRule::optimize"] +blacklist_methods = ["YOSYS_NAMESPACE::Pass::run_register", "YOSYS_NAMESPACE::Module::Pow"] enum_names = ["State","SyncType","ConstFlags"] From d245e2bae59d18eb641aa6b324eef1bbbfa13c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 6 Mar 2021 11:05:57 +0100 Subject: [PATCH 0249/2410] proc_clean: Fix empty case removal conditions. Fixes #2639. --- passes/proc/proc_clean.cc | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 5e78b7316dc..54d5a81ff22 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -76,22 +76,33 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did } else { - bool all_fully_def = true; for (auto cs : sw->cases) - { if (max_depth != 0) proc_clean_case(cs, did_something, count, max_depth-1); - int size = 0; - for (auto cmp : cs->compare) + + bool is_parallel_case = sw->get_bool_attribute(ID::parallel_case); + bool is_full_case = sw->get_bool_attribute(ID::full_case); + + // Empty case removal. The rules are: + // + // - for full_case: only remove cases if *all* cases are empty + // - for parallel_case but not full_case: remove any empty case + // - for non-parallel and non-full case: remove the final case if it's empty + + if (is_full_case) + { + bool all_empty = true; + for (auto cs : sw->cases) + if (!cs->empty()) + all_empty = false; + if (all_empty) { - size += cmp.size(); - if (!cmp.is_fully_def()) - all_fully_def = false; + for (auto cs : sw->cases) + delete cs; + sw->cases.clear(); } - if (sw->signal.size() != size) - all_fully_def = false; } - if (all_fully_def) + else if (is_parallel_case) { for (auto cs = sw->cases.begin(); cs != sw->cases.end();) { From b1a8e73a609d3065f1caf7a230529443b54295bc Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 3 Mar 2021 14:36:19 -0500 Subject: [PATCH 0250/2410] sv: fix some edge cases for unbased unsized literals - Fix explicit size cast of unbased unsized literals - Fix unbased unsized literal bound directly to port - Output `is_unsized` flag in `dumpAst` --- frontends/ast/ast.cc | 2 ++ frontends/ast/simplify.cc | 22 +++++++++++++++++- tests/verilog/unbased_unsized.sv | 40 ++++++++++++++++++++++++++++++++ tests/verilog/unbased_unsized.ys | 7 ++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/unbased_unsized.sv create mode 100644 tests/verilog/unbased_unsized.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 57552d86c62..88e6aa1c938 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -317,6 +317,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const fprintf(f, " reg"); if (is_signed) fprintf(f, " signed"); + if (is_unsized) + fprintf(f, " unsized"); if (basic_prep) fprintf(f, " basic_prep"); if (lookahead) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5c4dd290f7b..e7f897b3c8d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -915,6 +915,22 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } + if (type == AST_ARGUMENT) + { + if (children.size() == 1 && children[0]->type == AST_CONSTANT) + { + // HACK: For port bindings using unbased unsized literals, mark them + // signed so they sign-extend. The hierarchy will still incorrectly + // generate a warning complaining about resizing the expression. + // This also doesn't handle the complex of something like a ternary + // expression bound to a port, where the actual size of the port is + // needed to resolve the expression correctly. + AstNode *arg = children[0]; + if (arg->is_unsized) + arg->is_signed = true; + } + } + int backup_width_hint = width_hint; bool backup_sign_hint = sign_hint; @@ -3773,7 +3789,11 @@ replace_fcall_later:; case AST_CAST_SIZE: if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) { int width = children[0]->bitsAsConst().as_int(); - RTLIL::Const val = children[1]->bitsAsConst(width); + RTLIL::Const val; + if (children[1]->is_unsized) + val = children[1]->bitsAsUnsizedConst(width); + else + val = children[1]->bitsAsConst(width); newNode = mkconst_bits(val.bits, children[1]->is_signed); } break; diff --git a/tests/verilog/unbased_unsized.sv b/tests/verilog/unbased_unsized.sv new file mode 100644 index 00000000000..1d0c5a72c31 --- /dev/null +++ b/tests/verilog/unbased_unsized.sv @@ -0,0 +1,40 @@ +module pass_through( + input [63:0] inp, + output [63:0] out +); + assign out = inp; +endmodule + +module top; + logic [63:0] + o01, o02, o03, o04, + o05, o06, o07, o08, + o09, o10, o11, o12, + o13, o14, o15, o16; + assign o01 = '0; + assign o02 = '1; + assign o03 = 'x; + assign o04 = 'z; + assign o05 = 3'('0); + assign o06 = 3'('1); + assign o07 = 3'('x); + assign o08 = 3'('z); + pass_through pt09('0, o09); + pass_through pt10('1, o10); + pass_through pt11('x, o11); + pass_through pt12('z, o12); + always @* begin + assert (o01 === {64 {1'b0}}); + assert (o02 === {64 {1'b1}}); + assert (o03 === {64 {1'bx}}); + assert (o04 === {64 {1'bz}}); + assert (o05 === {61'b0, 3'b000}); + assert (o06 === {61'b0, 3'b111}); + assert (o07 === {61'b0, 3'bxxx}); + assert (o08 === {61'b0, 3'bzzz}); + assert (o09 === {64 {1'b0}}); + assert (o10 === {64 {1'b1}}); + assert (o11 === {64 {1'bx}}); + assert (o12 === {64 {1'bz}}); + end +endmodule diff --git a/tests/verilog/unbased_unsized.ys b/tests/verilog/unbased_unsized.ys new file mode 100644 index 00000000000..e1bc99c64a7 --- /dev/null +++ b/tests/verilog/unbased_unsized.ys @@ -0,0 +1,7 @@ +read_verilog -sv unbased_unsized.sv +hierarchy +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all From d1de08e38a31c312cb0bd23e7376e80461bdcb22 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 7 Mar 2021 14:28:45 +0000 Subject: [PATCH 0251/2410] cxxrtl: allow `always` sync rules in debug_eval. These can be produced from `always @*` processes, if `-noproc` is used. --- backends/cxxrtl/cxxrtl_backend.cc | 42 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index d7402087fdd..b6cc4bb6dc7 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1415,30 +1415,30 @@ struct CxxrtlWorker { collect_sigspec_rhs(port.second, for_debug, cells); } - void dump_assign(const RTLIL::SigSig &sigsig) + void dump_assign(const RTLIL::SigSig &sigsig, bool for_debug = false) { f << indent; - dump_sigspec_lhs(sigsig.first); + dump_sigspec_lhs(sigsig.first, for_debug); f << " = "; - dump_sigspec_rhs(sigsig.second); + dump_sigspec_rhs(sigsig.second, for_debug); f << ";\n"; } - void dump_case_rule(const RTLIL::CaseRule *rule) + void dump_case_rule(const RTLIL::CaseRule *rule, bool for_debug = false) { for (auto action : rule->actions) - dump_assign(action); + dump_assign(action, for_debug); for (auto switch_ : rule->switches) - dump_switch_rule(switch_); + dump_switch_rule(switch_, for_debug); } - void dump_switch_rule(const RTLIL::SwitchRule *rule) + void dump_switch_rule(const RTLIL::SwitchRule *rule, bool for_debug = false) { // The switch attributes are printed before the switch condition is captured. dump_attrs(rule); std::string signal_temp = fresh_temporary(); f << indent << "const value<" << rule->signal.size() << "> &" << signal_temp << " = "; - dump_sigspec(rule->signal, /*is_lhs=*/false); + dump_sigspec(rule->signal, /*is_lhs=*/false, for_debug); f << ";\n"; bool first = true; @@ -1458,7 +1458,7 @@ struct CxxrtlWorker { first = false; if (compare.is_fully_def()) { f << signal_temp << " == "; - dump_sigspec(compare, /*is_lhs=*/false); + dump_sigspec(compare, /*is_lhs=*/false, for_debug); } else if (compare.is_fully_const()) { RTLIL::Const compare_mask, compare_value; for (auto bit : compare.as_const()) { @@ -1492,26 +1492,28 @@ struct CxxrtlWorker { } f << "{\n"; inc_indent(); - dump_case_rule(case_); + dump_case_rule(case_, for_debug); dec_indent(); } f << indent << "}\n"; } - void dump_process_case(const RTLIL::Process *proc) + void dump_process_case(const RTLIL::Process *proc, bool for_debug = false) { dump_attrs(proc); f << indent << "// process " << proc->name.str() << " case\n"; // The case attributes (for root case) are always empty. log_assert(proc->root_case.attributes.empty()); - dump_case_rule(&proc->root_case); + dump_case_rule(&proc->root_case, for_debug); } - void dump_process_syncs(const RTLIL::Process *proc) + void dump_process_syncs(const RTLIL::Process *proc, bool for_debug = false) { dump_attrs(proc); f << indent << "// process " << proc->name.str() << " syncs\n"; for (auto sync : proc->syncs) { + log_assert(!for_debug || sync->type == RTLIL::STa); + RTLIL::SigBit sync_bit; if (!sync->signal.empty()) { sync_bit = sync->signal[0]; @@ -1556,7 +1558,7 @@ struct CxxrtlWorker { f << ") {\n"; inc_indent(); for (auto action : sync->actions) - dump_assign(action); + dump_assign(action, for_debug); dec_indent(); f << indent << "}\n"; } @@ -1725,12 +1727,12 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell); break; - case FlowGraph::Node::Type::PROCESS_SYNC: - dump_process_syncs(node.process); - break; case FlowGraph::Node::Type::PROCESS_CASE: dump_process_case(node.process); break; + case FlowGraph::Node::Type::PROCESS_SYNC: + dump_process_syncs(node.process); + break; } } } @@ -1754,6 +1756,12 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell, /*for_debug=*/true); break; + case FlowGraph::Node::Type::PROCESS_CASE: + dump_process_case(node.process, /*for_debug=*/true); + break; + case FlowGraph::Node::Type::PROCESS_SYNC: + dump_process_syncs(node.process, /*for_debug=*/true); + break; default: log_abort(); } From ab76d9cec5ba38539f1578a78f3c810a659ea092 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 7 Mar 2021 14:29:30 +0000 Subject: [PATCH 0252/2410] cxxrtl: don't assert on edge sync rules tied to a constant. These are commonly the result of tying an async reset to an inactive level. --- backends/cxxrtl/cxxrtl_backend.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index b6cc4bb6dc7..0071bda7f65 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1518,6 +1518,8 @@ struct CxxrtlWorker { if (!sync->signal.empty()) { sync_bit = sync->signal[0]; sync_bit = sigmaps[sync_bit.wire->module](sync_bit); + if (!sync_bit.is_wire()) + continue; // a clock, or more commonly a reset, can be tied to a constant driver } pool events; @@ -2285,6 +2287,8 @@ struct CxxrtlWorker { void register_edge_signal(SigMap &sigmap, RTLIL::SigSpec signal, RTLIL::SyncType type) { signal = sigmap(signal); + if (signal.is_fully_const()) + return; // a clock, or more commonly a reset, can be tied to a constant driver log_assert(is_valid_clock(signal)); log_assert(type == RTLIL::STp || type == RTLIL::STn || type == RTLIL::STe); From 9cdc6b5f2e416cd469a2480460986189f61b10a7 Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Fri, 5 Mar 2021 22:13:15 +0000 Subject: [PATCH 0253/2410] Replace assert in abc9_ops with more useful error message --- passes/techmap/abc9_ops.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 98d0207c4ce..3f3e667de47 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -778,7 +778,15 @@ void prep_xaiger(RTLIL::Module *module, bool dff) continue; if (!box_module->get_bool_attribute(ID::abc9_box)) continue; - log_assert(cell->parameters.empty()); + if (!cell->parameters.empty()) + // At this stage of the ABC9 flow, all modules must be nonparametric, because ABC itself requires concrete netlists, and the presence of + // parameters implies a non-concrete netlist. This error needs some explaining, because there are (at least) two ways to get this: + // 1) You have an (* abc9_box *) parametric whitebox but due to a bug somewhere this hasn't been monomorphised into a concrete blackbox. + // This is a bug, and a bug report would be welcomed. + // 2) You have an (* abc9_box *) parametric blackbox (e.g. to store associated cell data) but want to provide timing data for ABC9. + // This is not supported due to the presence of parameters. If you want to store associated cell data for a box, one approach could be + // to techmap the parameters to constant module inputs, and then after ABC9 use _TECHMAP_CONSTVAL_XX_ to retrieve the values again. + log_error("Black box '%s' is marked (* abc9_box *) and has parameters, which is forbidden in prep_xaiger\n", log_id(cell_name)); log_assert(box_module->get_blackbox_attribute()); cell->attributes[ID::abc9_box_seq] = box_count++; From bdc4fd0e92913961c6e3728d8d4976022514dc23 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 7 Mar 2021 16:06:25 -0500 Subject: [PATCH 0254/2410] Fix param without default log line --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index af5e326adbe..0cfde0fc3ed 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1248,7 +1248,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump for (const AstNode *node : (*it)->children) if (node->type == AST_PARAMETER && param_has_no_default(node)) { - log("Deferring `%s' because it contains parameter(s) without defaults.\n", ast->str.c_str()); + log("Deferring `%s' because it contains parameter(s) without defaults.\n", (*it)->str.c_str()); defer_local = true; break; } From d555454969aed080d345b044eefb20a2ce53eae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 4 Mar 2021 17:55:57 +0100 Subject: [PATCH 0255/2410] tests/bram: Do not generate write address collisions. These have no defined semantics, making the tests non-deterministic. --- tests/bram/generate.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/tests/bram/generate.py b/tests/bram/generate.py index def0b23c1d4..79dd500a388 100644 --- a/tests/bram/generate.py +++ b/tests/bram/generate.py @@ -93,18 +93,22 @@ def generate_clkpol(i): tb_dout = list() tb_addrlist = list() + addrmask = (1 << abits) - 1 + for i in range(10): - tb_addrlist.append(random.randrange(1048576)) + tb_addrlist.append(random.randrange(1048576) & addrmask) t = random.randrange(1048576) for i in range(10): - tb_addrlist.append(t ^ (1 << i)) + tb_addrlist.append((t ^ (1 << i)) & addrmask) v_stmts.append("(* nomem2reg *) reg [%d:0] memory [0:%d];" % (dbits-1, 2**abits-1)) portindex = 0 last_always_hdr = (-1, "") + addr2en = {} + for p1 in range(groups): for p2 in range(ports[p1]): pf = "%c%d" % (chr(ord("A") + p1), p2 + 1) @@ -143,6 +147,7 @@ def generate_clkpol(i): v_stmts.append("input [%d:0] %sEN;" % (enable[p1]-1, pf)) tb_decls.append("reg [%d:0] %sEN;" % (enable[p1]-1, pf)) tb_din.append("%sEN" % pf) + addr2en["%sADDR" % pf] = "%sEN" % pf assign_op = "<=" if clocks[p1] == 0: @@ -247,10 +252,23 @@ def generate_clkpol(i): print(" #100;", file=tb_f) print(" $display(\"bram_%02d_%02d %3d: %%b %%b %%s\", %s, %s, error ? \"ERROR\" : \"OK\");" % (k1, k2, i, expr_dout, expr_dout_ref), file=tb_f) - for p in tb_din: - print(" %s <= %d;" % (p, random.randrange(1048576)), file=tb_f) + a2e = {} for p in tb_addr: - print(" %s <= %d;" % (p, random.choice(tb_addrlist)), file=tb_f) + addr = random.choice(tb_addrlist) + if p in addr2en: + if addr not in a2e: + a2e[addr] = [] + a2e[addr].append(addr2en[p]) + print(" %s <= %d;" % (p, addr), file=tb_f) + enzero = set() + for v in a2e.values(): + x = random.choice(v) + for s in v: + if s != x: + enzero.add(s) + for p in tb_din: + val = 0 if p in enzero else random.randrange(1048576) + print(" %s <= %d;" % (p, val), file=tb_f) print(" #900;", file=tb_f) print(" end", file=tb_f) From bc717abad2187b2aacaac7e9b8e152462769056a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 5 Mar 2021 01:23:25 +0100 Subject: [PATCH 0256/2410] memory_dff: Remove code looking for $mux cells. This job is now performed by `opt_dff`, which runs before this pass. --- passes/memory/memory_dff.cc | 68 +++++++------------------------------ 1 file changed, 12 insertions(+), 56 deletions(-) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 4adcb462edf..64881672e18 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -33,7 +33,6 @@ struct MemoryDffWorker vector dff_cells; dict invbits; dict sigbit_users_count; - dict mux_cells_a, mux_cells_b; pool forward_merged_dffs, candidate_dffs; FfInitVals initvals; @@ -276,58 +275,19 @@ struct MemoryDffWorker if (sigbit_users_count[bit] > 1) goto skip_ff_after_read_merging; - if (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)) + if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { - RTLIL::SigSpec en; - std::vector check_q; - - do { - bool enable_invert = mux_cells_a.count(sig_data) != 0; - Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data); - check_q.push_back(sigmap(mux->getPort(enable_invert ? ID::B : ID::A))); - sig_data = sigmap(mux->getPort(ID::Y)); - en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort(ID::S)) : mux->getPort(ID::S)); - } while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)); - - for (auto bit : sig_data) - if (sigbit_users_count[bit] > 1) - goto skip_ff_after_read_merging; - - if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && - std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; })) - { - if (en_data != State::S1 || !en_polarity) { - if (!en_polarity) - en_data = module->LogicNot(NEW_ID, en_data); - en.append(en_data); - } - disconnect_dff(sig_data); - cell->setPort(ID::CLK, clk_data); - cell->setPort(ID::EN, en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en); - cell->setPort(ID::DATA, sig_data); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); - cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0); - log("merged data $dff with rd enable to cell.\n"); - return; - } - } - else - { - if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) - { - if (!en_polarity) - en_data = module->LogicNot(NEW_ID, en_data); - disconnect_dff(sig_data); - cell->setPort(ID::CLK, clk_data); - cell->setPort(ID::EN, en_data); - cell->setPort(ID::DATA, sig_data); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); - cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0); - log("merged data $dff to cell.\n"); - return; - } + if (!en_polarity) + en_data = module->LogicNot(NEW_ID, en_data); + disconnect_dff(sig_data); + cell->setPort(ID::CLK, clk_data); + cell->setPort(ID::EN, en_data); + cell->setPort(ID::DATA, sig_data); + cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); + cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); + cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0); + log("merged data $dff to cell.\n"); + return; } skip_ff_after_read_merging:; @@ -360,10 +320,6 @@ struct MemoryDffWorker for (auto cell : module->cells()) { if (cell->type.in(ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce))) dff_cells.push_back(cell); - if (cell->type == ID($mux)) { - mux_cells_a[sigmap(cell->getPort(ID::A))] = cell; - mux_cells_b[sigmap(cell->getPort(ID::B))] = cell; - } if (cell->type.in(ID($not), ID($_NOT_)) || (cell->type == ID($logic_not) && GetSize(cell->getPort(ID::A)) == 1)) { SigSpec sig_a = cell->getPort(ID::A); SigSpec sig_y = cell->getPort(ID::Y); From 760284033d6f255790d44bfcda0d1625a0c7bc87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 6 Mar 2021 03:59:03 +0100 Subject: [PATCH 0257/2410] proc_dff: Fix emitted FF when a register is not assigned in async reset Fixes #2619. --- passes/proc/proc_dff.cc | 4 ++++ tests/proc/bug2619.ys | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/proc/bug2619.ys diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index e320a72a678..2b6ca8449c8 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -328,6 +328,10 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) ce.assign_map.apply(sig); if (rstval == sig) { + if (sync_level->type == RTLIL::SyncType::ST1) + insig = mod->Mux(NEW_ID, insig, sig, sync_level->signal); + else + insig = mod->Mux(NEW_ID, sig, insig, sync_level->signal); rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); sync_level = NULL; } diff --git a/tests/proc/bug2619.ys b/tests/proc/bug2619.ys new file mode 100644 index 00000000000..a080b94f5f2 --- /dev/null +++ b/tests/proc/bug2619.ys @@ -0,0 +1,23 @@ +read_verilog << EOT + +module top(...); + +input D1, D2, R, CLK; +output reg Q1, Q2; + +always @(posedge CLK, posedge R) begin + Q1 <= 0; + if (!R) begin + Q1 <= D1; + Q2 <= D2; + end +end + +endmodule + +EOT + +proc +opt +select -assert-count 1 t:$adff +select -assert-count 1 t:$dffe From c00a29296c8d3446c7cfe253080c7e33358219b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 1 Mar 2021 20:01:39 +0100 Subject: [PATCH 0258/2410] sim: Avoid a crash on empty cell connection. Fixes #2513. --- passes/sat/sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 3ba66bd33cc..922be886c0a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -271,7 +271,7 @@ struct SimInstance { auto child = children.at(cell); for (auto &conn: cell->connections()) - if (cell->input(conn.first)) { + if (cell->input(conn.first) && GetSize(conn.second)) { Const value = get_state(conn.second); child->set_state(child->module->wire(conn.first), value); } From 4e03865d5bf3fafe0bd3735c88431675d53d2663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 00:21:46 +0100 Subject: [PATCH 0259/2410] Add support for memory writes in processes. --- backends/rtlil/rtlil_backend.cc | 23 ++++++- frontends/rtlil/rtlil_lexer.l | 1 + frontends/rtlil/rtlil_parser.y | 19 +++++- kernel/rtlil.cc | 1 + kernel/rtlil.h | 21 ++++++ manual/CHAPTER_Overview.tex | 5 +- passes/cmds/bugpoint.cc | 17 +++++ passes/cmds/check.cc | 8 +++ passes/cmds/show.cc | 5 ++ passes/proc/Makefile.inc | 1 + passes/proc/proc.cc | 2 + passes/proc/proc_arst.cc | 54 ++++++++++------ passes/proc/proc_clean.cc | 2 +- passes/proc/proc_dlatch.cc | 7 +- passes/proc/proc_init.cc | 11 +--- passes/proc/proc_memwr.cc | 111 ++++++++++++++++++++++++++++++++ 16 files changed, 245 insertions(+), 43 deletions(-) create mode 100644 passes/proc/proc_memwr.cc diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index 01b4bde5330..cfdf3efc5bf 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -242,11 +242,28 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT case RTLIL::STi: f << stringf("init\n"); break; } - for (auto it = sy->actions.begin(); it != sy->actions.end(); ++it) { + for (auto &it: sy->actions) { f << stringf("%s update ", indent.c_str()); - dump_sigspec(f, it->first); + dump_sigspec(f, it.first); f << stringf(" "); - dump_sigspec(f, it->second); + dump_sigspec(f, it.second); + f << stringf("\n"); + } + + for (auto &it: sy->mem_write_actions) { + for (auto it2 = it.attributes.begin(); it2 != it.attributes.end(); ++it2) { + f << stringf("%s attribute %s ", indent.c_str(), it2->first.c_str()); + dump_const(f, it2->second); + f << stringf("\n"); + } + f << stringf("%s memwr %s ", indent.c_str(), it.memid.c_str()); + dump_sigspec(f, it.address); + f << stringf(" "); + dump_sigspec(f, it.data); + f << stringf(" "); + dump_sigspec(f, it.enable); + f << stringf(" "); + dump_sigspec(f, it.priority_mask); f << stringf("\n"); } } diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l index beef220f6f0..897ebf66784 100644 --- a/frontends/rtlil/rtlil_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -79,6 +79,7 @@ USING_YOSYS_NAMESPACE "global" { return TOK_GLOBAL; } "init" { return TOK_INIT; } "update" { return TOK_UPDATE; } +"memwr" { return TOK_MEMWR; } "process" { return TOK_PROCESS; } "end" { return TOK_END; } diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 64648919623..7a8f508bf13 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -69,7 +69,7 @@ USING_YOSYS_NAMESPACE %token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_GLOBAL TOK_INIT -%token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET +%token TOK_UPDATE TOK_MEMWR TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET %token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_REAL TOK_UPTO %type sigspec_list_reversed @@ -155,6 +155,7 @@ param_defval_stmt: TOK_PARAMETER TOK_ID constant EOL { current_module->avail_parameters($2); current_module->parameter_default_values[$2] = *$3; + delete $3; free($2); }; @@ -389,6 +390,22 @@ update_list: delete $3; delete $4; } | + update_list attr_list TOK_MEMWR TOK_ID sigspec sigspec sigspec constant EOL { + RTLIL::MemWriteAction act; + act.attributes = attrbuf; + act.memid = $4; + act.address = *$5; + act.data = *$6; + act.enable = *$7; + act.priority_mask = *$8; + current_process->syncs.back()->mem_write_actions.push_back(std::move(act)); + attrbuf.clear(); + free($4); + delete $5; + delete $6; + delete $7; + delete $8; + } | /* empty */; constant: diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 40079ffc5f8..c3ae5d2438e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -4538,6 +4538,7 @@ RTLIL::SyncRule *RTLIL::SyncRule::clone() const new_syncrule->type = type; new_syncrule->signal = signal; new_syncrule->actions = actions; + new_syncrule->mem_write_actions = mem_write_actions; return new_syncrule; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f03f27617ec..10cb039d5d7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -69,6 +69,7 @@ namespace RTLIL struct SigSpec; struct CaseRule; struct SwitchRule; + struct MemWriteAction; struct SyncRule; struct Process; @@ -1541,11 +1542,21 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject RTLIL::SwitchRule *clone() const; }; +struct RTLIL::MemWriteAction : RTLIL::AttrObject +{ + RTLIL::IdString memid; + RTLIL::SigSpec address; + RTLIL::SigSpec data; + RTLIL::SigSpec enable; + RTLIL::Const priority_mask; +}; + struct RTLIL::SyncRule { RTLIL::SyncType type; RTLIL::SigSpec signal; std::vector actions; + std::vector mem_write_actions; template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); @@ -1693,6 +1704,11 @@ void RTLIL::SyncRule::rewrite_sigspecs(T &functor) functor(it.first); functor(it.second); } + for (auto &it : mem_write_actions) { + functor(it.address); + functor(it.data); + functor(it.enable); + } } template @@ -1702,6 +1718,11 @@ void RTLIL::SyncRule::rewrite_sigspecs2(T &functor) for (auto &it : actions) { functor(it.first, it.second); } + for (auto &it : mem_write_actions) { + functor(it.address); + functor(it.data); + functor(it.enable); + } } template diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex index 83db5aac7aa..50a56137cb0 100644 --- a/manual/CHAPTER_Overview.tex +++ b/manual/CHAPTER_Overview.tex @@ -350,8 +350,9 @@ \subsection{RTLIL::Process} An RTLIL::Process is a container for zero or more RTLIL::SyncRule objects and exactly one RTLIL::CaseRule object, which is called the {\it root case}. -An RTLIL::SyncRule object contains an (optional) synchronization condition (signal and edge-type) and zero or -more assignments (RTLIL::SigSig). The {\tt always} synchronization condition is used to break combinatorial +An RTLIL::SyncRule object contains an (optional) synchronization condition (signal and edge-type), zero or +more assignments (RTLIL::SigSig), and zero or more memory writes (RTLIL::MemWriteAction). +The {\tt always} synchronization condition is used to break combinatorial loops when a latch should be inferred instead. An RTLIL::CaseRule is a container for zero or more assignments (RTLIL::SigSig) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index da81e7f0915..40207b1fc59 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -339,6 +339,23 @@ struct BugpointPass : public Pass { return design_copy; } } + int i = 0; + for (auto it = sy->mem_write_actions.begin(); it != sy->mem_write_actions.end(); ++it, ++i) + { + if (index++ == seed) + { + log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), log_id(it->memid), log_signal(it->address), log_signal(it->data), log_signal(it->enable), log_id(mod), log_id(pr.first)); + sy->mem_write_actions.erase(it); + // Remove the bit for removed action from other actions' priority masks. + for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) { + auto &mask = it2->priority_mask; + if (GetSize(mask) > i) { + mask.bits.erase(mask.bits.begin() + i); + } + } + return design_copy; + } + } } } } diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 36febb98ac6..b502b078871 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -141,6 +141,14 @@ struct CheckPass : public Pass { for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); } + for (auto memwr : sync->mem_write_actions) { + for (auto bit : sigmap(memwr.address)) + if (bit.wire) used_wires.insert(bit); + for (auto bit : sigmap(memwr.data)) + if (bit.wire) used_wires.insert(bit); + for (auto bit : sigmap(memwr.enable)) + if (bit.wire) used_wires.insert(bit); + } } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 0c96f8c5d4d..a389c317934 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -339,6 +339,11 @@ struct ShowWorker { input_signals.insert(obj->signal); collect_proc_signals(obj->actions, input_signals, output_signals); + for (auto it : obj->mem_write_actions) { + input_signals.insert(it.address); + input_signals.insert(it.data); + input_signals.insert(it.enable); + } } void collect_proc_signals(RTLIL::Process *obj, std::set &input_signals, std::set &output_signals) diff --git a/passes/proc/Makefile.inc b/passes/proc/Makefile.inc index 4b56979f834..50244bf33de 100644 --- a/passes/proc/Makefile.inc +++ b/passes/proc/Makefile.inc @@ -8,3 +8,4 @@ OBJS += passes/proc/proc_arst.o OBJS += passes/proc/proc_mux.o OBJS += passes/proc/proc_dlatch.o OBJS += passes/proc/proc_dff.o +OBJS += passes/proc/proc_memwr.o diff --git a/passes/proc/proc.cc b/passes/proc/proc.cc index 09cf0af82dc..2151b0ce7f6 100644 --- a/passes/proc/proc.cc +++ b/passes/proc/proc.cc @@ -43,6 +43,7 @@ struct ProcPass : public Pass { log(" proc_mux\n"); log(" proc_dlatch\n"); log(" proc_dff\n"); + log(" proc_memwr\n"); log(" proc_clean\n"); log("\n"); log("This replaces the processes in the design with multiplexers,\n"); @@ -102,6 +103,7 @@ struct ProcPass : public Pass { Pass::call(design, ifxmode ? "proc_mux -ifx" : "proc_mux"); Pass::call(design, "proc_dlatch"); Pass::call(design, "proc_dff"); + Pass::call(design, "proc_memwr"); Pass::call(design, "proc_clean"); log_pop(); diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 16db461b258..4351321e02c 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -153,6 +153,30 @@ void eliminate_const(RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigSpec con } } +RTLIL::SigSpec apply_reset(RTLIL::Module *mod, RTLIL::Process *proc, RTLIL::SyncRule *sync, SigMap &assign_map, RTLIL::SigSpec root_sig, bool polarity, RTLIL::SigSpec sig, RTLIL::SigSpec log_sig) { + RTLIL::SigSpec rspec = assign_map(sig); + RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.size()); + for (int i = 0; i < GetSize(rspec); i++) + if (rspec[i].wire == NULL) + rval[i] = rspec[i]; + RTLIL::SigSpec last_rval; + for (int count = 0; rval != last_rval; count++) { + last_rval = rval; + apply_const(mod, rspec, rval, &proc->root_case, root_sig, polarity, false); + assign_map.apply(rval); + if (rval.is_fully_const()) + break; + if (count > 100) + log_error("Async reset %s yields endless loop at value %s for signal %s.\n", + log_signal(sync->signal), log_signal(rval), log_signal(log_sig)); + rspec = rval; + } + if (rval.has_marked_bits()) + log_error("Async reset %s yields non-constant value %s for signal %s.\n", + log_signal(sync->signal), log_signal(rval), log_signal(log_sig)); + return rval; +} + void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) { restart_proc_arst: @@ -172,28 +196,18 @@ void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) sync->type = sync->type == RTLIL::SyncType::STp ? RTLIL::SyncType::ST1 : RTLIL::SyncType::ST0; } for (auto &action : sync->actions) { - RTLIL::SigSpec rspec = assign_map(action.second); - RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.size()); - for (int i = 0; i < GetSize(rspec); i++) - if (rspec[i].wire == NULL) - rval[i] = rspec[i]; - RTLIL::SigSpec last_rval; - for (int count = 0; rval != last_rval; count++) { - last_rval = rval; - apply_const(mod, rspec, rval, &proc->root_case, root_sig, polarity, false); - assign_map.apply(rval); - if (rval.is_fully_const()) - break; - if (count > 100) - log_error("Async reset %s yields endless loop at value %s for signal %s.\n", - log_signal(sync->signal), log_signal(rval), log_signal(action.first)); - rspec = rval; + action.second = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, action.second, action.first); + } + for (auto &memwr : sync->mem_write_actions) { + RTLIL::SigSpec en = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.enable, memwr.enable); + if (!en.is_fully_zero()) { + log_error("Async reset %s causes memory write to %s.\n", + log_signal(sync->signal), log_id(memwr.memid)); } - if (rval.has_marked_bits()) - log_error("Async reset %s yields non-constant value %s for signal %s.\n", - log_signal(sync->signal), log_signal(rval), log_signal(action.first)); - action.second = rval; + apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.address, memwr.address); + apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.data, memwr.data); } + sync->mem_write_actions.clear(); eliminate_const(mod, &proc->root_case, root_sig, polarity); goto restart_proc_arst; } diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 54d5a81ff22..9e0b671f4c4 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -161,7 +161,7 @@ void proc_clean(RTLIL::Module *mod, RTLIL::Process *proc, int &total_count, bool for (size_t j = 0; j < proc->syncs[i]->actions.size(); j++) if (proc->syncs[i]->actions[j].first.size() == 0) proc->syncs[i]->actions.erase(proc->syncs[i]->actions.begin() + (j--)); - if (proc->syncs[i]->actions.size() == 0) { + if (proc->syncs[i]->actions.size() == 0 && proc->syncs[i]->mem_write_actions.size() == 0) { delete proc->syncs[i]; proc->syncs.erase(proc->syncs.begin() + (i--)); } diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index 7b8c05b21f7..03d072cf4c4 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -342,7 +342,6 @@ struct proc_dlatch_db_t void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) { - std::vector new_syncs; RTLIL::SigSig latches_bits, nolatches_bits; dict latches_out_in; dict latches_hold; @@ -351,7 +350,6 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) for (auto sr : proc->syncs) { if (sr->type != RTLIL::SyncType::STa) { - new_syncs.push_back(sr); continue; } @@ -373,8 +371,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) for (int i = 0; i < GetSize(ss.first); i++) latches_out_in[ss.first[i]] = ss.second[i]; } - - delete sr; + sr->actions.clear(); } latches_out_in.sort(); @@ -441,8 +438,6 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) offset += width; } - - new_syncs.swap(proc->syncs); } struct ProcDlatchPass : public Pass { diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index eb323038d1d..b705251ddce 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -71,17 +71,8 @@ void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc) offset += lhs_c.width; } } + sync->actions.clear(); } - - if (found_init) { - std::vector new_syncs; - for (auto &sync : proc->syncs) - if (sync->type == RTLIL::SyncType::STi) - delete sync; - else - new_syncs.push_back(sync); - proc->syncs.swap(new_syncs); - } } struct ProcInitPass : public Pass { diff --git a/passes/proc/proc_memwr.cc b/passes/proc/proc_memwr.cc new file mode 100644 index 00000000000..f898979d8c8 --- /dev/null +++ b/passes/proc/proc_memwr.cc @@ -0,0 +1,111 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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/register.h" +#include "kernel/sigtools.h" +#include "kernel/ffinit.h" +#include "kernel/consteval.h" +#include "kernel/log.h" +#include +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict &next_priority) +{ + for (auto sr : proc->syncs) + { + for (auto memwr : sr->mem_write_actions) { + RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($memwr)); + cell->attributes = memwr.attributes; + cell->setParam(ID::MEMID, Const(memwr.memid.str())); + cell->setParam(ID::ABITS, GetSize(memwr.address)); + cell->setParam(ID::WIDTH, GetSize(memwr.data)); + cell->setParam(ID::PRIORITY, next_priority[memwr.memid]++); + cell->setPort(ID::ADDR, memwr.address); + cell->setPort(ID::DATA, memwr.data); + SigSpec enable = memwr.enable; + for (auto sr2 : proc->syncs) { + if (sr2->type == RTLIL::SyncType::ST0) { + log_assert(sr2->mem_write_actions.empty()); + enable = mod->Mux(NEW_ID, Const(State::S0, GetSize(enable)), enable, sr2->signal); + } else if (sr2->type == RTLIL::SyncType::ST1) { + log_assert(sr2->mem_write_actions.empty()); + enable = mod->Mux(NEW_ID, enable, Const(State::S0, GetSize(enable)), sr2->signal); + } + } + cell->setPort(ID::EN, enable); + if (sr->type == RTLIL::SyncType::STa) { + cell->setPort(ID::CLK, State::Sx); + cell->setParam(ID::CLK_ENABLE, State::S0); + cell->setParam(ID::CLK_POLARITY, State::Sx); + } else if (sr->type == RTLIL::SyncType::STp) { + cell->setPort(ID::CLK, sr->signal); + cell->setParam(ID::CLK_ENABLE, State::S1); + cell->setParam(ID::CLK_POLARITY, State::S1); + } else if (sr->type == RTLIL::SyncType::STn) { + cell->setPort(ID::CLK, sr->signal); + cell->setParam(ID::CLK_ENABLE, State::S1); + cell->setParam(ID::CLK_POLARITY, State::S0); + } else { + log_error("process memory write with unsupported sync type in %s.%s", log_id(mod), log_id(proc)); + } + } + sr->mem_write_actions.clear(); + } +} + +struct ProcMemWrPass : public Pass { + ProcMemWrPass() : Pass("proc_memwr", "extract memory writes from processes") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" proc_memwr [selection]\n"); + log("\n"); + log("This pass converts memory writes in processes into $memwr cells.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing PROC_MEMWR pass (convert process memory writes to cells).\n"); + + extra_args(args, 1, design); + + for (auto module : design->selected_modules()) { + dict next_priority; + for (auto cell : module->cells()) { + if (cell->type == ID($memwr)) { + IdString memid = cell->parameters.at(ID::MEMID).decode_string(); + int priority = cell->parameters.at(ID::PRIORITY).as_int(); + if (priority >= next_priority[memid]) + next_priority[memid] = priority + 1; + } + } + for (auto &proc_it : module->processes) + if (design->selected(module, proc_it.second)) + proc_memwr(module, proc_it.second, next_priority); + } + } +} ProcMemWrPass; + +PRIVATE_NAMESPACE_END + From 89c74ffd7189d4898feb476ff70376385d516eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 16:48:29 +0100 Subject: [PATCH 0260/2410] verilog: Use proc memory writes in the frontend. --- frontends/ast/ast.cc | 2 ++ frontends/ast/ast.h | 2 ++ frontends/ast/genrtlil.cc | 56 ++++++++++++++++++++++++------------ frontends/ast/simplify.cc | 58 ++++++++++++++++++++++++++++++-------- manual/CHAPTER_Verilog.tex | 5 ++++ 5 files changed, 94 insertions(+), 29 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index af5e326adbe..3b631907180 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -54,6 +54,8 @@ namespace AST_INTERNAL { AstNode *current_always, *current_top_block, *current_block, *current_block_child; AstModule *current_module; bool current_always_clocked; + dict current_memwr_count; + dict> current_memwr_visible; } // convert node types to string diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 1c9a6ee47c6..1447bf568af 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -381,6 +381,8 @@ namespace AST_INTERNAL extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; extern bool current_always_clocked; + extern dict current_memwr_count; + extern dict> current_memwr_visible; struct LookaheadRewriter; struct ProcessGenerator; } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e0a52243054..ad5814f1b12 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -399,6 +399,9 @@ struct AST_INTERNAL::ProcessGenerator if (child->type == AST_BLOCK) processAst(child); + for (auto sync: proc->syncs) + processMemWrites(sync); + if (initSyncSignals.size() > 0) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; @@ -698,6 +701,34 @@ struct AST_INTERNAL::ProcessGenerator log_abort(); } } + + void processMemWrites(RTLIL::SyncRule *sync) + { + // Maps per-memid AST_MEMWR IDs to indices in the mem_write_actions array. + dict, int> port_map; + for (auto child : always->children) + if (child->type == AST_MEMWR) + { + std::string memid = child->str; + int portid = child->children[3]->asInt(false); + int cur_idx = GetSize(sync->mem_write_actions); + RTLIL::MemWriteAction action; + set_src_attr(&action, child); + action.memid = memid; + action.address = child->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); + action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid]->width, &subst_rvalue_map.stdmap()); + action.enable = child->children[2]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); + RTLIL::Const orig_priority_mask = child->children[4]->bitsAsConst(); + RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx); + for (int i = 0; i < portid; i++) { + int new_bit = port_map[std::make_pair(memid, i)]; + priority_mask.bits[new_bit] = orig_priority_mask.bits[i]; + } + action.priority_mask = priority_mask; + sync->mem_write_actions.push_back(action); + port_map[std::make_pair(memid, portid)] = cur_idx; + } + } }; // detect sign and width of an expression @@ -1644,26 +1675,22 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return RTLIL::SigSpec(wire); } - // generate $memwr cells for memory write ports - case AST_MEMWR: + // generate $meminit cells case AST_MEMINIT: { std::stringstream sstr; - sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); + sstr << "$meminit$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); - RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? ID($memwr) : ID($meminit)); + RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($meminit)); set_src_attr(cell, this); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); - int num_words = 1; - if (type == AST_MEMINIT) { - if (children[2]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n"); - num_words = int(children[2]->asInt(false)); - cell->parameters[ID::WORDS] = RTLIL::Const(num_words); - } + if (children[2]->type != AST_CONSTANT) + log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n"); + int num_words = int(children[2]->asInt(false)); + cell->parameters[ID::WORDS] = RTLIL::Const(num_words); SigSpec addr_sig = children[0]->genRTLIL(); @@ -1674,13 +1701,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig)); cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[str]->width); - if (type == AST_MEMWR) { - cell->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::Sx, 1)); - cell->setPort(ID::EN, children[2]->genRTLIL()); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(0); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(0); - } - cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); } break; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e7f897b3c8d..e0ac58f205d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1217,6 +1217,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } + dict> backup_memwr_visible; + dict> final_memwr_visible; + + if (type == AST_CASE && stage == 2) { + backup_memwr_visible = current_memwr_visible; + final_memwr_visible = current_memwr_visible; + } + // simplify all children first // (iterate by index as e.g. auto wires can add new children in the process) for (size_t i = 0; i < children.size(); i++) { @@ -1279,11 +1287,25 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } flag_autowire = backup_flag_autowire; unevaluated_tern_branch = backup_unevaluated_tern_branch; + if (stage == 2 && type == AST_CASE) { + for (auto &x : current_memwr_visible) { + for (int y : x.second) + final_memwr_visible[x.first].insert(y); + } + current_memwr_visible = backup_memwr_visible; + } } for (auto &attr : attributes) { while (attr.second->simplify(true, false, false, stage, -1, false, true)) did_something = true; } + if (type == AST_CASE && stage == 2) { + current_memwr_visible = final_memwr_visible; + } + if (type == AST_ALWAYS && stage == 2) { + current_memwr_visible.clear(); + current_memwr_count.clear(); + } if (reset_width_after_children) { width_hint = backup_width_hint; @@ -2570,12 +2592,12 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_addr->str] = wire_addr; while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } - AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); + AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; defNode->children.push_back(assign_addr); - assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); + assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; assign_addr->children[0]->was_checked = true; newNode->children.push_back(assign_addr); @@ -2596,7 +2618,7 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_data->str] = wire_data; while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } - AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); + AstNode *assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; defNode->children.push_back(assign_data); @@ -2616,7 +2638,7 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); + AstNode *assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; defNode->children.push_back(assign_en); @@ -2642,7 +2664,7 @@ skip_dynamic_range_lvalue_expansion:; std::vector padding_x(offset, RTLIL::State::Sx); - assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone())); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; @@ -2650,7 +2672,7 @@ skip_dynamic_range_lvalue_expansion:; if (current_always->type != AST_INITIAL) { for (int i = 0; i < mem_width; i++) set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; } @@ -2671,7 +2693,7 @@ skip_dynamic_range_lvalue_expansion:; log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; - assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; @@ -2679,7 +2701,7 @@ skip_dynamic_range_lvalue_expansion:; if (current_always->type != AST_INITIAL) { for (int i = 0; i < mem_width; i++) set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; @@ -2693,13 +2715,13 @@ skip_dynamic_range_lvalue_expansion:; else { if (!(children[0]->children.size() == 1 && children[1]->isConst())) { - assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); + assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[1]->clone()); assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; } if (current_always->type != AST_INITIAL) { - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; } @@ -2712,7 +2734,21 @@ skip_dynamic_range_lvalue_expansion:; AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR, node_addr, node_data, node_en); wrnode->str = children[0]->str; wrnode->id2ast = children[0]->id2ast; - current_ast_mod->children.push_back(wrnode); + wrnode->location = location; + if (wrnode->type == AST_MEMWR) { + int portid = current_memwr_count[wrnode->str]++; + wrnode->children.push_back(mkconst_int(portid, false)); + std::vector priority_mask; + for (int i = 0; i < portid; i++) { + bool has_prio = current_memwr_visible[wrnode->str].count(i); + priority_mask.push_back(State(has_prio)); + } + wrnode->children.push_back(mkconst_bits(priority_mask, false)); + current_memwr_visible[wrnode->str].insert(portid); + current_always->children.push_back(wrnode); + } else { + current_ast_mod->children.push_back(wrnode); + } if (newNode->children.empty()) { delete newNode; diff --git a/manual/CHAPTER_Verilog.tex b/manual/CHAPTER_Verilog.tex index d4cc55647df..c1ecc0397b4 100644 --- a/manual/CHAPTER_Verilog.tex +++ b/manual/CHAPTER_Verilog.tex @@ -503,6 +503,8 @@ \section{Synthesizing Verilog always Blocks} \item Finally a \lstinline[language=C++]{RTLIL::SyncRule} is created for the \lstinline[language=C++]{RTLIL::Process} that assigns the temporary signals for the final values to the actual signals. % +\item A process may also contain memory writes. A \lstinline[language=C++]{RTLIL::MemWriteAction} is created for each of them. +% \item Calls to \lstinline[language=C++]{AST::AstNode::genRTLIL()} are generated for right hand sides as needed. When blocking assignments are used, \lstinline[language=C++]{AST::AstNode::genRTLIL()} is configured using global variables to use the temporary signals that hold the correct intermediate values whenever one of the previously assigned signals is used @@ -821,6 +823,9 @@ \subsection{The proc pass} This pass replaces the \C{RTLIL::SyncRule}s to d-type flip-flops (with asynchronous resets if necessary). % +\item {\tt proc\_dff} \\ +This pass replaces the \C{RTLIL::MemWriteActions}s with {\tt \$memwr} cells. +% \item {\tt proc\_clean} \\ A final call to {\tt proc\_clean} removes the now empty \C{RTLIL::Process} objects. \end{itemize} From a3528649c82ed7c6d14850affef8e9368f4fe065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 19:42:51 +0100 Subject: [PATCH 0261/2410] memory_dff: Remove now-useless write port handling. --- passes/memory/memory.cc | 5 ++- passes/memory/memory_dff.cc | 78 +++------------------------------- passes/memory/memory_nordff.cc | 2 +- techlibs/common/prep.cc | 13 +++--- tests/opt/opt_clean_mem.ys | 1 - tests/tools/autotest.sh | 2 +- 6 files changed, 19 insertions(+), 82 deletions(-) diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index 282517992a5..9dec05db85f 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -36,7 +36,7 @@ struct MemoryPass : public Pass { log("This pass calls all the other memory_* passes in a useful order:\n"); log("\n"); log(" opt_mem\n"); - log(" memory_dff [-nordff] (-memx implies -nordff)\n"); + log(" memory_dff (skipped if called with -nordff or -memx)\n"); log(" opt_clean\n"); log(" memory_share\n"); log(" opt_clean\n"); @@ -83,7 +83,8 @@ struct MemoryPass : public Pass { extra_args(args, argidx, design); Pass::call(design, "opt_mem"); - Pass::call(design, flag_nordff ? "memory_dff -nordff" : "memory_dff"); + if (!flag_nordff) + Pass::call(design, "memory_dff"); Pass::call(design, "opt_clean"); Pass::call(design, "memory_share"); if (flag_memx) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 64881672e18..83c9d76312f 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -33,7 +33,6 @@ struct MemoryDffWorker vector dff_cells; dict invbits; dict sigbit_users_count; - pool forward_merged_dffs, candidate_dffs; FfInitVals initvals; MemoryDffWorker(Module *module) : module(module), sigmap(module) @@ -113,7 +112,6 @@ struct MemoryDffWorker bit = d; clk = this_clk; clk_polarity = this_clk_polarity; - candidate_dffs.insert(cell); goto replaced_this_bit; } @@ -135,8 +133,6 @@ struct MemoryDffWorker for (auto cell : dff_cells) { - if (forward_merged_dffs.count(cell)) - continue; if (!cell->type.in(ID($dff), ID($dffe))) continue; @@ -186,7 +182,6 @@ struct MemoryDffWorker clk_polarity = this_clk_polarity; en = this_en; en_polarity = this_en_polarity; - candidate_dffs.insert(cell); goto replaced_this_bit; } @@ -197,51 +192,6 @@ struct MemoryDffWorker return true; } - void handle_wr_cell(RTLIL::Cell *cell) - { - log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str()); - - RTLIL::SigSpec clk = RTLIL::SigSpec(RTLIL::State::Sx); - bool clk_polarity = 0; - candidate_dffs.clear(); - - RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR); - if (!find_sig_before_dff(sig_addr, clk, clk_polarity)) { - log("no (compatible) $dff for address input found.\n"); - return; - } - - RTLIL::SigSpec sig_data = cell->getPort(ID::DATA); - if (!find_sig_before_dff(sig_data, clk, clk_polarity)) { - log("no (compatible) $dff for data input found.\n"); - return; - } - - RTLIL::SigSpec sig_en = cell->getPort(ID::EN); - if (!find_sig_before_dff(sig_en, clk, clk_polarity)) { - log("no (compatible) $dff for enable input found.\n"); - return; - } - - if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) - { - for (auto cell : candidate_dffs) - forward_merged_dffs.insert(cell); - - cell->setPort(ID::CLK, clk); - cell->setPort(ID::ADDR, sig_addr); - cell->setPort(ID::DATA, sig_data); - cell->setPort(ID::EN, sig_en); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); - - log("merged $dff to cell.\n"); - return; - } - - log("no (compatible) $dff found.\n"); - } - void disconnect_dff(RTLIL::SigSpec sig) { sigmap.apply(sig); @@ -309,7 +259,7 @@ struct MemoryDffWorker log("no (compatible) $dff found.\n"); } - void run(bool flag_wr_only) + void run() { for (auto wire : module->wires()) { if (wire->port_output) @@ -337,51 +287,37 @@ struct MemoryDffWorker } for (auto cell : module->selected_cells()) - if (cell->type == ID($memwr) && !cell->parameters[ID::CLK_ENABLE].as_bool()) - handle_wr_cell(cell); - - if (!flag_wr_only) - for (auto cell : module->selected_cells()) - if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool()) - handle_rd_cell(cell); + if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool()) + handle_rd_cell(cell); } }; struct MemoryDffPass : public Pass { - MemoryDffPass() : Pass("memory_dff", "merge input/output DFFs into memories") { } + MemoryDffPass() : Pass("memory_dff", "merge input/output DFFs into memory read ports") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" memory_dff [options] [selection]\n"); log("\n"); - log("This pass detects DFFs at memory ports and merges them into the memory port.\n"); + log("This pass detects DFFs at memory read ports and merges them into the memory port.\n"); log("I.e. it consumes an asynchronous memory port and the flip-flops at its\n"); log("interface and yields a synchronous memory port.\n"); log("\n"); - log(" -nordfff\n"); - log(" do not merge registers on read ports\n"); - log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { - bool flag_wr_only = false; - - log_header(design, "Executing MEMORY_DFF pass (merging $dff cells to $memrd and $memwr).\n"); + log_header(design, "Executing MEMORY_DFF pass (merging $dff cells to $memrd).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-nordff" || args[argidx] == "-wr_only") { - flag_wr_only = true; - continue; - } break; } extra_args(args, argidx, design); for (auto mod : design->selected_modules()) { MemoryDffWorker worker(mod); - worker.run(flag_wr_only); + worker.run(); } } } MemoryDffPass; diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc index a4fdcfc3807..bb853c483eb 100644 --- a/passes/memory/memory_nordff.cc +++ b/passes/memory/memory_nordff.cc @@ -33,7 +33,7 @@ struct MemoryNordffPass : public Pass { log(" memory_nordff [options] [selection]\n"); log("\n"); log("This pass extracts FFs from memory read ports. This results in a netlist\n"); - log("similar to what one would get from calling memory_dff with -nordff.\n"); + log("similar to what one would get from not calling memory_dff.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index 93b0910d674..132d6aec202 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -61,7 +61,7 @@ struct PrepPass : public ScriptPass log(" do not run any of the memory_* passes\n"); log("\n"); log(" -rdff\n"); - log(" do not pass -nordff to 'memory_dff'. This enables merging of FFs into\n"); + log(" call 'memory_dff'. This enables merging of FFs into\n"); log(" memory read ports.\n"); log("\n"); log(" -nokeepdc\n"); @@ -79,7 +79,7 @@ struct PrepPass : public ScriptPass } string top_module, fsm_opts; - bool autotop, flatten, ifxmode, memxmode, nomemmode, nokeepdc, nordff; + bool autotop, flatten, ifxmode, memxmode, nomemmode, nokeepdc, rdff; void clear_flags() override { @@ -91,7 +91,7 @@ struct PrepPass : public ScriptPass memxmode = false; nomemmode = false; nokeepdc = false; - nordff = true; + rdff = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -137,11 +137,11 @@ struct PrepPass : public ScriptPass continue; } if (args[argidx] == "-nordff") { - nordff = true; + rdff = false; continue; } if (args[argidx] == "-rdff") { - nordff = false; + rdff = true; continue; } if (args[argidx] == "-nokeepdc") { @@ -202,7 +202,8 @@ struct PrepPass : public ScriptPass run(memxmode ? "wreduce -keepdc -memx" : "wreduce -keepdc"); } if (!nomemmode) { - run(string("memory_dff") + (help_mode ? " [-nordff]" : nordff ? " -nordff" : "")); + if (help_mode || rdff) + run("memory_dff", "(if -rdff)"); if (help_mode || memxmode) run("memory_memx", "(if -memx)"); run("opt_clean"); diff --git a/tests/opt/opt_clean_mem.ys b/tests/opt/opt_clean_mem.ys index b35b1587107..d08943da460 100644 --- a/tests/opt/opt_clean_mem.ys +++ b/tests/opt/opt_clean_mem.ys @@ -22,7 +22,6 @@ endmodule EOT proc -memory_dff select -assert-count 2 t:$memrd select -assert-count 1 t:$memwr diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 72a3d51eb86..e4aef9917c3 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -197,7 +197,7 @@ do test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext} if [ -n "$firrtl2verilog" ]; then if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then - "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine; pmuxtree" ${bn}_ref.${refext} + "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine; pmuxtree" ${bn}_ref.${refext} $firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine" ${bn}_ref.fir.v fi From 0b0e21976511e85b336d2724467ee8f93728f9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 8 Mar 2021 20:18:11 +0100 Subject: [PATCH 0262/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1fed7ae0e74..e6a27de07d9 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3981 +YOSYS_VER := 0.9+4008 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 83fc5cc28b60367a8cd16fb3d7eddb26db304513 Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Wed, 10 Mar 2021 19:31:55 +0000 Subject: [PATCH 0263/2410] Replace assert in xaiger with more useful error message --- backends/aiger/xaiger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 27499b64a7a..7ed8ff1cfce 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -432,7 +432,8 @@ struct XAigerWriter // that has been padded to its full width if (bit == State::Sx) continue; - log_assert(!aig_map.count(bit)); + if (aig_map.count(bit)) + log_error("Visited AIG node more than once; this could be a combinatorial loop that has not been broken - see Yosys bug 2530\n"); aig_map[bit] = 2*aig_m; } From 81c2b92bb419d5b58d47fa8bb8cbb134fb2773bc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 11 Mar 2021 15:56:32 +0100 Subject: [PATCH 0264/2410] Add _pm.h files to GENLIST, fixes vcxsrc target --- passes/pmgen/Makefile.inc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index c6bbc386a21..a7ef642825c 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -4,24 +4,31 @@ # -------------------------------------- OBJS += passes/pmgen/test_pmgen.o +GENFILES += passes/pmgen/test_pmgen_pm.h passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h passes/pmgen/xilinx_srl_pm.h $(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) # -------------------------------------- OBJS += passes/pmgen/ice40_dsp.o +GENFILES += passes/pmgen/ice40_dsp_pm.h passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) # -------------------------------------- OBJS += passes/pmgen/ice40_wrapcarry.o +GENFILES += passes/pmgen/ice40_wrapcarry_pm.h passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h $(eval $(call add_extra_objs,passes/pmgen/ice40_wrapcarry_pm.h)) # -------------------------------------- OBJS += passes/pmgen/xilinx_dsp.o +GENFILES += passes/pmgen/xilinx_dsp_pm.h +GENFILES += passes/pmgen/xilinx_dsp48a_pm.h +GENFILES += passes/pmgen/xilinx_dsp_CREG_pm.h +GENFILES += passes/pmgen/xilinx_dsp_cascade_pm.h passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h passes/pmgen/xilinx_dsp48a_pm.h passes/pmgen/xilinx_dsp_CREG_pm.h passes/pmgen/xilinx_dsp_cascade_pm.h $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_pm.h)) $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp48a_pm.h)) @@ -31,6 +38,7 @@ $(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp_cascade_pm.h)) # -------------------------------------- OBJS += passes/pmgen/peepopt.o +GENFILES += passes/pmgen/peepopt_pm.h passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h)) @@ -43,5 +51,6 @@ passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN) # -------------------------------------- OBJS += passes/pmgen/xilinx_srl.o +GENFILES += passes/pmgen/xilinx_srl_pm.h passes/pmgen/xilinx_srl.o: passes/pmgen/xilinx_srl_pm.h $(eval $(call add_extra_objs,passes/pmgen/xilinx_srl_pm.h)) From cb9f3b6abfbc769589e5e5ceb2497955a155065c Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 11 Mar 2021 11:49:15 -0500 Subject: [PATCH 0265/2410] verilog: disallow overriding global parameters It was previously possible to override global parameters on a per-instance basis. This could be dangerous when using positional parameter bindings, hiding oversupplied parameters. --- frontends/ast/ast.cc | 2 ++ tests/verilog/global_parameter.ys | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/verilog/global_parameter.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index b601d2e259d..06e2e23a839 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1286,6 +1286,8 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } else { // must be global definition + if ((*it)->type == AST_PARAMETER) + (*it)->type = AST_LOCALPARAM; // cannot be overridden (*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations design->verilog_globals.push_back((*it)->clone()); current_scope.clear(); diff --git a/tests/verilog/global_parameter.ys b/tests/verilog/global_parameter.ys new file mode 100644 index 00000000000..a7a3cddc793 --- /dev/null +++ b/tests/verilog/global_parameter.ys @@ -0,0 +1,16 @@ +read_verilog -sv < Date: Thu, 11 Mar 2021 13:05:04 -0500 Subject: [PATCH 0266/2410] sv: allow globals in one file to depend on globals in another This defers the simplification of globals so that globals in one file may depend on globals in other files. Adds a simplify() call downstream because globals are appended at the end. --- frontends/ast/ast.cc | 1 - frontends/ast/simplify.cc | 1 + tests/verilog/parameters_across_files.ys | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/parameters_across_files.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 06e2e23a839..7aa391c93ac 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1288,7 +1288,6 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump // must be global definition if ((*it)->type == AST_PARAMETER) (*it)->type = AST_LOCALPARAM; // cannot be overridden - (*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations design->verilog_globals.push_back((*it)->clone()); current_scope.clear(); } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e0ac58f205d..d68b13b2a9a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -192,6 +192,7 @@ void AstNode::annotateTypedEnums(AstNode *template_node) log_assert(current_scope.count(enum_type) == 1); AstNode *enum_node = current_scope.at(enum_type); log_assert(enum_node->type == AST_ENUM); + while (enum_node->simplify(true, false, false, 1, -1, false, true)) { } //get width from 1st enum item: log_assert(enum_node->children.size() >= 1); AstNode *enum_item0 = enum_node->children[0]; diff --git a/tests/verilog/parameters_across_files.ys b/tests/verilog/parameters_across_files.ys new file mode 100644 index 00000000000..c53e4017930 --- /dev/null +++ b/tests/verilog/parameters_across_files.ys @@ -0,0 +1,20 @@ +read_verilog -sv < Date: Tue, 9 Mar 2021 02:54:56 +0100 Subject: [PATCH 0267/2410] rtlil: Disallow 0-width chunks in SigSpec. Among other problems, this also fixes equality comparisons between SigSpec by enforcing a canonical form. Also fix another minor issue with possible non-canonical SigSpec. Fixes #2623. --- kernel/rtlil.cc | 67 ++++++++++++++++++++++++++++++++------------ tests/opt/bug2623.ys | 14 +++++++++ 2 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 tests/opt/bug2623.ys diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c3ae5d2438e..32069ce0365 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3276,8 +3276,12 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { cover("kernel.rtlil.sigspec.init.const"); - chunks_.emplace_back(value); - width_ = chunks_.back().width; + if (GetSize(value) != 0) { + chunks_.emplace_back(value); + width_ = chunks_.back().width; + } else { + width_ = 0; + } hash_ = 0; check(); } @@ -3286,8 +3290,12 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { cover("kernel.rtlil.sigspec.init.chunk"); - chunks_.emplace_back(chunk); - width_ = chunks_.back().width; + if (chunk.width != 0) { + chunks_.emplace_back(chunk); + width_ = chunks_.back().width; + } else { + width_ = 0; + } hash_ = 0; check(); } @@ -3296,8 +3304,12 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) { cover("kernel.rtlil.sigspec.init.wire"); - chunks_.emplace_back(wire); - width_ = chunks_.back().width; + if (wire->width != 0) { + chunks_.emplace_back(wire); + width_ = chunks_.back().width; + } else { + width_ = 0; + } hash_ = 0; check(); } @@ -3306,8 +3318,12 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) { cover("kernel.rtlil.sigspec.init.wire_part"); - chunks_.emplace_back(wire, offset, width); - width_ = chunks_.back().width; + if (width != 0) { + chunks_.emplace_back(wire, offset, width); + width_ = chunks_.back().width; + } else { + width_ = 0; + } hash_ = 0; check(); } @@ -3316,8 +3332,12 @@ RTLIL::SigSpec::SigSpec(const std::string &str) { cover("kernel.rtlil.sigspec.init.str"); - chunks_.emplace_back(str); - width_ = chunks_.back().width; + if (str.size() != 0) { + chunks_.emplace_back(str); + width_ = chunks_.back().width; + } else { + width_ = 0; + } hash_ = 0; check(); } @@ -3326,7 +3346,8 @@ RTLIL::SigSpec::SigSpec(int val, int width) { cover("kernel.rtlil.sigspec.init.int"); - chunks_.emplace_back(val, width); + if (width != 0) + chunks_.emplace_back(val, width); width_ = width; hash_ = 0; check(); @@ -3336,7 +3357,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { cover("kernel.rtlil.sigspec.init.state"); - chunks_.emplace_back(bit, width); + if (width != 0) + chunks_.emplace_back(bit, width); width_ = width; hash_ = 0; check(); @@ -3346,11 +3368,13 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width) { cover("kernel.rtlil.sigspec.init.bit"); - if (bit.wire == NULL) - chunks_.emplace_back(bit.data, width); - else - for (int i = 0; i < width; i++) - chunks_.push_back(bit); + if (width != 0) { + if (bit.wire == NULL) + chunks_.emplace_back(bit.data, width); + else + for (int i = 0; i < width; i++) + chunks_.push_back(bit); + } width_ = width; hash_ = 0; check(); @@ -3795,7 +3819,13 @@ void RTLIL::SigSpec::remove_const() width_ = 0; for (auto &chunk : chunks_) if (chunk.wire != NULL) { - new_chunks.push_back(chunk); + if (!new_chunks.empty() && + new_chunks.back().wire == chunk.wire && + new_chunks.back().offset + new_chunks.back().width == chunk.offset) { + new_chunks.back().width += chunk.width; + } else { + new_chunks.push_back(chunk); + } width_ += chunk.width; } @@ -3955,6 +3985,7 @@ void RTLIL::SigSpec::check() const int w = 0; for (size_t i = 0; i < chunks_.size(); i++) { const RTLIL::SigChunk &chunk = chunks_[i]; + log_assert(chunk.width != 0); if (chunk.wire == NULL) { if (i > 0) log_assert(chunks_[i-1].wire != NULL); diff --git a/tests/opt/bug2623.ys b/tests/opt/bug2623.ys new file mode 100644 index 00000000000..2ff23ea6f15 --- /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 From 3af871f969f7f5bd5201bac17544559671312a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 9 Mar 2021 21:32:16 +0100 Subject: [PATCH 0268/2410] opt_clean: Remove init attribute bits together with removed DFFs. Fixes #2546. --- passes/opt/opt_clean.cc | 4 ++++ tests/opt/opt_clean_init.ys | 31 ++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 883374cf6ae..c66f4530834 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" +#include "kernel/ffinit.h" #include #include #include @@ -101,6 +102,7 @@ void rmunused_module_cells(Module *module, bool verbose) pool used_raw_bits; dict> wire2driver; dict> driver_driver_logs; + FfInitVals ffinit(&sigmap, module); SigMap raw_sigmap; for (auto &it : module->connections_) { @@ -193,6 +195,8 @@ void rmunused_module_cells(Module *module, bool verbose) if (verbose) log_debug(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str()); module->design->scratchpad_set_bool("opt.did_something", true); + if (RTLIL::builtin_ff_cell_types().count(cell->type)) + ffinit.remove_init(cell->getPort(ID::Q)); module->remove(cell); count_rm_cells++; } diff --git a/tests/opt/opt_clean_init.ys b/tests/opt/opt_clean_init.ys index 0d567608d44..7933f3e1719 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 < Date: Fri, 12 Mar 2021 17:05:39 +0100 Subject: [PATCH 0269/2410] proc_arst: Add special-casing of clock signal in conditionals. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The already-existing special case for conditionals on clock has been remade as follows: - now triggered for the last remaining edge trigger after all others have been converted to async reset, not just when there is only one sync rule in the first place - does not require all contained assignments to be constant, as opposed to a reset conditional — merely const-folds the condition In addition, the code has been refactored a bit; as a bonus, the priority order of async resets found is now preserved in resulting sync rule ordering (though this is not yet respected by proc_dff). Fixes #2656. --- passes/proc/proc_arst.cc | 74 +++++++++++++++++++++++++++------------- tests/proc/bug2656.ys | 31 +++++++++++++++++ 2 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 tests/proc/bug2656.ys diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 4351321e02c..d1bfbc647bc 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -179,39 +179,67 @@ RTLIL::SigSpec apply_reset(RTLIL::Module *mod, RTLIL::Process *proc, RTLIL::Sync void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) { -restart_proc_arst: - if (proc->root_case.switches.size() != 1) - return; - - RTLIL::SigSpec root_sig = proc->root_case.switches[0]->signal; + std::vector arst_syncs; + std::vector edge_syncs; + std::vector other_syncs; for (auto &sync : proc->syncs) { - if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) { + if (sync->type == RTLIL::SyncType::ST0 || sync->type == RTLIL::SyncType::ST1) { + arst_syncs.push_back(sync); + } else if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) { + edge_syncs.push_back(sync); + } else { + other_syncs.push_back(sync); + } + } + + bool did_something = false; + + while (proc->root_case.switches.size() == 1) { + RTLIL::SigSpec root_sig = proc->root_case.switches[0]->signal; + + bool found = false; + for (auto it = edge_syncs.begin(); it != edge_syncs.end(); ++it) { + auto sync = *it; bool polarity = sync->type == RTLIL::SyncType::STp; if (check_signal(mod, root_sig, sync->signal, polarity)) { - if (proc->syncs.size() == 1) { - log("Found VHDL-style edge-trigger %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); - } else { + if (edge_syncs.size() > 1) { log("Found async reset %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); sync->type = sync->type == RTLIL::SyncType::STp ? RTLIL::SyncType::ST1 : RTLIL::SyncType::ST0; - } - for (auto &action : sync->actions) { - action.second = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, action.second, action.first); - } - for (auto &memwr : sync->mem_write_actions) { - RTLIL::SigSpec en = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.enable, memwr.enable); - if (!en.is_fully_zero()) { - log_error("Async reset %s causes memory write to %s.\n", - log_signal(sync->signal), log_id(memwr.memid)); + arst_syncs.push_back(sync); + edge_syncs.erase(it); + for (auto &action : sync->actions) { + action.second = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, action.second, action.first); } - apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.address, memwr.address); - apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.data, memwr.data); + for (auto &memwr : sync->mem_write_actions) { + RTLIL::SigSpec en = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.enable, memwr.enable); + if (!en.is_fully_zero()) { + log_error("Async reset %s causes memory write to %s.\n", + log_signal(sync->signal), log_id(memwr.memid)); + } + apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.address, memwr.address); + apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.data, memwr.data); + } + sync->mem_write_actions.clear(); + eliminate_const(mod, &proc->root_case, root_sig, polarity); + } else { + log("Found VHDL-style edge-trigger %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); + eliminate_const(mod, &proc->root_case, root_sig, !polarity); } - sync->mem_write_actions.clear(); - eliminate_const(mod, &proc->root_case, root_sig, polarity); - goto restart_proc_arst; + did_something = true; + found = true; + break; } } + if (!found) + break; + } + + if (did_something) { + proc->syncs.clear(); + proc->syncs.insert(proc->syncs.end(), arst_syncs.begin(), arst_syncs.end()); + proc->syncs.insert(proc->syncs.end(), edge_syncs.begin(), edge_syncs.end()); + proc->syncs.insert(proc->syncs.end(), other_syncs.begin(), other_syncs.end()); } } diff --git a/tests/proc/bug2656.ys b/tests/proc/bug2656.ys new file mode 100644 index 00000000000..3fe7cb33b21 --- /dev/null +++ b/tests/proc/bug2656.ys @@ -0,0 +1,31 @@ +read_verilog < Date: Tue, 9 Mar 2021 20:42:14 +0100 Subject: [PATCH 0270/2410] json: Add support for memories. Previously, memories were silently discarded by the JSON backend, making round-tripping modules with them crash. Since there are already some users using JSON to implement custom external passes that use memories (and infer width/size from memory ports), let's fix this by just making JSON backend and frontend support memories as first-class objects. Processes are still not supported, and will now cause a hard error. Fixes #1908. --- backends/json/json.cc | 42 +++++++++++++++++++++++++++++++++ frontends/json/jsonparse.cc | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/backends/json/json.cc b/backends/json/json.cc index eeadc1b8903..b13105f64a7 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -135,6 +135,10 @@ struct JsonWriter // reserve 0 and 1 to avoid confusion with "0" and "1" sigidcounter = 2; + if (module->has_processes()) { + log_error("Module %s contains processes, which are not supported by JSON backend.\n", log_id(module)); + } + f << stringf(" %s: {\n", get_name(module->name).c_str()); f << stringf(" \"attributes\": {"); @@ -216,6 +220,27 @@ struct JsonWriter } f << stringf("\n },\n"); + if (!module->memories.empty()) { + f << stringf(" \"memories\": {"); + first = true; + for (auto &it : module->memories) { + if (use_selection && !module->selected(it.second)) + continue; + f << stringf("%s\n", first ? "" : ","); + f << stringf(" %s: {\n", get_name(it.second->name).c_str()); + f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0"); + f << stringf(" \"attributes\": {"); + write_parameters(it.second->attributes); + f << stringf("\n },\n"); + f << stringf(" \"width\": %d,\n", it.second->width); + f << stringf(" \"start_offset\": %d,\n", it.second->start_offset); + f << stringf(" \"size\": %d\n", it.second->size); + f << stringf(" }"); + first = false; + } + f << stringf("\n },\n"); + } + f << stringf(" \"netnames\": {"); first = true; for (auto w : module->wires()) { @@ -332,6 +357,10 @@ struct JsonBackend : public Backend { log(" : ,\n"); log(" ...\n"); log(" },\n"); + log(" \"memories\": {\n"); + log(" : ,\n"); + log(" ...\n"); + log(" },\n"); log(" \"netnames\": {\n"); log(" : ,\n"); log(" ...\n"); @@ -379,6 +408,19 @@ struct JsonBackend : public Backend { log(" },\n"); log(" }\n"); log("\n"); + log("And is:\n"); + log("\n"); + log(" {\n"); + log(" \"hide_name\": <1 | 0>,\n"); + log(" \"attributes\": {\n"); + log(" : ,\n"); + log(" ...\n"); + log(" },\n"); + log(" \"width\": \n"); + log(" \"start_offset\": \n"); + log(" \"size\": \n"); + log(" }\n"); + log("\n"); log("And is:\n"); log("\n"); log(" {\n"); diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 312f6d3be50..d897ac20b22 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -539,6 +539,52 @@ void json_import(Design *design, string &modname, JsonNode *node) json_parse_attr_param(cell->parameters, cell_node->data_dict.at("parameters")); } } + + if (node->data_dict.count("memories")) + { + JsonNode *memories_node = node->data_dict.at("memories"); + + if (memories_node->type != 'D') + log_error("JSON memories node is not a dictionary.\n"); + + for (auto &memory_node_it : memories_node->data_dict) + { + IdString memory_name = RTLIL::escape_id(memory_node_it.first.c_str()); + JsonNode *memory_node = memory_node_it.second; + + RTLIL::Memory *mem = new RTLIL::Memory; + mem->name = memory_name; + + if (memory_node->type != 'D') + log_error("JSON memory node '%s' is not a dictionary.\n", log_id(memory_name)); + + if (memory_node->data_dict.count("width") == 0) + log_error("JSON memory node '%s' has no width attribute.\n", log_id(memory_name)); + JsonNode *width_node = memory_node->data_dict.at("width"); + if (width_node->type != 'N') + log_error("JSON memory node '%s' has a non-number width.\n", log_id(memory_name)); + mem->width = width_node->data_number; + + if (memory_node->data_dict.count("size") == 0) + log_error("JSON memory node '%s' has no size attribute.\n", log_id(memory_name)); + JsonNode *size_node = memory_node->data_dict.at("size"); + if (size_node->type != 'N') + log_error("JSON memory node '%s' has a non-number size.\n", log_id(memory_name)); + mem->size = size_node->data_number; + + mem->start_offset = 0; + if (memory_node->data_dict.count("start_offset") != 0) { + JsonNode *val = memory_node->data_dict.at("start_offset"); + if (val->type == 'N') + mem->start_offset = val->data_number; + } + + if (memory_node->data_dict.count("attributes")) + json_parse_attr_param(mem->attributes, memory_node->data_dict.at("attributes")); + + module->memories[mem->name] = mem; + } + } } struct JsonFrontend : public Frontend { From 4f187d53c5a0580275857ec308b41f57808ec727 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 4 Mar 2021 14:07:56 -0500 Subject: [PATCH 0271/2410] verilog: support module scope identifiers in parametric modules --- frontends/ast/simplify.cc | 12 ++++++++---- tests/simple/module_scope.v | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tests/simple/module_scope.v diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d68b13b2a9a..d9eae3a0612 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1691,11 +1691,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; - const std::string& mod_scope = current_scope_ast->str; - if (str[0] == '\\' && str.substr(0, mod_scope.size()) == mod_scope) { - std::string new_str = "\\" + str.substr(mod_scope.size() + 1); + size_t pos = str.find('.', 1); + if (str[0] == '\\' && pos != std::string::npos) { + std::string new_str = "\\" + str.substr(pos + 1); if (current_scope.count(new_str)) { - str = new_str; + std::string prefix = str.substr(0, pos); + auto it = current_scope_ast->attributes.find(ID::hdlname); + if ((it != current_scope_ast->attributes.end() && it->second->str == prefix) + || prefix == current_scope_ast->str) + str = new_str; } } for (auto node : current_scope_ast->children) { diff --git a/tests/simple/module_scope.v b/tests/simple/module_scope.v new file mode 100644 index 00000000000..3e46b72ef1f --- /dev/null +++ b/tests/simple/module_scope.v @@ -0,0 +1,29 @@ +`default_nettype none + +module Example(o1, o2); + parameter [31:0] v1 = 10; + parameter [31:0] v2 = 20; + output [31:0] o1, o2; + assign Example.o1 = Example.v1; + assign Example.o2 = Example.v2; +endmodule + +module ExampleLong(o1, o2); + parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1 = 10; + parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2 = 20; + output [31:0] o1, o2; + assign ExampleLong.o1 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1; + assign ExampleLong.o2 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2; +endmodule + +module top( + output [31:0] a1, a2, b1, b2, c1, c2, + output [31:0] d1, d2, e1, e2, f1, f2 +); + Example a(a1, a2); + Example #(1) b(b1, b2); + Example #(1, 2) c(c1, c2); + ExampleLong d(d1, d2); + ExampleLong #(1) e(e1, e2); + ExampleLong #(1, 2) f(f1, f2); +endmodule From 937392ad337c4f70569535e83f7016245addb2c7 Mon Sep 17 00:00:00 2001 From: Lofty Date: Wed, 17 Mar 2021 02:43:25 +0000 Subject: [PATCH 0272/2410] Replace assert in get_reference with more useful error message --- kernel/rtlil.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 10cb039d5d7..a747b9d3c8a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -166,7 +166,8 @@ namespace RTLIL log_assert(p[0] == '$' || p[0] == '\\'); log_assert(p[1] != 0); for (const char *c = p; *c; c++) - log_assert((unsigned)*c > (unsigned)' '); + if ((unsigned)*c <= (unsigned)' ') + log_error("Found control character or space (0x%02hhx) in string '%s' which is not allowed in RTLIL identifiers\n", *c, p); #ifndef YOSYS_NO_IDS_REFCNT if (global_free_idx_list_.empty()) { From dd6d34f461910a120ac95c485fe34cca6485b95e Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 17 Mar 2021 12:06:09 +0000 Subject: [PATCH 0273/2410] blackbox: Include whiteboxed modules Signed-off-by: gatecat --- kernel/rtlil.cc | 4 ++-- kernel/rtlil.h | 2 +- passes/cmds/blackbox.cc | 3 ++- tests/various/blackbox_wb.ys | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 tests/various/blackbox_wb.ys diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 32069ce0365..87cbaa0d537 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -808,12 +808,12 @@ std::vector RTLIL::Design::selected_whole_modules() const return result; } -std::vector RTLIL::Design::selected_whole_modules_warn() const +std::vector RTLIL::Design::selected_whole_modules_warn(bool include_wb) const { std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (it.second->get_blackbox_attribute()) + if (it.second->get_blackbox_attribute(include_wb)) continue; else if (selected_whole_module(it.first)) result.push_back(it.second); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a747b9d3c8a..bbdf355fa1f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1112,7 +1112,7 @@ struct RTLIL::Design std::vector selected_modules() const; std::vector selected_whole_modules() const; - std::vector selected_whole_modules_warn() const; + std::vector selected_whole_modules_warn(bool include_wb = false) const; #ifdef WITH_PYTHON static std::map *get_all_designs(void); #endif diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index 08a6355148e..fca91852c35 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -46,10 +46,11 @@ struct BlackboxPass : public Pass { } extra_args(args, argidx, design); - for (auto module : design->selected_whole_modules_warn()) + for (auto module : design->selected_whole_modules_warn(true)) { module->makeblackbox(); module->set_bool_attribute(ID::blackbox); + module->set_bool_attribute(ID::whitebox, false); } } } BlackboxPass; diff --git a/tests/various/blackbox_wb.ys b/tests/various/blackbox_wb.ys new file mode 100644 index 00000000000..f9c9bec0643 --- /dev/null +++ b/tests/various/blackbox_wb.ys @@ -0,0 +1,14 @@ +read_verilog < Date: Wed, 17 Mar 2021 00:18:36 +0100 Subject: [PATCH 0274/2410] verilog: fix buf/not primitives with multiple outputs From IEEE1364-2005, section 7.3 buf and not gates: > These two logic gates shall have one input and one or more outputs. > The last terminal in the terminal list shall connect to the input of the > logic gate, and the other terminals shall connect to the outputs of > the logic gate. yosys does not follow this and instead interprets the first argument as the output, the second as the input and ignores the rest. --- frontends/ast/simplify.cc | 19 +++++++++++++++---- tests/simple/verilog_primitives.v | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 tests/simple/verilog_primitives.v diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d9eae3a0612..b9965ba99e2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2223,6 +2223,21 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, children.push_back(node); did_something = true; } + else if (str == "buf" || str == "not") + { + AstNode *input = children_list.back(); + if (str == "not") + input = new AstNode(AST_BIT_NOT, input); + + newNode = new AstNode(AST_GENBLOCK); + for (auto it = children_list.begin(); it != std::prev(children_list.end()); it++) { + newNode->children.push_back(new AstNode(AST_ASSIGN, *it, input->clone())); + newNode->children.back()->was_checked = true; + } + delete input; + + did_something = true; + } else { AstNodeType op_type = AST_NONE; @@ -2240,10 +2255,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, op_type = AST_BIT_XOR; if (str == "xnor") op_type = AST_BIT_XOR, invert_results = true; - if (str == "buf") - op_type = AST_POS; - if (str == "not") - op_type = AST_POS, invert_results = true; log_assert(op_type != AST_NONE); AstNode *node = children_list[1]; diff --git a/tests/simple/verilog_primitives.v b/tests/simple/verilog_primitives.v new file mode 100644 index 00000000000..0ee07393bc8 --- /dev/null +++ b/tests/simple/verilog_primitives.v @@ -0,0 +1,15 @@ +module verilog_primitives ( + input wire in1, in2, in3, + output wire out_buf0, out_buf1, out_buf2, out_buf3, out_buf4, + output wire out_not0, out_not1, out_not2, + output wire out_xnor +); + +buf u_buf0 (out_buf0, in1); +buf u_buf1 (out_buf1, out_buf2, out_buf3, out_buf4, in2); + +not u_not0 (out_not0, out_not1, out_not2, in1); + +xnor u_xnor0 (out_xnor, in1, in2, in3); + +endmodule From f71c2dcca6b63ad3cbd3d5b6f51f67f9cd85f03e Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 16 Mar 2021 11:06:40 -0400 Subject: [PATCH 0275/2410] sv: carry over global typedefs from previous files This breaks the ability to use a global typename as a standard identifier in a subsequent input file. This is otherwise backwards compatible, including for sources which previously included conflicting typedefs in each input file. --- frontends/verilog/verilog_frontend.cc | 7 +++-- tests/verilog/typedef_across_files.ys | 23 +++++++++++++++ tests/verilog/typedef_legacy_conflict.ys | 37 ++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/verilog/typedef_across_files.ys create mode 100644 tests/verilog/typedef_legacy_conflict.ys diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index e2aecd99bac..5907707c8c7 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -61,8 +61,11 @@ static void add_package_types(dict &user_types, std } } } - user_type_stack.clear(); - user_type_stack.push_back(new UserTypeMap()); + + // carry over typedefs from previous files, but allow them to be overridden + // note that these type maps are currently never reclaimed + if (user_type_stack.empty() || !user_type_stack.back()->empty()) + user_type_stack.push_back(new UserTypeMap()); } struct VerilogFrontend : public Frontend { diff --git a/tests/verilog/typedef_across_files.ys b/tests/verilog/typedef_across_files.ys new file mode 100644 index 00000000000..ca9bba7361c --- /dev/null +++ b/tests/verilog/typedef_across_files.ys @@ -0,0 +1,23 @@ +read_verilog -sv < Date: Tue, 16 Mar 2021 10:54:22 -0400 Subject: [PATCH 0276/2410] bugpoint: add runner option --- manual/command-reference-manual.tex | 3 +++ passes/cmds/bugpoint.cc | 23 +++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index e2d54cb03c5..a3264b4cd93 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -656,6 +656,9 @@ \section{bugpoint -- minimize testcases} -updates try to remove process updates from syncs. + + -runner "" + child process wrapping command, e.g., "timeout 30", or valgrind. \end{lstlisting} \section{cd -- a shortcut for 'select -module '} diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 40207b1fc59..70c002c44a1 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -87,9 +87,12 @@ struct BugpointPass : public Pass { log(" -updates\n"); log(" try to remove process updates from syncs.\n"); log("\n"); + log(" -runner \"\"\n"); + log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); + log("\n"); } - bool run_yosys(RTLIL::Design *design, string yosys_cmd, string yosys_arg) + bool run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg) { design->sort(); @@ -97,7 +100,7 @@ struct BugpointPass : public Pass { RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); - string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log %s bugpoint-case.il", yosys_cmd.c_str(), yosys_arg.c_str()); + string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str()); return run_command(yosys_cmdline) == 0; } @@ -394,7 +397,7 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", yosys_arg, grep; + string yosys_cmd = "yosys", yosys_arg, grep, runner; bool fast = false, clean = false; bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; @@ -472,6 +475,14 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-runner" && argidx + 1 < args.size()) { + runner = args[++argidx]; + if (runner.size() && runner.at(0) == '"') { + log_assert(runner.back() == '"'); + runner = runner.substr(1, runner.size() - 2); + } + continue; + } break; } extra_args(args, argidx, design); @@ -495,7 +506,7 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - if (run_yosys(crashing_design, yosys_cmd, yosys_arg)) + if (run_yosys(crashing_design, runner, yosys_cmd, yosys_arg)) log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -512,12 +523,12 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - crashes = !run_yosys(testcase, yosys_cmd, yosys_arg); + crashes = !run_yosys(testcase, runner, yosys_cmd, yosys_arg); delete testcase; } else { - crashes = !run_yosys(simplified, yosys_cmd, yosys_arg); + crashes = !run_yosys(simplified, runner, yosys_cmd, yosys_arg); } if (crashes && check_logfile(grep)) From cae905f55128a77e8d2eecc75d861292d79baa79 Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 17 Mar 2021 12:16:53 +0000 Subject: [PATCH 0277/2410] Blackbox all whiteboxes after synthesis This prevents issues like processes in whiteboxes triggering an error in the JSON backend. Signed-off-by: gatecat --- techlibs/achronix/synth_achronix.cc | 1 + techlibs/anlogic/synth_anlogic.cc | 1 + techlibs/coolrunner2/synth_coolrunner2.cc | 1 + techlibs/easic/synth_easic.cc | 1 + techlibs/ecp5/synth_ecp5.cc | 1 + techlibs/efinix/synth_efinix.cc | 1 + techlibs/gowin/synth_gowin.cc | 1 + techlibs/greenpak4/synth_greenpak4.cc | 1 + techlibs/ice40/synth_ice40.cc | 1 + techlibs/intel/synth_intel.cc | 1 + techlibs/intel_alm/synth_intel_alm.cc | 1 + techlibs/machxo2/synth_machxo2.cc | 1 + techlibs/nexus/synth_nexus.cc | 1 + techlibs/sf2/synth_sf2.cc | 1 + techlibs/xilinx/synth_xilinx.cc | 1 + tests/arch/ecp5/mux.ys | 18 +++++++++--------- 16 files changed, 24 insertions(+), 9 deletions(-) diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index b203828d2c2..a31cbfc1416 100644 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -173,6 +173,7 @@ struct SynthAchronixPass : public ScriptPass { run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("vout")) diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index d953fae5e3f..604ca81ad8c 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -211,6 +211,7 @@ struct SynthAnlogicPass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("edif")) diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index 47102fbb1f7..a746ac222d0 100644 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ b/techlibs/coolrunner2/synth_coolrunner2.cc @@ -192,6 +192,7 @@ struct SynthCoolrunner2Pass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("json")) diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc index 897bc1c40ed..9b78b44af60 100644 --- a/techlibs/easic/synth_easic.cc +++ b/techlibs/easic/synth_easic.cc @@ -175,6 +175,7 @@ struct SynthEasicPass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("vlog")) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 3cee9722e10..482e7a1400b 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -385,6 +385,7 @@ struct SynthEcp5Pass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("blif")) diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 001b0594515..613063e34c4 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -213,6 +213,7 @@ struct SynthEfinixPass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("edif")) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 5bf0894da12..55a6bb66ce1 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -289,6 +289,7 @@ struct SynthGowinPass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("vout")) diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index d9af340d970..26d913ab33b 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -196,6 +196,7 @@ struct SynthGreenPAK4Pass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("json")) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index b945889fe43..ea038d325ac 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -417,6 +417,7 @@ struct SynthIce40Pass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("blif")) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index a513528f74f..1d8e660a085 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -233,6 +233,7 @@ struct SynthIntelPass : public ScriptPass { run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("vqm")) { diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 6719eb65cd0..11b6d0525a5 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -274,6 +274,7 @@ struct SynthIntelALMPass : public ScriptPass { run("hierarchy -check"); run("stat"); run("check"); + run("blackbox =A:whitebox"); } if (check_label("quartus")) { diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index bd56fbba930..bba8f48308d 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -212,6 +212,7 @@ struct SynthMachXO2Pass : public ScriptPass { run("hierarchy -check"); run("stat"); + run("blackbox =A:whitebox"); } if (check_label("blif")) diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 7f36eb2827e..9134b6e2a81 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -406,6 +406,7 @@ struct SynthNexusPass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("json")) diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index a0061ebd0fe..22cc4a1ae52 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -228,6 +228,7 @@ struct SynthSf2Pass : public ScriptPass run("hierarchy -check"); run("stat"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("edif")) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 0adec57a2d5..80d120fe1e5 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -662,6 +662,7 @@ struct SynthXilinxPass : public ScriptPass run("hierarchy -check"); run("stat -tech xilinx"); run("check -noinit"); + run("blackbox =A:whitebox"); } if (check_label("edif")) { diff --git a/tests/arch/ecp5/mux.ys b/tests/arch/ecp5/mux.ys index 92463aa3248..db63dda5f94 100644 --- a/tests/arch/ecp5/mux.ys +++ b/tests/arch/ecp5/mux.ys @@ -15,9 +15,9 @@ proc equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module -select -assert-count 1 t:L6MUX21 -select -assert-count 4 t:LUT4 -select -assert-count 2 t:PFUMX +select -assert-max 1 t:L6MUX21 +select -assert-max 4 t:LUT4 +select -assert-max 2 t:PFUMX select -assert-none t:LUT4 t:L6MUX21 t:PFUMX %% t:* %D @@ -27,9 +27,9 @@ proc equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module -select -assert-count 1 t:L6MUX21 -select -assert-count 7 t:LUT4 -select -assert-count 2 t:PFUMX +select -assert-max 1 t:L6MUX21 +select -assert-max 7 t:LUT4 +select -assert-max 2 t:PFUMX select -assert-none t:LUT4 t:L6MUX21 t:PFUMX %% t:* %D @@ -39,8 +39,8 @@ proc equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module -select -assert-count 8 t:L6MUX21 -select -assert-count 26 t:LUT4 -select -assert-count 12 t:PFUMX +select -assert-max 12 t:L6MUX21 +select -assert-max 34 t:LUT4 +select -assert-max 17 t:PFUMX select -assert-none t:LUT4 t:L6MUX21 t:PFUMX %% t:* %D From d05d47cc0484590e8fe63882d64913ea26485d70 Mon Sep 17 00:00:00 2001 From: Michael Singer Date: Wed, 17 Mar 2021 23:22:50 +0100 Subject: [PATCH 0278/2410] Fix check for bad std::regex (fixes #2606) --- kernel/log.h | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/kernel/log.h b/kernel/log.h index 8981c4cde1e..3d93f5bcd14 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -24,9 +24,29 @@ #include -// In GCC 4.8 std::regex is not working correctlty, in order to make features -// using regular expressions to work replacement regex library is used -#if defined(__GNUC__) && !defined( __clang__) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 8) +// In the libstdc++ headers that are provided by GCC 4.8, std::regex is not +// working correctly. In order to make features using regular expressions +// work, a replacement regex library is used. Just checking for GCC version +// is not enough though, because at least on RHEL7/CentOS7 even when compiling +// with Clang instead of GCC, the GCC 4.8 headers are still used for std::regex. +// We have to check the version of the libstdc++ headers specifically, not the +// compiler version. GCC headers of libstdc++ before version 3.4 define +// __GLIBCPP__, later versions define __GLIBCXX__. GCC 7 and newer additionaly +// define _GLIBCXX_RELEASE with a version number. +// Include limits std C++ header, so we get the version macros defined: +#if defined(__cplusplus) +# include +#endif +// Check if libstdc++ is from GCC +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) +// Check if version could be 4.8 or lower (this also matches for some 4.9 and +// 5.0 releases). See: +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning +# if !defined(_GLIBCXX_RELEASE) && (defined(__GLIBCPP__) || __GLIBCXX__ <= 20150623) +# define YS_HAS_BAD_STD_REGEX +# endif +#endif +#if defined(YS_HAS_BAD_STD_REGEX) #include #define YS_REGEX_TYPE boost::xpressive::sregex #define YS_REGEX_MATCH_TYPE boost::xpressive::smatch From 8740fdf1d799fd8a3196bac28fe4e418e74f2acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 17 Mar 2021 18:30:49 +0100 Subject: [PATCH 0279/2410] ast: Use better parameter serialization for paramod names. Calling log_signal is problematic for several reasons: - with recent changes, empty string is serialized as { }, which violates the "no spaces in IdString" rule - the type (plain / real / signed / string) is dropped, wrongly conflating functionally different values and potentially introducing a subtle elaboration bug Instead, use a custom simple serialization scheme. --- frontends/ast/ast.cc | 27 +++++++++++++++++++++++++-- tests/arch/xilinx/abc9_dff.ys | 6 +++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7aa391c93ac..84a4de41c7a 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1575,6 +1575,29 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict= 0; i--) { + switch (val.bits[i]) { + case RTLIL::State::S0: res.push_back('0'); break; + case RTLIL::State::S1: res.push_back('1'); break; + case RTLIL::State::Sx: res.push_back('x'); break; + case RTLIL::State::Sz: res.push_back('z'); break; + case RTLIL::State::Sa: res.push_back('?'); break; + case RTLIL::State::Sm: res.push_back('m'); break; + } + } + return res; +} + // create a new parametric module (when needed) and return the name of the generated module std::string AstModule::derive_common(RTLIL::Design *design, const dict ¶meters, AstNode **new_ast_out, bool quiet) { @@ -1594,14 +1617,14 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictstr.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); continue; } it = parameters.find(stringf("$%d", para_counter)); if (it != parameters.end()) { if (!quiet) log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); continue; } } diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys index 210e87477ce..0ba3901f703 100644 --- a/tests/arch/xilinx/abc9_dff.ys +++ b/tests/arch/xilinx/abc9_dff.ys @@ -50,10 +50,10 @@ FDCE_1 /*#(.INIT(1))*/ fd7(.C(C), .CE(1'b0), .D(D), .CLR(1'b0), .Q(Q[6])); FDPE_1 #(.INIT(1)) fd8(.C(C), .CE(1'b0), .D(D), .PRE(1'b0), .Q(Q[7])); endmodule EOT -logger -expect warning "Whitebox '\$paramod\\FDRE\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 -logger -expect warning "Whitebox '\$paramod\\FDRE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 +logger -expect warning "Whitebox '\$paramod\\FDRE\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 +logger -expect warning "Whitebox '\$paramod\\FDRE_1\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 logger -expect warning "Whitebox 'FDSE' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 -logger -expect warning "Whitebox '\$paramod\\FDSE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 +logger -expect warning "Whitebox '\$paramod\\FDSE_1\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1 equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf design -load postopt select -assert-count 8 t:FD* From f4298b057ae0939b83283c8c7431097e71a32b62 Mon Sep 17 00:00:00 2001 From: Lofty Date: Wed, 17 Mar 2021 02:34:30 +0000 Subject: [PATCH 0280/2410] quicklogic: PolarPro 3 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Grzegorz Latosiński Co-authored-by: Maciej Kurc Co-authored-by: Tarachand Pagarani Co-authored-by: Lalit Sharma Co-authored-by: kkumar23 --- Makefile | 1 + techlibs/quicklogic/Makefile.inc | 9 + techlibs/quicklogic/cells_sim.v | 36 +++ techlibs/quicklogic/lut_sim.v | 76 ++++++ techlibs/quicklogic/pp3_cells_map.v | 36 +++ techlibs/quicklogic/pp3_cells_sim.v | 330 ++++++++++++++++++++++++ techlibs/quicklogic/pp3_ffs_map.v | 4 + techlibs/quicklogic/pp3_latches_map.v | 11 + techlibs/quicklogic/pp3_lut_map.v | 53 ++++ techlibs/quicklogic/synth_quicklogic.cc | 215 +++++++++++++++ tests/arch/quicklogic/add_sub.ys | 11 + tests/arch/quicklogic/adffs.ys | 67 +++++ tests/arch/quicklogic/counter.ys | 18 ++ tests/arch/quicklogic/dffs.ys | 20 ++ tests/arch/quicklogic/fsm.ys | 24 ++ tests/arch/quicklogic/latches.ys | 39 +++ tests/arch/quicklogic/logic.ys | 14 + tests/arch/quicklogic/mux.ys | 52 ++++ tests/arch/quicklogic/run-test.sh | 4 + tests/arch/quicklogic/tribuf.ys | 13 + 20 files changed, 1033 insertions(+) create mode 100644 techlibs/quicklogic/Makefile.inc create mode 100644 techlibs/quicklogic/cells_sim.v create mode 100644 techlibs/quicklogic/lut_sim.v create mode 100644 techlibs/quicklogic/pp3_cells_map.v create mode 100644 techlibs/quicklogic/pp3_cells_sim.v create mode 100644 techlibs/quicklogic/pp3_ffs_map.v create mode 100644 techlibs/quicklogic/pp3_latches_map.v create mode 100644 techlibs/quicklogic/pp3_lut_map.v create mode 100644 techlibs/quicklogic/synth_quicklogic.cc create mode 100644 tests/arch/quicklogic/add_sub.ys create mode 100644 tests/arch/quicklogic/adffs.ys create mode 100644 tests/arch/quicklogic/counter.ys create mode 100644 tests/arch/quicklogic/dffs.ys create mode 100644 tests/arch/quicklogic/fsm.ys create mode 100644 tests/arch/quicklogic/latches.ys create mode 100644 tests/arch/quicklogic/logic.ys create mode 100644 tests/arch/quicklogic/mux.ys create mode 100755 tests/arch/quicklogic/run-test.sh create mode 100644 tests/arch/quicklogic/tribuf.ys diff --git a/Makefile b/Makefile index e6a27de07d9..763871523d2 100644 --- a/Makefile +++ b/Makefile @@ -816,6 +816,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/arch/gowin && bash run-test.sh $(SEEDOPT) +cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT) +cd tests/arch/nexus && bash run-test.sh $(SEEDOPT) + +cd tests/arch/quicklogic && bash run-test.sh $(SEEDOPT) +cd tests/rpc && bash run-test.sh +cd tests/memfile && bash run-test.sh +cd tests/verilog && bash run-test.sh diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc new file mode 100644 index 00000000000..9a07c2eed20 --- /dev/null +++ b/techlibs/quicklogic/Makefile.inc @@ -0,0 +1,9 @@ +OBJS += techlibs/quicklogic/synth_quicklogic.o + +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_ffs_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_lut_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_latches_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/lut_sim.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_sim.v)) diff --git a/techlibs/quicklogic/cells_sim.v b/techlibs/quicklogic/cells_sim.v new file mode 100644 index 00000000000..f24782ec3f3 --- /dev/null +++ b/techlibs/quicklogic/cells_sim.v @@ -0,0 +1,36 @@ +module inv ( + output Q, + input A +); + assign Q = A ? 0 : 1; +endmodule + +module buff ( + output Q, + input A +); + assign Q = A; +endmodule + +module logic_0 ( + output A +); + assign A = 0; +endmodule + +module logic_1 ( + output A +); + assign A = 1; +endmodule + +module gclkbuff ( + input A, + output Z +); + specify + (A => Z) = 0; + endspecify + + assign Z = A; +endmodule diff --git a/techlibs/quicklogic/lut_sim.v b/techlibs/quicklogic/lut_sim.v new file mode 100644 index 00000000000..851ce4d6845 --- /dev/null +++ b/techlibs/quicklogic/lut_sim.v @@ -0,0 +1,76 @@ +(* abc9_lut=1, lib_whitebox *) +module LUT1 ( + output O, + input I0 +); + parameter [1:0] INIT = 0; + parameter EQN = "(I0)"; + + // These timings are for PolarPro 3E; other families will need updating. + specify + (I0 => O) = 698; // FS -> FZ + endspecify + + assign O = I0 ? INIT[1] : INIT[0]; +endmodule + +// TZ TSL TAB +(* abc9_lut=2, lib_whitebox *) +module LUT2 ( + output O, + input I0, I1 +); + parameter [3:0] INIT = 4'h0; + parameter EQN = "(I0)"; + + // These timings are for PolarPro 3E; other families will need updating. + specify + (I0 => O) = 1251; // TAB -> TZ + (I1 => O) = 1406; // TSL -> TZ + endspecify + + wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0]; + assign O = I0 ? s1[1] : s1[0]; +endmodule + +(* abc9_lut=2, lib_whitebox *) +module LUT3 ( + output O, + input I0, I1, I2 +); + parameter [7:0] INIT = 8'h0; + parameter EQN = "(I0)"; + + // These timings are for PolarPro 3E; other families will need updating. + specify + (I0 => O) = 1251; // TAB -> TZ + (I1 => O) = 1406; // TSL -> TZ + (I2 => O) = 1699; // ('TA1', 'TA2', 'TB1', 'TB2') -> TZ + endspecify + + wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0]; + wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0]; + assign O = I0 ? s1[1] : s1[0]; +endmodule + +(* abc9_lut=4, lib_whitebox *) +module LUT4 ( + output O, + input I0, I1, I2, I3 +); + parameter [15:0] INIT = 16'h0; + parameter EQN = "(I0)"; + + // These timings are for PolarPro 3E; other families will need updating. + specify + (I0 => O) = 995; // TBS -> CZ + (I1 => O) = 1437; // ('TAB', 'BAB') -> CZ + (I2 => O) = 1593; // ('TSL', 'BSL') -> CZ + (I3 => O) = 1887; // ('TA1', 'TA2', 'TB1', 'TB2', 'BA1', 'BA2', 'BB1', 'BB2') -> CZ + endspecify + + wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0]; + wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0]; + wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0]; + assign O = I0 ? s1[1] : s1[0]; +endmodule diff --git a/techlibs/quicklogic/pp3_cells_map.v b/techlibs/quicklogic/pp3_cells_map.v new file mode 100644 index 00000000000..10e270d4e05 --- /dev/null +++ b/techlibs/quicklogic/pp3_cells_map.v @@ -0,0 +1,36 @@ +module \$_MUX8_ ( + A, B, C, D, E, F, G, H, S, T, U, Y +); + input A, B, C, D, E, F, G, H, S, T, U; + output Y; + mux8x0 _TECHMAP_REPLACE_ ( + .A(A), + .B(B), + .C(C), + .D(D), + .E(E), + .F(F), + .G(G), + .H(H), + .S0(S), + .S1(T), + .S2(U), + .Q(Y) + ); +endmodule + +module \$_MUX4_ ( + A, B, C, D, S, T, U, Y +); + input A, B, C, D, S, T, U; + output Y; + mux4x0 _TECHMAP_REPLACE_ ( + .A(A), + .B(B), + .C(C), + .D(D), + .S0(S), + .S1(T), + .Q(Y) + ); +endmodule diff --git a/techlibs/quicklogic/pp3_cells_sim.v b/techlibs/quicklogic/pp3_cells_sim.v new file mode 100644 index 00000000000..61d1ee314f8 --- /dev/null +++ b/techlibs/quicklogic/pp3_cells_sim.v @@ -0,0 +1,330 @@ +module inpad ( + output Q, + (* iopad_external_pin *) + input P +); + specify + (P => Q) = 0; + endspecify + assign Q = P; +endmodule + +module outpad ( + (* iopad_external_pin *) + output P, + input A +); + specify + (A => P) = 0; + endspecify + assign P = A; +endmodule + +module ckpad ( + output Q, + (* iopad_external_pin *) + input P +); + specify + (P => Q) = 0; + endspecify + assign Q = P; +endmodule + +module bipad ( + input A, + input EN, + output Q, + (* iopad_external_pin *) + inout P +); + assign Q = P; + assign P = EN ? A : 1'bz; +endmodule + +module dff ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(posedge CLK) Q <= D; +endmodule + +module dffc ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + (* clkbuf_sink *) + input CLR +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + + always @(posedge CLK or posedge CLR) + if (CLR) Q <= 1'b0; + else Q <= D; +endmodule + +module dffp ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + (* clkbuf_sink *) + input PRE +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + + always @(posedge CLK or posedge PRE) + if (PRE) Q <= 1'b1; + else Q <= D; +endmodule + +module dffpc ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + (* clkbuf_sink *) + input CLR, + (* clkbuf_sink *) + input PRE +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + + always @(posedge CLK or posedge CLR or posedge PRE) + if (CLR) Q <= 1'b0; + else if (PRE) Q <= 1'b1; + else Q <= D; +endmodule + +module dffe ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + input EN +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(posedge CLK) if (EN) Q <= D; +endmodule + +module dffec ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + input EN, + (* clkbuf_sink *) + input CLR +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + + always @(posedge CLK or posedge CLR) + if (CLR) Q <= 1'b0; + else if (EN) Q <= D; +endmodule + +(* lib_whitebox *) +module dffepc ( + output reg Q, + input D, + (* clkbuf_sink *) + input CLK, + input EN, + (* clkbuf_sink *) + input CLR, + (* clkbuf_sink *) + input PRE +); + parameter [0:0] INIT = 1'b0; + + // The CLR => Q and PRE => Q paths are commented out due to YosysHQ/yosys#2530. + specify + if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ + // if (CLR) (CLR => Q) = 967; // QRT -> QZ + // if (PRE) (PRE => Q) = 1252; // QST -> QZ + $setup(D, posedge CLK, 216); // QCK -> QDS + $setup(EN, posedge CLK, 590); // QCK -> QEN + endspecify + + initial Q = INIT; + always @(posedge CLK or posedge CLR or posedge PRE) + if (CLR) Q <= 1'b0; + else if (PRE) Q <= 1'b1; + else if (EN) Q <= D; +endmodule + +// FZ FS F2 (F1 TO 0) +(* abc9_box, lib_whitebox *) +module AND2I0 ( + output Q, + input A, B +); + specify + (A => Q) = 698; // FS -> FZ + (B => Q) = 639; // F2 -> FZ + endspecify + + assign Q = A ? B : 0; +endmodule + +(* abc9_box, lib_whitebox *) +module mux2x0 ( + output Q, + input S, A, B +); + specify + (S => Q) = 698; // FS -> FZ + (A => Q) = 639; // F1 -> FZ + (B => Q) = 639; // F2 -> FZ + endspecify + + assign Q = S ? B : A; +endmodule + +(* abc9_box, lib_whitebox *) +module mux2x1 ( + output Q, + input S, A, B +); + specify + (S => Q) = 698; // FS -> FZ + (A => Q) = 639; // F1 -> FZ + (B => Q) = 639; // F2 -> FZ + endspecify + + assign Q = S ? B : A; +endmodule + +(* abc9_box, lib_whitebox *) +module mux4x0 ( + output Q, + input S0, S1, A, B, C, D +); + specify + (S0 => Q) = 1251; // TAB -> TZ + (S1 => Q) = 1406; // TSL -> TZ + (A => Q) = 1699; // TA1 -> TZ + (B => Q) = 1687; // TA2 -> TZ + (C => Q) = 1669; // TB1 -> TZ + (D => Q) = 1679; // TB2 -> TZ + endspecify + + assign Q = S1 ? (S0 ? D : C) : (S0 ? B : A); +endmodule + +// S0 BSL TSL +// S1 BAB TAB +// S2 TBS +// A TA1 +// B TA2 +// C TB1 +// D TB2 +// E BA1 +// F BA2 +// G BB1 +// H BB2 +// Q CZ +(* abc9_box, lib_whitebox *) +module mux8x0 ( + output Q, + input S0, S1, S2, A, B, C, D, E, F, G, H +); + specify + (S0 => Q) = 1593; // ('TSL', 'BSL') -> CZ + (S1 => Q) = 1437; // ('TAB', 'BAB') -> CZ + (S2 => Q) = 995; // TBS -> CZ + (A => Q) = 1887; // TA1 -> CZ + (B => Q) = 1873; // TA2 -> CZ + (C => Q) = 1856; // TB1 -> CZ + (D => Q) = 1860; // TB2 -> CZ + (E => Q) = 1714; // BA1 -> CZ + (F => Q) = 1773; // BA2 -> CZ + (G => Q) = 1749; // BB1 -> CZ + (H => Q) = 1723; // BB2 -> CZ + endspecify + + assign Q = S2 ? (S1 ? (S0 ? H : G) : (S0 ? F : E)) : (S1 ? (S0 ? D : C) : (S0 ? B : A)); +endmodule + +(* blackbox *) +(* keep *) +module qlal4s3b_cell_macro ( + input WB_CLK, + input WBs_ACK, + input [31:0] WBs_RD_DAT, + output [3:0] WBs_BYTE_STB, + output WBs_CYC, + output WBs_WE, + output WBs_RD, + output WBs_STB, + output [16:0] WBs_ADR, + input [3:0] SDMA_Req, + input [3:0] SDMA_Sreq, + output [3:0] SDMA_Done, + output [3:0] SDMA_Active, + input [3:0] FB_msg_out, + input [7:0] FB_Int_Clr, + output FB_Start, + input FB_Busy, + output WB_RST, + output Sys_PKfb_Rst, + output Clk16, + output Clk16_Rst, + output Clk21, + output Clk21_Rst, + output Sys_Pclk, + output Sys_Pclk_Rst, + input Sys_PKfb_Clk, + input [31:0] FB_PKfbData, + output [31:0] WBs_WR_DAT, + input [3:0] FB_PKfbPush, + input FB_PKfbSOF, + input FB_PKfbEOF, + output [7:0] Sensor_Int, + output FB_PKfbOverflow, + output [23:0] TimeStamp, + input Sys_PSel, + input [15:0] SPIm_Paddr, + input SPIm_PEnable, + input SPIm_PWrite, + input [31:0] SPIm_PWdata, + output SPIm_PReady, + output SPIm_PSlvErr, + output [31:0] SPIm_Prdata, + input [15:0] Device_ID, + input [13:0] FBIO_In_En, + input [13:0] FBIO_Out, + input [13:0] FBIO_Out_En, + output [13:0] FBIO_In, + inout [13:0] SFBIO, + input Device_ID_6S, + input Device_ID_4S, + input SPIm_PWdata_26S, + input SPIm_PWdata_24S, + input SPIm_PWdata_14S, + input SPIm_PWdata_11S, + input SPIm_PWdata_0S, + input SPIm_Paddr_8S, + input SPIm_Paddr_6S, + input FB_PKfbPush_1S, + input FB_PKfbData_31S, + input FB_PKfbData_21S, + input FB_PKfbData_19S, + input FB_PKfbData_9S, + input FB_PKfbData_6S, + input Sys_PKfb_ClkS, + input FB_BusyS, + input WB_CLKS +); + +endmodule diff --git a/techlibs/quicklogic/pp3_ffs_map.v b/techlibs/quicklogic/pp3_ffs_map.v new file mode 100644 index 00000000000..73ba6c9c8db --- /dev/null +++ b/techlibs/quicklogic/pp3_ffs_map.v @@ -0,0 +1,4 @@ +module \$_DFFSRE_PPPP_ (input C, S, R, E, D, output Q); + wire _TECHMAP_REMOVEINIT_Q_ = 1; + dffepc #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.CLK(C), .PRE(S), .CLR(R), .EN(E), .D(D), .Q(Q)); +endmodule diff --git a/techlibs/quicklogic/pp3_latches_map.v b/techlibs/quicklogic/pp3_latches_map.v new file mode 100644 index 00000000000..240a3fb4ee9 --- /dev/null +++ b/techlibs/quicklogic/pp3_latches_map.v @@ -0,0 +1,11 @@ +module \$_DLATCH_P_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = E ? D : Q; +endmodule + +module \$_DLATCH_N_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = !E ? D : Q; +endmodule diff --git a/techlibs/quicklogic/pp3_lut_map.v b/techlibs/quicklogic/pp3_lut_map.v new file mode 100644 index 00000000000..4c375c9fdb0 --- /dev/null +++ b/techlibs/quicklogic/pp3_lut_map.v @@ -0,0 +1,53 @@ +module \$lut ( + A, Y +); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + LUT1 #( + .EQN(""), + .INIT(LUT) + ) _TECHMAP_REPLACE_ ( + .O(Y), + .I0(A[0]) + ); + end else if (WIDTH == 2) begin + LUT2 #( + .EQN(""), + .INIT(LUT) + ) _TECHMAP_REPLACE_ ( + .O(Y), + .I0(A[0]), + .I1(A[1]) + ); + end else if (WIDTH == 3) begin + LUT3 #( + .EQN(""), + .INIT(LUT) + ) _TECHMAP_REPLACE_ ( + .O(Y), + .I0(A[0]), + .I1(A[1]), + .I2(A[2]) + ); + end else if (WIDTH == 4) begin + LUT4 #( + .EQN(""), + .INIT(LUT) + ) _TECHMAP_REPLACE_ ( + .O(Y), + .I0(A[0]), + .I1(A[1]), + .I2(A[2]), + .I3(A[3]) + ); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc new file mode 100644 index 00000000000..90eb0f78b87 --- /dev/null +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -0,0 +1,215 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 QuickLogic Corp. + * + * 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/celltypes.h" +#include "kernel/log.h" +#include "kernel/register.h" +#include "kernel/rtlil.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthQuickLogicPass : public ScriptPass { + + SynthQuickLogicPass() : ScriptPass("synth_quicklogic", "Synthesis for QuickLogic FPGAs") {} + + void help() override + { + log("\n"); + log(" synth_quicklogic [options]\n"); + log("This command runs synthesis for QuickLogic FPGAs\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -family \n"); + log(" run synthesis for the specified QuickLogic architecture\n"); + log(" generate the synthesis netlist for the specified family.\n"); + log(" supported values:\n"); + log(" - pp3: PolarPro 3 \n"); + log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -verilog \n"); + log(" write the design to the specified verilog file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, blif_file, family, currmodule, verilog_file; + + void clear_flags() override + { + top_opt = "-auto-top"; + blif_file = ""; + verilog_file = ""; + currmodule = ""; + family = "pp3"; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-family" && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-verilog" && argidx+1 < args.size()) { + verilog_file = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + if (family != "pp3") + log_cmd_error("Invalid family specified: '%s'\n", family.c_str()); + + log_header(design, "Executing SYNTH_QUICKLOGIC pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + if (check_label("begin")) { + run(stringf("read_verilog -lib -specify +/quicklogic/cells_sim.v +/quicklogic/%s_cells_sim.v", family.c_str())); + run("read_verilog -lib -specify +/quicklogic/lut_sim.v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (check_label("coarse")) { + run("proc"); + run("flatten"); + run("tribuf -logic"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4"); + run("opt_expr"); + run("opt_clean"); + run("alumacc"); + run("pmuxtree"); + run("opt"); + run("memory -nomap"); + run("opt_clean"); + } + + if (check_label("map_ffram")) { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " + "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " + "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("opt -undriven -fine"); + } + + if (check_label("map_gates")) { + run("techmap"); + run("opt -fast"); + run("muxcover -mux8 -mux4"); + } + + if (check_label("map_ffs")) { + run("opt_expr"); + run("dfflegalize -cell $_DFFSRE_PPPP_ 0 -cell $_DLATCH_?_ x"); + + run(stringf("techmap -map +/quicklogic/%s_cells_map.v -map +/quicklogic/%s_ffs_map.v", family.c_str(), family.c_str())); + + run("opt_expr -mux_undef"); + } + + if (check_label("map_luts")) { + run(stringf("techmap -map +/quicklogic/%s_latches_map.v", family.c_str())); + run("abc -luts 1,2,2,4 -dress"); + + run("clean"); + } + + if (check_label("map_cells")) { + run(stringf("techmap -map +/quicklogic/%s_lut_map.v", family.c_str())); + run("clean"); + } + + if (check_label("check")) { + run("autoname"); + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + } + + if (check_label("iomap")) { + run("clkbufmap -inpad ckpad Q:P"); + run("iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top"); + } + + if (check_label("finalize")) { + run("setundef -zero -params -undriven"); + run("hilomap -hicell logic_1 A -locell logic_0 A -singleton A:top"); + run("opt_clean -purge"); + run("check"); + run("blackbox =A:whitebox"); + } + + if (check_label("blif")) { + if (!blif_file.empty() || help_mode) { + run(stringf("write_blif -attr -param %s %s", top_opt.c_str(), blif_file.c_str())); + } + } + + if (check_label("verilog")) { + if (!verilog_file.empty()) { + run("write_verilog -noattr -nohex " + verilog_file); + } + } + } + +} SynthQuicklogicPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/arch/quicklogic/add_sub.ys b/tests/arch/quicklogic/add_sub.ys new file mode 100644 index 00000000000..168b3f8b33f --- /dev/null +++ b/tests/arch/quicklogic/add_sub.ys @@ -0,0 +1,11 @@ +read_verilog ../common/add_sub.v +hierarchy -top top +equiv_opt -assert -map +/quicklogic/lut_sim.v -map +/quicklogic/pp3_cells_sim.v synth_quicklogic -family pp3 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 3 t:LUT2 +select -assert-count 4 t:LUT3 +select -assert-count 4 t:LUT4 +select -assert-count 8 t:inpad +select -assert-count 8 t:outpad +select -assert-none t:LUT2 t:LUT3 t:LUT4 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/adffs.ys b/tests/arch/quicklogic/adffs.ys new file mode 100644 index 00000000000..41a17584427 --- /dev/null +++ b/tests/arch/quicklogic/adffs.ys @@ -0,0 +1,67 @@ +read_verilog ../common/adffs.v +design -save read + +hierarchy -top adff +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adff # Constrain all select calls below inside the top module +select -assert-count 1 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 1 t:inpad +select -assert-count 1 t:outpad +select -assert-count 2 t:ckpad + +select -assert-none t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D + + +design -load read +hierarchy -top adffn +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adffn # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT1 +select -assert-count 1 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 2 t:inpad +select -assert-count 1 t:outpad +select -assert-count 1 t:ckpad + +select -assert-none t:LUT1 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D + + +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT2 +select -assert-count 1 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 3 t:inpad +select -assert-count 1 t:outpad +select -assert-count 1 t:ckpad + +select -assert-none t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D + + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT1 +select -assert-count 1 t:LUT2 +select -assert-count 1 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 4 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT1 t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/counter.ys b/tests/arch/quicklogic/counter.ys new file mode 100644 index 00000000000..0c04b5742ed --- /dev/null +++ b/tests/arch/quicklogic/counter.ys @@ -0,0 +1,18 @@ +read_verilog ../common/counter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -multiclock -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT1 +select -assert-count 5 t:LUT2 +select -assert-count 2 t:LUT3 +select -assert-count 3 t:LUT4 +select -assert-count 8 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 8 t:outpad +select -assert-count 2 t:ckpad + +select -assert-none t:LUT1 t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:outpad t:ckpad %% t:* %D diff --git a/tests/arch/quicklogic/dffs.ys b/tests/arch/quicklogic/dffs.ys new file mode 100644 index 00000000000..2e0a34540ec --- /dev/null +++ b/tests/arch/quicklogic/dffs.ys @@ -0,0 +1,20 @@ +read_verilog ../common/dffs.v +rename dff my_dff # Work around conflicting module names between test and vendor cells +rename dffe my_dffe +design -save read + +hierarchy -top my_dff +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dff # Constrain all select calls below inside the top module +select -assert-none t:* + +design -load read +hierarchy -top my_dffe +proc +equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffe # Constrain all select calls below inside the top module + +select -assert-none t:* \ No newline at end of file diff --git a/tests/arch/quicklogic/fsm.ys b/tests/arch/quicklogic/fsm.ys new file mode 100644 index 00000000000..7ed36b9e4cd --- /dev/null +++ b/tests/arch/quicklogic/fsm.ys @@ -0,0 +1,24 @@ +read_verilog ../common/fsm.v +hierarchy -top fsm +proc +flatten + +equiv_opt -run :prove -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic +async2sync +miter -equiv -make_assert -flatten gold gate miter +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +select -assert-count 3 t:LUT2 +select -assert-count 6 t:LUT3 +select -assert-count 7 t:LUT4 +select -assert-count 6 t:dffepc +select -assert-count 1 t:logic_0 +select -assert-count 1 t:logic_1 +select -assert-count 3 t:inpad +select -assert-count 2 t:outpad +select -assert-count 1 t:ckpad + +select -assert-none t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D diff --git a/tests/arch/quicklogic/latches.ys b/tests/arch/quicklogic/latches.ys new file mode 100644 index 00000000000..d7652f749ad --- /dev/null +++ b/tests/arch/quicklogic/latches.ys @@ -0,0 +1,39 @@ +read_verilog ../common/latches.v +design -save read + +hierarchy -top latchp +proc +# Can't run any sort of equivalence check because latches are blown to LUTs +synth_quicklogic +cd latchp # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 +select -assert-count 3 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D + + +design -load read +hierarchy -top latchn +proc +# Can't run any sort of equivalence check because latches are blown to LUTs +synth_quicklogic +cd latchn # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 +select -assert-count 3 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D + + +design -load read +hierarchy -top latchsr +proc +# Can't run any sort of equivalence check because latches are blown to LUTs +synth_quicklogic +cd latchsr # Constrain all select calls below inside the top module +select -assert-count 2 t:LUT3 +select -assert-count 5 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/logic.ys b/tests/arch/quicklogic/logic.ys new file mode 100644 index 00000000000..65f48a42b61 --- /dev/null +++ b/tests/arch/quicklogic/logic.ys @@ -0,0 +1,14 @@ +read_verilog ../common/logic.v +hierarchy -top top +proc +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:LUT1 +select -assert-count 6 t:LUT2 +select -assert-count 2 t:LUT4 +select -assert-count 8 t:inpad +select -assert-count 10 t:outpad + +select -assert-none t:LUT1 t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/mux.ys b/tests/arch/quicklogic/mux.ys new file mode 100644 index 00000000000..632d1468759 --- /dev/null +++ b/tests/arch/quicklogic/mux.ys @@ -0,0 +1,52 @@ +read_verilog ../common/mux.v +design -save read + +hierarchy -top mux2 +proc +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux2 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 +select -assert-count 3 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 3 t:LUT3 +select -assert-count 6 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 4 t:LUT2 +select -assert-count 1 t:LUT3 +select -assert-count 2 t:mux4x0 +select -assert-count 11 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT2 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D + +design -load read +hierarchy -top mux16 +proc +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux16 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 +select -assert-count 2 t:mux8x0 +select -assert-count 20 t:inpad +select -assert-count 1 t:outpad + +select -assert-none t:LUT3 t:mux8x0 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/run-test.sh b/tests/arch/quicklogic/run-test.sh new file mode 100755 index 00000000000..4be4b70ae17 --- /dev/null +++ b/tests/arch/quicklogic/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/quicklogic/tribuf.ys b/tests/arch/quicklogic/tribuf.ys new file mode 100644 index 00000000000..de763009eaf --- /dev/null +++ b/tests/arch/quicklogic/tribuf.ys @@ -0,0 +1,13 @@ +read_verilog ../common/tribuf.v +hierarchy -top tristate +proc +tribuf +flatten +synth +equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/simcells.v synth_quicklogic # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd tristate # Constrain all select calls below inside the top module +select -assert-count 2 t:inpad +select -assert-count 1 t:outpad +select -assert-count 1 t:$_TBUF_ +select -assert-none t:inpad t:outpad t:$_TBUF_ %% t:* %D From 3aa10e90ba1d57e4d01c199396a52fbd1a66fa7e Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 15 Mar 2021 15:55:18 +0100 Subject: [PATCH 0281/2410] modtools: fix use-after-free of cell pointers in ModWalker cell_inputs and cell_outputs retain cell pointers as their keys across invocations of setup(), which may however be invalidated in the meantime (as happens in e.g. passes/opt/share.cc:1432). A later rehash of the dicts (caused by inserting in ModWalker::add_wire()) will cause them to be dereferenced. --- kernel/modtools.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/modtools.h b/kernel/modtools.h index 29c510059ff..3af5367b177 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -395,6 +395,8 @@ struct ModWalker signal_consumers.clear(); signal_inputs.clear(); signal_outputs.clear(); + cell_inputs.clear(); + cell_outputs.clear(); for (auto &it : module->wires_) add_wire(it.second); From 3a12617ec0713aeb81fbf4beede804545f762a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 17 Mar 2021 19:32:50 +0100 Subject: [PATCH 0282/2410] Add simple CI using github actions. --- .github/workflows/test.yml | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..401589cd87c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,87 @@ +name: Build and run tests + +on: [push, pull_request] + +jobs: + test-linux: + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install g++ gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + + - name: Get iverilog + run: | + git clone git://github.com/steveicarus/iverilog.git + + - name: Cache iverilog + id: cache-iverilog + uses: actions/cache@v2 + with: + path: iverilog-bin + key: ${{ runner.os }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} + + - name: Build iverilog + if: steps.cache-iverilog.outputs.cache-hit != 'true' + run: | + mkdir iverilog-bin + cd iverilog + autoconf + CC=gcc CXX=g++ ./configure --prefix=$PWD/../iverilog-bin + make -j$(nproc) + make install + + - name: Build yosys + run: | + make -j$(nproc) + + - name: Run tests + run: | + PATH=$PWD/iverilog-bin/bin:$PATH make -j$(nproc) test + + test-osx: + runs-on: macos-latest + steps: + + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + brew update + brew tap Homebrew/bundle + brew bundle + + - name: Get iverilog + run: | + git clone git://github.com/steveicarus/iverilog.git + + - name: Cache iverilog + id: cache-iverilog + uses: actions/cache@v2 + with: + path: iverilog-bin + key: ${{ runner.os }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} + + - name: Build iverilog + if: steps.cache-iverilog.outputs.cache-hit != 'true' + run: | + export PATH="$(brew --prefix bison)/bin:$PATH" + mkdir iverilog-bin + cd iverilog + autoconf + CC=gcc CXX=g++ ./configure --prefix=$PWD/../iverilog-bin + make -j$(sysctl -n hw.ncpu) + make install + + - name: Build yosys + run: | + export PATH="$(brew --prefix bison)/bin:$PATH" + make -j$(sysctl -n hw.ncpu) + + - name: Run tests + run: | + PATH=$PWD/iverilog-bin/bin:$PATH make -j$(sysctl -n hw.ncpu) test From 0c66141ed25b0af229551f9ce8fe844be1e88bf3 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Tue, 16 Mar 2021 16:42:14 +0100 Subject: [PATCH 0283/2410] verilog: rebuild user_type_stack from globals before parsing file This was actually a ticking UB bomb: after running the parser, the type maps contain pointers to children of the current AST, which is recursively deleted after the pass has executed. This leaves the pointers in user_type_stack dangling, which just happened to never be a problem due to another bug that causes typedefs from higher-level type maps to never be considered. Rebuilding the type stack from the design's globals ensures the AstNode pointers are valid. --- frontends/verilog/verilog_frontend.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 5907707c8c7..84ac73e910f 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -61,11 +61,6 @@ static void add_package_types(dict &user_types, std } } } - - // carry over typedefs from previous files, but allow them to be overridden - // note that these type maps are currently never reclaimed - if (user_type_stack.empty() || !user_type_stack.back()->empty()) - user_type_stack.push_back(new UserTypeMap()); } struct VerilogFrontend : public Frontend { @@ -487,6 +482,19 @@ struct VerilogFrontend : public Frontend { // make package typedefs available to parser add_package_types(pkg_user_types, design->verilog_packages); + UserTypeMap *global_types_map = new UserTypeMap(); + for (auto def : design->verilog_globals) { + if (def->type == AST::AST_TYPEDEF) { + (*global_types_map)[def->str] = def; + } + } + + log_assert(user_type_stack.empty()); + // use previous global typedefs as bottom level of user type stack + user_type_stack.push_back(global_types_map); + // add a new empty type map to allow overriding existing global definitions + user_type_stack.push_back(new UserTypeMap()); + frontend_verilog_yyset_lineno(1); frontend_verilog_yyrestart(NULL); frontend_verilog_yyparse(); @@ -509,6 +517,14 @@ struct VerilogFrontend : public Frontend { if (!flag_nopp) delete lexin; + // only the previous and new global type maps remain + log_assert(user_type_stack.size() == 2); + for (auto it : user_type_stack) { + // the global typedefs have to remain valid for future invocations, so just drop the map without deleting values + delete it; + } + user_type_stack.clear(); + delete current_ast; current_ast = NULL; From 4f4e70876f06738fa7dda24e01ac296fe318264a Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 18 Mar 2021 13:38:25 -0400 Subject: [PATCH 0284/2410] sv: allow typenames as function return types --- frontends/verilog/verilog_parser.y | 6 +++++ tests/verilog/func_typename_ret.sv | 35 ++++++++++++++++++++++++++++++ tests/verilog/func_typename_ret.ys | 5 +++++ 3 files changed, 46 insertions(+) create mode 100644 tests/verilog/func_typename_ret.sv create mode 100644 tests/verilog/func_typename_ret.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index ea8cc0765d0..91b7afddfaa 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -861,6 +861,7 @@ task_func_decl: outreg->children.push_back($4); outreg->is_signed = $4->is_signed; $4->is_signed = false; + outreg->is_custom_type = $4->type == AST_WIRETYPE; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; @@ -871,6 +872,11 @@ task_func_decl: }; func_return_type: + hierarchical_type_id { + $$ = new AstNode(AST_WIRETYPE); + $$->str = *$1; + delete $1; + } | opt_type_vec opt_signedness_default_unsigned { $$ = makeRange(0, 0, $2); } | diff --git a/tests/verilog/func_typename_ret.sv b/tests/verilog/func_typename_ret.sv new file mode 100644 index 00000000000..423975f97c5 --- /dev/null +++ b/tests/verilog/func_typename_ret.sv @@ -0,0 +1,35 @@ +typedef logic [1:0] T; + +package P; + typedef logic [3:0] S; +endpackage + +module gate( + output wire [31:0] out1, out2 +); + function automatic T func1; + input reg signed inp; + func1 = inp; + endfunction + assign out1 = func1(1); + function automatic P::S func2; + input reg signed inp; + func2 = inp; + endfunction + assign out2 = func2(1); +endmodule + +module gold( + output wire [31:0] out1, out2 +); + function automatic [1:0] func1; + input reg signed inp; + func1 = inp; + endfunction + assign out1 = func1(1); + function automatic [3:0] func2; + input reg signed inp; + func2 = inp; + endfunction + assign out2 = func2(1); +endmodule diff --git a/tests/verilog/func_typename_ret.ys b/tests/verilog/func_typename_ret.ys new file mode 100644 index 00000000000..7f604996119 --- /dev/null +++ b/tests/verilog/func_typename_ret.ys @@ -0,0 +1,5 @@ +read_verilog -sv func_typename_ret.sv +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From 92d5550a90558a0292c8ac63cecabb2de30eb6aa Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 18 Mar 2021 21:53:02 +0100 Subject: [PATCH 0285/2410] verilog: check entire user type stack for type definition --- frontends/verilog/verilog_parser.y | 18 ++++++++++++------ tests/svtypes/typedef_scopes.sv | 10 ++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 91b7afddfaa..e4b3258c23f 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -163,12 +163,18 @@ static bool isInLocalScope(const std::string *name) static AstNode *getTypeDefinitionNode(std::string type_name) { - // return the definition nodes from the typedef statement - auto user_types = user_type_stack.back(); - log_assert(user_types->count(type_name) > 0); - auto typedef_node = (*user_types)[type_name]; - log_assert(typedef_node->type == AST_TYPEDEF); - return typedef_node->children[0]; + // check current scope then outer scopes for a name + for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) { + if ((*it)->count(type_name) > 0) { + // return the definition nodes from the typedef statement + auto typedef_node = (**it)[type_name]; + log_assert(typedef_node->type == AST_TYPEDEF); + return typedef_node->children[0]; + } + } + + // The lexer recognized the name as a TOK_USER_TYPE, but now we can't find it anymore? + log_error("typedef for user type `%s' not found", type_name.c_str()); } static AstNode *copyTypeDefinition(std::string type_name) diff --git a/tests/svtypes/typedef_scopes.sv b/tests/svtypes/typedef_scopes.sv index 5507d84f28e..9a898fac8a4 100644 --- a/tests/svtypes/typedef_scopes.sv +++ b/tests/svtypes/typedef_scopes.sv @@ -4,6 +4,7 @@ typedef enum logic {s0, s1} outer_enum_t; module top; + // globals are inherited outer_uint4_t u4_i = 8'hA5; outer_enum_t enum4_i = s0; always @(*) assert(u4_i == 4'h5); @@ -17,13 +18,22 @@ module top; always @(*) assert(inner_enum1 == 3'h3); if (1) begin: genblock + // type declarations in child scopes shadow their parents typedef logic [7:0] inner_type; parameter inner_type inner_const = 8'hA5; typedef enum logic [2:0] {s5=5, s6, s7} inner_enum_t; + inner_type inner_gb_i = inner_const; //8'hA5; inner_enum_t inner_gb_enum1 = s7; always @(*) assert(inner_gb_i == 8'hA5); always @(*) assert(inner_gb_enum1 == 3'h7); + + // check that copying of struct member types works over multiple type scopes + typedef struct packed { + outer_uint4_t x; + } mystruct_t; + mystruct_t mystruct; + always @(*) assert($bits(mystruct) == 4); end inner_type inner_i2 = 8'h42; From d9ec35a526b9583727ef484ec68bc288dcddb0c8 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 22 Mar 2021 19:16:25 +0100 Subject: [PATCH 0286/2410] split CodingReadme into multiple files --- .clang-format | 2 +- .dockerignore | 3 +- README.md | 2 +- guidelines/Checklists | 120 +++++++++ CodeOfConduct => guidelines/CodeOfConduct | 0 guidelines/CodingStyle | 35 +++ CodingReadme => guidelines/GettingStarted | 309 +--------------------- guidelines/UnitTests | 69 +++++ guidelines/Windows | 60 +++++ kernel/yosys.h | 2 +- manual/CHAPTER_Prog.tex | 11 +- 11 files changed, 295 insertions(+), 318 deletions(-) create mode 100644 guidelines/Checklists rename CodeOfConduct => guidelines/CodeOfConduct (100%) create mode 100644 guidelines/CodingStyle rename CodingReadme => guidelines/GettingStarted (53%) create mode 100644 guidelines/UnitTests create mode 100644 guidelines/Windows diff --git a/.clang-format b/.clang-format index 28d13da2564..c86fa8c1cda 100644 --- a/.clang-format +++ b/.clang-format @@ -6,7 +6,7 @@ BreakBeforeBraces: Linux AllowShortIfStatementsOnASingleLine: false IndentCaseLabels: false -# From CodingReadme +# From guidelines/CodingStyle TabWidth: 8 ContinuationIndentWidth: 2 ColumnLimit: 150 diff --git a/.dockerignore b/.dockerignore index 9910e9954e9..9f1da94da71 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,8 +6,7 @@ Dockerfile README.md manual -CodingReadme +guidelines CodeOfConduct .travis .travis.yml - diff --git a/README.md b/README.md index 203a292d1b9..74b6170b17f 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ The "Documentation" page on the web site contains links to more resources, including a manual that even describes some of the Yosys internals: - http://www.clifford.at/yosys/documentation.html -The file `CodingReadme` in this directory contains additional information +The directory `guidelines` contains additional information for people interested in using the Yosys C++ APIs. Users interested in formal verification might want to use the formal verification diff --git a/guidelines/Checklists b/guidelines/Checklists new file mode 100644 index 00000000000..cc61c787679 --- /dev/null +++ b/guidelines/Checklists @@ -0,0 +1,120 @@ +Checklist for adding internal cell types +======================================== + +Things to do right away: + + - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) + - Add to InternalCellChecker::check() in kernel/rtlil.cc + - Add to techlibs/common/simlib.v + - Add to techlibs/common/techmap.v + +Things to do after finalizing the cell interface: + + - Add support to kernel/satgen.h for the new cell type + - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom) + - Maybe add support to the Verilog backend for dumping such cells as expression + + + +Checklist for creating Yosys releases +===================================== + +Update the CHANGELOG file: + + cd ~yosys + gitk & + vi CHANGELOG + + +Update and check documentation: + + cd ~yosys + make update-manual + make manual + - sanity check the figures in the appnotes and presentation + - if there are any odd things -> investigate + - make cosmetic changes to the .tex files if necessary + + cd ~yosys + vi README guidelines/* + - is the information provided in those file still up to date + + +Then with default config setting: + + cd ~yosys + make vgtest + + cd ~yosys + ./yosys -p 'proc; show' tests/simple/fiedler-cooley.v + ./yosys -p 'proc; opt; show' tests/simple/fiedler-cooley.v + ./yosys -p 'synth; show' tests/simple/fiedler-cooley.v + ./yosys -p 'synth_xilinx -top up3down5; show' tests/simple/fiedler-cooley.v + + cd ~yosys/examples/cmos + bash testbench.sh + + cd ~yosys/examples/basys3 + bash run.sh + + +Test building plugins with various of the standard passes: + + yosys-config --build test.so equiv_simple.cc + - also check the code examples in guidelines/GettingStarted + + +And if a version of the verific library is currently available: + + cd ~yosys + cat frontends/verific/build_amd64.txt + - follow instructions + + cd frontends/verific + ../../yosys test_navre.ys + + +Finally run all tests with "make config-{clang,gcc,gcc-4.8}": + + cd ~yosys + make clean + make test + make ystests + make vloghtb + make install + + cd ~yosys-bigsim + make clean + make full + + cd ~vloghammer + make purge gen_issues gen_samples + make SYN_LIST="yosys" SIM_LIST="icarus yosim verilator" REPORT_FULL=1 world + chromium-browser report.html + + +Release: + + - set YOSYS_VER to x.y.z in Makefile + - remove "bumpversion" target from Makefile + - update version string in CHANGELOG + git commit -am "Yosys x.y.z" + + - push tag to github + - post changelog on github + - post short release note on reddit + + +Updating the website: + + cd ~yosys + make manual + make install + + - update pdf files on the website + + cd ~yosys-web + make update_cmd + make update_show + git commit -am update + make push diff --git a/CodeOfConduct b/guidelines/CodeOfConduct similarity index 100% rename from CodeOfConduct rename to guidelines/CodeOfConduct diff --git a/guidelines/CodingStyle b/guidelines/CodingStyle new file mode 100644 index 00000000000..d3d3a7134d1 --- /dev/null +++ b/guidelines/CodingStyle @@ -0,0 +1,35 @@ +Coding Style +============ + + +Formatting of code +------------------ + +- Yosys code is using tabs for indentation. Tabs are 8 characters. + +- A continuation of a statement in the following line is indented by + two additional tabs. + +- Lines are as long as you want them to be. A good rule of thumb is + to break lines at about column 150. + +- Opening braces can be put on the same or next line as the statement + opening the block (if, switch, for, while, do). Put the opening brace + on its own line for larger blocks, especially blocks that contains + blank lines. + +- Otherwise stick to the Linux Kernel Coding Style: + https://www.kernel.org/doc/Documentation/CodingStyle + + +C++ Language +------------- + +Yosys is written in C++11. At the moment only constructs supported by +gcc 4.8 are allowed in Yosys code. This will change in future releases. + +In general Yosys uses "int" instead of "size_t". To avoid compiler +warnings for implicit type casts, always use "GetSize(foobar)" instead +of "foobar.size()". (GetSize() is defined in kernel/yosys.h) + +Use range-based for loops whenever applicable. \ No newline at end of file diff --git a/CodingReadme b/guidelines/GettingStarted similarity index 53% rename from CodingReadme rename to guidelines/GettingStarted index 7d4ded93d2f..fcc84c15300 100644 --- a/CodingReadme +++ b/guidelines/GettingStarted @@ -1,10 +1,3 @@ - -This file contains some very brief documentation on things like programming APIs. -Also consult the Yosys manual and the section about programming in the presentation. -(Both can be downloaded as PDF from the yosys webpage.) - - ---snip-- only the lines below this mark are included in the yosys manual --snip-- Getting Started =============== @@ -253,304 +246,4 @@ Notes on the existing codebase For historical reasons not all parts of Yosys adhere to the current coding style. When adding code to existing parts of the system, adhere to this guide -for the new code instead of trying to mimic the style of the surrounding code. - - - -Coding Style -============ - - -Formatting of code ------------------- - -- Yosys code is using tabs for indentation. Tabs are 8 characters. - -- A continuation of a statement in the following line is indented by - two additional tabs. - -- Lines are as long as you want them to be. A good rule of thumb is - to break lines at about column 150. - -- Opening braces can be put on the same or next line as the statement - opening the block (if, switch, for, while, do). Put the opening brace - on its own line for larger blocks, especially blocks that contains - blank lines. - -- Otherwise stick to the Linux Kernel Coding Style: - https://www.kernel.org/doc/Documentation/CodingStyle - - -C++ Language -------------- - -Yosys is written in C++11. At the moment only constructs supported by -gcc 4.8 are allowed in Yosys code. This will change in future releases. - -In general Yosys uses "int" instead of "size_t". To avoid compiler -warnings for implicit type casts, always use "GetSize(foobar)" instead -of "foobar.size()". (GetSize() is defined in kernel/yosys.h) - -Use range-based for loops whenever applicable. - - ---snap-- only the lines above this mark are included in the yosys manual --snap-- - - -Creating the Visual Studio Template Project -=========================================== - -1. Create an empty Visual C++ Win32 Console App project - - Microsoft Visual Studio Express 2013 for Windows Desktop - Open New Project Wizard (File -> New Project..) - - Project Name: YosysVS - Solution Name: YosysVS - [X] Create directory for solution - [ ] Add to source control - - [X] Console applications - [X] Empty Project - [ ] SDL checks - -2. Open YosysVS Project Properties - - Select Configuration: All Configurations - - C/C++ -> General -> Additional Include Directories - Add: ..\yosys - - C/C++ -> Preprocessor -> Preprocessor Definitions - Add: _YOSYS_;_CRT_SECURE_NO_WARNINGS - -3. Resulting file system tree: - - YosysVS/ - YosysVS/YosysVS - YosysVS/YosysVS/YosysVS.vcxproj - YosysVS/YosysVS/YosysVS.vcxproj.filters - YosysVS/YosysVS.sdf - YosysVS/YosysVS.sln - YosysVS/YosysVS.v12.suo - -4. Zip YosysVS as YosysVS-Tpl-v1.zip - - - -Checklist for adding internal cell types -======================================== - -Things to do right away: - - - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) - - Add to InternalCellChecker::check() in kernel/rtlil.cc - - Add to techlibs/common/simlib.v - - Add to techlibs/common/techmap.v - -Things to do after finalizing the cell interface: - - - Add support to kernel/satgen.h for the new cell type - - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom) - - Maybe add support to the Verilog backend for dumping such cells as expression - - - -Checklist for creating Yosys releases -===================================== - -Update the CHANGELOG file: - - cd ~yosys - gitk & - vi CHANGELOG - - -Update and check documentation: - - cd ~yosys - make update-manual - make manual - - sanity check the figures in the appnotes and presentation - - if there are any odd things -> investigate - - make cosmetic changes to the .tex files if necessary - - cd ~yosys - vi README CodingReadme - - is the information provided in those file still up to date - - -Then with default config setting: - - cd ~yosys - make vgtest - - cd ~yosys - ./yosys -p 'proc; show' tests/simple/fiedler-cooley.v - ./yosys -p 'proc; opt; show' tests/simple/fiedler-cooley.v - ./yosys -p 'synth; show' tests/simple/fiedler-cooley.v - ./yosys -p 'synth_xilinx -top up3down5; show' tests/simple/fiedler-cooley.v - - cd ~yosys/examples/cmos - bash testbench.sh - - cd ~yosys/examples/basys3 - bash run.sh - - -Test building plugins with various of the standard passes: - - yosys-config --build test.so equiv_simple.cc - - also check the code examples in CodingReadme - - -And if a version of the verific library is currently available: - - cd ~yosys - cat frontends/verific/build_amd64.txt - - follow instructions - - cd frontends/verific - ../../yosys test_navre.ys - - -Finally run all tests with "make config-{clang,gcc,gcc-4.8}": - - cd ~yosys - make clean - make test - make ystests - make vloghtb - make install - - cd ~yosys-bigsim - make clean - make full - - cd ~vloghammer - make purge gen_issues gen_samples - make SYN_LIST="yosys" SIM_LIST="icarus yosim verilator" REPORT_FULL=1 world - chromium-browser report.html - - -Release: - - - set YOSYS_VER to x.y.z in Makefile - - remove "bumpversion" target from Makefile - - update version string in CHANGELOG - git commit -am "Yosys x.y.z" - - - push tag to github - - post changelog on github - - post short release note on reddit - - -Updating the website: - - cd ~yosys - make manual - make install - - - update pdf files on the website - - cd ~yosys-web - make update_cmd - make update_show - git commit -am update - make push - - - -Cross-Building for Windows with MXE -=================================== - -Check http://mxe.cc/#requirements and install all missing requirements. - -As root (or other user with write access to /usr/local/src): - - cd /usr/local/src - git clone https://github.com/mxe/mxe.git - cd mxe - - make -j$(nproc) MXE_PLUGIN_DIRS="plugins/tcl.tk" \ - MXE_TARGETS="i686-w64-mingw32.static" \ - gcc tcl readline - -Then as regular user in some directory where you build stuff: - - git clone https://github.com/cliffordwolf/yosys.git yosys-win32 - cd yosys-win32 - make config-mxe - make -j$(nproc) mxebin - - - -How to add unit test -==================== - -Unit test brings some advantages, briefly, we can list some of them (reference -[1](https://en.wikipedia.org/wiki/Unit_testing)): - -* Tests reduce bugs in new features; -* Tests reduce bugs in existing features; -* Tests are good documentation; -* Tests reduce the cost of change; -* Tests allow refactoring; - -With those advantages in mind, it was required to choose a framework which fits -well with C/C++ code. Hence, it was chosen (google test) -[https://github.com/google/googletest], because it is largely used and it is -relatively easy learn. - -Install and configure google test (manually) --------------------------------------------- - -In this section, you will see a brief description of how to install google -test. However, it is strongly recommended that you take a look to the official -repository (https://github.com/google/googletest) and refers to that if you -have any problem to install it. Follow the steps below: - -* Install: cmake and pthread -* Clone google test project from: https://github.com/google/googletest and - enter in the project directory -* Inside project directory, type: - -``` -cmake -DBUILD_SHARED_LIBS=ON . -make -``` - -* After compilation, copy all "*.so" inside directory "googlemock" and - "googlemock/gtest" to "/usr/lib/" -* Done! Now you can compile your tests. - -If you have any problem, go to the official repository to find help. - -Ps.: Some distros already have googletest packed. If your distro supports it, -you can use it instead of compile. - -Create new unit test --------------------- - -If you want to add new unit tests for Yosys, just follow the steps below: - -* Go to directory "yosys/test/unit/" -* In this directory you can find something similar Yosys's directory structure. - To create your unit test file you have to follow this pattern: - fileNameToImplementUnitTest + Test.cc. E.g.: if you want to implement the - unit test for kernel/celledges.cc, you will need to create a file like this: - tests/unit/kernel/celledgesTest.cc; -* Implement your unit test - -Run unit test -------------- - -To compile and run all unit tests, just go to yosys root directory and type: -``` -make unit-test -``` - -If you want to remove all unit test files, type: -``` -make clean-unit-test -``` +for the new code instead of trying to mimic the style of the surrounding code. \ No newline at end of file diff --git a/guidelines/UnitTests b/guidelines/UnitTests new file mode 100644 index 00000000000..d42a63ce587 --- /dev/null +++ b/guidelines/UnitTests @@ -0,0 +1,69 @@ +How to add unit test +==================== + +Unit test brings some advantages, briefly, we can list some of them (reference +[1](https://en.wikipedia.org/wiki/Unit_testing)): + +* Tests reduce bugs in new features; +* Tests reduce bugs in existing features; +* Tests are good documentation; +* Tests reduce the cost of change; +* Tests allow refactoring; + +With those advantages in mind, it was required to choose a framework which fits +well with C/C++ code. Hence, it was chosen (google test) +[https://github.com/google/googletest], because it is largely used and it is +relatively easy learn. + +Install and configure google test (manually) +-------------------------------------------- + +In this section, you will see a brief description of how to install google +test. However, it is strongly recommended that you take a look to the official +repository (https://github.com/google/googletest) and refers to that if you +have any problem to install it. Follow the steps below: + +* Install: cmake and pthread +* Clone google test project from: https://github.com/google/googletest and + enter in the project directory +* Inside project directory, type: + +``` +cmake -DBUILD_SHARED_LIBS=ON . +make +``` + +* After compilation, copy all "*.so" inside directory "googlemock" and + "googlemock/gtest" to "/usr/lib/" +* Done! Now you can compile your tests. + +If you have any problem, go to the official repository to find help. + +Ps.: Some distros already have googletest packed. If your distro supports it, +you can use it instead of compile. + +Create new unit test +-------------------- + +If you want to add new unit tests for Yosys, just follow the steps below: + +* Go to directory "yosys/test/unit/" +* In this directory you can find something similar Yosys's directory structure. + To create your unit test file you have to follow this pattern: + fileNameToImplementUnitTest + Test.cc. E.g.: if you want to implement the + unit test for kernel/celledges.cc, you will need to create a file like this: + tests/unit/kernel/celledgesTest.cc; +* Implement your unit test + +Run unit test +------------- + +To compile and run all unit tests, just go to yosys root directory and type: +``` +make unit-test +``` + +If you want to remove all unit test files, type: +``` +make clean-unit-test +``` diff --git a/guidelines/Windows b/guidelines/Windows new file mode 100644 index 00000000000..3bd86f3ec5c --- /dev/null +++ b/guidelines/Windows @@ -0,0 +1,60 @@ +Creating the Visual Studio Template Project +=========================================== + +1. Create an empty Visual C++ Win32 Console App project + + Microsoft Visual Studio Express 2013 for Windows Desktop + Open New Project Wizard (File -> New Project..) + + Project Name: YosysVS + Solution Name: YosysVS + [X] Create directory for solution + [ ] Add to source control + + [X] Console applications + [X] Empty Project + [ ] SDL checks + +2. Open YosysVS Project Properties + + Select Configuration: All Configurations + + C/C++ -> General -> Additional Include Directories + Add: ..\yosys + + C/C++ -> Preprocessor -> Preprocessor Definitions + Add: _YOSYS_;_CRT_SECURE_NO_WARNINGS + +3. Resulting file system tree: + + YosysVS/ + YosysVS/YosysVS + YosysVS/YosysVS/YosysVS.vcxproj + YosysVS/YosysVS/YosysVS.vcxproj.filters + YosysVS/YosysVS.sdf + YosysVS/YosysVS.sln + YosysVS/YosysVS.v12.suo + +4. Zip YosysVS as YosysVS-Tpl-v1.zip + +Cross-Building for Windows with MXE +=================================== + +Check http://mxe.cc/#requirements and install all missing requirements. + +As root (or other user with write access to /usr/local/src): + + cd /usr/local/src + git clone https://github.com/mxe/mxe.git + cd mxe + + make -j$(nproc) MXE_PLUGIN_DIRS="plugins/tcl.tk" \ + MXE_TARGETS="i686-w64-mingw32.static" \ + gcc tcl readline + +Then as regular user in some directory where you build stuff: + + git clone https://github.com/cliffordwolf/yosys.git yosys-win32 + cd yosys-win32 + make config-mxe + make -j$(nproc) mxebin \ No newline at end of file diff --git a/kernel/yosys.h b/kernel/yosys.h index 43aecdbc8e5..e93d09cd41b 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -33,7 +33,7 @@ // This header is very boring. It just defines some general things that // belong nowhere else and includes the interesting headers. // -// Find more information in the "CodingReadme" file. +// Find more information in the "guidelines/GettingStarted" file. #ifndef YOSYS_H diff --git a/manual/CHAPTER_Prog.tex b/manual/CHAPTER_Prog.tex index 3cbc95a195d..49432f73b64 100644 --- a/manual/CHAPTER_Prog.tex +++ b/manual/CHAPTER_Prog.tex @@ -5,13 +5,15 @@ \chapter{Programming Yosys Extensions} This chapter contains some bits and pieces of information about programming yosys extensions. Also consult the section on programming in the ``Yosys Presentation'' (can be downloaded from the Yosys website as PDF) and don't -be afraid to ask questions on the Yosys Subreddit. +be afraid to ask questions on the YosysHQ Slack. -\section{The ``CodingReadme'' File} +\section{Guidelines} -The following is an excerpt of the {\tt CodingReadme} file from the Yosys source tree. +The {\tt guidelines} directory contains notes on various aspects of Yosys development. The files {\tt GettingStarted} and {\tt CodingStyle} may be of particular interest, and are reproduced here. -\lstinputlisting[title=CodingReadme,rangeprefix=--,rangesuffix=--,includerangemarker=false,linerange=snip-snap,numbers=left,frame=single]{../CodingReadme} +\lstinputlisting[title=GettingStarted,numbers=left,frame=single]{../guidelines/GettingStarted} + +\lstinputlisting[title=CodingStyle,numbers=left,frame=single]{../guidelines/CodingStyle} \section{The ``stubsnets'' Example Module} @@ -23,4 +25,3 @@ \section{The ``stubsnets'' Example Module} \lstinputlisting[title=Makefile,numbers=left,frame=single,language=make]{CHAPTER_Prog/Makefile} \lstinputlisting[title=test.v,numbers=left,frame=single,language=Verilog]{CHAPTER_Prog/test.v} - From 6b2100bf0185a8f9d0c1b2fb5657721b9853838b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Mar 2021 14:47:32 +0100 Subject: [PATCH 0287/2410] json: Improve the "processes in module" message a bit. --- backends/json/json.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/json/json.cc b/backends/json/json.cc index b13105f64a7..b7e51f1e8a2 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -136,7 +136,7 @@ struct JsonWriter sigidcounter = 2; if (module->has_processes()) { - log_error("Module %s contains processes, which are not supported by JSON backend.\n", log_id(module)); + log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module)); } f << stringf(" %s: {\n", get_name(module->name).c_str()); From 4a35f244aa6ac187610cae0014d261e38cbab550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Mar 2021 14:51:37 +0100 Subject: [PATCH 0288/2410] quicklogic: Add .gitignore file for test outputs. --- tests/arch/quicklogic/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/arch/quicklogic/.gitignore diff --git a/tests/arch/quicklogic/.gitignore b/tests/arch/quicklogic/.gitignore new file mode 100644 index 00000000000..9a71dca69b0 --- /dev/null +++ b/tests/arch/quicklogic/.gitignore @@ -0,0 +1,4 @@ +*.log +/run-test.mk ++*_synth.v ++*_testbench From 192601385f0237f23c7f1611ea4ecaba8bfd9ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Mar 2021 17:39:06 +0100 Subject: [PATCH 0289/2410] rtlil: Fix process memwr roundtrip. Fixes #2646 fallout. --- backends/rtlil/rtlil_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index cfdf3efc5bf..0846208ba48 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -263,7 +263,7 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT f << stringf(" "); dump_sigspec(f, it.enable); f << stringf(" "); - dump_sigspec(f, it.priority_mask); + dump_const(f, it.priority_mask); f << stringf("\n"); } } From c58bb1d2e1e7ff3181c7b5d4d0a0d10d95d3b6fe Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 23 Mar 2021 12:49:11 -0400 Subject: [PATCH 0290/2410] ast: make design available to process_module() --- frontends/ast/ast.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 84a4de41c7a..614c9bcefbf 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -980,8 +980,8 @@ static bool param_has_no_default(const AstNode *param) { (children.size() == 1 && children[0]->type == AST_RANGE); } -// create a new AstModule from an AST_MODULE AST node -static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) +// create and add a new AstModule from an AST_MODULE AST node +static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { log_assert(current_scope.empty()); log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE); @@ -1039,6 +1039,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast } } + // TODO(zachjs): make design available to simplify() in the future while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } if (flag_dump_ast2) { @@ -1190,7 +1191,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log("--- END OF RTLIL DUMP ---\n"); } - return current_module; + design->add(current_module); } // create AstModule instances for all modules in the AST tree and add them to 'design' @@ -1275,7 +1276,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } } - design->add(process_module(*it, defer_local)); + process_module(design, *it, defer_local); current_ast_mod = nullptr; } else if ((*it)->type == AST_PACKAGE) { @@ -1456,9 +1457,8 @@ void AstModule::reprocess_module(RTLIL::Design *design, const dictadd(newmod); RTLIL::Module* mod = design->module(original_name); if (is_top) mod->set_bool_attribute(ID::top); @@ -1514,7 +1514,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dictadd(process_module(new_ast, false)); + process_module(design, new_ast, false); design->module(modname)->check(); RTLIL::Module* mod = design->module(modname); @@ -1565,7 +1565,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dicthas(modname)) { new_ast->str = modname; - design->add(process_module(new_ast, false, NULL, quiet)); + process_module(design, new_ast, false, NULL, quiet); design->module(modname)->check(); } else if (!quiet) { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); From 4c39189b137ab3ebcc3db0b5df09c9bf43d97a8c Mon Sep 17 00:00:00 2001 From: Iris Johnson Date: Wed, 24 Mar 2021 16:24:33 -0500 Subject: [PATCH 0291/2410] Clarify bugpoint documentation regarding output Bugpoint's current documentation does specify that the result of a run is stored as the current design, however it's easy to skim over what that means in practice. Add a documentation comment to explain specifically that an after bugpoint `write_xyz` pass is required to save the reduced design. --- passes/cmds/bugpoint.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 70c002c44a1..c782d9a3858 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -38,6 +38,8 @@ struct BugpointPass : public Pass { log("and the same script, repeating these steps while it can find a smaller design that\n"); log("still causes a crash. Once this command finishes, it replaces the current design\n"); log("with the smallest testcase it was able to produce.\n"); + log("In order to save the reduced testcase you must write this out to a file with\n"); + log("another command after `bugpoint` like `write_rtlil` or `write_verilog`.\n"); log("\n"); log(" -script | -command \"\"\n"); log(" use this script file or command to crash Yosys. required.\n"); From d6d5c2ef342240bd8adb925055667d140cb8dd29 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 24 Mar 2021 11:23:23 -0400 Subject: [PATCH 0292/2410] rtlil: add const accessors for modules, wires, and cells --- kernel/rtlil.cc | 5 +++++ kernel/rtlil.h | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 87cbaa0d537..7704057206e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -580,6 +580,11 @@ RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) return modules_.count(name) ? modules_.at(name) : NULL; } +const RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) const +{ + return modules_.count(name) ? modules_.at(name) : NULL; +} + RTLIL::Module *RTLIL::Design::top_module() { RTLIL::Module *module = nullptr; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index bbdf355fa1f..3137deb00c8 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1043,6 +1043,7 @@ struct RTLIL::Design RTLIL::ObjRange modules(); RTLIL::Module *module(RTLIL::IdString name); + const RTLIL::Module *module(RTLIL::IdString name) const; RTLIL::Module *top_module(); bool has(RTLIL::IdString id) const { @@ -1191,6 +1192,15 @@ struct RTLIL::Module : public RTLIL::AttrObject return it == cells_.end() ? nullptr : it->second; } + const RTLIL::Wire* wire(RTLIL::IdString id) const{ + auto it = wires_.find(id); + return it == wires_.end() ? nullptr : it->second; + } + const RTLIL::Cell* cell(RTLIL::IdString id) const { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } + RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } From e314a05e0a7337a55f4d2608c310e918d571326f Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 28 Mar 2021 15:28:23 -0400 Subject: [PATCH 0293/2410] gha: combine jobs using matrix --- .github/workflows/test.yml | 67 ++++++++++++++------------------------ 1 file changed, 24 insertions(+), 43 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 401589cd87c..d83cff5cd3e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,57 +3,40 @@ name: Build and run tests on: [push, pull_request] jobs: - test-linux: - runs-on: ubuntu-latest + test: + strategy: + matrix: + runner: + - ubuntu-20.04 + - macOS-10.15 + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v2 - - name: Install dependencies + - name: Install dependencies (Linux) + if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install g++ gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev - - name: Get iverilog - run: | - git clone git://github.com/steveicarus/iverilog.git - - - name: Cache iverilog - id: cache-iverilog - uses: actions/cache@v2 - with: - path: iverilog-bin - key: ${{ runner.os }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} - - - name: Build iverilog - if: steps.cache-iverilog.outputs.cache-hit != 'true' - run: | - mkdir iverilog-bin - cd iverilog - autoconf - CC=gcc CXX=g++ ./configure --prefix=$PWD/../iverilog-bin - make -j$(nproc) - make install - - - name: Build yosys + - name: Install dependencies (macOS) + if: runner.os == 'macOS' run: | - make -j$(nproc) + brew update + brew tap Homebrew/bundle + brew bundle - - name: Run tests + - name: Setup environment (Linux) + if: runner.os == 'Linux' run: | - PATH=$PWD/iverilog-bin/bin:$PATH make -j$(nproc) test - - test-osx: - runs-on: macos-latest - steps: - - - uses: actions/checkout@v2 + echo "procs=$(nproc)" >> $GITHUB_ENV - - name: Install dependencies + - name: Setup environment (macOS) + if: runner.os == 'macOS' run: | - brew update - brew tap Homebrew/bundle - brew bundle + echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH + echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV - name: Get iverilog run: | @@ -69,19 +52,17 @@ jobs: - name: Build iverilog if: steps.cache-iverilog.outputs.cache-hit != 'true' run: | - export PATH="$(brew --prefix bison)/bin:$PATH" mkdir iverilog-bin cd iverilog autoconf CC=gcc CXX=g++ ./configure --prefix=$PWD/../iverilog-bin - make -j$(sysctl -n hw.ncpu) + make -j${{ env.procs }} make install - name: Build yosys run: | - export PATH="$(brew --prefix bison)/bin:$PATH" - make -j$(sysctl -n hw.ncpu) + make -j${{ env.procs }} - name: Run tests run: | - PATH=$PWD/iverilog-bin/bin:$PATH make -j$(sysctl -n hw.ncpu) test + PATH=$PWD/iverilog-bin/bin:$PATH make -j${{ env.procs }} test From 1af994802ed75d5805191113f669409c3872fcf7 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 28 Mar 2021 17:45:38 -0400 Subject: [PATCH 0294/2410] gha: trim macOS dependencies - Only install needed dependencies rather than using Brewfile - Remove brew update (recent enough formulae already baked in) - Saves ~16 minutes in macOS CI --- .github/workflows/test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d83cff5cd3e..2a757d1533c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,9 +23,7 @@ jobs: - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | - brew update - brew tap Homebrew/bundle - brew bundle + brew install bison gawk libffi pkg-config bash - name: Setup environment (Linux) if: runner.os == 'Linux' From 0505c604e70c6d9621eb6ace6a9d8a3a5ac71eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 30 Mar 2021 01:15:49 +0200 Subject: [PATCH 0295/2410] preproc: Fix up conditional handling. Fixes #2710. Fixes #2711. --- frontends/verilog/preproc.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 84966e50190..568224da241 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -726,8 +726,16 @@ frontend_verilog_preproc(std::istream &f, defines.merge(global_defines_cache); std::vector filename_stack; + // We are inside pass_level levels of satisfied ifdefs, and then within + // fail_level levels of unsatisfied ifdefs. The unsatisfied ones are + // always within satisfied ones — even if some condition within is true, + // the parent condition failing renders it moot. int ifdef_fail_level = 0; int ifdef_pass_level = 0; + // For the outermost unsatisfied ifdef, true iff that ifdef already + // had a satisfied branch, and further elsif/else branches should be + // considered unsatisfied even if the condition is true. + // Meaningless if ifdef_fail_level == 0. bool ifdef_already_satisfied = false; output_code.clear(); @@ -745,7 +753,7 @@ frontend_verilog_preproc(std::istream &f, if (ifdef_fail_level > 0) ifdef_fail_level--; else if (ifdef_pass_level > 0) - ifdef_already_satisfied = --ifdef_pass_level; + ifdef_pass_level--; else log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); continue; @@ -755,8 +763,9 @@ frontend_verilog_preproc(std::istream &f, if (ifdef_fail_level == 0) { if (ifdef_pass_level == 0) log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); - log_assert(ifdef_already_satisfied); + ifdef_pass_level--; ifdef_fail_level = 1; + ifdef_already_satisfied = true; } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied) { ifdef_fail_level = 0; ifdef_pass_level++; @@ -771,8 +780,9 @@ frontend_verilog_preproc(std::istream &f, if (ifdef_fail_level == 0) { if (ifdef_pass_level == 0) log_error("Found %s outside of macro conditional branch!\n", tok.c_str()); - log_assert(ifdef_already_satisfied); + ifdef_pass_level--; ifdef_fail_level = 1; + ifdef_already_satisfied = true; } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied && defines.find(name)) { ifdef_fail_level = 0; ifdef_pass_level++; @@ -931,6 +941,10 @@ frontend_verilog_preproc(std::istream &f, output_code.push_back(tok); } + if (ifdef_fail_level > 0 || ifdef_pass_level > 0) { + log_error("Unterminated preprocessor conditional!\n"); + } + std::string output; for (auto &str : output_code) output += str; From 687f381b6985d9dda7e11535628e2fafff267af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 30 Mar 2021 02:30:17 +0200 Subject: [PATCH 0296/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 763871523d2..4760eaa35a3 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4008 +YOSYS_VER := 0.9+4052 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 55dc5a4e4f7335741d2155dc0183ed4e26e8ddf8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 29 Mar 2021 22:01:57 -0700 Subject: [PATCH 0297/2410] abc9: fix SCC issues (#2694) * xilinx: add SCC test for DSP48E1 * xilinx: Gate DSP48E1 being a whitebox behind ALLOW_WHITEBOX_DSP48E1 Have a test that checks it works through ABC9 when enabled * abc9 to break SCCs using $__ABC9_SCC_BREAKER module * Add test * abc9_ops: remove refs to (* abc9_keep *) on wires * abc9_ops: do not bypass cells in an SCC * Add myself to CODEOWNERS for abc9* * Fix compile * abc9_ops: run -prep_hier before scc * Fix tests * Remove bug reference pending fix * abc9: fix for -prep_hier -dff * xaiger: restore PI handling * abc9_ops: -prep_xaiger sigmap * abc9_ops: -mark_scc -> -break_scc * abc9: eliminate hard-coded abc9.box from tests Also tidy up * Address review --- CODEOWNERS | 2 ++ backends/aiger/xaiger.cc | 9 +++-- passes/techmap/abc9.cc | 17 ++++++---- passes/techmap/abc9_ops.cc | 63 +++++++++++++++++++++++------------ techlibs/common/abc9_model.v | 4 +++ techlibs/common/abc9_unmap.v | 5 +++ tests/simple_abc9/abc9.box | 3 -- tests/simple_abc9/abc9.v | 24 ++++++++++--- tests/simple_abc9/run-test.sh | 12 ++++--- 9 files changed, 94 insertions(+), 45 deletions(-) delete mode 100644 tests/simple_abc9/abc9.box diff --git a/CODEOWNERS b/CODEOWNERS index 0419e6e4410..0c92691f4ae 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -16,6 +16,8 @@ backends/cxxrtl/ @whitequark passes/cmds/bugpoint.cc @whitequark passes/techmap/flowmap.cc @whitequark passes/opt/opt_lut.cc @whitequark +passes/techmap/abc9*.cc @eddiehung +backends/aiger/xaiger.cc @eddiehung ## External Contributors diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 7ed8ff1cfce..65ccc748f54 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -156,7 +156,7 @@ struct XAigerWriter // promote keep wires for (auto wire : module->wires()) - if (wire->get_bool_attribute(ID::keep) || wire->get_bool_attribute(ID::abc9_keep)) + if (wire->get_bool_attribute(ID::keep)) sigmap.add(wire); for (auto wire : module->wires()) { @@ -177,11 +177,10 @@ struct XAigerWriter undriven_bits.insert(bit); unused_bits.insert(bit); - bool keep = wire->get_bool_attribute(ID::abc9_keep); - if (wire->port_input || keep) + if (wire->port_input) input_bits.insert(bit); - keep = keep || wire->get_bool_attribute(ID::keep); + bool keep = wire->get_bool_attribute(ID::keep); if (wire->port_output || keep) { if (bit != wirebit) alias_map[wirebit] = bit; @@ -433,7 +432,7 @@ struct XAigerWriter if (bit == State::Sx) continue; if (aig_map.count(bit)) - log_error("Visited AIG node more than once; this could be a combinatorial loop that has not been broken - see Yosys bug 2530\n"); + log_error("Visited AIG node more than once; this could be a combinatorial loop that has not been broken\n"); aig_map[bit] = 2*aig_m; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 56bb1549578..0fef4a9f26c 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -283,9 +283,14 @@ struct Abc9Pass : public ScriptPass if (check_label("map")) { if (help_mode) - run("abc9_ops -prep_hier -prep_bypass [-prep_dff -dff]", "(option if -dff)"); + run("abc9_ops -prep_hier [-dff]", "(option if -dff)"); else - run(stringf("abc9_ops -prep_hier -prep_bypass %s", dff_mode ? "-prep_dff -dff" : "")); + run(stringf("abc9_ops -prep_hier %s", dff_mode ? "-dff" : "")); + run("scc -specify -set_attr abc9_scc_id {}"); + if (help_mode) + run("abc9_ops -prep_bypass [-prep_dff]", "(option if -dff)"); + else + run(stringf("abc9_ops -prep_bypass %s", dff_mode ? "-prep_dff" : "")); if (dff_mode) { run("design -copy-to $abc9_map @$abc9_flops", "(only if -dff)"); run("select -unset $abc9_flops", " (only if -dff)"); @@ -330,20 +335,20 @@ struct Abc9Pass : public ScriptPass run("design -stash $abc9_map"); run("design -load $abc9"); run("design -delete $abc9"); + // Insert bypass modules (and perform +/abc9_map.v transformations), except for those cells part of a SCC if (help_mode) run("techmap -wb -max_iter 1 -map %$abc9_map -map +/abc9_map.v [-D DFF]", "(option if -dff)"); else - run(stringf("techmap -wb -max_iter 1 -map %%$abc9_map -map +/abc9_map.v %s", dff_mode ? "-D DFF" : "")); + run(stringf("techmap -wb -max_iter 1 -map %%$abc9_map -map +/abc9_map.v %s a:abc9_scc_id %%n", dff_mode ? "-D DFF" : "")); run("design -delete $abc9_map"); } if (check_label("pre")) { run("read_verilog -icells -lib -specify +/abc9_model.v"); - run("scc -specify -set_attr abc9_scc_id {}"); if (help_mode) - run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); + run("abc9_ops -break_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); else - run("abc9_ops -mark_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : "")); + run("abc9_ops -break_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : "")); if (help_mode) run("abc9_ops -prep_lut ", "(skip if -lut or -luts)"); else if (!lut_mode) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 3f3e667de47..d3bb31cd911 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -544,18 +544,31 @@ void prep_dff_unmap(RTLIL::Design *design) } } -void mark_scc(RTLIL::Module *module) +void break_scc(RTLIL::Module *module) { // For every unique SCC found, (arbitrarily) find the first - // cell in the component, and replace its output connections - // with a new wire driven by the old connection but with a - // special (* abc9_keep *) attribute set (which is used by - // write_xaiger to break this wire into PI and POs) + // cell in the component, and interrupt all its output connections + // with the $__ABC9_SCC_BREAKER cell + + // Do not break SCCs which have a cell instantiating an abc9_bypass-able + // module (but which wouldn't have been bypassed) + auto design = module->design; + pool scc_cells; pool ids_seen; for (auto cell : module->cells()) { auto it = cell->attributes.find(ID::abc9_scc_id); if (it == cell->attributes.end()) continue; + scc_cells.insert(cell); + auto inst_module = design->module(cell->type); + if (inst_module && inst_module->has_attribute(ID::abc9_bypass)) + ids_seen.insert(it->second); + } + + SigSpec I, O; + for (auto cell : scc_cells) { + auto it = cell->attributes.find(ID::abc9_scc_id); + log_assert(it != cell->attributes.end()); auto id = it->second; auto r = ids_seen.insert(id); cell->attributes.erase(it); @@ -565,12 +578,21 @@ void mark_scc(RTLIL::Module *module) if (c.second.is_fully_const()) continue; if (cell->output(c.first)) { Wire *w = module->addWire(NEW_ID, GetSize(c.second)); - w->set_bool_attribute(ID::abc9_keep); - module->connect(w, c.second); + I.append(w); + O.append(c.second); c.second = w; } } } + + if (!I.empty()) + { + auto cell = module->addCell(NEW_ID, ID($__ABC9_SCC_BREAKER)); + log_assert(GetSize(I) == GetSize(O)); + cell->setParam(ID::WIDTH, GetSize(I)); + cell->setPort(ID::I, std::move(I)); + cell->setPort(ID::O, std::move(O)); + } } void prep_delays(RTLIL::Design *design, bool dff_mode) @@ -721,10 +743,8 @@ void prep_xaiger(RTLIL::Module *module, bool dff) bit_users[bit].insert(cell->name); if (cell->output(conn.first) && !abc9_flop) - for (const auto &chunk : conn.second.chunks()) - if (!chunk.wire->get_bool_attribute(ID::abc9_keep)) - for (auto b : sigmap(SigSpec(chunk))) - bit_drivers[b].insert(cell->name); + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); } toposort.node(cell->name); } @@ -1424,7 +1444,6 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) RTLIL::Wire *mapped_wire = mapped_mod->wire(port); RTLIL::Wire *wire = module->wire(port); log_assert(wire); - wire->attributes.erase(ID::abc9_keep); RTLIL::Wire *remap_wire = module->wire(remap_name(port)); RTLIL::SigSpec signal(wire, remap_wire->start_offset-wire->start_offset, GetSize(remap_wire)); @@ -1587,11 +1606,11 @@ struct Abc9OpsPass : public Pass { log(" insert `$__ABC9_DELAY' blackbox cells into the design to account for\n"); log(" certain required times.\n"); log("\n"); - log(" -mark_scc\n"); + log(" -break_scc\n"); log(" for an arbitrarily chosen cell in each unique SCC of each selected module\n"); - log(" (tagged with an (* abc9_scc_id = *) attribute), temporarily mark all\n"); - log(" wires driven by this cell's outputs with a (* keep *) attribute in order\n"); - log(" to break the SCC. this temporary attribute will be removed on -reintegrate.\n"); + log(" (tagged with an (* abc9_scc_id = *) attribute) interrupt all wires\n"); + log(" driven by this cell's outputs with a temporary $__ABC9_SCC_BREAKER cell\n"); + log(" to break the SCC.\n"); log("\n"); log(" -prep_xaiger\n"); log(" prepare the design for XAIGER output. this includes computing the\n"); @@ -1628,7 +1647,7 @@ struct Abc9OpsPass : public Pass { bool check_mode = false; bool prep_delays_mode = false; - bool mark_scc_mode = false; + bool break_scc_mode = false; bool prep_hier_mode = false; bool prep_bypass_mode = false; bool prep_dff_mode = false, prep_dff_submod_mode = false, prep_dff_unmap_mode = false; @@ -1650,8 +1669,8 @@ struct Abc9OpsPass : public Pass { valid = true; continue; } - if (arg == "-mark_scc") { - mark_scc_mode = true; + if (arg == "-break_scc") { + break_scc_mode = true; valid = true; continue; } @@ -1727,7 +1746,7 @@ struct Abc9OpsPass : public Pass { extra_args(args, argidx, design); if (!valid) - log_cmd_error("At least one of -check, -mark_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate must be specified.\n"); + log_cmd_error("At least one of -check, -break_scc, -prep_{delays,xaiger,dff[123],lut,box}, -write_{lut,box}, -reintegrate must be specified.\n"); if (dff_mode && !check_mode && !prep_hier_mode && !prep_delays_mode && !prep_xaiger_mode && !reintegrate_mode) log_cmd_error("'-dff' option is only relevant for -prep_{hier,delay,xaiger} or -reintegrate.\n"); @@ -1764,8 +1783,8 @@ struct Abc9OpsPass : public Pass { write_lut(mod, write_lut_dst); if (!write_box_dst.empty()) write_box(mod, write_box_dst); - if (mark_scc_mode) - mark_scc(mod); + if (break_scc_mode) + break_scc(mod); if (prep_xaiger_mode) prep_xaiger(mod, dff_mode); if (reintegrate_mode) diff --git a/techlibs/common/abc9_model.v b/techlibs/common/abc9_model.v index 4fee60f752a..570a1ec40da 100644 --- a/techlibs/common/abc9_model.v +++ b/techlibs/common/abc9_model.v @@ -6,6 +6,10 @@ module $__ABC9_DELAY (input I, output O); endspecify endmodule +module $__ABC9_SCC_BREAKER (input [WIDTH-1:0] I, output [WIDTH-1:0] O); +parameter WIDTH = 0; +endmodule + (* abc9_flop, abc9_box, lib_whitebox *) module $__DFF_N__$abc9_flop (input C, D, Q, output n1); assign n1 = D; diff --git a/techlibs/common/abc9_unmap.v b/techlibs/common/abc9_unmap.v index c39648c623a..b1bc4fb6e28 100644 --- a/techlibs/common/abc9_unmap.v +++ b/techlibs/common/abc9_unmap.v @@ -9,3 +9,8 @@ module $__DFF_x__$abc9_flop (input C, D, (* init = 1'b0 *) input Q, output n1); $error("Unrecognised _TECHMAP_CELLTYPE_"); endgenerate endmodule + +module $__ABC9_SCC_BREAKER (input [WIDTH-1:0] I, output [WIDTH-1:0] O); +parameter WIDTH = 0; +assign O = I; +endmodule diff --git a/tests/simple_abc9/abc9.box b/tests/simple_abc9/abc9.box deleted file mode 100644 index b3c88437ca9..00000000000 --- a/tests/simple_abc9/abc9.box +++ /dev/null @@ -1,3 +0,0 @@ -MUXF8 1 0 3 1 -#I0 I1 S -0 0 0 # O diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v index 5e969c61456..fba089b1f8b 100644 --- a/tests/simple_abc9/abc9.v +++ b/tests/simple_abc9/abc9.v @@ -213,7 +213,7 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode input rst; endmodule -(* abc9_box_id=1, blackbox *) +(* abc9_box, blackbox *) module MUXF8(input I0, I1, S, output O); specify (I0 => O) = 0; @@ -300,15 +300,29 @@ endmodule module abc9_test036(input A, B, S, output [1:0] O); (* keep *) MUXF8 m ( - .I0(I0), - .I1(I1), + .I0(A), + .I1(B), .O(O[0]), .S(S) ); MUXF8 m2 ( - .I0(I0), - .I1(I1), + .I0(A), + .I1(B), .O(O[1]), .S(S) ); endmodule + +(* abc9_box, whitebox *) +module MUXF7(input I0, I1, S, output O); +assign O = S ? I1 : I0; +specify + (I0 => O) = 0; + (I1 => O) = 0; + (S => O) = 0; +endspecify +endmodule + +module abc9_test037(output o); +MUXF7 m(.I0(1'b1), .I1(1'b0), .S(o), .O(o)); +endmodule diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index b48505e29ad..4a5bf01a33c 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -37,14 +37,18 @@ done cp ../simple/*.v . cp ../simple/*.sv . +rm specify.v # bug 2675 DOLLAR='?' -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-n 300 -p '\ +exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-f \"verilog -noblackbox -specify\" -n 300 -p '\ + read_verilog -icells -lib +/abc9_model.v; \ hierarchy; \ synth -run coarse; \ opt -full; \ techmap; \ - abc9 -lut 4 -box ../abc9.box; \ + abc9 -lut 4; \ clean; \ - check -assert; \ + check -assert * abc9_test037 %d; \ select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ - setattr -mod -unset blackbox'" + setattr -mod -unset blackbox -unset whitebox'" + +# NOTE: Skip 'check -assert' on abc9_test037 because it intentionally has a combinatorial loop From 8c5f379435a1140a4320cdd4152b60338e45a362 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 29 Mar 2021 22:02:06 -0700 Subject: [PATCH 0298/2410] abc9: uniquify blackboxes like whiteboxes (#2695) * abc9_ops: uniquify blackboxes too * abc9_ops: update comment * abc9_ops: allow bypass for param-less blackboxes * Add tests --- passes/techmap/abc9_ops.cc | 16 ++++------- tests/various/abc9.ys | 57 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index d3bb31cd911..6e18cb5f697 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -189,8 +189,6 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) derived_type = inst_module->derive(design, cell->parameters); derived_module = design->module(derived_type); } - if (derived_module->get_blackbox_attribute(true /* ignore_wb */)) - continue; if (derived_module->get_bool_attribute(ID::abc9_flop)) { if (!dff_mode) @@ -799,14 +797,12 @@ void prep_xaiger(RTLIL::Module *module, bool dff) if (!box_module->get_bool_attribute(ID::abc9_box)) continue; if (!cell->parameters.empty()) - // At this stage of the ABC9 flow, all modules must be nonparametric, because ABC itself requires concrete netlists, and the presence of - // parameters implies a non-concrete netlist. This error needs some explaining, because there are (at least) two ways to get this: - // 1) You have an (* abc9_box *) parametric whitebox but due to a bug somewhere this hasn't been monomorphised into a concrete blackbox. - // This is a bug, and a bug report would be welcomed. - // 2) You have an (* abc9_box *) parametric blackbox (e.g. to store associated cell data) but want to provide timing data for ABC9. - // This is not supported due to the presence of parameters. If you want to store associated cell data for a box, one approach could be - // to techmap the parameters to constant module inputs, and then after ABC9 use _TECHMAP_CONSTVAL_XX_ to retrieve the values again. - log_error("Black box '%s' is marked (* abc9_box *) and has parameters, which is forbidden in prep_xaiger\n", log_id(cell_name)); + { + // At this stage of the ABC9 flow, all modules must be nonparametric, because ABC itself requires concrete netlists, and the presence of + // parameters implies a non-concrete netlist. This means an (* abc9_box *) parametric module but due to a bug somewhere this hasn't been + // uniquified into a concrete parameter-free module. This is a bug, and a bug report would be welcomed. + log_error("Not expecting parameters on module '%s' marked (* abc9_box *)\n", log_id(cell_name)); + } log_assert(box_module->get_blackbox_attribute()); cell->attributes[ID::abc9_box_seq] = box_count++; diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys index a9880c722bf..e0add714b1b 100644 --- a/tests/various/abc9.ys +++ b/tests/various/abc9.ys @@ -90,7 +90,7 @@ $_DFF_N_ ff4(.C(clk), .D(1'b1), .Q(z)); endmodule EOT simplemap -equiv_opt abc9 -lut 4 -dff +equiv_opt -assert abc9 -lut 4 -dff design -load postopt cd abc9_test038 select -assert-count 3 t:$_DFF_N_ @@ -99,3 +99,58 @@ clean select -assert-count 2 a:init select -assert-count 1 w:w a:init %i select -assert-count 1 c:ff4 %co c:ff4 %d %a a:init %i + + +# Check that non-dangling ABC9 black-boxes are preserved +design -reset +read_verilog -specify < O) = P; + (I1 => O) = P; + (S => O) = P; +endspecify +endmodule + +module abc9_test039(output O); + mux_with_param #(.P(1)) m ( + .I0(1'b1), + .I1(1'b1), + .O(O), + .S(1'b0) + ); +endmodule +EOT +abc9 -lut 4 +cd abc9_test039 +select -assert-count 1 t:mux_with_param + + +# Check that dangling ABC9 black-boxes are swept away +design -reset +read_verilog -specify < O) = P; + (I1 => O) = P; + (S => O) = P; +endspecify +endmodule + +module abc9_test040(output O); + wire w; + mux_with_param #(.P(1)) m ( + .I0(1'b1), + .I1(1'b1), + .O(w), + .S(1'b0) + ); +endmodule +EOT +abc9 -lut 4 +cd abc9_test040 +select -assert-count 0 t:mux_with_param From ba2ff1ea986b73d025938ab1cf102e1cf35d6773 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 29 Mar 2021 11:03:46 -0400 Subject: [PATCH 0299/2410] verilog: revise hot comment warnings --- frontends/verilog/verilog_lexer.l | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 66772a09758..1a6dc96fd02 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -431,8 +431,13 @@ supply1 { return TOK_SUPPLY1; } "/*"[ \t]*(synopsys|synthesis)[ \t]*translate_off[ \t]*"*/" { static bool printed_warning = false; if (!printed_warning) { - log_warning("Found one of those horrible `(synopsys|synthesis) translate_off' comments.\n" - "Yosys does support them but it is recommended to use `ifdef constructs instead!\n"); + log_warning( + "Encountered `translate_off' comment! Such legacy hot " + "comments are supported by Yosys, but are not part of " + "any formal language specification. Using a portable " + "and standards-compliant construct such as `ifdef is " + "recommended!\n" + ); printed_warning = true; } BEGIN(SYNOPSYS_TRANSLATE_OFF); @@ -447,8 +452,13 @@ supply1 { return TOK_SUPPLY1; } full_case { static bool printed_warning = false; if (!printed_warning) { - log_warning("Found one of those horrible `(synopsys|synthesis) full_case' comments.\n" - "Yosys does support them but it is recommended to use Verilog `full_case' attributes instead!\n"); + log_warning( + "Encountered `full_case' comment! Such legacy hot " + "comments are supported by Yosys, but are not part of " + "any formal language specification. Using the Verilog " + "`full_case' attribute or the SystemVerilog `unique' " + "or `unique0' keywords is recommended!\n" + ); printed_warning = true; } return TOK_SYNOPSYS_FULL_CASE; @@ -456,8 +466,13 @@ supply1 { return TOK_SUPPLY1; } parallel_case { static bool printed_warning = false; if (!printed_warning) { - log_warning("Found one of those horrible `(synopsys|synthesis) parallel_case' comments.\n" - "Yosys does support them but it is recommended to use Verilog `parallel_case' attributes instead!\n"); + log_warning( + "Encountered `parallel_case' comment! Such legacy hot " + "comments are supported by Yosys, but are not part of " + "any formal language specification. Using the Verilog " + "`parallel_case' attribute or the SystemVerilog " + "`unique' or `priority' keywords is recommended!\n" + ); printed_warning = true; } return TOK_SYNOPSYS_PARALLEL_CASE; From b7ea71e6e39dfda903e1060e1b254ce0002fcf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 30 Mar 2021 04:00:45 +0200 Subject: [PATCH 0300/2410] equiv: Suggest running async2sync or clk2fflogic where appropriate. See #2713. --- passes/equiv/equiv_induct.cc | 5 ++++- passes/equiv/equiv_simple.cc | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index 37aec50cd42..5f14416da1c 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -55,7 +55,10 @@ struct EquivInductWorker for (auto cell : cells) { if (!satgen.importCell(cell, step) && !cell_warn_cache.count(cell)) { - log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); + if (RTLIL::builtin_ff_cell_types().count(cell->type)) + log_warning("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); + else + log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); cell_warn_cache.insert(cell); } if (cell->type == ID($equiv)) { diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 408c5a7934f..8d9e870da44 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -184,8 +184,12 @@ struct EquivSimpleWorker for (auto cell : problem_cells) { auto key = pair(cell, step+1); - if (!imported_cells_cache.count(key) && !satgen.importCell(cell, step+1)) - log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); + if (!imported_cells_cache.count(key) && !satgen.importCell(cell, step+1)) { + if (RTLIL::builtin_ff_cell_types().count(cell->type)) + log_cmd_error("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); + else + log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); + } imported_cells_cache.insert(key); } From 0ccc7229c02449618209a20d66b9fa07e3ea79f2 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 30 Mar 2021 09:38:00 -0400 Subject: [PATCH 0301/2410] preproc: test coverage for #2712 --- tests/verilog/ifdef_nest.ys | 7 +++++++ tests/verilog/ifdef_unterminated.ys | 4 ++++ tests/verilog/unmatched_endif_2.ys | 7 +++++++ 3 files changed, 18 insertions(+) create mode 100644 tests/verilog/ifdef_nest.ys create mode 100644 tests/verilog/ifdef_unterminated.ys create mode 100644 tests/verilog/unmatched_endif_2.ys diff --git a/tests/verilog/ifdef_nest.ys b/tests/verilog/ifdef_nest.ys new file mode 100644 index 00000000000..2202109aa95 --- /dev/null +++ b/tests/verilog/ifdef_nest.ys @@ -0,0 +1,7 @@ +read_verilog < Date: Fri, 9 Apr 2021 09:46:53 +0000 Subject: [PATCH 0302/2410] flatten: rewrite memid in memwr actions. --- passes/techmap/flatten.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index f35b7ff6050..0509eedb870 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -122,6 +122,9 @@ struct FlattenWorker for (auto &tpl_proc_it : tpl->processes) { RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second), tpl_proc_it.second); map_attributes(cell, new_proc, tpl_proc_it.second->name); + for (auto new_proc_sync : new_proc->syncs) + for (auto &memwr_action : new_proc_sync->mem_write_actions) + memwr_action.memid = memory_map.at(memwr_action.memid).str(); auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); }; new_proc->rewrite_sigspecs(rewriter); design->select(module, new_proc); From a58571d0fe8971cb7d3a619a31b2c21be6d75bac Mon Sep 17 00:00:00 2001 From: Stefan Riesenberger Date: Fri, 9 Apr 2021 15:44:08 +0200 Subject: [PATCH 0303/2410] sf2: fix name of AND modules --- techlibs/sf2/cells_sim.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index eff57a65534..4b57bad7b95 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -1,20 +1,20 @@ // https://coredocs.s3.amazonaws.com/Libero/12_0_0/Tool/sf2_mlg.pdf -module ADD2 ( +module AND2 ( input A, B, output Y ); assign Y = A & B; endmodule -module ADD3 ( +module AND3 ( input A, B, C, output Y ); assign Y = A & B & C; endmodule -module ADD4 ( +module AND4 ( input A, B, C, D, output Y ); From dce037a62c5bda9a8256d271d39b06be366120e8 Mon Sep 17 00:00:00 2001 From: Lofty Date: Mon, 12 Apr 2021 10:33:40 +0100 Subject: [PATCH 0304/2410] quicklogic: ABC9 synthesis --- techlibs/quicklogic/Makefile.inc | 4 ++++ techlibs/quicklogic/abc9_map.v | 26 +++++++++++++++++++++++++ techlibs/quicklogic/abc9_model.v | 11 +++++++++++ techlibs/quicklogic/abc9_unmap.v | 14 +++++++++++++ techlibs/quicklogic/pp3_cells_sim.v | 5 ++--- techlibs/quicklogic/synth_quicklogic.cc | 25 ++++++++++++++++++++++-- tests/arch/quicklogic/add_sub.ys | 6 +++--- tests/arch/quicklogic/counter.ys | 6 +++--- tests/arch/quicklogic/fsm.ys | 9 ++++----- tests/arch/quicklogic/latches.ys | 5 +++-- tests/arch/quicklogic/logic.ys | 4 ++-- tests/arch/quicklogic/mux.ys | 4 ++-- 12 files changed, 97 insertions(+), 22 deletions(-) create mode 100644 techlibs/quicklogic/abc9_map.v create mode 100644 techlibs/quicklogic/abc9_model.v create mode 100644 techlibs/quicklogic/abc9_unmap.v diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc index 9a07c2eed20..51eb28d44bd 100644 --- a/techlibs/quicklogic/Makefile.inc +++ b/techlibs/quicklogic/Makefile.inc @@ -7,3 +7,7 @@ $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_map. $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v)) $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/lut_sim.v)) $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_sim.v)) + +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_model.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_unmap.v)) diff --git a/techlibs/quicklogic/abc9_map.v b/techlibs/quicklogic/abc9_map.v new file mode 100644 index 00000000000..46c11d6752a --- /dev/null +++ b/techlibs/quicklogic/abc9_map.v @@ -0,0 +1,26 @@ +// This file exists to map purely-synchronous flops to ABC9 flops, while +// mapping flops with asynchronous-set/clear as boxes, this is because ABC9 +// doesn't support asynchronous-set/clear flops in sequential synthesis. + +module dffepc ( + output Q, + input D, + input CLK, + input EN, + input CLR, + input PRE +); + +parameter INIT = 1'b0; + +parameter _TECHMAP_CONSTMSK_CLR_ = 1'b0; +parameter _TECHMAP_CONSTMSK_PRE_ = 1'b0; +parameter _TECHMAP_CONSTVAL_CLR_ = 1'b0; +parameter _TECHMAP_CONSTVAL_PRE_ = 1'b0; + +if (_TECHMAP_CONSTMSK_CLR_ != 1'b0 && _TECHMAP_CONSTMSK_PRE_ != 1'b0 && _TECHMAP_CONSTVAL_CLR_ == 1'b0 && _TECHMAP_CONSTVAL_PRE_ == 1'b0) + $__PP3_DFFEPC_SYNCONLY _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN)); +else + wire _TECHMAP_FAIL_ = 1; + +endmodule diff --git a/techlibs/quicklogic/abc9_model.v b/techlibs/quicklogic/abc9_model.v new file mode 100644 index 00000000000..06d4a2a5656 --- /dev/null +++ b/techlibs/quicklogic/abc9_model.v @@ -0,0 +1,11 @@ +(* abc9_flop, lib_whitebox *) +module $__PP3_DFFEPC_SYNCONLY ( + output Q, + input D, + input CLK, + input EN, +); + + dffepc ff (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0)); + +endmodule diff --git a/techlibs/quicklogic/abc9_unmap.v b/techlibs/quicklogic/abc9_unmap.v new file mode 100644 index 00000000000..1681e01bb16 --- /dev/null +++ b/techlibs/quicklogic/abc9_unmap.v @@ -0,0 +1,14 @@ +module $__PP3_DFFEPC_SYNCONLY ( + output Q, + input D, + input CLK, + input EN, +); + +// For some reason ABC9 adds init attributes to wires even though they were removed before mapping. +// As a workaround, remove any init attributes that get reintroduced. +wire _TECHMAP_REMOVEINIT_Q_ = 1; + +dffepc _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0)); + +endmodule diff --git a/techlibs/quicklogic/pp3_cells_sim.v b/techlibs/quicklogic/pp3_cells_sim.v index 61d1ee314f8..5820d7a9ec0 100644 --- a/techlibs/quicklogic/pp3_cells_sim.v +++ b/techlibs/quicklogic/pp3_cells_sim.v @@ -147,11 +147,10 @@ module dffepc ( ); parameter [0:0] INIT = 1'b0; - // The CLR => Q and PRE => Q paths are commented out due to YosysHQ/yosys#2530. specify if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ - // if (CLR) (CLR => Q) = 967; // QRT -> QZ - // if (PRE) (PRE => Q) = 1252; // QST -> QZ + if (CLR) (CLR => Q) = 967; // QRT -> QZ + if (PRE) (PRE => Q) = 1252; // QST -> QZ $setup(D, posedge CLK, 216); // QCK -> QDS $setup(EN, posedge CLK, 590); // QCK -> QEN endspecify diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 90eb0f78b87..a67b167b843 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -51,12 +51,17 @@ struct SynthQuickLogicPass : public ScriptPass { log(" write the design to the specified verilog file. writing of an output file\n"); log(" is omitted if this parameter is not specified.\n"); log("\n"); + log(" -abc\n"); + log(" use old ABC flow, which has generally worse mapping results but is less\n"); + log(" likely to have bugs.\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, blif_file, family, currmodule, verilog_file; + bool abc9; void clear_flags() override { @@ -65,6 +70,7 @@ struct SynthQuickLogicPass : public ScriptPass { verilog_file = ""; currmodule = ""; family = "pp3"; + abc9 = true; } void execute(std::vector args, RTLIL::Design *design) override @@ -91,6 +97,10 @@ struct SynthQuickLogicPass : public ScriptPass { verilog_file = args[++argidx]; continue; } + if (args[argidx] == "-abc") { + abc9 = false; + continue; + } break; } extra_args(args, argidx, design); @@ -101,6 +111,11 @@ struct SynthQuickLogicPass : public ScriptPass { if (family != "pp3") log_cmd_error("Invalid family specified: '%s'\n", family.c_str()); + if (abc9 && design->scratchpad_get_int("abc9.D", 0) == 0) { + log_warning("delay target has not been set via SDC or scratchpad; assuming 12 MHz clock.\n"); + design->scratchpad_set_int("abc9.D", 41667); // 12MHz = 83.33.. ns; divided by two to allow for interconnect delay. + } + log_header(design, "Executing SYNTH_QUICKLOGIC pass.\n"); log_push(); @@ -167,8 +182,14 @@ struct SynthQuickLogicPass : public ScriptPass { if (check_label("map_luts")) { run(stringf("techmap -map +/quicklogic/%s_latches_map.v", family.c_str())); - run("abc -luts 1,2,2,4 -dress"); - + if (abc9) { + run("read_verilog -lib -specify -icells +/quicklogic/abc9_model.v"); + run("techmap -map +/quicklogic/abc9_map.v"); + run("abc9 -maxlut 4 -dff"); + run("techmap -map +/quicklogic/abc9_unmap.v"); + } else { + run("abc -luts 1,2,2,4 -dress"); + } run("clean"); } diff --git a/tests/arch/quicklogic/add_sub.ys b/tests/arch/quicklogic/add_sub.ys index 168b3f8b33f..73ee5cb4413 100644 --- a/tests/arch/quicklogic/add_sub.ys +++ b/tests/arch/quicklogic/add_sub.ys @@ -3,9 +3,9 @@ hierarchy -top top equiv_opt -assert -map +/quicklogic/lut_sim.v -map +/quicklogic/pp3_cells_sim.v synth_quicklogic -family pp3 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 3 t:LUT2 -select -assert-count 4 t:LUT3 -select -assert-count 4 t:LUT4 +select -assert-count 2 t:LUT2 +select -assert-count 8 t:LUT3 +select -assert-count 2 t:LUT4 select -assert-count 8 t:inpad select -assert-count 8 t:outpad select -assert-none t:LUT2 t:LUT3 t:LUT4 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/counter.ys b/tests/arch/quicklogic/counter.ys index 0c04b5742ed..2e266417caf 100644 --- a/tests/arch/quicklogic/counter.ys +++ b/tests/arch/quicklogic/counter.ys @@ -6,9 +6,9 @@ equiv_opt -assert -multiclock -map +/quicklogic/pp3_cells_sim.v -map +/quicklogi design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 1 t:LUT1 -select -assert-count 5 t:LUT2 -select -assert-count 2 t:LUT3 -select -assert-count 3 t:LUT4 +select -assert-count 3 t:LUT2 +select -assert-count 5 t:LUT3 +select -assert-count 1 t:LUT4 select -assert-count 8 t:dffepc select -assert-count 1 t:logic_0 select -assert-count 1 t:logic_1 diff --git a/tests/arch/quicklogic/fsm.ys b/tests/arch/quicklogic/fsm.ys index 7ed36b9e4cd..130dacf42a9 100644 --- a/tests/arch/quicklogic/fsm.ys +++ b/tests/arch/quicklogic/fsm.ys @@ -11,14 +11,13 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module -select -assert-count 3 t:LUT2 -select -assert-count 6 t:LUT3 -select -assert-count 7 t:LUT4 -select -assert-count 6 t:dffepc +select -assert-count 1 t:LUT2 +select -assert-count 9 t:LUT3 +select -assert-count 4 t:dffepc select -assert-count 1 t:logic_0 select -assert-count 1 t:logic_1 select -assert-count 3 t:inpad select -assert-count 2 t:outpad select -assert-count 1 t:ckpad -select -assert-none t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D +select -assert-none t:LUT2 t:LUT3 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D diff --git a/tests/arch/quicklogic/latches.ys b/tests/arch/quicklogic/latches.ys index d7652f749ad..bcef429904b 100644 --- a/tests/arch/quicklogic/latches.ys +++ b/tests/arch/quicklogic/latches.ys @@ -32,8 +32,9 @@ proc # Can't run any sort of equivalence check because latches are blown to LUTs synth_quicklogic cd latchsr # Constrain all select calls below inside the top module -select -assert-count 2 t:LUT3 +select -assert-count 1 t:LUT2 +select -assert-count 1 t:LUT4 select -assert-count 5 t:inpad select -assert-count 1 t:outpad -select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D +select -assert-none t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/logic.ys b/tests/arch/quicklogic/logic.ys index 65f48a42b61..4b327c00af7 100644 --- a/tests/arch/quicklogic/logic.ys +++ b/tests/arch/quicklogic/logic.ys @@ -7,8 +7,8 @@ cd top # Constrain all select calls below inside the top module select -assert-count 1 t:LUT1 select -assert-count 6 t:LUT2 -select -assert-count 2 t:LUT4 +select -assert-count 2 t:LUT3 select -assert-count 8 t:inpad select -assert-count 10 t:outpad -select -assert-none t:LUT1 t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D +select -assert-none t:LUT1 t:LUT2 t:LUT3 t:inpad t:outpad %% t:* %D diff --git a/tests/arch/quicklogic/mux.ys b/tests/arch/quicklogic/mux.ys index 632d1468759..ea17fa99b3d 100644 --- a/tests/arch/quicklogic/mux.ys +++ b/tests/arch/quicklogic/mux.ys @@ -30,13 +30,13 @@ proc equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module -select -assert-count 4 t:LUT2 +select -assert-count 1 t:LUT1 select -assert-count 1 t:LUT3 select -assert-count 2 t:mux4x0 select -assert-count 11 t:inpad select -assert-count 1 t:outpad -select -assert-none t:LUT2 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D +select -assert-none t:LUT1 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D design -load read hierarchy -top mux16 From 8aee80040de0b0812f2aec7ba4059c14407a0567 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 15 Mar 2021 23:27:55 +0100 Subject: [PATCH 0305/2410] Add default assignments to SB_LUT4 Signed-off-by: Claire Xenia Wolf --- techlibs/ice40/cells_sim.v | 18 +++++++++++++++++- tests/arch/run-test.sh | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 7ee809262b0..2af99269c8c 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -2,6 +2,16 @@ `define SB_DFF_REG reg Q = 0 // `define SB_DFF_REG reg Q +`ifndef NO_ICE40_DEFAULT_ASSIGNMENTS +`define ICE40_DEFAULT_ASSIGNMENT_V(v) = v +`define ICE40_DEFAULT_ASSIGNMENT_0 = 1'b0 +`define ICE40_DEFAULT_ASSIGNMENT_1 = 1'b1 +`else +`define ICE40_DEFAULT_ASSIGNMENT_V(v) +`define ICE40_DEFAULT_ASSIGNMENT_0 +`define ICE40_DEFAULT_ASSIGNMENT_1 +`endif + // SiliconBlue IO Cells module SB_IO ( @@ -164,7 +174,13 @@ endmodule // SiliconBlue Logic Cells (* abc9_lut=1, lib_whitebox *) -module SB_LUT4 (output O, input I0, I1, I2, I3); +module SB_LUT4 ( + output O, + input I0 `ICE40_DEFAULT_ASSIGNMENT_0, + input I1 `ICE40_DEFAULT_ASSIGNMENT_0, + input I2 `ICE40_DEFAULT_ASSIGNMENT_0, + input I3 `ICE40_DEFAULT_ASSIGNMENT_0 +); parameter [15:0] LUT_INIT = 0; wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0]; wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0]; diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh index 170078a7fde..5d923db560b 100755 --- a/tests/arch/run-test.sh +++ b/tests/arch/run-test.sh @@ -11,7 +11,7 @@ for arch in ../../techlibs/*; do if [ "${defines[$arch_name]}" ]; then for def in ${defines[$arch_name]}; do echo -n "Test $path -D$def ->" - iverilog -t null -I$arch -D$def $path + iverilog -t null -I$arch -D$def -DNO_ICE40_DEFAULT_ASSIGNMENTS $path echo " ok" done else From 46d3f03d27b4851b64f909ddbb663cbdac0fed70 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 20 Apr 2021 18:52:36 +0200 Subject: [PATCH 0306/2410] Add default assignments to other SB_* simulation models Signed-off-by: Claire Xenia Wolf --- techlibs/ice40/cells_sim.v | 68 ++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 2af99269c8c..bde3c1a87ed 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -17,7 +17,7 @@ module SB_IO ( inout PACKAGE_PIN, input LATCH_INPUT_VALUE, - input CLOCK_ENABLE, + input CLOCK_ENABLE `ICE40_DEFAULT_ASSIGNMENT_1, input INPUT_CLK, input OUTPUT_CLK, input OUTPUT_ENABLE, @@ -124,7 +124,7 @@ module SB_GB_IO ( inout PACKAGE_PIN, output GLOBAL_BUFFER_OUTPUT, input LATCH_INPUT_VALUE, - input CLOCK_ENABLE, + input CLOCK_ENABLE `ICE40_DEFAULT_ASSIGNMENT_1, input INPUT_CLK, input OUTPUT_CLK, input OUTPUT_ENABLE, @@ -300,7 +300,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFE ( output `SB_DFF_REG, - input C, E, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); always @(posedge C) if (E) @@ -577,7 +577,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESR ( output `SB_DFF_REG, - input C, E, R, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); always @(posedge C) if (E) begin @@ -633,7 +633,7 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFER ( output `SB_DFF_REG, - input C, E, R, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); always @(posedge C, posedge R) if (R) @@ -708,7 +708,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESS ( output `SB_DFF_REG, - input C, E, S, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); always @(posedge C) if (E) begin @@ -764,7 +764,7 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFES ( output `SB_DFF_REG, - input C, E, S, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); always @(posedge C, posedge S) if (S) @@ -877,7 +877,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNE ( output `SB_DFF_REG, - input C, E, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); always @(negedge C) if (E) @@ -1154,7 +1154,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESR ( output `SB_DFF_REG, - input C, E, R, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); always @(negedge C) if (E) begin @@ -1210,7 +1210,7 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNER ( output `SB_DFF_REG, - input C, E, R, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); always @(negedge C, posedge R) if (R) @@ -1285,7 +1285,7 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESS ( output `SB_DFF_REG, - input C, E, S, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); always @(negedge C) if (E) begin @@ -1341,7 +1341,7 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNES ( output `SB_DFF_REG, - input C, E, S, D + input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); always @(negedge C, posedge S) if (S) @@ -1418,11 +1418,16 @@ endmodule module SB_RAM40_4K ( output [15:0] RDATA, - input RCLK, RCLKE, RE, + input RCLK, + input RCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input RE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] RADDR, - input WCLK, WCLKE, WE, + input WCLK, + input WCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input WE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] WADDR, - input [15:0] MASK, WDATA + input [15:0] MASK `ICE40_DEFAULT_ASSIGNMENT_V(16'h 0000), + input [15:0] WDATA ); // MODE 0: 256 x 16 // MODE 1: 512 x 8 @@ -1652,11 +1657,16 @@ endmodule module SB_RAM40_4KNR ( output [15:0] RDATA, - input RCLKN, RCLKE, RE, + input RCLKN, + input RCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input RE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] RADDR, - input WCLK, WCLKE, WE, + input WCLK, + input WCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input WE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] WADDR, - input [15:0] MASK, WDATA + input [15:0] MASK `ICE40_DEFAULT_ASSIGNMENT_V(16'h 0000), + input [15:0] WDATA ); parameter WRITE_MODE = 0; parameter READ_MODE = 0; @@ -1783,11 +1793,16 @@ endmodule module SB_RAM40_4KNW ( output [15:0] RDATA, - input RCLK, RCLKE, RE, + input RCLK, + input RCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input RE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] RADDR, - input WCLKN, WCLKE, WE, + input WCLKN, + input WCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input WE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] WADDR, - input [15:0] MASK, WDATA + input [15:0] MASK `ICE40_DEFAULT_ASSIGNMENT_V(16'h 0000), + input [15:0] WDATA ); parameter WRITE_MODE = 0; parameter READ_MODE = 0; @@ -1914,11 +1929,16 @@ endmodule module SB_RAM40_4KNRNW ( output [15:0] RDATA, - input RCLKN, RCLKE, RE, + input RCLKN, + input RCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input RE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] RADDR, - input WCLKN, WCLKE, WE, + input WCLKN, + input WCLKE `ICE40_DEFAULT_ASSIGNMENT_1, + input WE `ICE40_DEFAULT_ASSIGNMENT_0, input [10:0] WADDR, - input [15:0] MASK, WDATA + input [15:0] MASK `ICE40_DEFAULT_ASSIGNMENT_V(16'h 0000), + input [15:0] WDATA ); parameter WRITE_MODE = 0; parameter READ_MODE = 0; From 58290c0c77e09aa40a098065ea999c85aaba398c Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 26 Apr 2021 16:31:44 +0200 Subject: [PATCH 0307/2410] Remove duplicates from conns array in JSON front-end, fixes #2736 --- frontends/json/jsonparse.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index d897ac20b22..cbfa038a184 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -585,6 +585,10 @@ void json_import(Design *design, string &modname, JsonNode *node) module->memories[mem->name] = mem; } } + + // remove duplicates from connections array + pool unique_connections(module->connections_.begin(), module->connections_.end()); + module->connections_ = std::vector(unique_connections.begin(), unique_connections.end()); } struct JsonFrontend : public Frontend { From 67d6f3973b5dc3f017b24eb43950707e99b10dff Mon Sep 17 00:00:00 2001 From: Michael Christensen Date: Tue, 27 Apr 2021 02:29:52 -0700 Subject: [PATCH 0308/2410] Fix use of blif name in synth_xilinx command --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 80d120fe1e5..1fd2d4f8bca 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -672,7 +672,7 @@ struct SynthXilinxPass : public ScriptPass if (check_label("blif")) { if (!blif_file.empty() || help_mode) - run(stringf("write_blif %s", edif_file.c_str())); + run(stringf("write_blif %s", blif_file.c_str())); } } } SynthXilinxPass; From 5c1e6a0e201f1bb623c3fc7d2c8ee13c783c9c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 4 May 2021 19:14:24 +0200 Subject: [PATCH 0309/2410] opt_dff: Fix NOT gates wired in reverse. --- passes/opt/opt_dff.cc | 4 ++-- tests/opt/opt_dff_sr.ys | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index a47071a30f8..c87ac3163e5 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -318,9 +318,9 @@ struct OptDffWorker if (!ff.pol_clr) { module->connect(ff.sig_q[i], ff.sig_clr[i]); } else if (ff.is_fine) { - module->addNotGate(NEW_ID, ff.sig_q[i], ff.sig_clr[i]); + module->addNotGate(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); } else { - module->addNot(NEW_ID, ff.sig_q[i], ff.sig_clr[i]); + module->addNot(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); } log("Handling always-active SET at position %d on %s (%s) from module %s (changing to combinatorial circuit).\n", i, log_id(cell), log_id(cell->type), log_id(module)); diff --git a/tests/opt/opt_dff_sr.ys b/tests/opt/opt_dff_sr.ys index daedb115cdd..0961cb11ef2 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_ From a6081b46ce61a35fee18756de151d72581c8f49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 5 May 2021 20:32:07 +0200 Subject: [PATCH 0310/2410] connect: Add -assert option, fix non-working sigmap. Should be useful for writing tests. --- passes/cmds/connect.cc | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 0cc6cbe52a0..d85ea9ad561 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -60,7 +60,7 @@ struct ConnectPass : public Pass { log("Unconnect all existing drivers for the specified expression.\n"); log("\n"); log("\n"); - log(" connect [-nomap] -port \n"); + log(" connect [-nomap] [-assert] -port \n"); log("\n"); log("Connect the specified cell port to the specified cell port.\n"); log("\n"); @@ -72,6 +72,9 @@ struct ConnectPass : public Pass { log("The connect command operates in one module only. Either only one module must\n"); log("be selected or an active module must be set using the 'cd' command.\n"); log("\n"); + log("The -assert option verifies that the connection already exists, instead of\n"); + log("making it.\n"); + log("\n"); log("This command does not operate on module with processes.\n"); log("\n"); } @@ -88,7 +91,7 @@ struct ConnectPass : public Pass { if (!module->processes.empty()) log_cmd_error("Found processes in selected module.\n"); - bool flag_nounset = false, flag_nomap = false; + bool flag_nounset = false, flag_nomap = false, flag_assert = false; std::string set_lhs, set_rhs, unset_expr; std::string port_cell, port_port, port_expr; @@ -104,6 +107,10 @@ struct ConnectPass : public Pass { flag_nomap = true; continue; } + if (arg == "-assert") { + flag_assert = true; + continue; + } if (arg == "-set" && argidx+2 < args.size()) { set_lhs = args[++argidx]; set_rhs = args[++argidx]; @@ -126,7 +133,7 @@ struct ConnectPass : public Pass { if (!flag_nomap) for (auto &it : module->connections()) { std::vector lhs = it.first.to_sigbit_vector(); - std::vector rhs = it.first.to_sigbit_vector(); + std::vector rhs = it.second.to_sigbit_vector(); for (size_t i = 0; i < lhs.size(); i++) if (rhs[i].wire != nullptr) sigmap.add(lhs[i], rhs[i]); @@ -137,6 +144,9 @@ struct ConnectPass : public Pass { if (!unset_expr.empty() || !port_cell.empty()) log_cmd_error("Can't use -set together with -unset and/or -port.\n"); + if (flag_assert) + log_cmd_error("The -assert option is only supported with -port.\n"); + RTLIL::SigSpec sig_lhs, sig_rhs; if (!RTLIL::SigSpec::parse_sel(sig_lhs, design, module, set_lhs)) log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs.c_str()); @@ -157,6 +167,9 @@ struct ConnectPass : public Pass { if (!port_cell.empty() || flag_nounset) log_cmd_error("Can't use -unset together with -port and/or -nounset.\n"); + if (flag_assert) + log_cmd_error("The -assert option is only supported with -port.\n"); + RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, unset_expr)) log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr.c_str()); @@ -177,7 +190,14 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); + if (!flag_assert) { + module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); + } else { + SigSpec cur = module->cell(RTLIL::escape_id(port_cell))->getPort(RTLIL::escape_id(port_port)); + if (sigmap(sig) != sigmap(cur)) { + log_cmd_error("Expected connection not present: expected %s, found %s.\n", log_signal(sig), log_signal(cur)); + } + } } else log_cmd_error("Expected -set, -unset, or -port.\n"); From 32a0ce9d6809d073abcbf19fe3eaf7a0cf936963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 5 May 2021 20:31:27 +0200 Subject: [PATCH 0311/2410] blif: Use library cells' start_offset and upto for wideports. Fixes #2729. --- Makefile | 1 + frontends/blif/blifparse.cc | 37 +++++++++++++++++++++++++++---------- tests/blif/bug2729.ys | 20 ++++++++++++++++++++ tests/blif/run-test.sh | 6 ++++++ 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 tests/blif/bug2729.ys create mode 100755 tests/blif/run-test.sh diff --git a/Makefile b/Makefile index 4760eaa35a3..ff62aca2562 100644 --- a/Makefile +++ b/Makefile @@ -804,6 +804,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) +cd tests/svtypes && bash run-test.sh $(SEEDOPT) +cd tests/proc && bash run-test.sh + +cd tests/blif && bash run-test.sh +cd tests/opt && bash run-test.sh +cd tests/aiger && bash run-test.sh $(ABCOPT) +cd tests/arch && bash run-test.sh diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 9ae3fac2c0e..52b46c228e9 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -65,17 +65,21 @@ static std::pair wideports_split(std::string name) for (int i = 0; i+1 < GetSize(name); i++) { if (name[i] == '[') pos = i; - else if (name[i] < '0' || name[i] > '9') + else if (name[i] != '-' && (name[i] < '0' || name[i] > '9')) + pos = -1; + else if (name[i] == '-' && ((i != pos+1) || name[i+1] == ']')) + pos = -1; + else if (i == pos+2 && name[i] == '0' && name[i-1] == '-') pos = -1; else if (i == pos+1 && name[i] == '0' && name[i+1] != ']') pos = -1; } if (pos >= 0) - return std::pair("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1)+1); + return std::pair("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1)); failed: - return std::pair("\\" + name, 0); + return std::pair(RTLIL::IdString(), 0); } void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool run_clean, bool sop_mode, bool wideports) @@ -263,8 +267,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool if (wideports) { std::pair wp = wideports_split(p); - if (wp.second > 0) { - wideports_cache[wp.first].first = std::max(wideports_cache[wp.first].first, wp.second); + if (!wp.first.empty() && wp.second >= 0) { + wideports_cache[wp.first].first = std::max(wideports_cache[wp.first].first, wp.second + 1); wideports_cache[wp.first].second = !strcmp(cmd, ".inputs"); } } @@ -375,6 +379,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool IdString celltype = RTLIL::escape_id(p); RTLIL::Cell *cell = module->addCell(NEW_ID, celltype); + RTLIL::Module *cell_mod = design->module(celltype); dict> cell_wideports_cache; @@ -387,10 +392,10 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool if (wideports) { std::pair wp = wideports_split(p); - if (wp.second > 0) - cell_wideports_cache[wp.first][wp.second-1] = blif_wire(q); - else + if (wp.first.empty()) cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec()); + else + cell_wideports_cache[wp.first][wp.second] = blif_wire(q); } else { cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec()); } @@ -399,14 +404,26 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool for (auto &it : cell_wideports_cache) { int width = 0; + int offset = 0; + bool upto = false; for (auto &b : it.second) width = std::max(width, b.first + 1); + if (cell_mod) { + Wire *cell_port = cell_mod->wire(it.first); + if (cell_port && (cell_port->port_input || cell_port->port_output)) { + offset = cell_port->start_offset; + upto = cell_port->upto; + width = cell_port->width; + } + } + SigSpec sig; for (int i = 0; i < width; i++) { - if (it.second.count(i)) - sig.append(it.second.at(i)); + int idx = offset + (upto ? width - 1 - i: i); + if (it.second.count(idx)) + sig.append(it.second.at(idx)); else sig.append(module->addWire(NEW_ID)); } diff --git a/tests/blif/bug2729.ys b/tests/blif/bug2729.ys new file mode 100644 index 00000000000..0cbc21aa08e --- /dev/null +++ b/tests/blif/bug2729.ys @@ -0,0 +1,20 @@ +read_verilog < Date: Mon, 10 May 2021 11:06:02 -0400 Subject: [PATCH 0312/2410] sv: check validity of package end label --- frontends/verilog/verilog_parser.y | 2 ++ tests/verilog/package_end_label.ys | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/verilog/package_end_label.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index e4b3258c23f..dd25f412f17 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -579,6 +579,8 @@ package: append_attr(mod, $1); } ';' package_body TOK_ENDPACKAGE opt_label { ast_stack.pop_back(); + if ($4 != NULL && $9 != NULL && *$4 != *$9) + frontend_verilog_yyerror("Package name (%s) and end label (%s) don't match.", $4->c_str()+1, $9->c_str()+1); current_ast_mod = NULL; exitTypeScope(); }; diff --git a/tests/verilog/package_end_label.ys b/tests/verilog/package_end_label.ys new file mode 100644 index 00000000000..ccc5c96e90c --- /dev/null +++ b/tests/verilog/package_end_label.ys @@ -0,0 +1,15 @@ +logger -expect-no-warnings +read_verilog -sv < Date: Wed, 27 Jan 2021 18:51:19 +0000 Subject: [PATCH 0313/2410] Add missing parameters for MULT18X18D and ALU54B to ECP5 techlib. --- techlibs/ecp5/cells_bb.v | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v index 756f0536621..c4cedfe3612 100644 --- a/techlibs/ecp5/cells_bb.v +++ b/techlibs/ecp5/cells_bb.v @@ -27,16 +27,23 @@ module MULT18X18D( parameter REG_INPUTB_CE = "CE0"; parameter REG_INPUTB_RST = "RST0"; parameter REG_INPUTC_CLK = "NONE"; + parameter REG_INPUTC_CE = "CE0"; + parameter REG_INPUTC_RST = "RST0"; parameter REG_PIPELINE_CLK = "NONE"; parameter REG_PIPELINE_CE = "CE0"; parameter REG_PIPELINE_RST = "RST0"; parameter REG_OUTPUT_CLK = "NONE"; + parameter REG_OUTPUT_CE = "CE0"; + parameter REG_OUTPUT_RST = "RST0"; parameter [127:0] CLK0_DIV = "ENABLED"; parameter [127:0] CLK1_DIV = "ENABLED"; parameter [127:0] CLK2_DIV = "ENABLED"; parameter [127:0] CLK3_DIV = "ENABLED"; + parameter HIGHSPEED_CLK = "NONE"; parameter [127:0] GSR = "ENABLED"; + parameter CAS_MATCH_REG = "FALSE"; parameter [127:0] SOURCEB_MODE = "B_SHIFT"; + parameter [127:0] MULT_BYPASS = "DISABLED"; parameter [127:0] RESETMODE = "SYNC"; endmodule @@ -61,7 +68,11 @@ module ALU54B( output SIGNEDR ); parameter REG_INPUTC0_CLK = "NONE"; + parameter REG_INPUTC0_CE = "CE0"; + parameter REG_INPUTC0_RST = "RST0"; parameter REG_INPUTC1_CLK = "NONE"; + parameter REG_INPUTC1_CE = "CE0"; + parameter REG_INPUTC1_RST = "RST0"; parameter REG_OPCODEOP0_0_CLK = "NONE"; parameter REG_OPCODEOP0_0_CE = "CE0"; parameter REG_OPCODEOP0_0_RST = "RST0"; @@ -69,6 +80,7 @@ module ALU54B( parameter REG_OPCODEOP0_1_CLK = "NONE"; parameter REG_OPCODEOP0_1_CE = "CE0"; parameter REG_OPCODEOP0_1_RST = "RST0"; + parameter REG_OPCODEOP1_1_CLK = "NONE"; parameter REG_OPCODEIN_0_CLK = "NONE"; parameter REG_OPCODEIN_0_CE = "CE0"; parameter REG_OPCODEIN_0_RST = "RST0"; @@ -76,8 +88,17 @@ module ALU54B( parameter REG_OPCODEIN_1_CE = "CE0"; parameter REG_OPCODEIN_1_RST = "RST0"; parameter REG_OUTPUT0_CLK = "NONE"; + parameter REG_OUTPUT0_CE = "CE0"; + parameter REG_OUTPUT0_RST = "RST0"; parameter REG_OUTPUT1_CLK = "NONE"; + parameter REG_OUTPUT1_CE = "CE0"; + parameter REG_OUTPUT1_RST = "RST0"; parameter REG_FLAG_CLK = "NONE"; + parameter REG_FLAG_CE = "CE0"; + parameter REG_FLAG_RST = "RST0"; + parameter REG_INPUTCFB_CLK = "NONE"; + parameter REG_INPUTCFB_CE = "CE0"; + parameter REG_INPUTCFB_RST = "RST0"; parameter [127:0] MCPAT_SOURCE = "STATIC"; parameter [127:0] MASKPAT_SOURCE = "STATIC"; parameter MASK01 = "0x00000000000000"; @@ -90,6 +111,7 @@ module ALU54B( parameter RNDPAT = "0x00000000000000"; parameter [127:0] GSR = "ENABLED"; parameter [127:0] RESETMODE = "SYNC"; + parameter MULT9_MODE = "DISABLED"; parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; parameter LEGACY = "DISABLED"; endmodule From 51ed4a7149f64729edeb5ee8419f3303636180e7 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 20 Apr 2020 16:24:57 +0100 Subject: [PATCH 0314/2410] Use range-based for loop in AST::process No functional change: just get rid of the explicit iterator and replace (*it)-> with child->. It's even the same number of characters, but is hopefully a little easier to read. --- frontends/ast/ast.cc | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 614c9bcefbf..7e4f38aa9a4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1219,12 +1219,12 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_autowire = autowire; log_assert(current_ast->type == AST_DESIGN); - for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) + for (AstNode *child : current_ast->children) { - if ((*it)->type == AST_MODULE || (*it)->type == AST_INTERFACE) + if (child->type == AST_MODULE || child->type == AST_INTERFACE) { for (auto n : design->verilog_globals) - (*it)->children.push_back(n->clone()); + child->children.push_back(n->clone()); // append nodes from previous packages using package-qualified names for (auto &n : design->verilog_packages) { @@ -1239,57 +1239,57 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } else { cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1); } - (*it)->children.push_back(cloned_node); + child->children.push_back(cloned_node); } } - if (flag_icells && (*it)->str.compare(0, 2, "\\$") == 0) - (*it)->str = (*it)->str.substr(1); + if (flag_icells && child->str.compare(0, 2, "\\$") == 0) + child->str = child->str.substr(1); bool defer_local = defer; if (!defer_local) - for (const AstNode *node : (*it)->children) + for (const AstNode *node : child->children) if (node->type == AST_PARAMETER && param_has_no_default(node)) { - log("Deferring `%s' because it contains parameter(s) without defaults.\n", (*it)->str.c_str()); + log("Deferring `%s' because it contains parameter(s) without defaults.\n", child->str.c_str()); defer_local = true; break; } if (defer_local) - (*it)->str = "$abstract" + (*it)->str; + child->str = "$abstract" + child->str; - if (design->has((*it)->str)) { - RTLIL::Module *existing_mod = design->module((*it)->str); + if (design->has(child->str)) { + RTLIL::Module *existing_mod = design->module(child->str); if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { - log_file_error((*it)->filename, (*it)->location.first_line, "Re-definition of module `%s'!\n", (*it)->str.c_str()); + log_file_error(child->filename, child->location.first_line, "Re-definition of module `%s'!\n", child->str.c_str()); } else if (nooverwrite) { log("Ignoring re-definition of module `%s' at %s.\n", - (*it)->str.c_str(), (*it)->loc_string().c_str()); + child->str.c_str(), child->loc_string().c_str()); continue; } else { log("Replacing existing%s module `%s' at %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", - (*it)->str.c_str(), (*it)->loc_string().c_str()); + child->str.c_str(), child->loc_string().c_str()); design->remove(existing_mod); } } - process_module(design, *it, defer_local); + process_module(design, child, defer_local); current_ast_mod = nullptr; } - else if ((*it)->type == AST_PACKAGE) { + else if (child->type == AST_PACKAGE) { // process enum/other declarations - (*it)->simplify(true, false, false, 1, -1, false, false); - design->verilog_packages.push_back((*it)->clone()); + child->simplify(true, false, false, 1, -1, false, false); + design->verilog_packages.push_back(child->clone()); current_scope.clear(); } else { // must be global definition - if ((*it)->type == AST_PARAMETER) - (*it)->type = AST_LOCALPARAM; // cannot be overridden - design->verilog_globals.push_back((*it)->clone()); + if (child->type == AST_PARAMETER) + child->type = AST_LOCALPARAM; // cannot be overridden + design->verilog_globals.push_back(child->clone()); current_scope.clear(); } } From 3421979f00664443c77b0899d34438f979b4c51c Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 20 Apr 2020 14:41:55 +0100 Subject: [PATCH 0315/2410] Change the type of current_module to Module The current_module global is needed so that genRTLIL has somewhere to put cells and wires that it generates as it makes sense of expressions that it sees. However, that doesn't actually need to be an AstModule: the Module base class is enough. This patch should cause no functional change, but the point is that it's now possible to call genRTLIL with a module that isn't an AstModule as "current_module". This will be needed for 'bind' support. --- frontends/ast/ast.cc | 48 +++++++++++++++++++++++--------------------- frontends/ast/ast.h | 2 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e4f38aa9a4..7e5cc941104 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -52,7 +52,7 @@ namespace AST_INTERNAL { const dict *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_always, *current_top_block, *current_block, *current_block_child; - AstModule *current_module; + Module *current_module; bool current_always_clocked; dict current_memwr_count; dict> current_memwr_visible; @@ -992,11 +992,13 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); } - current_module = new AstModule; - current_module->ast = NULL; - current_module->name = ast->str; - set_src_attr(current_module, ast); - current_module->set_bool_attribute(ID::cells_not_processed); + AstModule *module = new AstModule; + current_module = module; + + module->ast = NULL; + module->name = ast->str; + set_src_attr(module, ast); + module->set_bool_attribute(ID::cells_not_processed); current_ast_mod = ast; AstNode *ast_before_simplify; @@ -1137,7 +1139,7 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); - current_module->attributes[attr.first] = attr.second->asAttrConst(); + module->attributes[attr.first] = attr.second->asAttrConst(); } for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; @@ -1165,29 +1167,29 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) continue; - current_module->attributes[attr.first] = attr.second->asAttrConst(); + module->attributes[attr.first] = attr.second->asAttrConst(); } } if (ast->type == AST_INTERFACE) - current_module->set_bool_attribute(ID::is_interface); - current_module->ast = ast_before_simplify; - current_module->nolatches = flag_nolatches; - current_module->nomeminit = flag_nomeminit; - current_module->nomem2reg = flag_nomem2reg; - current_module->mem2reg = flag_mem2reg; - current_module->noblackbox = flag_noblackbox; - current_module->lib = flag_lib; - current_module->nowb = flag_nowb; - current_module->noopt = flag_noopt; - current_module->icells = flag_icells; - current_module->pwires = flag_pwires; - current_module->autowire = flag_autowire; - current_module->fixup_ports(); + module->set_bool_attribute(ID::is_interface); + module->ast = ast_before_simplify; + module->nolatches = flag_nolatches; + module->nomeminit = flag_nomeminit; + module->nomem2reg = flag_nomem2reg; + module->mem2reg = flag_mem2reg; + module->noblackbox = flag_noblackbox; + module->lib = flag_lib; + module->nowb = flag_nowb; + module->noopt = flag_noopt; + module->icells = flag_icells; + module->pwires = flag_pwires; + module->autowire = flag_autowire; + module->fixup_ports(); if (flag_dump_rtlil) { log("Dumping generated RTLIL:\n"); - log_module(current_module); + log_module(module); log("--- END OF RTLIL DUMP ---\n"); } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 1447bf568af..06947935382 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -379,7 +379,7 @@ namespace AST_INTERNAL extern const dict *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; - extern AST::AstModule *current_module; + extern RTLIL::Module *current_module; extern bool current_always_clocked; extern dict current_memwr_count; extern dict> current_memwr_visible; From 5dba138c87762d4b5bb7b9348da372a92fab1cc0 Mon Sep 17 00:00:00 2001 From: gatecat Date: Sat, 15 May 2021 14:23:22 +0100 Subject: [PATCH 0316/2410] intel_alm: Add IO buffer insertion Signed-off-by: gatecat --- techlibs/intel_alm/Makefile.inc | 1 + techlibs/intel_alm/common/megafunction_bb.v | 35 ++++++++++++++++ techlibs/intel_alm/common/misc_sim.v | 12 ++++++ techlibs/intel_alm/common/quartus_rename.v | 44 +++++++++++++++++++++ techlibs/intel_alm/cyclonev/cells_sim.v | 28 ++++++++++--- techlibs/intel_alm/synth_intel_alm.cc | 14 ++++++- tests/arch/intel_alm/add_sub.ys | 4 +- tests/arch/intel_alm/adffs.ys | 16 ++++---- tests/arch/intel_alm/blockram.ys | 2 +- tests/arch/intel_alm/counter.ys | 4 +- tests/arch/intel_alm/dffs.ys | 8 ++-- tests/arch/intel_alm/fsm.ys | 4 +- tests/arch/intel_alm/logic.ys | 4 +- tests/arch/intel_alm/lutram.ys | 4 +- tests/arch/intel_alm/mul.ys | 10 ++--- tests/arch/intel_alm/mux.ys | 12 +++--- tests/arch/intel_alm/quartus_ice.ys | 2 +- tests/arch/intel_alm/shifter.ys | 4 +- tests/arch/intel_alm/tribuf.ys | 4 +- 19 files changed, 166 insertions(+), 46 deletions(-) create mode 100644 techlibs/intel_alm/common/misc_sim.v diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc index da88762c427..614d5802ca9 100644 --- a/techlibs/intel_alm/Makefile.inc +++ b/techlibs/intel_alm/Makefile.inc @@ -13,6 +13,7 @@ $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/df $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_sim.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/mem_sim.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/misc_sim.v)) $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclonev/cells_sim.v)) diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index 874f293b17f..aabcd45391f 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -627,3 +627,38 @@ output [port_b_data_width-1:0] portbdataout; input clk0, portawe, portbre; endmodule + +(* blackbox *) +module cyclone10gx_io_ibuf(i, ibar, dynamicterminationcontrol, o); + +parameter differential_mode ="false"; +parameter bus_hold = "false"; +parameter simulate_z_as = "Z"; +parameter lpm_type = "cyclone10gx_io_ibuf"; + +(* iopad_external_pin *) input i; +(* iopad_external_pin *) input ibar; +input dynamicterminationcontrol; +output o; + +endmodule + +(* blackbox *) +module cyclone10gx_io_obuf(i, oe, dynamicterminationcontrol, seriesterminationcontrol, parallelterminationcontrol, devoe, o, obar); + +parameter open_drain_output = "false"; +parameter bus_hold = "false"; +parameter shift_series_termination_control = "false"; +parameter sim_dynamic_termination_control_is_connected = "false"; +parameter lpm_type = "cyclone10gx_io_obuf"; + +input i; +input oe; +input devoe; +input dynamicterminationcontrol; +input [15:0] seriesterminationcontrol; +input [15:0] parallelterminationcontrol; +(* iopad_external_pin *) output o; +(* iopad_external_pin *) output obar; + +endmodule diff --git a/techlibs/intel_alm/common/misc_sim.v b/techlibs/intel_alm/common/misc_sim.v new file mode 100644 index 00000000000..e9494a8ee09 --- /dev/null +++ b/techlibs/intel_alm/common/misc_sim.v @@ -0,0 +1,12 @@ +module MISTRAL_IB((* iopad_external_pin *) input PAD, output O); + assign O = PAD; +endmodule + +module MISTRAL_OB((* iopad_external_pin *) output PAD, input I); + assign PAD = I; +endmodule + +module MISTRAL_IO((* iopad_external_pin *) inout PAD, input I, input OE, output O); + assign PAD = OE ? I : 1'bz; + assign O = PAD; +endmodule diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v index 3b462867598..964a094ddb3 100644 --- a/techlibs/intel_alm/common/quartus_rename.v +++ b/techlibs/intel_alm/common/quartus_rename.v @@ -2,11 +2,15 @@ `define LCELL cyclonev_lcell_comb `define MAC cyclonev_mac `define MLAB cyclonev_mlab_cell +`define IBUF cyclonev_io_ibuf +`define OBUF cyclonev_io_obuf `endif `ifdef cyclone10gx `define LCELL cyclone10gx_lcell_comb `define MAC cyclone10gx_mac `define MLAB cyclone10gx_mlab_cell +`define IBUF cyclone10gx_io_ibuf +`define OBUF cyclone10gx_io_obuf `endif module __MISTRAL_VCC(output Q); @@ -233,3 +237,43 @@ parameter B_SIGNED = 1; ); endmodule + +module MISTRAL_IB(input PAD, output O); +`IBUF #( + .bus_hold("false"), + .differential_mode("false") +) _TECHMAP_REPLACE_ ( + .i(PAD), + .o(O) +); +endmodule + +module MISTRAL_OB(output PAD, input I, OE); +`OBUF #( + .bus_hold("false"), + .differential_mode("false") +) _TECHMAP_REPLACE_ ( + .i(I), + .o(PAD), + .oe(OE) +); +endmodule + +module MISTRAL_IO(output PAD, input I, OE, output O); +`IBUF #( + .bus_hold("false"), + .differential_mode("false") +) ibuf ( + .i(PAD), + .o(O) +); + +`OBUF #( + .bus_hold("false"), + .differential_mode("false") +) obuf ( + .i(I), + .o(PAD), + .oe(OE) +); +endmodule diff --git a/techlibs/intel_alm/cyclonev/cells_sim.v b/techlibs/intel_alm/cyclonev/cells_sim.v index 9b2a10e72f1..d0a9d9179a2 100644 --- a/techlibs/intel_alm/cyclonev/cells_sim.v +++ b/techlibs/intel_alm/cyclonev/cells_sim.v @@ -26,16 +26,34 @@ endmodule // GND /* Altera Cyclone V devices Input Buffer Primitive */ module cyclonev_io_ibuf - (output o, input i, input ibar); - assign ibar = ibar; + (output o, + (* iopad_external_pin *) input i, + (* iopad_external_pin *) input ibar, + input dynamicterminationcontrol); + + parameter differential_mode = "false"; + parameter bus_hold = "false"; + parameter simulate_z_as = "Z"; + parameter lpm_type = "cyclonev_io_ibuf"; + assign o = i; endmodule // cyclonev_io_ibuf /* Altera Cyclone V devices Output Buffer Primitive */ module cyclonev_io_obuf - (output o, input i, input oe); - assign o = i; - assign oe = oe; + ((* iopad_external_pin *) output o, + input i, oe, dynamicterminationcontrol, + input [15:0] seriesterminationcontrol, parallelterminationcontrol, + input devoe, + (* iopad_external_pin *) output obar); + + parameter open_drain_output = "false"; + parameter bus_hold = "false"; + parameter shift_series_termination_control = "false"; + parameter sim_dynamic_termination_control_is_connected = "false"; + parameter lpm_type = "cyclonev_io_obuf"; + + assign o = oe ? i : 1'bz; endmodule // cyclonev_io_obuf /* Altera Cyclone V LUT Primitive */ diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 11b6d0525a5..7c9e3d117d3 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -72,13 +72,16 @@ struct SynthIntelALMPass : public ScriptPass { log(" -nodsp\n"); log(" do not map multipliers to MISTRAL_MUL cells\n"); log("\n"); + log(" -noiopad\n"); + log(" do not instantiate IO buffers\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, family_opt, bram_type, vout_file; - bool flatten, quartus, nolutram, nobram, dff, nodsp; + bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad; void clear_flags() override { @@ -92,6 +95,7 @@ struct SynthIntelALMPass : public ScriptPass { nobram = false; dff = false; nodsp = false; + noiopad = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -146,6 +150,10 @@ struct SynthIntelALMPass : public ScriptPass { dff = true; continue; } + if (args[argidx] == "-noiopad") { + noiopad = true; + continue; + } break; } extra_args(args, argidx, design); @@ -183,8 +191,8 @@ struct SynthIntelALMPass : public ScriptPass { run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dsp_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str())); + run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/misc_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s -icells +/intel_alm/common/abc9_model.v", family_opt.c_str())); - // Misc and common cells run("read_verilog -lib +/intel/common/altpll_bb.v"); run("read_verilog -lib +/intel_alm/common/megafunction_bb.v"); @@ -231,6 +239,8 @@ struct SynthIntelALMPass : public ScriptPass { } } run("alumacc"); + if (!noiopad) + run("iopadmap -bits -outpad MISTRAL_OB I:PAD -inpad MISTRAL_IB O:PAD -toutpad MISTRAL_IO OE:O:PAD -tinoutpad MISTRAL_IO OE:O:I:PAD A:top", "(unless -noiopad)"); run("techmap -map +/intel_alm/common/arith_alm_map.v -map +/intel_alm/common/dsp_map.v"); run("opt"); run("memory -nomap"); diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys index 0f552a27cb1..a189ada1b84 100644 --- a/tests/arch/intel_alm/add_sub.ys +++ b/tests/arch/intel_alm/add_sub.ys @@ -1,6 +1,6 @@ read_verilog ../common/add_sub.v hierarchy -top top -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat @@ -10,7 +10,7 @@ select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D design -reset read_verilog ../common/add_sub.v hierarchy -top top -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat diff --git a/tests/arch/intel_alm/adffs.ys b/tests/arch/intel_alm/adffs.ys index 4565dcc64bd..7013ebb73ca 100644 --- a/tests/arch/intel_alm/adffs.ys +++ b/tests/arch/intel_alm/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -15,7 +15,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -27,7 +27,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -38,7 +38,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -49,7 +49,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -61,7 +61,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -73,7 +73,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -85,7 +85,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/blockram.ys b/tests/arch/intel_alm/blockram.ys index 610ae1ffdbd..b7c0e9564b0 100644 --- a/tests/arch/intel_alm/blockram.ys +++ b/tests/arch/intel_alm/blockram.ys @@ -1,6 +1,6 @@ read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 10 sync_ram_sdp -synth_intel_alm -family cyclonev +synth_intel_alm -family cyclonev -noiopad cd sync_ram_sdp select -assert-count 1 t:MISTRAL_M10K select -assert-none t:MISTRAL_M10K %% t:* %D diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys index 50103fefc93..98a9e360a44 100644 --- a/tests/arch/intel_alm/counter.ys +++ b/tests/arch/intel_alm/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -17,7 +17,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/dffs.ys b/tests/arch/intel_alm/dffs.ys index 9ae6c637a83..811a5d82f9e 100644 --- a/tests/arch/intel_alm/dffs.ys +++ b/tests/arch/intel_alm/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -13,7 +13,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -24,7 +24,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -35,7 +35,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/fsm.ys b/tests/arch/intel_alm/fsm.ys index e54b5c21e62..96c050bad3b 100644 --- a/tests/arch/intel_alm/fsm.ys +++ b/tests/arch/intel_alm/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad async2sync miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter @@ -26,7 +26,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad async2sync miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys index e8b26a524fb..916c1161c9f 100644 --- a/tests/arch/intel_alm/logic.ys +++ b/tests/arch/intel_alm/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -15,7 +15,7 @@ design -reset read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/lutram.ys b/tests/arch/intel_alm/lutram.ys index 66f8a15362a..c21c9103bbd 100644 --- a/tests/arch/intel_alm/lutram.ys +++ b/tests/arch/intel_alm/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad memory opt -full @@ -24,7 +24,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad memory opt -full diff --git a/tests/arch/intel_alm/mul.ys b/tests/arch/intel_alm/mul.ys index 49934740f1c..10f3f7bf411 100644 --- a/tests/arch/intel_alm/mul.ys +++ b/tests/arch/intel_alm/mul.ys @@ -2,7 +2,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -16,7 +16,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -28,7 +28,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -40,7 +40,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -52,7 +52,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys index ac3b9b08f08..c386542c479 100644 --- a/tests/arch/intel_alm/mux.ys +++ b/tests/arch/intel_alm/mux.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -14,7 +14,7 @@ select -assert-none t:MISTRAL_ALUT3 %% t:* %D design -load read hierarchy -top mux2 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -24,7 +24,7 @@ select -assert-none t:MISTRAL_ALUT3 %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT6 @@ -34,7 +34,7 @@ select -assert-none t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT6 @@ -44,7 +44,7 @@ select -assert-none t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -55,7 +55,7 @@ select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 diff --git a/tests/arch/intel_alm/quartus_ice.ys b/tests/arch/intel_alm/quartus_ice.ys index a88226e13ba..286e6653ca4 100644 --- a/tests/arch/intel_alm/quartus_ice.ys +++ b/tests/arch/intel_alm/quartus_ice.ys @@ -22,5 +22,5 @@ module top(); endmodule EOT -synth_intel_alm -family cyclone10gx -quartus +synth_intel_alm -family cyclone10gx -quartus -noiopad select -assert-none w:*[* w:*]* diff --git a/tests/arch/intel_alm/shifter.ys b/tests/arch/intel_alm/shifter.ys index e307b5486f0..bf19beef1cf 100644 --- a/tests/arch/intel_alm/shifter.ys +++ b/tests/arch/intel_alm/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:MISTRAL_FF @@ -14,7 +14,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/tribuf.ys b/tests/arch/intel_alm/tribuf.ys index 7f3b3849396..8b81c4cd41e 100644 --- a/tests/arch/intel_alm/tribuf.ys +++ b/tests/arch/intel_alm/tribuf.ys @@ -4,7 +4,7 @@ proc tribuf flatten synth -equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclonev -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. @@ -19,7 +19,7 @@ proc tribuf flatten synth -equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. From eb106732d94322fb5b48fbff0420ce5a6fc83eb9 Mon Sep 17 00:00:00 2001 From: gatecat Date: Sat, 15 May 2021 14:34:48 +0100 Subject: [PATCH 0317/2410] intel_alm: Add global buffer insertion Signed-off-by: gatecat --- techlibs/intel_alm/common/dff_sim.v | 4 ++- techlibs/intel_alm/common/megafunction_bb.v | 35 +++++++++++++++++++++ techlibs/intel_alm/common/mem_sim.v | 6 ++-- techlibs/intel_alm/common/misc_sim.v | 9 ++++++ techlibs/intel_alm/common/quartus_rename.v | 16 ++++++++++ techlibs/intel_alm/synth_intel_alm.cc | 12 ++++++- tests/arch/intel_alm/add_sub.ys | 4 +-- tests/arch/intel_alm/adffs.ys | 16 +++++----- tests/arch/intel_alm/blockram.ys | 2 +- tests/arch/intel_alm/counter.ys | 4 +-- tests/arch/intel_alm/dffs.ys | 8 ++--- tests/arch/intel_alm/fsm.ys | 4 +-- tests/arch/intel_alm/logic.ys | 4 +-- tests/arch/intel_alm/lutram.ys | 4 +-- tests/arch/intel_alm/mul.ys | 10 +++--- tests/arch/intel_alm/mux.ys | 16 +++++----- tests/arch/intel_alm/quartus_ice.ys | 2 +- tests/arch/intel_alm/shifter.ys | 4 +-- tests/arch/intel_alm/tribuf.ys | 4 +-- 19 files changed, 119 insertions(+), 45 deletions(-) diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v index d2cff0adb96..6bee994be50 100644 --- a/techlibs/intel_alm/common/dff_sim.v +++ b/techlibs/intel_alm/common/dff_sim.v @@ -56,7 +56,9 @@ (* abc9_box, lib_whitebox *) module MISTRAL_FF( - input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, + input DATAIN, + (* clkbuf_sink *) input CLK, + input ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q ); diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index aabcd45391f..414d1c9410e 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -662,3 +662,38 @@ input [15:0] parallelterminationcontrol; (* iopad_external_pin *) output obar; endmodule + +(* blackbox *) +module cyclonev_clkena(inclk, ena, enaout, outclk); + +parameter clock_type = "auto"; +parameter ena_register_mode = "always enabled"; +parameter lpm_type = "cyclonev_clkena"; +parameter ena_register_power_up = "high"; +parameter disable_mode = "low"; +parameter test_syn = "high"; + +input inclk; +input ena; +output enaout; +output outclk; + +endmodule + +(* blackbox *) +module cyclone10gx_clkena(inclk, ena, enaout, outclk); + +parameter clock_type = "auto"; +parameter ena_register_mode = "always enabled"; +parameter lpm_type = "cyclone10gx_clkena"; +parameter ena_register_power_up = "high"; +parameter disable_mode = "low"; +parameter test_syn = "high"; + +input inclk; +input ena; +output enaout; +output outclk; + +endmodule + diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index e09aafaa2d2..dbdf6983941 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -50,7 +50,9 @@ // model can be treated as always returning a defined result. (* abc9_box, lib_whitebox *) -module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA); +module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, + (* clkbuf_sink *) input CLK1, + input [4:0] B1ADDR, output B1DATA); reg [31:0] mem = 32'b0; @@ -83,7 +85,7 @@ module MISTRAL_M10K(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 10; parameter CFG_DBITS = 10; -input CLK1; +(* clkbuf_sink *) input CLK1; input [CFG_ABITS-1:0] A1ADDR, B1ADDR; input [CFG_DBITS-1:0] A1DATA; input A1EN, B1EN; diff --git a/techlibs/intel_alm/common/misc_sim.v b/techlibs/intel_alm/common/misc_sim.v index e9494a8ee09..b1f970a21f9 100644 --- a/techlibs/intel_alm/common/misc_sim.v +++ b/techlibs/intel_alm/common/misc_sim.v @@ -10,3 +10,12 @@ module MISTRAL_IO((* iopad_external_pin *) inout PAD, input I, input OE, output assign PAD = OE ? I : 1'bz; assign O = PAD; endmodule + +// Eventually, we should support clock enables and model them here too. +// For now, CLKENA is used as a basic entry point to global routing. +module MISTRAL_CLKBUF ( + input A, + (* clkbuf_driver *) output Q +); + assign Q = A; +endmodule \ No newline at end of file diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v index 964a094ddb3..57321de7788 100644 --- a/techlibs/intel_alm/common/quartus_rename.v +++ b/techlibs/intel_alm/common/quartus_rename.v @@ -4,6 +4,7 @@ `define MLAB cyclonev_mlab_cell `define IBUF cyclonev_io_ibuf `define OBUF cyclonev_io_obuf +`define CLKENA cyclonev_clkena `endif `ifdef cyclone10gx `define LCELL cyclone10gx_lcell_comb @@ -11,6 +12,7 @@ `define MLAB cyclone10gx_mlab_cell `define IBUF cyclone10gx_io_ibuf `define OBUF cyclone10gx_io_obuf +`define CLKENA cyclone10gx_clkena `endif module __MISTRAL_VCC(output Q); @@ -277,3 +279,17 @@ module MISTRAL_IO(output PAD, input I, OE, output O); .oe(OE) ); endmodule + +module MISTRAL_CLKBUF (input A, output Q); +`CLKENA #( + .clock_type("auto"), + .ena_register_mode("always enabled"), + .ena_register_power_up("high"), + .disable_mode("low"), + .test_syn("high") +) _TECHMAP_REPLACE_ ( + .inclk(A), + .ena(1'b1), + .outclk(Q) +); +endmodule diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 7c9e3d117d3..d0e84aabd21 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -75,13 +75,16 @@ struct SynthIntelALMPass : public ScriptPass { log(" -noiopad\n"); log(" do not instantiate IO buffers\n"); log("\n"); + log(" -noclkbuf\n"); + log(" do not insert global clock buffers\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, family_opt, bram_type, vout_file; - bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad; + bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad, noclkbuf; void clear_flags() override { @@ -96,6 +99,7 @@ struct SynthIntelALMPass : public ScriptPass { dff = false; nodsp = false; noiopad = false; + noclkbuf = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -154,6 +158,10 @@ struct SynthIntelALMPass : public ScriptPass { noiopad = true; continue; } + if (args[argidx] == "-noclkbuf") { + noclkbuf = true; + continue; + } break; } extra_args(args, argidx, design); @@ -268,6 +276,8 @@ struct SynthIntelALMPass : public ScriptPass { run("techmap -map +/intel_alm/common/dff_map.v"); run("opt -full -undriven -mux_undef"); run("clean -purge"); + if (!noclkbuf) + run("clkbufmap -buf MISTRAL_CLKBUF Q:A", "(unless -noclkbuf)"); } if (check_label("map_luts")) { diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys index a189ada1b84..2d464788bde 100644 --- a/tests/arch/intel_alm/add_sub.ys +++ b/tests/arch/intel_alm/add_sub.ys @@ -1,6 +1,6 @@ read_verilog ../common/add_sub.v hierarchy -top top -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat @@ -10,7 +10,7 @@ select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D design -reset read_verilog ../common/add_sub.v hierarchy -top top -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat diff --git a/tests/arch/intel_alm/adffs.ys b/tests/arch/intel_alm/adffs.ys index 7013ebb73ca..d7487c40bec 100644 --- a/tests/arch/intel_alm/adffs.ys +++ b/tests/arch/intel_alm/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -15,7 +15,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -27,7 +27,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -38,7 +38,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -49,7 +49,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -61,7 +61,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -73,7 +73,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -85,7 +85,7 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/blockram.ys b/tests/arch/intel_alm/blockram.ys index b7c0e9564b0..c157c31656c 100644 --- a/tests/arch/intel_alm/blockram.ys +++ b/tests/arch/intel_alm/blockram.ys @@ -1,6 +1,6 @@ read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 10 sync_ram_sdp -synth_intel_alm -family cyclonev -noiopad +synth_intel_alm -family cyclonev -noiopad -noclkbuf cd sync_ram_sdp select -assert-count 1 t:MISTRAL_M10K select -assert-none t:MISTRAL_M10K %% t:* %D diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys index 98a9e360a44..f2f3f14f7cb 100644 --- a/tests/arch/intel_alm/counter.ys +++ b/tests/arch/intel_alm/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -17,7 +17,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/dffs.ys b/tests/arch/intel_alm/dffs.ys index 811a5d82f9e..34b99f04cbf 100644 --- a/tests/arch/intel_alm/dffs.ys +++ b/tests/arch/intel_alm/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -13,7 +13,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dff proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -24,7 +24,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF @@ -35,7 +35,7 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/fsm.ys b/tests/arch/intel_alm/fsm.ys index 96c050bad3b..0aeea450ac5 100644 --- a/tests/arch/intel_alm/fsm.ys +++ b/tests/arch/intel_alm/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf async2sync miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter @@ -26,7 +26,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf async2sync miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys index 916c1161c9f..d34d1bc65de 100644 --- a/tests/arch/intel_alm/logic.ys +++ b/tests/arch/intel_alm/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -15,7 +15,7 @@ design -reset read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/lutram.ys b/tests/arch/intel_alm/lutram.ys index c21c9103bbd..5d33b8e12d8 100644 --- a/tests/arch/intel_alm/lutram.ys +++ b/tests/arch/intel_alm/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad -noclkbuf memory opt -full @@ -24,7 +24,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram -noiopad -noclkbuf memory opt -full diff --git a/tests/arch/intel_alm/mul.ys b/tests/arch/intel_alm/mul.ys index 10f3f7bf411..e147d93ac1e 100644 --- a/tests/arch/intel_alm/mul.ys +++ b/tests/arch/intel_alm/mul.ys @@ -2,7 +2,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -16,7 +16,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -28,7 +28,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -40,7 +40,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -52,7 +52,7 @@ read_verilog ../common/mul.v chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 hierarchy -top top proc -equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys index c386542c479..6fb6ae80a42 100644 --- a/tests/arch/intel_alm/mux.ys +++ b/tests/arch/intel_alm/mux.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -14,7 +14,7 @@ select -assert-none t:MISTRAL_ALUT3 %% t:* %D design -load read hierarchy -top mux2 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -24,7 +24,7 @@ select -assert-none t:MISTRAL_ALUT3 %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT6 @@ -34,7 +34,7 @@ select -assert-none t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT6 @@ -44,7 +44,7 @@ select -assert-none t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -55,7 +55,7 @@ select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -66,7 +66,7 @@ select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 @@ -78,7 +78,7 @@ select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 diff --git a/tests/arch/intel_alm/quartus_ice.ys b/tests/arch/intel_alm/quartus_ice.ys index 286e6653ca4..4e1896b82a8 100644 --- a/tests/arch/intel_alm/quartus_ice.ys +++ b/tests/arch/intel_alm/quartus_ice.ys @@ -22,5 +22,5 @@ module top(); endmodule EOT -synth_intel_alm -family cyclone10gx -quartus -noiopad +synth_intel_alm -family cyclone10gx -quartus -noiopad -noclkbuf select -assert-none w:*[* w:*]* diff --git a/tests/arch/intel_alm/shifter.ys b/tests/arch/intel_alm/shifter.ys index bf19beef1cf..77ff9889658 100644 --- a/tests/arch/intel_alm/shifter.ys +++ b/tests/arch/intel_alm/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:MISTRAL_FF @@ -14,7 +14,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:MISTRAL_FF diff --git a/tests/arch/intel_alm/tribuf.ys b/tests/arch/intel_alm/tribuf.ys index 8b81c4cd41e..fb5fecb7855 100644 --- a/tests/arch/intel_alm/tribuf.ys +++ b/tests/arch/intel_alm/tribuf.ys @@ -4,7 +4,7 @@ proc tribuf flatten synth -equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclonev -noiopad # equivalency check +equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. @@ -19,7 +19,7 @@ proc tribuf flatten synth -equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx -noiopad # equivalency check +equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. From 34a08750fa1a490be09411b07f64f4236eff234e Mon Sep 17 00:00:00 2001 From: gatecat Date: Sat, 15 May 2021 14:40:37 +0100 Subject: [PATCH 0318/2410] intel_alm: Fix illegal carry chains Signed-off-by: gatecat --- techlibs/intel_alm/common/alm_sim.v | 6 ++++-- techlibs/intel_alm/common/arith_alm_map.v | 2 +- tests/arch/intel_alm/add_sub.ys | 4 ++-- tests/arch/intel_alm/counter.ys | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index 906a95b0b6c..6e70be86529 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -230,8 +230,10 @@ assign Q = ~A; endmodule -(* abc9_box, lib_whitebox *) -module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO); +// Despite the abc9_carry attributes, this doesn't seem to stop ABC9 adding illegal fanout to the carry chain that nextpnr cannot handle. +// So we treat it as a total blackbox from ABC9's perspective for now. +// (* abc9_box, lib_whitebox *) +module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, /* (* abc9_carry *) */ input CI, output SO, /* (* abc9_carry *) */ output CO); parameter LUT0 = 16'h0000; parameter LUT1 = 16'h0000; diff --git a/techlibs/intel_alm/common/arith_alm_map.v b/techlibs/intel_alm/common/arith_alm_map.v index 8515eeb5625..7cbf02e9c54 100644 --- a/techlibs/intel_alm/common/arith_alm_map.v +++ b/techlibs/intel_alm/common/arith_alm_map.v @@ -34,7 +34,7 @@ wire [Y_WIDTH:0] ALM_CARRY; // Start of carry chain generate - if (_TECHMAP_CONSTMSK_CI_ == 1) begin + if (_TECHMAP_CONSTMSK_CI_ == 1 && _TECHMAP_CONSTVAL_CI_ == 1'b0) begin assign ALM_CARRY[0] = _TECHMAP_CONSTVAL_CI_; end else begin MISTRAL_ALUT_ARITH #( diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys index 2d464788bde..8f87adf2713 100644 --- a/tests/arch/intel_alm/add_sub.ys +++ b/tests/arch/intel_alm/add_sub.ys @@ -4,7 +4,7 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat -select -assert-count 8 t:MISTRAL_ALUT_ARITH +select -assert-count 9 t:MISTRAL_ALUT_ARITH select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D design -reset @@ -14,5 +14,5 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module stat -select -assert-count 8 t:MISTRAL_ALUT_ARITH +select -assert-count 9 t:MISTRAL_ALUT_ARITH select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys index f2f3f14f7cb..56c9cabb38a 100644 --- a/tests/arch/intel_alm/counter.ys +++ b/tests/arch/intel_alm/counter.ys @@ -6,7 +6,7 @@ equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/ design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 2 t:MISTRAL_NOT +select -assert-count 1 t:MISTRAL_NOT select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D @@ -21,7 +21,7 @@ equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/ design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 2 t:MISTRAL_NOT +select -assert-count 1 t:MISTRAL_NOT select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D From d8c5d6815cc80af852ce0969e4cf775f44539c80 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 17 May 2021 10:24:30 +0200 Subject: [PATCH 0319/2410] Visual Studio build action --- .github/workflows/vs.yml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/vs.yml diff --git a/.github/workflows/vs.yml b/.github/workflows/vs.yml new file mode 100644 index 00000000000..12b0cf00340 --- /dev/null +++ b/.github/workflows/vs.yml @@ -0,0 +1,40 @@ +name: Visual Studio Build + +on: + workflow_dispatch: + +jobs: + yosys-vcxsrc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: 'master' + - name: Cache sources + id: cache-sources + uses: actions/cache@v2 + with: + path: . + key: cache-yosys + - name: Build + run: make vcxsrc YOSYS_VER=latest + - uses: actions/upload-artifact@v2 + with: + name: vcxsrc + path: yosys-win32-vcxsrc-latest.zip + + build: + runs-on: windows-latest + needs: yosys-vcxsrc + steps: + - uses: actions/download-artifact@v2 + with: + name: vcxsrc + path: . + - name: unzip + run: unzip yosys-win32-vcxsrc-latest.zip + - name: setup-msbuild + uses: microsoft/setup-msbuild@v1 + - name: MSBuild + working-directory: yosys-win32-vcxsrc-latest + run: msbuild YosysVS.sln /p:PlatformToolset=v142 /p:Configuration=Release /p:WindowsTargetPlatformVersion=10.0.17763.0 From 4240498f71e61dbb57668ef31be67ef5ad7e574a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 20 May 2021 12:49:51 +0200 Subject: [PATCH 0320/2410] tests/blif: Add missing gitignore --- tests/blif/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/blif/.gitignore diff --git a/tests/blif/.gitignore b/tests/blif/.gitignore new file mode 100644 index 00000000000..397b4a7624e --- /dev/null +++ b/tests/blif/.gitignore @@ -0,0 +1 @@ +*.log From 25de8faf10157ab0cb40f77c7cbf3143527c598e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 20 May 2021 12:50:32 +0200 Subject: [PATCH 0321/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ff62aca2562..b8ef9343a5f 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4052 +YOSYS_VER := 0.9+4081 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 9420bde09f425293dbb6bd2ad5f46ae1bd7e1373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Thu, 20 May 2021 19:21:34 +0200 Subject: [PATCH 0322/2410] Run VS build on PRs and each push --- .github/workflows/vs.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/vs.yml b/.github/workflows/vs.yml index 12b0cf00340..a48821cf803 100644 --- a/.github/workflows/vs.yml +++ b/.github/workflows/vs.yml @@ -1,15 +1,12 @@ name: Visual Studio Build -on: - workflow_dispatch: +on: [push, pull_request] jobs: yosys-vcxsrc: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - with: - ref: 'master' - name: Cache sources id: cache-sources uses: actions/cache@v2 From 8c734e07b87974fc4931d41b37b459d2c664e1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 23 Oct 2020 17:48:00 +0200 Subject: [PATCH 0323/2410] memory_dff: Use Mem helper. --- passes/memory/memory_dff.cc | 45 +++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 83c9d76312f..3698092b444 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -21,6 +21,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -210,16 +211,17 @@ struct MemoryDffWorker } } - void handle_rd_cell(RTLIL::Cell *cell) + void handle_rd_port(Mem &mem, int idx) { - log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str()); + auto &port = mem.rd_ports[idx]; + log("Checking read port `%s'[%d] in module `%s': ", mem.memid.c_str(), idx, module->name.c_str()); bool clk_polarity = 0; bool en_polarity = 0; RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); RTLIL::SigSpec en_data; - RTLIL::SigSpec sig_data = cell->getPort(ID::DATA); + RTLIL::SigSpec sig_data = port.data; for (auto bit : sigmap(sig_data)) if (sigbit_users_count[bit] > 1) @@ -230,28 +232,30 @@ struct MemoryDffWorker if (!en_polarity) en_data = module->LogicNot(NEW_ID, en_data); disconnect_dff(sig_data); - cell->setPort(ID::CLK, clk_data); - cell->setPort(ID::EN, en_data); - cell->setPort(ID::DATA, sig_data); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); - cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0); + port.clk = clk_data; + port.en = en_data; + port.data = sig_data; + port.clk_enable = true; + port.clk_polarity = clk_polarity; + port.transparent = false; + mem.emit(); log("merged data $dff to cell.\n"); return; } skip_ff_after_read_merging:; RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR); + RTLIL::SigSpec sig_addr = port.addr; if (find_sig_before_dff(sig_addr, clk_addr, clk_polarity) && clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->setPort(ID::CLK, clk_addr); - cell->setPort(ID::EN, State::S1); - cell->setPort(ID::ADDR, sig_addr); - cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); - cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); - cell->parameters[ID::TRANSPARENT] = RTLIL::Const(1); + port.clk = clk_addr; + port.en = State::S1; + port.addr = sig_addr; + port.clk_enable = true; + port.clk_polarity = clk_polarity; + port.transparent = true; + mem.emit(); log("merged address $dff to cell.\n"); return; } @@ -286,9 +290,12 @@ struct MemoryDffWorker sigbit_users_count[bit]++; } - for (auto cell : module->selected_cells()) - if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool()) - handle_rd_cell(cell); + for (auto &mem : Mem::get_selected_memories(module)) { + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + if (!mem.rd_ports[i].clk_enable) + handle_rd_port(mem, i); + } + } } }; From ff9e0394b86f701db17ceda48bf8075ce8ac597d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 16:10:18 +0200 Subject: [PATCH 0324/2410] kernel/mem: defer port removal to emit() --- kernel/mem.cc | 48 ++++++++++++++++++++++++++++++++++-------------- kernel/mem.h | 8 ++++---- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 0301a913c42..9d68dbbb742 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -52,6 +52,40 @@ void Mem::remove() { } void Mem::emit() { + std::vector rd_left; + for (int i = 0; i < GetSize(rd_ports); i++) { + auto &port = rd_ports[i]; + if (port.removed) { + if (port.cell) { + module->remove(port.cell); + } + } else { + rd_left.push_back(i); + } + } + std::vector wr_left; + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &port = wr_ports[i]; + if (port.removed) { + if (port.cell) { + module->remove(port.cell); + } + } else { + wr_left.push_back(i); + } + } + for (int i = 0; i < GetSize(rd_left); i++) + if (i != rd_left[i]) + std::swap(rd_ports[i], rd_ports[rd_left[i]]); + rd_ports.resize(GetSize(rd_left)); + for (int i = 0; i < GetSize(wr_left); i++) + if (i != wr_left[i]) + std::swap(wr_ports[i], wr_ports[wr_left[i]]); + wr_ports.resize(GetSize(wr_left)); + + // for future: handle transparency mask here + // for future: handle priority mask here + if (packed) { if (mem) { module->memories.erase(mem->name); @@ -205,20 +239,6 @@ void Mem::emit() { } } -void Mem::remove_wr_port(int idx) { - if (wr_ports[idx].cell) { - module->remove(wr_ports[idx].cell); - } - wr_ports.erase(wr_ports.begin() + idx); -} - -void Mem::remove_rd_port(int idx) { - if (rd_ports[idx].cell) { - module->remove(rd_ports[idx].cell); - } - rd_ports.erase(rd_ports.begin() + idx); -} - void Mem::clear_inits() { for (auto &init : inits) if (init.cell) diff --git a/kernel/mem.h b/kernel/mem.h index 6d727e71d1a..547386f3cb8 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -25,20 +25,22 @@ YOSYS_NAMESPACE_BEGIN struct MemRd { + bool removed; dict attributes; Cell *cell; bool clk_enable, clk_polarity; bool transparent; SigSpec clk, en, addr, data; - MemRd() : cell(nullptr) {} + MemRd() : removed(false), cell(nullptr) {} }; struct MemWr { + bool removed; dict attributes; Cell *cell; bool clk_enable, clk_polarity; SigSpec clk, en, addr, data; - MemWr() : cell(nullptr) {} + MemWr() : removed(false), cell(nullptr) {} }; struct MemInit { @@ -63,8 +65,6 @@ struct Mem { void remove(); void emit(); - void remove_wr_port(int idx); - void remove_rd_port(int idx); void clear_inits(); Const get_init_data() const; static std::vector get_all_memories(Module *module); From c7076495f197732725456992c9a02aed9966139a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 16:36:50 +0200 Subject: [PATCH 0325/2410] kernel/mem: Add a check() function. --- kernel/mem.cc | 25 +++++++++++++++++++++++++ kernel/mem.h | 1 + 2 files changed, 26 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index 9d68dbbb742..7d20833e543 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -52,6 +52,7 @@ void Mem::remove() { } void Mem::emit() { + check(); std::vector rd_left; for (int i = 0; i < GetSize(rd_ports); i++) { auto &port = rd_ports[i]; @@ -257,6 +258,27 @@ Const Mem::get_init_data() const { return init_data; } +void Mem::check() { + for (auto &port : rd_ports) { + if (port.removed) + continue; + log_assert(GetSize(port.clk) == 1); + log_assert(GetSize(port.en) == 1); + log_assert(GetSize(port.data) == width); + if (!port.clk_enable) { + log_assert(!port.transparent); + } + } + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &port = wr_ports[i]; + if (port.removed) + continue; + log_assert(GetSize(port.clk) == 1); + log_assert(GetSize(port.en) == width); + log_assert(GetSize(port.data) == width); + } +} + namespace { struct MemIndex { @@ -333,6 +355,7 @@ namespace { for (auto &it : inits) res.inits.push_back(it.second); } + res.check(); return res; } @@ -389,6 +412,7 @@ namespace { mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, res.width); res.wr_ports.push_back(mwr); } + res.check(); return res; } @@ -451,6 +475,7 @@ Cell *Mem::extract_rdff(int idx) { port.clk = State::S0; port.clk_enable = false; port.clk_polarity = true; + port.transparent = false; return c; } diff --git a/kernel/mem.h b/kernel/mem.h index 547386f3cb8..f5c7b641ffa 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -66,6 +66,7 @@ struct Mem { void remove(); void emit(); void clear_inits(); + void check(); Const get_init_data() const; static std::vector get_all_memories(Module *module); static std::vector get_selected_memories(Module *module); From c4cc888b2c51a6507b73fdcde1dc61c37384105d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 19:14:13 +0200 Subject: [PATCH 0326/2410] kernel/rtlil: Extract some helpers for checking memory cell types. There will soon be more (versioned) memory cells, so handle passes that only care if a cell is memory-related by a simple helper call instead of a hardcoded list. --- backends/btor/btor.cc | 2 +- backends/smt2/smt2.cc | 4 ++-- backends/verilog/verilog_backend.cc | 2 +- kernel/rtlil.cc | 10 ++++++++++ kernel/rtlil.h | 3 +++ passes/cmds/delete.cc | 2 +- passes/sat/sim.cc | 2 +- passes/techmap/abc9_ops.cc | 17 +---------------- passes/techmap/flatten.cc | 4 ++-- passes/techmap/techmap.cc | 6 ++---- 10 files changed, 24 insertions(+), 28 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 692452aad5b..936cb20fb63 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -708,7 +708,7 @@ struct BtorWorker goto okay; } - if (cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) + if (cell->is_mem_cell()) { Mem *mem = mem_cells[cell]; diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 8be9e05f11e..e0f43d6865d 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -182,7 +182,7 @@ struct Smt2Worker continue; // Handled above. - if (cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) { + if (cell->is_mem_cell()) { mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; continue; } @@ -694,7 +694,7 @@ struct Smt2Worker // FIXME: $slice $concat } - if (memmode && cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) + if (memmode && cell->is_mem_cell()) { Mem *mem = mem_cells[cell]; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 165ce1ea4b3..cfdc0316ad9 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1464,7 +1464,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) { // Handled by dump_memory - if (cell->type.in(ID($mem), ID($memwr), ID($memrd), ID($meminit))) + if (cell->is_mem_cell()) return; if (cell->type[0] == '$' && !noexpr) { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7704057206e..f9ae947b634 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3125,6 +3125,16 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) check(); } +bool RTLIL::Cell::has_memid() const +{ + return type.in(ID($memwr), ID($memrd), ID($meminit)); +} + +bool RTLIL::Cell::is_mem_cell() const +{ + return type == ID($mem) || has_memid(); +} + RTLIL::SigChunk::SigChunk() { wire = NULL; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3137deb00c8..2f06690d1f5 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1522,6 +1522,9 @@ struct RTLIL::Cell : public RTLIL::AttrObject #ifdef WITH_PYTHON static std::map *get_all_cells(void); #endif + + bool has_memid() const; + bool is_mem_cell() const; }; struct RTLIL::CaseRule : public RTLIL::AttrObject diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 684fa37b047..2855f0cdc1b 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -103,7 +103,7 @@ struct DeletePass : public Pass { for (auto cell : module->cells()) { if (design->selected(module, cell)) delete_cells.insert(cell); - if (cell->type.in(ID($memrd), ID($memwr)) && + if (cell->has_memid() && delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0) delete_cells.insert(cell); } diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 922be886c0a..2e7a92cecfd 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -164,7 +164,7 @@ struct SimInstance ff_database[cell] = ff; } - if (cell->type.in(ID($mem), ID($meminit), ID($memwr), ID($memrd))) + if (cell->is_mem_cell()) { mem_cells[cell] = cell->parameters.at(ID::MEMID).decode_string(); } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 6e18cb5f697..edb52901012 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -155,21 +155,6 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) r.first->second = new Design; Design *unmap_design = r.first->second; - static const pool seq_types{ - ID($dff), ID($dffsr), ID($adff), - ID($dlatch), ID($dlatchsr), ID($sr), - ID($mem), - ID($_DFF_N_), ID($_DFF_P_), - ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), - ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - ID($_DLATCH_N_), ID($_DLATCH_P_), - ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), - ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), - ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_) - }; - for (auto module : design->selected_modules()) for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); @@ -221,7 +206,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) } else if (derived_module->get_bool_attribute(ID::abc9_box)) { for (auto derived_cell : derived_module->cells()) - if (seq_types.count(derived_cell->type)) { + if (derived_cell->is_mem_cell() || RTLIL::builtin_ff_cell_types().count(derived_cell->type)) { derived_module->set_bool_attribute(ID::abc9_box, false); derived_module->set_bool_attribute(ID::abc9_bypass); break; diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 0509eedb870..35257273ce6 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -133,10 +133,10 @@ struct FlattenWorker for (auto tpl_cell : tpl->cells()) { RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell), tpl_cell); map_attributes(cell, new_cell, tpl_cell->name); - if (new_cell->type.in(ID($memrd), ID($memwr), ID($meminit))) { + if (new_cell->has_memid()) { IdString memid = new_cell->getParam(ID::MEMID).decode_string(); new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str())); - } else if (new_cell->type == ID($mem)) { + } else if (new_cell->is_mem_cell()) { IdString memid = new_cell->getParam(ID::MEMID).decode_string(); new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid).str())); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 96843d7108d..1f9a89aec95 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -364,13 +364,11 @@ struct TechmapWorker for (auto &it2 : autopurge_ports) c->unsetPort(it2); - if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) { + if (c->has_memid()) { IdString memid = c->getParam(ID::MEMID).decode_string(); log_assert(memory_renames.count(memid) != 0); c->setParam(ID::MEMID, Const(memory_renames[memid].str())); - } - - if (c->type == ID($mem)) { + } else if (c->is_mem_cell()) { IdString memid = c->getParam(ID::MEMID).decode_string(); apply_prefix(cell->name, memid); c->setParam(ID::MEMID, Const(memid.c_str())); From 039f4f48d55609f254850112a948f26e66550095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 20:19:00 +0200 Subject: [PATCH 0327/2410] memory_memx: Use Mem helper. --- passes/memory/memory_memx.cc | 73 +++++++++++++++--------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 02e00cf3031..11bbe75cce3 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -17,11 +17,8 @@ * */ -#include "kernel/register.h" -#include "kernel/log.h" -#include -#include -#include +#include "kernel/yosys.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -38,53 +35,45 @@ struct MemoryMemxPass : public Pass { log("behavior for out-of-bounds memory reads and writes.\n"); log("\n"); } + + SigSpec make_addr_check(Mem &mem, SigSpec addr) { + int start_addr = mem.start_offset; + int end_addr = mem.start_offset + mem.size; + + addr.extend_u0(32); + + SigSpec res = mem.module->Nex(NEW_ID, mem.module->ReduceXor(NEW_ID, addr), mem.module->ReduceXor(NEW_ID, {addr, State::S1})); + if (start_addr != 0) + res = mem.module->LogicAnd(NEW_ID, res, mem.module->Ge(NEW_ID, addr, start_addr)); + res = mem.module->LogicAnd(NEW_ID, res, mem.module->Lt(NEW_ID, addr, end_addr)); + return res; + } + void execute(std::vector args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_MEMX pass (converting $mem cells to logic and flip-flops).\n"); extra_args(args, 1, design); for (auto module : design->selected_modules()) + for (auto &mem : Mem::get_selected_memories(module)) { - vector mem_port_cells; - - for (auto cell : module->selected_cells()) - if (cell->type.in(ID($memrd), ID($memwr))) - mem_port_cells.push_back(cell); - - for (auto cell : mem_port_cells) + for (auto &port : mem.rd_ports) { - IdString memid = cell->getParam(ID::MEMID).decode_string(); - RTLIL::Memory *mem = module->memories.at(memid); + if (port.clk_enable) + log_error("Memory %s.%s has a synchronous read port. Synchronous read ports are not supported by memory_memx!\n", + log_id(module), log_id(mem.memid)); - int lowest_addr = mem->start_offset; - int highest_addr = mem->start_offset + mem->size - 1; - - SigSpec addr = cell->getPort(ID::ADDR); - addr.extend_u0(32); - - SigSpec addr_ok = module->Nex(NEW_ID, module->ReduceXor(NEW_ID, addr), module->ReduceXor(NEW_ID, {addr, State::S1})); - if (lowest_addr != 0) - addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Ge(NEW_ID, addr, lowest_addr)); - addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Le(NEW_ID, addr, highest_addr)); - - if (cell->type == ID($memrd)) - { - if (cell->getParam(ID::CLK_ENABLE).as_bool()) - log_error("Cell %s.%s (%s) has an enabled clock. Clocked $memrd cells are not supported by memory_memx!\n", - log_id(module), log_id(cell), log_id(cell->type)); - - SigSpec rdata = cell->getPort(ID::DATA); - Wire *raw_rdata = module->addWire(NEW_ID, GetSize(rdata)); - module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(rdata)), raw_rdata, addr_ok, rdata); - cell->setPort(ID::DATA, raw_rdata); - } + SigSpec addr_ok = make_addr_check(mem, port.addr); + Wire *raw_rdata = module->addWire(NEW_ID, GetSize(port.data)); + module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(port.data)), raw_rdata, addr_ok, port.data); + port.data = raw_rdata; + } - if (cell->type == ID($memwr)) - { - SigSpec en = cell->getPort(ID::EN); - en = module->And(NEW_ID, en, addr_ok.repeat(GetSize(en))); - cell->setPort(ID::EN, en); - } + for (auto &port : mem.wr_ports) { + SigSpec addr_ok = make_addr_check(mem, port.addr); + port.en = module->And(NEW_ID, port.en, addr_ok.repeat(GetSize(port.en))); } + + mem.emit(); } } } MemoryMemxPass; From a23d9409e7d04fcfa31a139d0cf6169be4c46fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 20:27:51 +0200 Subject: [PATCH 0328/2410] opt_mem: Remove write ports with const-0 EN. Fixes #2765. --- passes/opt/opt_mem.cc | 12 ++++++++++++ tests/opt/bug2765.ys | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tests/opt/bug2765.ys diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 49a0ac51a0c..0409fb736f4 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -52,6 +52,18 @@ struct OptMemPass : public Pass { int total_count = 0; for (auto module : design->selected_modules()) { for (auto &mem : Mem::get_selected_memories(module)) { + bool changed = false; + for (auto &port : mem.wr_ports) { + if (port.en.is_fully_zero()) { + port.removed = true; + changed = true; + total_count++; + } + } + if (changed) { + mem.emit(); + } + if (mem.wr_ports.empty() && mem.inits.empty()) { mem.remove(); total_count++; diff --git a/tests/opt/bug2765.ys b/tests/opt/bug2765.ys new file mode 100644 index 00000000000..de670c2d1a0 --- /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 +opt_mem +select -assert-count 1 t:$memwr From 1eea06bcc0750de02a460f3e949df2f68f800382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 15 Mar 2021 15:38:45 +0100 Subject: [PATCH 0329/2410] Add new helper class for merging FFs into cells, use for memory_dff. Fixes #1854. --- Makefile | 2 +- kernel/ff.h | 2 +- kernel/ffinit.h | 1 - kernel/ffmerge.cc | 332 +++++++++++++++++++++++++++++++++++ kernel/ffmerge.h | 141 +++++++++++++++ passes/memory/memory_dff.cc | 341 +++++++++++------------------------- tests/opt/bug1854.ys | 17 ++ 7 files changed, 596 insertions(+), 240 deletions(-) create mode 100644 kernel/ffmerge.cc create mode 100644 kernel/ffmerge.h create mode 100644 tests/opt/bug1854.ys diff --git a/Makefile b/Makefile index b8ef9343a5f..b35a11d531c 100644 --- a/Makefile +++ b/Makefile @@ -622,7 +622,7 @@ ifneq ($(ABCEXTERNAL),) kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' endif endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/mem.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/mem.o kernel/ffmerge.o kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' diff --git a/kernel/ff.h b/kernel/ff.h index 0aecbaa2aac..3e83db678bb 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -57,7 +57,7 @@ struct FfData { int width; dict attributes; - FfData(FfInitVals *initvals, Cell *cell = nullptr) : initvals(initvals) { + FfData(FfInitVals *initvals = nullptr, Cell *cell = nullptr) : initvals(initvals) { width = 0; has_d = true; has_clk = false; diff --git a/kernel/ffinit.h b/kernel/ffinit.h index 025b0c8626d..9d33ac572d3 100644 --- a/kernel/ffinit.h +++ b/kernel/ffinit.h @@ -28,7 +28,6 @@ YOSYS_NAMESPACE_BEGIN struct FfInitVals { const SigMap *sigmap; - RTLIL::Module *module; dict> initbits; void set(const SigMap *sigmap_, RTLIL::Module *module) diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc new file mode 100644 index 00000000000..6a29acc960c --- /dev/null +++ b/kernel/ffmerge.cc @@ -0,0 +1,332 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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/ffmerge.h" + +USING_YOSYS_NAMESPACE + +bool FfMergeHelper::is_output_unused(RTLIL::SigSpec sig) { + for (auto bit : (*sigmap)(sig)) + if (sigbit_users_count[bit] != 0) + return false; + return true; +} + +bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { + ff = FfData(); + sigmap->apply(sig); + + bool found = false; + + for (auto bit : sig) + { + if (bit.wire == NULL || sigbit_users_count[bit] == 0) { + ff.width++; + ff.sig_q.append(bit); + ff.sig_d.append(bit); + ff.sig_clr.append(State::Sx); + ff.sig_set.append(State::Sx); + ff.val_init.bits.push_back(State::Sx); + ff.val_srst.bits.push_back(State::Sx); + ff.val_arst.bits.push_back(State::Sx); + continue; + } + + if (sigbit_users_count[bit] != 1) + return false; + + auto &sinks = dff_sink[bit]; + if (sinks.size() != 1) + return false; + + Cell *cell; + int idx; + std::tie(cell, idx) = *sinks.begin(); + bits.insert(std::make_pair(cell, idx)); + + FfData cur_ff(initvals, cell); + + log_assert(cur_ff.has_d); + log_assert((*sigmap)(cur_ff.sig_d[idx]) == bit); + + if (!found) { + ff.sig_clk = cur_ff.sig_clk; + ff.sig_en = cur_ff.sig_en; + ff.sig_srst = cur_ff.sig_srst; + ff.sig_arst = cur_ff.sig_arst; + ff.has_clk = cur_ff.has_clk; + ff.has_en = cur_ff.has_en; + ff.has_srst = cur_ff.has_srst; + ff.has_arst = cur_ff.has_arst; + ff.has_sr = cur_ff.has_sr; + ff.ce_over_srst = cur_ff.ce_over_srst; + ff.pol_clk = cur_ff.pol_clk; + ff.pol_en = cur_ff.pol_en; + ff.pol_arst = cur_ff.pol_arst; + ff.pol_srst = cur_ff.pol_srst; + ff.pol_clr = cur_ff.pol_clr; + ff.pol_set = cur_ff.pol_set; + } else { + if (ff.has_clk != cur_ff.has_clk) + return false; + if (ff.has_en != cur_ff.has_en) + return false; + if (ff.has_srst != cur_ff.has_srst) + return false; + if (ff.has_arst != cur_ff.has_arst) + return false; + if (ff.has_sr != cur_ff.has_sr) + return false; + if (ff.has_clk) { + if (ff.sig_clk != cur_ff.sig_clk) + return false; + if (ff.pol_clk != cur_ff.pol_clk) + return false; + } + if (ff.has_en) { + if (ff.sig_en != cur_ff.sig_en) + return false; + if (ff.pol_en != cur_ff.pol_en) + return false; + } + if (ff.has_srst) { + if (ff.sig_srst != cur_ff.sig_srst) + return false; + if (ff.pol_srst != cur_ff.pol_srst) + return false; + if (ff.has_en && ff.ce_over_srst != cur_ff.ce_over_srst) + return false; + } + if (ff.has_arst) { + if (ff.sig_arst != cur_ff.sig_arst) + return false; + if (ff.pol_arst != cur_ff.pol_arst) + return false; + } + if (ff.has_sr) { + if (ff.pol_clr != cur_ff.pol_clr) + return false; + if (ff.pol_set != cur_ff.pol_set) + return false; + } + } + + ff.width++; + ff.sig_d.append(cur_ff.sig_d[idx]); + ff.sig_q.append(cur_ff.sig_q[idx]); + ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0); + ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0); + ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); + ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); + ff.val_init.bits.push_back(cur_ff.val_init[idx]); + found = true; + } + + return found; +} + +bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { + ff = FfData(); + sigmap->apply(sig); + + bool found = false; + + pool const_bits; + + for (auto bit : sig) + { + if (bit.wire == NULL) { + const_bits.insert(ff.width); + ff.width++; + ff.sig_q.append(bit); + ff.sig_d.append(bit); + // These two will be fixed up later. + ff.sig_clr.append(State::Sx); + ff.sig_set.append(State::Sx); + ff.val_init.bits.push_back(bit.data); + ff.val_srst.bits.push_back(bit.data); + ff.val_arst.bits.push_back(bit.data); + continue; + } + + if (!dff_driver.count(bit)) + return false; + + Cell *cell; + int idx; + std::tie(cell, idx) = dff_driver[bit]; + bits.insert(std::make_pair(cell, idx)); + + FfData cur_ff(initvals, cell); + + log_assert((*sigmap)(cur_ff.sig_q[idx]) == bit); + + if (!found) { + ff.sig_clk = cur_ff.sig_clk; + ff.sig_en = cur_ff.sig_en; + ff.sig_srst = cur_ff.sig_srst; + ff.sig_arst = cur_ff.sig_arst; + ff.has_d = cur_ff.has_d; + ff.has_clk = cur_ff.has_clk; + ff.has_en = cur_ff.has_en; + ff.has_srst = cur_ff.has_srst; + ff.has_arst = cur_ff.has_arst; + ff.has_sr = cur_ff.has_sr; + ff.ce_over_srst = cur_ff.ce_over_srst; + ff.pol_clk = cur_ff.pol_clk; + ff.pol_en = cur_ff.pol_en; + ff.pol_arst = cur_ff.pol_arst; + ff.pol_srst = cur_ff.pol_srst; + ff.pol_clr = cur_ff.pol_clr; + ff.pol_set = cur_ff.pol_set; + } else { + if (ff.has_d != cur_ff.has_d) + return false; + if (ff.has_clk != cur_ff.has_clk) + return false; + if (ff.has_en != cur_ff.has_en) + return false; + if (ff.has_srst != cur_ff.has_srst) + return false; + if (ff.has_arst != cur_ff.has_arst) + return false; + if (ff.has_sr != cur_ff.has_sr) + return false; + if (ff.has_clk) { + if (ff.sig_clk != cur_ff.sig_clk) + return false; + if (ff.pol_clk != cur_ff.pol_clk) + return false; + } + if (ff.has_en) { + if (ff.sig_en != cur_ff.sig_en) + return false; + if (ff.pol_en != cur_ff.pol_en) + return false; + } + if (ff.has_srst) { + if (ff.sig_srst != cur_ff.sig_srst) + return false; + if (ff.pol_srst != cur_ff.pol_srst) + return false; + if (ff.has_en && ff.ce_over_srst != cur_ff.ce_over_srst) + return false; + } + if (ff.has_arst) { + if (ff.sig_arst != cur_ff.sig_arst) + return false; + if (ff.pol_arst != cur_ff.pol_arst) + return false; + } + if (ff.has_sr) { + if (ff.pol_clr != cur_ff.pol_clr) + return false; + if (ff.pol_set != cur_ff.pol_set) + return false; + } + } + + ff.width++; + ff.sig_d.append(ff.has_d ? cur_ff.sig_d[idx] : State::Sx); + ff.sig_q.append(cur_ff.sig_q[idx]); + ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0); + ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0); + ff.val_arst.bits.push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx); + ff.val_srst.bits.push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx); + ff.val_init.bits.push_back(cur_ff.val_init[idx]); + found = true; + } + + if (found && ff.has_sr) { + for (auto i: const_bits) { + if (ff.sig_d[i] == State::S0) { + ff.sig_set[i] = ff.pol_set ? State::S0 : State::S1; + } else if (ff.sig_d[i] == State::S1) { + ff.sig_clr[i] = ff.pol_clr ? State::S0 : State::S1; + } + } + } + + return found; +} + + +void FfMergeHelper::remove_output_ff(const pool> &bits) { + for (auto &it : bits) { + Cell *cell = it.first; + int idx = it.second; + SigSpec q = cell->getPort(ID::Q); + initvals->remove_init(q[idx]); + dff_driver.erase((*sigmap)(q[idx])); + q[idx] = module->addWire(stringf("$ffmerge_disconnected$%d", autoidx++)); + cell->setPort(ID::Q, q); + } +} + +void FfMergeHelper::mark_input_ff(const pool> &bits) { + for (auto &it : bits) { + Cell *cell = it.first; + int idx = it.second; + if (cell->hasPort(ID::D)) { + SigSpec d = cell->getPort(ID::D); + // The user count was already at least 1 + // (for the D port). Bump it as it is now connected + // to the merged-to cell as well. This suffices for + // it to not be considered for output merging. + sigbit_users_count[d[idx]]++; + } + } +} + +void FfMergeHelper::set(FfInitVals *initvals_, RTLIL::Module *module_) +{ + clear(); + initvals = initvals_; + sigmap = initvals->sigmap; + module = module_; + + for (auto wire : module->wires()) { + if (wire->port_output) + for (auto bit : (*sigmap)(wire)) + sigbit_users_count[bit]++; + } + + for (auto cell : module->cells()) { + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + if (cell->hasPort(ID::D)) { + SigSpec d = (*sigmap)(cell->getPort(ID::D)); + for (int i = 0; i < GetSize(d); i++) + dff_sink[d[i]].insert(std::make_pair(cell, i)); + } + SigSpec q = (*sigmap)(cell->getPort(ID::Q)); + for (int i = 0; i < GetSize(q); i++) + dff_driver[q[i]] = std::make_pair(cell, i); + } + for (auto &conn : cell->connections()) + if (!cell->known() || cell->input(conn.first)) + for (auto bit : (*sigmap)(conn.second)) + sigbit_users_count[bit]++; + } +} + +void FfMergeHelper::clear() { + dff_driver.clear(); + dff_sink.clear(); + sigbit_users_count.clear(); +} diff --git a/kernel/ffmerge.h b/kernel/ffmerge.h new file mode 100644 index 00000000000..5428da324a5 --- /dev/null +++ b/kernel/ffmerge.h @@ -0,0 +1,141 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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. + * + */ + +#ifndef FFMERGE_H +#define FFMERGE_H + +#include "kernel/ffinit.h" +#include "kernel/ff.h" + +YOSYS_NAMESPACE_BEGIN + +// A helper class for passes that want to merge FFs on the input or output +// of a cell into the cell itself. +// +// The procedure is: +// +// 1. Construct this class (at beginning of processing for a given module). +// 2. For every considered cell: +// +// a. Call find_output_ff for every considered output. +// b. Call find_input_ff for every considered input. +// c. Look at the FF description returned (if any) from each call, reject +// results that cannot be merged into given cell for any reason. +// If both inputs and outputs are being merged, take care of FF bits that +// are returned in both input and output results (a FF bit cannot be +// merged to both). Decide on the final set of FF bits to merge. +// d. Call remove_output_ff for every find_output_ff result that will be used +// for merging. This removes the actual FF bits from design and from index. +// e. Call mark_input_ff for every find_input_ff result that will be used +// for merging. This updates the index disallowing further usage of these +// FF bits for output FF merging, if they were eligible before. The actual +// FF bits are still left in the design and can be merged into other inputs. +// If the FF bits are not otherwise used, they will be removed by later +// opt passes. +// f. Merge the FFs into the cell. +// +// Note that, if both inputs and outputs are being considered for merging in +// a single pass, the result may be nondeterministic (depending on cell iteration +// order) because a given FF bit could be eligible for both input and output merge, +// perhaps in different cells. For this reason, it may be a good idea to separate +// input and output merging. + +struct FfMergeHelper +{ + const SigMap *sigmap; + RTLIL::Module *module; + FfInitVals *initvals; + + dict> dff_driver; + dict>> dff_sink; + dict sigbit_users_count; + + // Returns true if all bits in sig are completely unused. + bool is_output_unused(RTLIL::SigSpec sig); + + // Finds the FF to merge into a given cell output. Takes sig, which + // is the current cell output — it will be the sig_d of the found FF. + // If found, returns true, and fills the two output arguments. + // + // For every bit of sig, this function finds a FF bit that has + // the same sig_d, and fills the output FfData according to the FF + // bits found. This function will only consider FF bits that are + // the only user of the given sig bits — if any bit in sig is used + // by anything other than a single FF, this function will return false. + // + // The returned FfData structure does not correspond to any actual FF + // cell in the design — it is the amalgamation of extracted FF bits, + // possibly coming from several FF cells. + // + // If some of the bits in sig have no users at all, this function + // will accept them as well (and fill returned FfData with dummy values + // for the given bit, effectively synthesizing an unused FF bit of the + // appropriate type). However, if all bits in sig are completely + // unused, this function will fail and return false (having no idea + // what kind of FF to produce) — use the above helper if that case + // is important to handle. + // + // Note that this function does not remove the FF bits returned from + // the design — this is so that the caller can decide whether to accept + // this FF for merging or not. If the result is accepted, + // remove_output_ff should be called on the second output argument. + bool find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits); + + // Like above, but returns a FF to merge into a given cell input. Takes + // sig_q, which is the current cell input — it will search for FFs with + // matching sig_q. + // + // As opposed to find_output_ff, this function doesn't care about usage + // counts, and may return FF bits that also have other fanout. This + // should not be a problem for input FF merging. + // + // As a special case, if some of the bits in sig_q are constant, this + // function will accept them as well, by synthesizing in-place + // a constant-input FF bit (with matching initial value and reset value). + // However, this will not work if the input is all-constant — if the caller + // cares about this case, it needs to check for it explicitely. + bool find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits); + + // To be called on find_output_ff result that will be merged. This + // marks the given FF bits as used up (and not to be considered for + // further merging as inputs), and reconnects their Q ports to a dummy + // wire (since the wire previously connected there will now be driven + // by the merged-to cell instead). + void remove_output_ff(const pool> &bits); + + // To be called on find_input_ff result that will be merged. This + // marks the given FF bits as used, and disallows merging them as + // outputs. They can, however, still be merged as inputs again + // (perhaps for another cell). + void mark_input_ff(const pool> &bits); + + void set(FfInitVals *initvals_, RTLIL::Module *module_); + + void clear(); + + FfMergeHelper(FfInitVals *initvals, RTLIL::Module *module) { + set(initvals, module); + } + + FfMergeHelper() {} +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 3698092b444..3248d4e9f79 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -17,11 +17,12 @@ * */ -#include #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" #include "kernel/mem.h" +#include "kernel/ff.h" +#include "kernel/ffmerge.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -30,270 +31,136 @@ struct MemoryDffWorker { Module *module; SigMap sigmap; - - vector dff_cells; - dict invbits; - dict sigbit_users_count; FfInitVals initvals; + FfMergeHelper merger; MemoryDffWorker(Module *module) : module(module), sigmap(module) { initvals.set(&sigmap, module); + merger.set(&initvals, module); } - bool find_sig_before_dff(RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity) + void handle_rd_port(Mem &mem, int idx) { - sigmap.apply(sig); - - dict cache; - - for (auto &bit : sig) - { - if (cache.count(bit)) { - bit = cache[bit]; - continue; - } - - if (bit.wire == NULL) - continue; - - if (initvals(bit) != State::Sx) - return false; - - for (auto cell : dff_cells) - { - SigSpec this_clk = cell->getPort(ID::CLK); - bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool(); - - if (invbits.count(this_clk)) { - this_clk = invbits.at(this_clk); - this_clk_polarity = !this_clk_polarity; - } - - if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - if (this_clk != clk) - continue; - if (this_clk_polarity != clk_polarity) - continue; - } - - RTLIL::SigSpec q_norm = cell->getPort(ID::Q); - sigmap.apply(q_norm); - - RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(ID::D)); - if (d.size() != 1) - continue; - - if (cell->type == ID($sdffce)) { - SigSpec rval = cell->parameters[ID::SRST_VALUE]; - SigSpec rbit = q_norm.extract(bit, &rval); - if (cell->parameters[ID::SRST_POLARITY].as_bool()) - d = module->Mux(NEW_ID, d, rbit, cell->getPort(ID::SRST)); - else - d = module->Mux(NEW_ID, rbit, d, cell->getPort(ID::SRST)); - } - - if (cell->type.in(ID($dffe), ID($sdffe), ID($sdffce))) { - if (cell->parameters[ID::EN_POLARITY].as_bool()) - d = module->Mux(NEW_ID, bit, d, cell->getPort(ID::EN)); - else - d = module->Mux(NEW_ID, d, bit, cell->getPort(ID::EN)); - } - - if (cell->type.in(ID($sdff), ID($sdffe))) { - SigSpec rval = cell->parameters[ID::SRST_VALUE]; - SigSpec rbit = q_norm.extract(bit, &rval); - if (cell->parameters[ID::SRST_POLARITY].as_bool()) - d = module->Mux(NEW_ID, d, rbit, cell->getPort(ID::SRST)); - else - d = module->Mux(NEW_ID, rbit, d, cell->getPort(ID::SRST)); - } - - cache[bit] = d; - bit = d; - clk = this_clk; - clk_polarity = this_clk_polarity; - goto replaced_this_bit; - } + auto &port = mem.rd_ports[idx]; + log("Checking read port `%s'[%d] in module `%s': ", mem.memid.c_str(), idx, module->name.c_str()); - return false; - replaced_this_bit:; + FfData ff; + pool> bits; + if (!merger.find_output_ff(port.data, ff, bits)) { + log("no output FF found.\n"); + return; } - - return true; - } - - bool find_sig_after_dffe(RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, RTLIL::SigSpec &en, bool &en_polarity) - { - sigmap.apply(sig); - - for (auto &bit : sig) - { - if (bit.wire == NULL) - continue; - - for (auto cell : dff_cells) - { - if (!cell->type.in(ID($dff), ID($dffe))) - continue; - - SigSpec this_clk = cell->getPort(ID::CLK); - bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool(); - SigSpec this_en = State::S1; - bool this_en_polarity = true; - - if (cell->type == ID($dffe)) { - this_en = cell->getPort(ID::EN); - this_en_polarity = cell->parameters[ID::EN_POLARITY].as_bool(); - } - - if (invbits.count(this_clk)) { - this_clk = invbits.at(this_clk); - this_clk_polarity = !this_clk_polarity; - } - - if (invbits.count(this_en)) { - this_en = invbits.at(this_en); - this_en_polarity = !this_en_polarity; - } - - if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - if (this_clk != clk) - continue; - if (this_clk_polarity != clk_polarity) - continue; - if (this_en != en) - continue; - if (this_en_polarity != en_polarity) - continue; - } - - RTLIL::SigSpec q_norm = cell->getPort(ID::D); - sigmap.apply(q_norm); - - RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(ID::Q)); - if (d.size() != 1) - continue; - - if (initvals(d) != State::Sx) - return false; - - bit = d; - clk = this_clk; - clk_polarity = this_clk_polarity; - en = this_en; - en_polarity = this_en_polarity; - goto replaced_this_bit; - } - - return false; - replaced_this_bit:; + if (!ff.has_clk) { + log("output latches are not supported.\n"); + return; } - - return true; - } - - void disconnect_dff(RTLIL::SigSpec sig) - { - sigmap.apply(sig); - sig.sort_and_unify(); - - std::stringstream sstr; - sstr << "$memory_dff_disconnected$" << (autoidx++); - - RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); - - for (auto cell : module->cells()) - if (cell->type.in(ID($dff), ID($dffe))) { - RTLIL::SigSpec new_q = cell->getPort(ID::Q); - new_q.replace(sig, new_sig); - cell->setPort(ID::Q, new_q); - } + if (ff.has_sr) { + // Latches and FFs with SR are not supported. + log("output FF has both set and reset, not supported.\n"); + return; + } + if (ff.has_srst || ff.has_arst || !ff.val_init.is_fully_undef()) { + // TODO: not supported yet + log("output FF has reset and/or init value, not supported yet.\n"); + return; + } + merger.remove_output_ff(bits); + if (ff.has_en && !ff.pol_en) + ff.sig_en = module->LogicNot(NEW_ID, ff.sig_en); + if (ff.has_arst && !ff.pol_arst) + ff.sig_arst = module->LogicNot(NEW_ID, ff.sig_arst); + if (ff.has_srst && !ff.pol_srst) + ff.sig_srst = module->LogicNot(NEW_ID, ff.sig_srst); + port.clk = ff.sig_clk; + port.clk_enable = true; + port.clk_polarity = ff.pol_clk; + if (ff.has_en) + port.en = ff.sig_en; + else + port.en = State::S1; +#if 0 + if (ff.has_arst) { + port.arst = ff.sig_arst; + port.arst_value = ff.val_arst; + } else { + port.arst = State::S0; + } + if (ff.has_srst) { + port.srst = ff.sig_srst; + port.srst_value = ff.val_srst; + port.ce_over_srst = ff.ce_over_srst; + } else { + port.srst = State::S0; + } + port.init_value = ff.val_init; +#endif + port.data = ff.sig_q; + mem.emit(); + log("merged output FF to cell.\n"); } - void handle_rd_port(Mem &mem, int idx) + void handle_rd_port_addr(Mem &mem, int idx) { auto &port = mem.rd_ports[idx]; - log("Checking read port `%s'[%d] in module `%s': ", mem.memid.c_str(), idx, module->name.c_str()); - - bool clk_polarity = 0; - bool en_polarity = 0; + log("Checking read port address `%s'[%d] in module `%s': ", mem.memid.c_str(), idx, module->name.c_str()); - RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec en_data; - RTLIL::SigSpec sig_data = port.data; - - for (auto bit : sigmap(sig_data)) - if (sigbit_users_count[bit] > 1) - goto skip_ff_after_read_merging; - - if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) - { - if (!en_polarity) - en_data = module->LogicNot(NEW_ID, en_data); - disconnect_dff(sig_data); - port.clk = clk_data; - port.en = en_data; - port.data = sig_data; - port.clk_enable = true; - port.clk_polarity = clk_polarity; - port.transparent = false; - mem.emit(); - log("merged data $dff to cell.\n"); + FfData ff; + pool> bits; + if (!merger.find_input_ff(port.addr, ff, bits)) { + log("no address FF found.\n"); return; } - - skip_ff_after_read_merging:; - RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_addr = port.addr; - if (find_sig_before_dff(sig_addr, clk_addr, clk_polarity) && - clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) - { - port.clk = clk_addr; - port.en = State::S1; - port.addr = sig_addr; - port.clk_enable = true; - port.clk_polarity = clk_polarity; - port.transparent = true; - mem.emit(); - log("merged address $dff to cell.\n"); + if (!ff.has_clk) { + log("address latches are not supported.\n"); return; } - - log("no (compatible) $dff found.\n"); + if (ff.has_sr || ff.has_arst) { + log("address FF has async set and/or reset, not supported.\n"); + return; + } + // Trick part: this transform is invalid if the initial + // value of the FF is fully-defined. However, we + // cannot simply reject FFs with any defined init bit, + // as this is often the result of merging a const bit. + if (ff.val_init.is_fully_def()) { + log("address FF has fully-defined init value, not supported.\n"); + return; + } + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &wport = mem.wr_ports[i]; + if (!wport.clk_enable || wport.clk != ff.sig_clk || wport.clk_polarity != ff.pol_clk) { + log("address FF clock is not compatible with write clock.\n"); + return; + } + } + // Now we're commited to merge it. + merger.mark_input_ff(bits); + // If the address FF has enable and/or sync reset, unmap it. + ff.unmap_ce_srst(module); + port.clk = ff.sig_clk; + port.en = State::S1; + port.addr = ff.sig_d; + port.clk_enable = true; + port.clk_polarity = ff.pol_clk; + port.transparent = true; + mem.emit(); + log("merged address FF to cell.\n"); } void run() { - for (auto wire : module->wires()) { - if (wire->port_output) - for (auto bit : sigmap(wire)) - sigbit_users_count[bit]++; - } - - for (auto cell : module->cells()) { - if (cell->type.in(ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce))) - dff_cells.push_back(cell); - if (cell->type.in(ID($not), ID($_NOT_)) || (cell->type == ID($logic_not) && GetSize(cell->getPort(ID::A)) == 1)) { - SigSpec sig_a = cell->getPort(ID::A); - SigSpec sig_y = cell->getPort(ID::Y); - if (cell->type == ID($not)) - sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); - if (cell->type == ID($logic_not)) - sig_y.extend_u0(1); - for (int i = 0; i < GetSize(sig_y); i++) - invbits[sig_y[i]] = sig_a[i]; + std::vector memories = Mem::get_selected_memories(module); + for (auto &mem : memories) { + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + if (!mem.rd_ports[i].clk_enable) + handle_rd_port(mem, i); } - for (auto &conn : cell->connections()) - if (!cell->known() || cell->input(conn.first)) - for (auto bit : sigmap(conn.second)) - sigbit_users_count[bit]++; } - - for (auto &mem : Mem::get_selected_memories(module)) { + for (auto &mem : memories) { for (int i = 0; i < GetSize(mem.rd_ports); i++) { if (!mem.rd_ports[i].clk_enable) - handle_rd_port(mem, i); + handle_rd_port_addr(mem, i); } } } diff --git a/tests/opt/bug1854.ys b/tests/opt/bug1854.ys new file mode 100644 index 00000000000..00a36ae94d8 --- /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 From d905990d0194decb9f673ccf10aa488820816b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 15:42:51 +0200 Subject: [PATCH 0330/2410] memory_share: Split off feedback path finding as a separate pass. memory_share is actually three passes in a trenchcoat. Split off the one that has the least in common with the other two as a separate pass. --- passes/memory/memory.cc | 4 +- passes/memory/memory_share.cc | 247 +----------------------- passes/opt/Makefile.inc | 1 + passes/opt/opt_mem_feedback.cc | 333 +++++++++++++++++++++++++++++++++ 4 files changed, 343 insertions(+), 242 deletions(-) create mode 100644 passes/opt/opt_mem_feedback.cc diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index 9dec05db85f..57e43694334 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -38,9 +38,10 @@ struct MemoryPass : public Pass { log(" opt_mem\n"); log(" memory_dff (skipped if called with -nordff or -memx)\n"); log(" opt_clean\n"); + log(" opt_mem_feedback\n"); log(" memory_share\n"); - log(" opt_clean\n"); log(" memory_memx (when called with -memx)\n"); + log(" opt_clean\n"); log(" memory_collect\n"); log(" memory_bram -rules (when called with -bram)\n"); log(" memory_map (skipped if called with -nomap)\n"); @@ -86,6 +87,7 @@ struct MemoryPass : public Pass { if (!flag_nordff) Pass::call(design, "memory_dff"); Pass::call(design, "opt_clean"); + Pass::call(design, "opt_mem_feedback"); Pass::call(design, "memory_share"); if (flag_memx) Pass::call(design, "memory_memx"); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 7315aeae10d..22227bf2b18 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -25,12 +25,8 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) +bool memwr_cmp(RTLIL::Cell *a, RTLIL::Cell *b) { - if (a->type == ID($memrd) && b->type == ID($memrd)) - return a->name < b->name; - if (a->type == ID($memrd) || b->type == ID($memrd)) - return (a->type == ID($memrd)) < (b->type == ID($memrd)); return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int(); } @@ -42,219 +38,6 @@ struct MemoryShareWorker ModWalker modwalker; CellTypes cone_ct; - std::map> sig_to_mux; - std::map>, SigBit>, SigBit> conditions_logic_cache; - - - // ----------------------------------------------------------------- - // Converting feedbacks to async read ports to proper enable signals - // ----------------------------------------------------------------- - - bool find_data_feedback(const std::set &async_rd_bits, RTLIL::SigBit sig, - std::map &state, std::set> &conditions) - { - if (async_rd_bits.count(sig)) { - conditions.insert(state); - return true; - } - - if (sig_to_mux.count(sig) == 0) - return false; - - RTLIL::Cell *cell = sig_to_mux.at(sig).first; - int bit_idx = sig_to_mux.at(sig).second; - - std::vector sig_a = sigmap(cell->getPort(ID::A)); - std::vector sig_b = sigmap(cell->getPort(ID::B)); - std::vector sig_s = sigmap(cell->getPort(ID::S)); - std::vector sig_y = sigmap(cell->getPort(ID::Y)); - log_assert(sig_y.at(bit_idx) == sig); - - for (int i = 0; i < int(sig_s.size()); i++) - if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) { - RTLIL::SigSpec new_b = cell->getPort(ID::B); - new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->setPort(ID::B, new_b); - } - return false; - } - - - for (int i = 0; i < int(sig_s.size()); i++) - { - if (state.count(sig_s[i]) && state.at(sig_s[i]) == false) - continue; - - std::map new_state = state; - new_state[sig_s[i]] = true; - - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) { - RTLIL::SigSpec new_b = cell->getPort(ID::B); - new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->setPort(ID::B, new_b); - } - } - - std::map new_state = state; - for (int i = 0; i < int(sig_s.size()); i++) - new_state[sig_s[i]] = false; - - if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) { - RTLIL::SigSpec new_a = cell->getPort(ID::A); - new_a.replace(bit_idx, RTLIL::State::Sx); - cell->setPort(ID::A, new_a); - } - - return false; - } - - RTLIL::SigBit conditions_to_logic(std::set> &conditions, SigBit olden, int &created_conditions) - { - auto key = make_pair(conditions, olden); - - if (conditions_logic_cache.count(key)) - return conditions_logic_cache.at(key); - - RTLIL::SigSpec terms; - for (auto &cond : conditions) { - RTLIL::SigSpec sig1, sig2; - for (auto &it : cond) { - sig1.append(it.first); - sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0); - } - terms.append(module->Ne(NEW_ID, sig1, sig2)); - created_conditions++; - } - - if (olden.wire != nullptr || olden != State::S1) - terms.append(olden); - - if (GetSize(terms) == 0) - terms = State::S1; - - if (GetSize(terms) > 1) - terms = module->ReduceAnd(NEW_ID, terms); - - return conditions_logic_cache[key] = terms; - } - - void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) - { - std::map>> async_rd_bits; - std::map> muxtree_upstream_map; - std::set non_feedback_nets; - - for (auto wire : module->wires()) - if (wire->port_output) { - std::vector bits = sigmap(wire); - non_feedback_nets.insert(bits.begin(), bits.end()); - } - - for (auto cell : module->cells()) - { - bool ignore_data_port = false; - - if (cell->type.in(ID($mux), ID($pmux))) - { - std::vector sig_a = sigmap(cell->getPort(ID::A)); - std::vector sig_b = sigmap(cell->getPort(ID::B)); - std::vector sig_s = sigmap(cell->getPort(ID::S)); - std::vector sig_y = sigmap(cell->getPort(ID::Y)); - - non_feedback_nets.insert(sig_s.begin(), sig_s.end()); - - for (int i = 0; i < int(sig_y.size()); i++) { - muxtree_upstream_map[sig_y[i]].insert(sig_a[i]); - for (int j = 0; j < int(sig_s.size()); j++) - muxtree_upstream_map[sig_y[i]].insert(sig_b[i + j*sig_y.size()]); - } - - continue; - } - - if (cell->type.in(ID($memwr), ID($memrd)) && - cell->parameters.at(ID::MEMID).decode_string() == memid) - ignore_data_port = true; - - for (auto conn : cell->connections()) - { - if (ignore_data_port && conn.first == ID::DATA) - continue; - std::vector bits = sigmap(conn.second); - non_feedback_nets.insert(bits.begin(), bits.end()); - } - } - - std::set expand_non_feedback_nets = non_feedback_nets; - while (!expand_non_feedback_nets.empty()) - { - std::set new_expand_non_feedback_nets; - - for (auto &bit : expand_non_feedback_nets) - if (muxtree_upstream_map.count(bit)) - for (auto &new_bit : muxtree_upstream_map.at(bit)) - if (!non_feedback_nets.count(new_bit)) { - non_feedback_nets.insert(new_bit); - new_expand_non_feedback_nets.insert(new_bit); - } - - expand_non_feedback_nets.swap(new_expand_non_feedback_nets); - } - - for (auto cell : rd_ports) - { - if (cell->parameters.at(ID::CLK_ENABLE).as_bool()) - continue; - - RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR)); - std::vector sig_data = sigmap(cell->getPort(ID::DATA)); - - for (int i = 0; i < int(sig_data.size()); i++) - if (non_feedback_nets.count(sig_data[i])) - goto not_pure_feedback_port; - - async_rd_bits[sig_addr].resize(max(async_rd_bits.size(), sig_data.size())); - for (int i = 0; i < int(sig_data.size()); i++) - async_rd_bits[sig_addr][i].insert(sig_data[i]); - - not_pure_feedback_port:; - } - - if (async_rd_bits.empty()) - return; - - log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(memid)); - - for (auto cell : wr_ports) - { - RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR)); - if (!async_rd_bits.count(sig_addr)) - continue; - - log(" Analyzing write port %s.\n", log_id(cell)); - - std::vector cell_data = cell->getPort(ID::DATA); - std::vector cell_en = cell->getPort(ID::EN); - - int created_conditions = 0; - for (int i = 0; i < int(cell_data.size()); i++) - if (cell_en[i] != RTLIL::SigBit(RTLIL::State::S0)) - { - std::map state; - std::set> conditions; - - find_data_feedback(async_rd_bits.at(sig_addr).at(i), cell_data[i], state, conditions); - cell_en[i] = conditions_to_logic(conditions, cell_en[i], created_conditions); - } - - if (created_conditions) { - log(" Added enable logic for %d different cases.\n", created_conditions); - cell->setPort(ID::EN, cell_en); - } - } - } - // ------------------------------------------------------ // Consolidate write ports that write to the same address @@ -669,21 +452,16 @@ struct MemoryShareWorker void operator()(RTLIL::Module* module) { - std::map, std::vector>> memindex; + std::map> memindex; this->module = module; sigmap.set(module); - sig_to_mux.clear(); - conditions_logic_cache.clear(); sigmap_xmux = sigmap; for (auto cell : module->cells()) { - if (cell->type == ID($memrd)) - memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell); - if (cell->type == ID($memwr)) - memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell); + memindex[cell->parameters.at(ID::MEMID).decode_string()].push_back(cell); if (cell->type == ID($mux)) { @@ -695,20 +473,11 @@ struct MemoryShareWorker else if (sig_b.is_fully_undef()) sigmap_xmux.add(cell->getPort(ID::Y), sig_a); } - - if (cell->type.in(ID($mux), ID($pmux))) - { - std::vector sig_y = sigmap(cell->getPort(ID::Y)); - for (int i = 0; i < int(sig_y.size()); i++) - sig_to_mux[sig_y[i]] = std::pair(cell, i); - } } for (auto &it : memindex) { - std::sort(it.second.first.begin(), it.second.first.end(), memcells_cmp); - std::sort(it.second.second.begin(), it.second.second.end(), memcells_cmp); - translate_rd_feedback_to_en(it.first, it.second.first, it.second.second); - consolidate_wr_by_addr(it.first, it.second.second); + std::sort(it.second.begin(), it.second.end(), memwr_cmp); + consolidate_wr_by_addr(it.first, it.second); } cone_ct.setup_internals(); @@ -728,7 +497,7 @@ struct MemoryShareWorker modwalker.setup(module, &cone_ct); for (auto &it : memindex) - consolidate_wr_using_sat(it.first, it.second.second); + consolidate_wr_using_sat(it.first, it.second); } }; @@ -744,10 +513,6 @@ struct MemorySharePass : public Pass { log("\n"); log("The following methods are used to consolidate the number of memory ports:\n"); log("\n"); - log(" - When write ports are connected to async read ports accessing the same\n"); - log(" address, then this feedback path is converted to a write port with\n"); - log(" byte/part enable signals.\n"); - log("\n"); log(" - When multiple write ports access the same address then this is converted\n"); log(" to a single write port with a more complex data and/or enable logic path.\n"); log("\n"); diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 4ae9b8895f9..b0192235b12 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -2,6 +2,7 @@ OBJS += passes/opt/opt.o OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_mem.o +OBJS += passes/opt/opt_mem_feedback.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_dff.o diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc new file mode 100644 index 00000000000..75e24451468 --- /dev/null +++ b/passes/opt/opt_mem_feedback.cc @@ -0,0 +1,333 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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/satgen.h" +#include "kernel/sigtools.h" +#include "kernel/modtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +bool memrd_cmp(RTLIL::Cell *a, RTLIL::Cell *b) +{ + return a->name < b->name; +} + +bool memwr_cmp(RTLIL::Cell *a, RTLIL::Cell *b) +{ + return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int(); +} + +struct OptMemFeedbackWorker +{ + RTLIL::Design *design; + RTLIL::Module *module; + SigMap sigmap, sigmap_xmux; + + std::map> sig_to_mux; + std::map>, SigBit>, SigBit> conditions_logic_cache; + + + // ----------------------------------------------------------------- + // Converting feedbacks to async read ports to proper enable signals + // ----------------------------------------------------------------- + + bool find_data_feedback(const std::set &async_rd_bits, RTLIL::SigBit sig, + std::map &state, std::set> &conditions) + { + if (async_rd_bits.count(sig)) { + conditions.insert(state); + return true; + } + + if (sig_to_mux.count(sig) == 0) + return false; + + RTLIL::Cell *cell = sig_to_mux.at(sig).first; + int bit_idx = sig_to_mux.at(sig).second; + + std::vector sig_a = sigmap(cell->getPort(ID::A)); + std::vector sig_b = sigmap(cell->getPort(ID::B)); + std::vector sig_s = sigmap(cell->getPort(ID::S)); + std::vector sig_y = sigmap(cell->getPort(ID::Y)); + log_assert(sig_y.at(bit_idx) == sig); + + for (int i = 0; i < int(sig_s.size()); i++) + if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) { + RTLIL::SigSpec new_b = cell->getPort(ID::B); + new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->setPort(ID::B, new_b); + } + return false; + } + + + for (int i = 0; i < int(sig_s.size()); i++) + { + if (state.count(sig_s[i]) && state.at(sig_s[i]) == false) + continue; + + std::map new_state = state; + new_state[sig_s[i]] = true; + + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) { + RTLIL::SigSpec new_b = cell->getPort(ID::B); + new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->setPort(ID::B, new_b); + } + } + + std::map new_state = state; + for (int i = 0; i < int(sig_s.size()); i++) + new_state[sig_s[i]] = false; + + if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) { + RTLIL::SigSpec new_a = cell->getPort(ID::A); + new_a.replace(bit_idx, RTLIL::State::Sx); + cell->setPort(ID::A, new_a); + } + + return false; + } + + RTLIL::SigBit conditions_to_logic(std::set> &conditions, SigBit olden, int &created_conditions) + { + auto key = make_pair(conditions, olden); + + if (conditions_logic_cache.count(key)) + return conditions_logic_cache.at(key); + + RTLIL::SigSpec terms; + for (auto &cond : conditions) { + RTLIL::SigSpec sig1, sig2; + for (auto &it : cond) { + sig1.append(it.first); + sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0); + } + terms.append(module->Ne(NEW_ID, sig1, sig2)); + created_conditions++; + } + + if (olden.wire != nullptr || olden != State::S1) + terms.append(olden); + + if (GetSize(terms) == 0) + terms = State::S1; + + if (GetSize(terms) > 1) + terms = module->ReduceAnd(NEW_ID, terms); + + return conditions_logic_cache[key] = terms; + } + + void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) + { + std::map>> async_rd_bits; + std::map> muxtree_upstream_map; + std::set non_feedback_nets; + + for (auto wire : module->wires()) + if (wire->port_output) { + std::vector bits = sigmap(wire); + non_feedback_nets.insert(bits.begin(), bits.end()); + } + + for (auto cell : module->cells()) + { + bool ignore_data_port = false; + + if (cell->type.in(ID($mux), ID($pmux))) + { + std::vector sig_a = sigmap(cell->getPort(ID::A)); + std::vector sig_b = sigmap(cell->getPort(ID::B)); + std::vector sig_s = sigmap(cell->getPort(ID::S)); + std::vector sig_y = sigmap(cell->getPort(ID::Y)); + + non_feedback_nets.insert(sig_s.begin(), sig_s.end()); + + for (int i = 0; i < int(sig_y.size()); i++) { + muxtree_upstream_map[sig_y[i]].insert(sig_a[i]); + for (int j = 0; j < int(sig_s.size()); j++) + muxtree_upstream_map[sig_y[i]].insert(sig_b[i + j*sig_y.size()]); + } + + continue; + } + + if (cell->type.in(ID($memwr), ID($memrd)) && + cell->parameters.at(ID::MEMID).decode_string() == memid) + ignore_data_port = true; + + for (auto conn : cell->connections()) + { + if (ignore_data_port && conn.first == ID::DATA) + continue; + std::vector bits = sigmap(conn.second); + non_feedback_nets.insert(bits.begin(), bits.end()); + } + } + + std::set expand_non_feedback_nets = non_feedback_nets; + while (!expand_non_feedback_nets.empty()) + { + std::set new_expand_non_feedback_nets; + + for (auto &bit : expand_non_feedback_nets) + if (muxtree_upstream_map.count(bit)) + for (auto &new_bit : muxtree_upstream_map.at(bit)) + if (!non_feedback_nets.count(new_bit)) { + non_feedback_nets.insert(new_bit); + new_expand_non_feedback_nets.insert(new_bit); + } + + expand_non_feedback_nets.swap(new_expand_non_feedback_nets); + } + + for (auto cell : rd_ports) + { + if (cell->parameters.at(ID::CLK_ENABLE).as_bool()) + continue; + + RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR)); + std::vector sig_data = sigmap(cell->getPort(ID::DATA)); + + for (int i = 0; i < int(sig_data.size()); i++) + if (non_feedback_nets.count(sig_data[i])) + goto not_pure_feedback_port; + + async_rd_bits[sig_addr].resize(max(async_rd_bits.size(), sig_data.size())); + for (int i = 0; i < int(sig_data.size()); i++) + async_rd_bits[sig_addr][i].insert(sig_data[i]); + + not_pure_feedback_port:; + } + + if (async_rd_bits.empty()) + return; + + log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(memid)); + + for (auto cell : wr_ports) + { + RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR)); + if (!async_rd_bits.count(sig_addr)) + continue; + + log(" Analyzing write port %s.\n", log_id(cell)); + + std::vector cell_data = cell->getPort(ID::DATA); + std::vector cell_en = cell->getPort(ID::EN); + + int created_conditions = 0; + for (int i = 0; i < int(cell_data.size()); i++) + if (cell_en[i] != RTLIL::SigBit(RTLIL::State::S0)) + { + std::map state; + std::set> conditions; + + find_data_feedback(async_rd_bits.at(sig_addr).at(i), cell_data[i], state, conditions); + cell_en[i] = conditions_to_logic(conditions, cell_en[i], created_conditions); + } + + if (created_conditions) { + log(" Added enable logic for %d different cases.\n", created_conditions); + cell->setPort(ID::EN, cell_en); + } + } + } + + // ------------- + // Setup and run + // ------------- + + OptMemFeedbackWorker(RTLIL::Design *design) : design(design) {} + + void operator()(RTLIL::Module* module) + { + std::map, std::vector>> memindex; + + this->module = module; + sigmap.set(module); + sig_to_mux.clear(); + conditions_logic_cache.clear(); + + sigmap_xmux = sigmap; + for (auto cell : module->cells()) + { + if (cell->type == ID($memrd)) + memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell); + + if (cell->type == ID($memwr)) + memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell); + + if (cell->type == ID($mux)) + { + RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort(ID::B)); + + if (sig_a.is_fully_undef()) + sigmap_xmux.add(cell->getPort(ID::Y), sig_b); + else if (sig_b.is_fully_undef()) + sigmap_xmux.add(cell->getPort(ID::Y), sig_a); + } + + if (cell->type.in(ID($mux), ID($pmux))) + { + std::vector sig_y = sigmap(cell->getPort(ID::Y)); + for (int i = 0; i < int(sig_y.size()); i++) + sig_to_mux[sig_y[i]] = std::pair(cell, i); + } + } + + for (auto &it : memindex) { + std::sort(it.second.first.begin(), it.second.first.end(), memrd_cmp); + std::sort(it.second.second.begin(), it.second.second.end(), memwr_cmp); + translate_rd_feedback_to_en(it.first, it.second.first, it.second.second); + } + } +}; + +struct OptMemFeedbackPass : public Pass { + OptMemFeedbackPass() : Pass("opt_mem_feedback", "convert memory read-to-write port feedback paths to write enables") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_mem_feedback [selection]\n"); + log("\n"); + log("This pass detects cases where an asynchronous read port is connected via\n"); + log("a mux tree to a write port with the same address. When such a path is\n"); + log("found, it is replaced with a new condition on an enable signal, possibly\n"); + log("allowing for removal of the read port.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override { + log_header(design, "Executing OPT_MEM_FEEDBACK pass (finding memory read-to-write feedback paths).\n"); + extra_args(args, 1, design); + OptMemFeedbackWorker worker(design); + + for (auto module : design->selected_modules()) + worker(module); + } +} OptMemFeedbackPass; + +PRIVATE_NAMESPACE_END + From 33513d923a398a955c1c7e5f534e3099f3940154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 18:08:34 +0200 Subject: [PATCH 0331/2410] btor: Use is_mem_cell in one more place. --- backends/btor/btor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 936cb20fb63..bc0504d6479 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -1083,7 +1083,7 @@ struct BtorWorker for (auto &mem : memories) mem_dict[mem.memid] = &mem; for (auto cell : module->cells()) - if (cell->type.in(ID($mem), ID($memwr), ID($memrd), ID($meminit))) + if (cell->is_mem_cell()) mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; btorf_push("inputs"); From afd5366fc2841ef21acc9f994ca2052b9dfa21e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 18:29:44 +0200 Subject: [PATCH 0332/2410] extract_rdff: Add initvals parameter. This is not used yet, but will be needed when read port reset/initial value support lands. --- kernel/mem.cc | 2 +- kernel/mem.h | 3 ++- passes/memory/memory_map.cc | 6 ++++-- passes/memory/memory_nordff.cc | 18 +++++++++++------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 7d20833e543..4c3b333c1c3 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -445,7 +445,7 @@ std::vector Mem::get_selected_memories(Module *module) { return res; } -Cell *Mem::extract_rdff(int idx) { +Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { MemRd &port = rd_ports[idx]; if (!port.clk_enable) diff --git a/kernel/mem.h b/kernel/mem.h index f5c7b641ffa..a2af6a183c6 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -21,6 +21,7 @@ #define MEM_H #include "kernel/yosys.h" +#include "kernel/ffinit.h" YOSYS_NAMESPACE_BEGIN @@ -70,7 +71,7 @@ struct Mem { Const get_init_data() const; static std::vector get_all_memories(Module *module); static std::vector get_selected_memories(Module *module); - Cell *extract_rdff(int idx); + Cell *extract_rdff(int idx, FfInitVals *initvals); Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} }; diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 032b8fbbdf7..57863c0b677 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -34,10 +34,12 @@ struct MemoryMapWorker RTLIL::Design *design; RTLIL::Module *module; + SigMap sigmap; + FfInitVals initvals; std::map, RTLIL::SigBit> decoder_cache; - MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module) {} + MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), sigmap(module), initvals(&sigmap, module) {} std::string map_case(std::string value) const { @@ -228,7 +230,7 @@ struct MemoryMapWorker for (int i = 0; i < GetSize(mem.rd_ports); i++) { auto &port = mem.rd_ports[i]; - if (mem.extract_rdff(i)) + if (mem.extract_rdff(i, &initvals)) count_dff++; RTLIL::SigSpec rd_addr = port.addr; rd_addr.extend_u0(abits, false); diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc index bb853c483eb..665efceb202 100644 --- a/passes/memory/memory_nordff.cc +++ b/passes/memory/memory_nordff.cc @@ -51,15 +51,19 @@ struct MemoryNordffPass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) - for (auto &mem : Mem::get_selected_memories(module)) { - bool changed = false; - for (int i = 0; i < GetSize(mem.rd_ports); i++) - if (mem.extract_rdff(i)) - changed = true; + SigMap sigmap(module); + FfInitVals initvals(&sigmap, module); + for (auto &mem : Mem::get_selected_memories(module)) + { + bool changed = false; + for (int i = 0; i < GetSize(mem.rd_ports); i++) + if (mem.extract_rdff(i, &initvals)) + changed = true; - if (changed) - mem.emit(); + if (changed) + mem.emit(); + } } } } MemoryNordffPass; From df2b79ca7687ae46360084f2e3ef27222bb3a640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 17:20:51 +0200 Subject: [PATCH 0333/2410] memory_share: Use Mem helpers. --- passes/memory/memory_share.cc | 160 +++++++++++++++------------------- 1 file changed, 71 insertions(+), 89 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 22227bf2b18..d5a44f20c11 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -21,15 +21,11 @@ #include "kernel/satgen.h" #include "kernel/sigtools.h" #include "kernel/modtools.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool memwr_cmp(RTLIL::Cell *a, RTLIL::Cell *b) -{ - return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int(); -} - struct MemoryShareWorker { RTLIL::Design *design; @@ -134,12 +130,12 @@ struct MemoryShareWorker merged_data = new_merged_data; } - void consolidate_wr_by_addr(std::string memid, std::vector &wr_ports) + void consolidate_wr_by_addr(Mem &mem) { - if (wr_ports.size() <= 1) + if (GetSize(mem.wr_ports) <= 1) return; - log("Consolidating write ports of memory %s.%s by address:\n", log_id(module), log_id(memid)); + log("Consolidating write ports of memory %s.%s by address:\n", log_id(module), log_id(mem.memid)); std::map last_port_by_addr; std::vector> active_bits_on_port; @@ -148,18 +144,20 @@ struct MemoryShareWorker bool cache_clk_polarity = false; RTLIL::SigSpec cache_clk; - for (int i = 0; i < int(wr_ports.size()); i++) + bool changed = false; + + for (int i = 0; i < GetSize(mem.wr_ports); i++) { - RTLIL::Cell *cell = wr_ports.at(i); - RTLIL::SigSpec addr = sigmap_xmux(cell->getPort(ID::ADDR)); + auto &port = mem.wr_ports[i]; + RTLIL::SigSpec addr = sigmap_xmux(port.addr); - if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk || - cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity))) + if (port.clk_enable != cache_clk_enable || + (cache_clk_enable && (sigmap(port.clk) != cache_clk || + port.clk_polarity != cache_clk_polarity))) { - cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); - cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); - cache_clk = sigmap(cell->getPort(ID::CLK)); + cache_clk_enable = port.clk_enable; + cache_clk_polarity = port.clk_polarity; + cache_clk = sigmap(port.clk); last_port_by_addr.clear(); if (cache_clk_enable) @@ -168,10 +166,10 @@ struct MemoryShareWorker log(" New clock domain: unclocked\n"); } - log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); + log(" Port %d has addr %s.\n", i, log_signal(addr)); log(" Active bits: "); - std::vector en_bits = sigmap(cell->getPort(ID::EN)); + std::vector en_bits = sigmap(port.en); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) { active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; @@ -193,17 +191,17 @@ struct MemoryShareWorker // Force this ports addr input to addr directly (skip don't care muxes) - cell->setPort(ID::ADDR, addr); + port.addr = addr; // If any of the ports between `last_i' and `i' write to the same address, this // will have priority over whatever `last_i` wrote. So we need to revisit those // ports and mask the EN bits accordingly. - RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort(ID::EN)); + RTLIL::SigSpec merged_en = sigmap(mem.wr_ports[last_i].en); for (int j = last_i+1; j < i; j++) { - if (wr_ports[j] == NULL) + if (mem.wr_ports[j].removed) continue; for (int k = 0; k < int(en_bits.size()); k++) @@ -214,20 +212,20 @@ struct MemoryShareWorker found_overlapping_bits_i_j: log(" Creating collosion-detect logic for port %d.\n", j); RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); - module->addEq(NEW_ID, addr, wr_ports[j]->getPort(ID::ADDR), is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort(ID::EN))); + module->addEq(NEW_ID, addr, mem.wr_ports[j].addr, is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(mem.wr_ports[j].en)); } } // Then we need to merge the (masked) EN and the DATA signals. - RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort(ID::DATA); + RTLIL::SigSpec merged_data = mem.wr_ports[last_i].data; if (found_overlapping_bits) { log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(cell->getPort(ID::EN)), sigmap(cell->getPort(ID::DATA))); + merge_en_data(merged_en, merged_data, sigmap(port.en), sigmap(port.data)); } else { - RTLIL::SigSpec cell_en = sigmap(cell->getPort(ID::EN)); - RTLIL::SigSpec cell_data = sigmap(cell->getPort(ID::DATA)); + RTLIL::SigSpec cell_en = sigmap(port.en); + RTLIL::SigSpec cell_data = sigmap(port.data); for (int k = 0; k < int(en_bits.size()); k++) if (!active_bits_on_port[last_i][k]) { merged_en.replace(k, cell_en.extract(k, 1)); @@ -237,14 +235,14 @@ struct MemoryShareWorker // Connect the new EN and DATA signals and remove the old write port. - cell->setPort(ID::EN, merged_en); - cell->setPort(ID::DATA, merged_data); + port.en = merged_en; + port.data = merged_data; - module->remove(wr_ports[last_i]); - wr_ports[last_i] = NULL; + mem.wr_ports[last_i].removed = true; + changed = true; log(" Active bits: "); - std::vector en_bits = sigmap(cell->getPort(ID::EN)); + std::vector en_bits = sigmap(port.en); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) log("%c", active_bits_on_port[i][k] ? '1' : '0'); @@ -254,14 +252,8 @@ struct MemoryShareWorker last_port_by_addr[addr] = i; } - // Clean up `wr_ports': remove all NULL entries - - std::vector wr_ports_with_nulls; - wr_ports_with_nulls.swap(wr_ports); - - for (auto cell : wr_ports_with_nulls) - if (cell != NULL) - wr_ports.push_back(cell); + if (changed) + mem.emit(); } @@ -269,9 +261,9 @@ struct MemoryShareWorker // Consolidate write ports using sat-based resource sharing // -------------------------------------------------------- - void consolidate_wr_using_sat(std::string memid, std::vector &wr_ports) + void consolidate_wr_using_sat(Mem &mem) { - if (wr_ports.size() <= 1) + if (GetSize(mem.wr_ports) <= 1) return; ezSatPtr ez; @@ -282,8 +274,9 @@ struct MemoryShareWorker std::set considered_ports; std::set considered_port_pairs; - for (int i = 0; i < int(wr_ports.size()); i++) { - std::vector bits = modwalker.sigmap(wr_ports[i]->getPort(ID::EN)); + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &port = mem.wr_ports[i]; + std::vector bits = modwalker.sigmap(port.en); for (auto bit : bits) if (bit == RTLIL::State::S1) goto port_is_always_active; @@ -292,33 +285,33 @@ struct MemoryShareWorker port_is_always_active:; } - log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", log_id(module), log_id(memid)); + log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", log_id(module), log_id(mem.memid)); bool cache_clk_enable = false; bool cache_clk_polarity = false; RTLIL::SigSpec cache_clk; - for (int i = 0; i < int(wr_ports.size()); i++) + for (int i = 0; i < GetSize(mem.wr_ports); i++) { - RTLIL::Cell *cell = wr_ports.at(i); + auto &port = mem.wr_ports[i]; - if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk || - cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity))) + if (port.clk_enable != cache_clk_enable || + (cache_clk_enable && (sigmap(port.clk) != cache_clk || + port.clk_polarity != cache_clk_polarity))) { - cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); - cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); - cache_clk = sigmap(cell->getPort(ID::CLK)); + cache_clk_enable = port.clk_enable; + cache_clk_polarity = port.clk_polarity; + cache_clk = sigmap(port.clk); } else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) considered_port_pairs.insert(i); if (cache_clk_enable) - log(" Port %d (%s) on %s %s: %s\n", i, log_id(cell), + log(" Port %d on %s %s: %s\n", i, cache_clk_polarity ? "posedge" : "negedge", log_signal(cache_clk), considered_ports.count(i) ? "considered" : "not considered"); else - log(" Port %d (%s) unclocked: %s\n", i, log_id(cell), + log(" Port %d unclocked: %s\n", i, considered_ports.count(i) ? "considered" : "not considered"); } @@ -334,10 +327,10 @@ struct MemoryShareWorker std::set bits_queue; std::map port_to_sat_variable; - for (int i = 0; i < int(wr_ports.size()); i++) + for (int i = 0; i < GetSize(mem.wr_ports); i++) if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) { - RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort(ID::EN)); + RTLIL::SigSpec sig = modwalker.sigmap(mem.wr_ports[i].en); port_to_sat_variable[i] = ez->expression(ez->OpOr, satgen.importSigSpec(sig)); std::vector bits = sig; @@ -379,7 +372,8 @@ struct MemoryShareWorker // merge subsequent ports if possible - for (int i = 0; i < int(wr_ports.size()); i++) + bool changed = false; + for (int i = 0; i < GetSize(mem.wr_ports); i++) { if (!considered_port_pairs.count(i)) continue; @@ -392,13 +386,13 @@ struct MemoryShareWorker log(" Merging port %d into port %d.\n", i-1, i); port_to_sat_variable.at(i) = ez->OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); - RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort(ID::ADDR); - RTLIL::SigSpec last_data = wr_ports[i-1]->getPort(ID::DATA); - std::vector last_en = modwalker.sigmap(wr_ports[i-1]->getPort(ID::EN)); + RTLIL::SigSpec last_addr = mem.wr_ports[i-1].addr; + RTLIL::SigSpec last_data = mem.wr_ports[i-1].data; + std::vector last_en = modwalker.sigmap(mem.wr_ports[i-1].en); - RTLIL::SigSpec this_addr = wr_ports[i]->getPort(ID::ADDR); - RTLIL::SigSpec this_data = wr_ports[i]->getPort(ID::DATA); - std::vector this_en = modwalker.sigmap(wr_ports[i]->getPort(ID::EN)); + RTLIL::SigSpec this_addr = mem.wr_ports[i].addr; + RTLIL::SigSpec this_data = mem.wr_ports[i].data; + std::vector this_en = modwalker.sigmap(mem.wr_ports[i].en); RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); @@ -407,9 +401,8 @@ struct MemoryShareWorker else this_addr.extend_u0(GetSize(last_addr)); - wr_ports[i]->setParam(ID::ABITS, GetSize(this_addr)); - wr_ports[i]->setPort(ID::ADDR, module->Mux(NEW_ID, last_addr, this_addr, this_en_active)); - wr_ports[i]->setPort(ID::DATA, module->Mux(NEW_ID, last_data, this_data, this_en_active)); + mem.wr_ports[i].addr = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); + mem.wr_ports[i].data = module->Mux(NEW_ID, last_data, this_data, this_en_active); std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; @@ -427,20 +420,14 @@ struct MemoryShareWorker } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - wr_ports[i]->setPort(ID::EN, en); + mem.wr_ports[i].en = en; - module->remove(wr_ports[i-1]); - wr_ports[i-1] = NULL; + mem.wr_ports[i-1].removed = true; + changed = true; } - // Clean up `wr_ports': remove all NULL entries - - std::vector wr_ports_with_nulls; - wr_ports_with_nulls.swap(wr_ports); - - for (auto cell : wr_ports_with_nulls) - if (cell != NULL) - wr_ports.push_back(cell); + if (changed) + mem.emit(); } @@ -452,7 +439,7 @@ struct MemoryShareWorker void operator()(RTLIL::Module* module) { - std::map> memindex; + std::vector memories = Mem::get_selected_memories(module); this->module = module; sigmap.set(module); @@ -460,9 +447,6 @@ struct MemoryShareWorker sigmap_xmux = sigmap; for (auto cell : module->cells()) { - if (cell->type == ID($memwr)) - memindex[cell->parameters.at(ID::MEMID).decode_string()].push_back(cell); - if (cell->type == ID($mux)) { RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A)); @@ -475,10 +459,8 @@ struct MemoryShareWorker } } - for (auto &it : memindex) { - std::sort(it.second.begin(), it.second.end(), memwr_cmp); - consolidate_wr_by_addr(it.first, it.second); - } + for (auto &mem : memories) + consolidate_wr_by_addr(mem); cone_ct.setup_internals(); cone_ct.cell_types.erase(ID($mul)); @@ -496,8 +478,8 @@ struct MemoryShareWorker modwalker.setup(module, &cone_ct); - for (auto &it : memindex) - consolidate_wr_using_sat(it.first, it.second); + for (auto &mem : memories) + consolidate_wr_using_sat(mem); } }; From ef4ddfacf391acc0f681d72a6ca31974f62b2ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 21:20:04 +0200 Subject: [PATCH 0334/2410] github actions: Test on several gcc and clang versions on Linux. Fixes #2776. --- .github/workflows/test.yml | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a757d1533c..ee5b5c00ebf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,9 +6,22 @@ jobs: test: strategy: matrix: - runner: - - ubuntu-20.04 - - macOS-10.15 + include: + - runner: ubuntu-20.04 + config: clang + cc: clang + - runner: ubuntu-20.04 + config: gcc + cc: gcc + - runner: ubuntu-18.04 + config: gcc + cc: gcc-4.8 + - runner: ubuntu-18.04 + config: clang + cc: clang-3.9 + - runner: macOS-10.15 + config: clang + cc: clang runs-on: ${{ matrix.runner }} steps: @@ -20,6 +33,16 @@ jobs: sudo apt-get update sudo apt-get install g++ gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev + - name: Install gcc-4.8 + if: matrix.cc == 'gcc-4.8' + run: | + sudo apt-get install g++-4.8 + + - name: Install clang-3.9 + if: matrix.cc == 'clang-3.9' + run: | + sudo apt-get install clang-3.9 + - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | @@ -45,7 +68,7 @@ jobs: uses: actions/cache@v2 with: path: iverilog-bin - key: ${{ runner.os }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} + key: ${{ matrix.runner }}-${{ hashFiles('iverilog/.git/refs/heads/master') }} - name: Build iverilog if: steps.cache-iverilog.outputs.cache-hit != 'true' @@ -59,8 +82,10 @@ jobs: - name: Build yosys run: | - make -j${{ env.procs }} + ${{ matrix.cc }} --version + make config-${{ matrix.config }} + make -j${{ env.procs }} CC=${{ matrix.cc }} CXX=${{ matrix.cc }} LD=${{ matrix.cc }} - name: Run tests run: | - PATH=$PWD/iverilog-bin/bin:$PATH make -j${{ env.procs }} test + PATH=$PWD/iverilog-bin/bin:$PATH make -j${{ env.procs }} test CC=${{ matrix.cc }} CXX=${{ matrix.cc }} LD=${{ matrix.cc }} From b6721aa9d824ec5b4ec1c61167b53bab62fb1e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 00:41:31 +0200 Subject: [PATCH 0335/2410] backend/firrtl: Convert to use Mem helpers. --- backends/firrtl/firrtl.cc | 352 ++++++++++---------------------------- 1 file changed, 88 insertions(+), 264 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 44c3397da37..f99becacffa 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -23,6 +23,7 @@ #include "kernel/celltypes.h" #include "kernel/cellaigs.h" #include "kernel/log.h" +#include "kernel/mem.h" #include #include #include @@ -366,126 +367,6 @@ struct FirrtlWorker RTLIL::Design *design; std::string indent; - // Define read/write ports and memories. - // We'll collect their definitions and emit the corresponding FIRRTL definitions at the appropriate point in module construction. - // For the moment, we don't handle $readmemh or $readmemb. - // These will be part of a subsequent PR. - struct read_port { - string name; - bool clk_enable; - bool clk_parity; - bool transparent; - RTLIL::SigSpec clk; - RTLIL::SigSpec ena; - RTLIL::SigSpec addr; - read_port(string name, bool clk_enable, bool clk_parity, bool transparent, RTLIL::SigSpec clk, RTLIL::SigSpec ena, RTLIL::SigSpec addr) : name(name), clk_enable(clk_enable), clk_parity(clk_parity), transparent(transparent), clk(clk), ena(ena), addr(addr) { - // Current (3/13/2019) conventions: - // generate a constant 0 for clock and a constant 1 for enable if they are undefined. - if (!clk.is_fully_def()) - this->clk = SigSpec(State::S0); - if (!ena.is_fully_def()) - this->ena = SigSpec(State::S1); - } - string gen_read(const char * indent) { - string addr_expr = make_expr(addr); - string ena_expr = make_expr(ena); - string clk_expr = make_expr(clk); - string addr_str = stringf("%s%s.addr <= %s\n", indent, name.c_str(), addr_expr.c_str()); - string ena_str = stringf("%s%s.en <= %s\n", indent, name.c_str(), ena_expr.c_str()); - string clk_str = stringf("%s%s.clk <= asClock(%s)\n", indent, name.c_str(), clk_expr.c_str()); - return addr_str + ena_str + clk_str; - } - }; - struct write_port : read_port { - RTLIL::SigSpec mask; - write_port(string name, bool clk_enable, bool clk_parity, bool transparent, RTLIL::SigSpec clk, RTLIL::SigSpec ena, RTLIL::SigSpec addr, RTLIL::SigSpec mask) : read_port(name, clk_enable, clk_parity, transparent, clk, ena, addr), mask(mask) { - if (!clk.is_fully_def()) - this->clk = SigSpec(RTLIL::Const(0)); - if (!ena.is_fully_def()) - this->ena = SigSpec(RTLIL::Const(0)); - if (!mask.is_fully_def()) - this->ena = SigSpec(RTLIL::Const(1)); - } - string gen_read(const char * /* indent */) { - log_error("gen_read called on write_port: %s\n", name.c_str()); - return stringf("gen_read called on write_port: %s\n", name.c_str()); - } - string gen_write(const char * indent) { - string addr_expr = make_expr(addr); - string ena_expr = make_expr(ena); - string clk_expr = make_expr(clk); - string mask_expr = make_expr(mask); - string mask_str = stringf("%s%s.mask <= %s\n", indent, name.c_str(), mask_expr.c_str()); - string addr_str = stringf("%s%s.addr <= %s\n", indent, name.c_str(), addr_expr.c_str()); - string ena_str = stringf("%s%s.en <= %s\n", indent, name.c_str(), ena_expr.c_str()); - string clk_str = stringf("%s%s.clk <= asClock(%s)\n", indent, name.c_str(), clk_expr.c_str()); - return addr_str + ena_str + clk_str + mask_str; - } - }; - /* Memories defined within this module. */ - struct memory { - Cell *pCell; // for error reporting - string name; // memory name - int abits; // number of address bits - int size; // size (in units) of the memory - int width; // size (in bits) of each element - int read_latency; - int write_latency; - vector read_ports; - vector write_ports; - std::string init_file; - std::string init_file_srcFileSpec; - string srcLine; - memory(Cell *pCell, string name, int abits, int size, int width) : pCell(pCell), name(name), abits(abits), size(size), width(width), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec("") { - // Provide defaults for abits or size if one (but not the other) is specified. - if (this->abits == 0 && this->size != 0) { - this->abits = ceil_log2(this->size); - } else if (this->abits != 0 && this->size == 0) { - this->size = 1 << this->abits; - } - // Sanity-check this construction. - if (this->name == "") { - log_error("Nameless memory%s\n", this->atLine()); - } - if (this->abits == 0 && this->size == 0) { - log_error("Memory %s has zero address bits and size%s\n", this->name.c_str(), this->atLine()); - } - if (this->width == 0) { - log_error("Memory %s has zero width%s\n", this->name.c_str(), this->atLine()); - } - } - - // We need a default constructor for the dict insert. - memory() : pCell(0), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec(""){} - - const char *atLine() { - if (srcLine == "") { - if (pCell) { - auto p = pCell->attributes.find(ID::src); - srcLine = " at " + p->second.decode_string(); - } - } - return srcLine.c_str(); - } - void add_memory_read_port(read_port &rp) { - read_ports.push_back(rp); - } - void add_memory_write_port(write_port &wp) { - write_ports.push_back(wp); - } - void add_memory_file(std::string init_file, std::string init_file_srcFileSpec) { - this->init_file = init_file; - this->init_file_srcFileSpec = init_file_srcFileSpec; - } - - }; - dict memories; - - void register_memory(memory &m) - { - memories[m.name] = m; - } - void register_reverse_wire_map(string id, SigSpec sig) { for (int i = 0; i < GetSize(sig); i++) @@ -658,7 +539,9 @@ struct FirrtlWorker { std::string moduleFileinfo = getFileinfo(module); f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo.c_str()); - vector port_decls, wire_decls, cell_exprs, wire_exprs; + vector port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs; + + std::vector memories = Mem::get_all_memories(module); for (auto wire : module->wires()) { @@ -686,14 +569,15 @@ struct FirrtlWorker for (auto cell : module->cells()) { - static Const ndef(0, 0); + Const ndef(0, 0); // Is this cell is a module instance? - if (cell->type[0] != '$') + if (module->design->module(cell->type)) { process_instance(cell, wire_exprs); continue; } + // Not a module instance. Set up cell properties bool extract_y_bits = false; // Assume no extraction of final bits will be required. int a_width = cell->parameters.at(ID::A_WIDTH, ndef).as_int(); // The width of "A" @@ -1004,126 +888,9 @@ struct FirrtlWorker continue; } - if (cell->type.in(ID($mem))) - { - string mem_id = make_id(cell->name); - int abits = cell->parameters.at(ID::ABITS).as_int(); - int width = cell->parameters.at(ID::WIDTH).as_int(); - int size = cell->parameters.at(ID::SIZE).as_int(); - memory m(cell, mem_id, abits, size, width); - int rd_ports = cell->parameters.at(ID::RD_PORTS).as_int(); - int wr_ports = cell->parameters.at(ID::WR_PORTS).as_int(); - - Const initdata = cell->parameters.at(ID::INIT); - for (State bit : initdata.bits) - if (bit != State::Sx) - log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(cell)); - - Const rd_clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE); - Const wr_clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE); - Const wr_clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY); - - int offset = cell->parameters.at(ID::OFFSET).as_int(); - if (offset != 0) - log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(cell)); - - for (int i = 0; i < rd_ports; i++) - { - if (rd_clk_enable[i] != State::S0) - log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(cell)); - - SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(i*abits, abits); - SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(i*width, width); - string addr_expr = make_expr(addr_sig); - string name(stringf("%s.r%d", m.name.c_str(), i)); - bool clk_enable = false; - bool clk_parity = true; - bool transparency = false; - SigSpec ena_sig = RTLIL::SigSpec(RTLIL::State::S1, 1); - SigSpec clk_sig = RTLIL::SigSpec(RTLIL::State::S0, 1); - read_port rp(name, clk_enable, clk_parity, transparency, clk_sig, ena_sig, addr_sig); - m.add_memory_read_port(rp); - cell_exprs.push_back(rp.gen_read(indent.c_str())); - register_reverse_wire_map(stringf("%s.data", name.c_str()), data_sig); - } - - for (int i = 0; i < wr_ports; i++) - { - if (wr_clk_enable[i] != State::S1) - log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(cell)); - - if (wr_clk_polarity[i] != State::S1) - log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(cell)); - - string name(stringf("%s.w%d", m.name.c_str(), i)); - bool clk_enable = true; - bool clk_parity = true; - bool transparency = false; - SigSpec addr_sig =cell->getPort(ID::WR_ADDR).extract(i*abits, abits); - string addr_expr = make_expr(addr_sig); - SigSpec data_sig =cell->getPort(ID::WR_DATA).extract(i*width, width); - string data_expr = make_expr(data_sig); - SigSpec clk_sig = cell->getPort(ID::WR_CLK).extract(i); - string clk_expr = make_expr(clk_sig); - - SigSpec wen_sig = cell->getPort(ID::WR_EN).extract(i*width, width); - string wen_expr = make_expr(wen_sig[0]); - - for (int i = 1; i < GetSize(wen_sig); i++) - if (wen_sig[0] != wen_sig[i]) - log_error("Complex write enable on port %d on memory %s.%s.\n", i, log_id(module), log_id(cell)); - - SigSpec mask_sig = RTLIL::SigSpec(RTLIL::State::S1, 1); - write_port wp(name, clk_enable, clk_parity, transparency, clk_sig, wen_sig[0], addr_sig, mask_sig); - m.add_memory_write_port(wp); - cell_exprs.push_back(stringf("%s%s.data <= %s\n", indent.c_str(), name.c_str(), data_expr.c_str())); - cell_exprs.push_back(wp.gen_write(indent.c_str())); - } - register_memory(m); - continue; - } - - if (cell->type.in(ID($memwr), ID($memrd), ID($meminit))) + if (cell->is_mem_cell()) { - std::string cell_type = fid(cell->type); - std::string mem_id = make_id(cell->parameters[ID::MEMID].decode_string()); - int abits = cell->parameters.at(ID::ABITS).as_int(); - int width = cell->parameters.at(ID::WIDTH).as_int(); - memory *mp = nullptr; - if (cell->type == ID($meminit) ) { - log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str()); - } else { - // It's a $memwr or $memrd. Remember the read/write port parameters for the eventual FIRRTL memory definition. - auto addrSig = cell->getPort(ID::ADDR); - auto dataSig = cell->getPort(ID::DATA); - auto enableSig = cell->getPort(ID::EN); - auto clockSig = cell->getPort(ID::CLK); - Const clk_enable = cell->parameters.at(ID::CLK_ENABLE); - Const clk_polarity = cell->parameters.at(ID::CLK_POLARITY); - - // Do we already have an entry for this memory? - if (memories.count(mem_id) == 0) { - memory m(cell, mem_id, abits, 0, width); - register_memory(m); - } - mp = &memories.at(mem_id); - int portNum = 0; - bool transparency = false; - string data_expr = make_expr(dataSig); - if (cell->type.in(ID($memwr))) { - portNum = (int) mp->write_ports.size(); - write_port wp(stringf("%s.w%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig, dataSig); - mp->add_memory_write_port(wp); - cell_exprs.push_back(stringf("%s%s.data <= %s\n", indent.c_str(), wp.name.c_str(), data_expr.c_str())); - cell_exprs.push_back(wp.gen_write(indent.c_str())); - } else if (cell->type.in(ID($memrd))) { - portNum = (int) mp->read_ports.size(); - read_port rp(stringf("%s.r%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig); - mp->add_memory_read_port(rp); - cell_exprs.push_back(rp.gen_read(indent.c_str())); - register_reverse_wire_map(stringf("%s.data", rp.name.c_str()), dataSig); - } - } + // Will be handled below, as part of a Mem. continue; } @@ -1145,12 +912,6 @@ struct FirrtlWorker continue; } - // This may be a parameterized module - paramod. - if (cell->type.begins_with("$paramod")) - { - process_instance(cell, wire_exprs); - continue; - } if (cell->type == ID($shiftx)) { // assign y = a[b +: y_width]; // We'll extract the correct bits as part of the primop. @@ -1215,6 +976,82 @@ struct FirrtlWorker log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } + for (auto &mem : memories) { + string mem_id = make_id(mem.memid); + + Const init_data = mem.get_init_data(); + if (!init_data.is_fully_undef()) + log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(mem.memid)); + + if (mem.start_offset != 0) + log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(mem.memid)); + + for (int i = 0; i < GetSize(mem.rd_ports); i++) + { + auto &port = mem.rd_ports[i]; + string port_name(stringf("%s.r%d", mem_id.c_str(), i)); + + if (port.clk_enable) + log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + + std::ostringstream rpe; + + string addr_expr = make_expr(port.addr); + string ena_expr = make_expr(State::S1); + string clk_expr = make_expr(State::S0); + + rpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str()); + rpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str()); + rpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str()); + cell_exprs.push_back(rpe.str()); + register_reverse_wire_map(stringf("%s.data", port_name.c_str()), port.data); + } + + for (int i = 0; i < GetSize(mem.wr_ports); i++) + { + auto &port = mem.wr_ports[i]; + string port_name(stringf("%s.w%d", mem_id.c_str(), i)); + + if (!port.clk_enable) + log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + if (!port.clk_polarity) + log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + for (int i = 1; i < GetSize(port.en); i++) + if (port.en[0] != port.en[i]) + log_error("Complex write enable on port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + + std::ostringstream wpe; + + string data_expr = make_expr(port.data); + string addr_expr = make_expr(port.addr); + string ena_expr = make_expr(port.en[0]); + string clk_expr = make_expr(port.clk); + string mask_expr = make_expr(State::S1); + wpe << stringf("%s%s.data <= %s\n", indent.c_str(), port_name.c_str(), data_expr.c_str()); + wpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str()); + wpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str()); + wpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str()); + wpe << stringf("%s%s.mask <= %s\n", indent.c_str(), port_name.c_str(), mask_expr.c_str()); + + cell_exprs.push_back(wpe.str()); + } + + std::ostringstream me; + + me << stringf(" mem %s:\n", mem_id.c_str()); + me << stringf(" data-type => UInt<%d>\n", mem.width); + me << stringf(" depth => %d\n", mem.size); + for (int i = 0; i < GetSize(mem.rd_ports); i++) + me << stringf(" reader => r%d\n", i); + for (int i = 0; i < GetSize(mem.wr_ports); i++) + me << stringf(" writer => w%d\n", i); + me << stringf(" read-latency => %d\n", 0); + me << stringf(" write-latency => %d\n", 1); + me << stringf(" read-under-write => undefined\n"); + + mem_exprs.push_back(me.str()); + } + for (auto conn : module->connections()) { string y_id = next_id(); @@ -1316,22 +1153,9 @@ struct FirrtlWorker f << stringf("\n"); - // If we have any memory definitions, output them. - for (auto kv : memories) { - memory &m = kv.second; - f << stringf(" mem %s:\n", m.name.c_str()); - f << stringf(" data-type => UInt<%d>\n", m.width); - f << stringf(" depth => %d\n", m.size); - for (int i = 0; i < (int) m.read_ports.size(); i += 1) { - f << stringf(" reader => r%d\n", i); - } - for (int i = 0; i < (int) m.write_ports.size(); i += 1) { - f << stringf(" writer => w%d\n", i); - } - f << stringf(" read-latency => %d\n", m.read_latency); - f << stringf(" write-latency => %d\n", m.write_latency); - f << stringf(" read-under-write => undefined\n"); - } + for (auto str : mem_exprs) + f << str; + f << stringf("\n"); for (auto str : cell_exprs) From c3e65a4ce0e0f14b279441c17e76b6c2ca9a7444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 17:18:03 +0200 Subject: [PATCH 0336/2410] Remove Travis CI. It has been replaced by GitHub Actions, and travis-ci.org is shutting down in a few days anyway. --- .travis.yml | 144 -------------------------------- .travis/build-and-test.sh | 51 ----------- .travis/common.sh | 15 ---- .travis/deploy-after-success.sh | 6 -- .travis/setup.sh | 63 -------------- 5 files changed, 279 deletions(-) delete mode 100644 .travis.yml delete mode 100755 .travis/build-and-test.sh delete mode 100644 .travis/common.sh delete mode 100755 .travis/deploy-after-success.sh delete mode 100755 .travis/setup.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 09f3808313a..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,144 +0,0 @@ -sudo: false -language: cpp - -cache: - ccache: true - directories: - - ~/.local-bin - - -env: - global: - - MAKEFLAGS="-j 2" - -matrix: - include: - # Latest gcc-4.8, earliest version supported by Travis - - os: linux - addons: - apt: - packages: - - g++-4.8 - - gperf - - build-essential - - bison - - flex - - libreadline-dev - - gawk - - tcl-dev - - libffi-dev - - git - - graphviz - - xdot - - pkg-config - - python - - python3 - - libboost-system-dev - - libboost-python-dev - - libboost-filesystem-dev - - zlib1g-dev - env: - - MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8" - - # Latest gcc supported on Travis Linux - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-9 - - gperf - - build-essential - - bison - - flex - - libreadline-dev - - gawk - - tcl-dev - - libffi-dev - - git - - graphviz - - xdot - - pkg-config - - python - - python3 - - libboost-system-dev - - libboost-python-dev - - libboost-filesystem-dev - - zlib1g-dev - env: - - MATRIX_EVAL="CONFIG=gcc && CC=gcc-9 && CXX=g++-9" - - # Clang which ships on Trusty Linux - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.8 - packages: - - clang-3.8 - - gperf - - build-essential - - bison - - flex - - libreadline-dev - - gawk - - tcl-dev - - libffi-dev - - git - - graphviz - - xdot - - pkg-config - - python - - python3 - - libboost-system-dev - - libboost-python-dev - - libboost-filesystem-dev - - zlib1g-dev - env: - - MATRIX_EVAL="CONFIG=clang && CC=clang-3.8 && CXX=clang++-3.8" - - # Latest clang supported by Travis Linux - - os: linux - addons: - apt: - sources: - - llvm-toolchain-xenial-8 - packages: - - clang-8 - - gperf - - build-essential - - bison - - flex - - libreadline-dev - - gawk - - tcl-dev - - libffi-dev - - git - - graphviz - - xdot - - pkg-config - - python - - python3 - - libboost-system-dev - - libboost-python-dev - - libboost-filesystem-dev - - zlib1g-dev - env: - - MATRIX_EVAL="CONFIG=clang && CC=clang-8 && CXX=clang++-8" - -# # Latest clang on Mac OS X -# - os: osx -# osx_image: xcode9.4 -# env: -# - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++" - -before_install: - - ./.travis/setup.sh - -script: - - ./.travis/build-and-test.sh - -after_success: - - ./.travis/deploy-after-success.sh diff --git a/.travis/build-and-test.sh b/.travis/build-and-test.sh deleted file mode 100755 index 801407d1e8f..00000000000 --- a/.travis/build-and-test.sh +++ /dev/null @@ -1,51 +0,0 @@ -#! /bin/bash - -set -e - -source .travis/common.sh - -########################################################################## - -echo -echo 'Configuring...' && echo -en 'travis_fold:start:script.configure\\r' -echo - -if [ "$CONFIG" = "gcc" ]; then - echo "Configuring for gcc." - make config-gcc -elif [ "$CONFIG" = "clang" ]; then - echo "Configuring for clang." - make config-clang -fi - -echo -echo -en 'travis_fold:end:script.configure\\r' -echo - -########################################################################## - -echo -echo 'Building...' && echo -en 'travis_fold:start:script.build\\r' -echo - -make CC=$CC CXX=$CC LD=$CC - -echo -echo -en 'travis_fold:end:script.build\\r' -echo - -########################################################################## - -./yosys tests/simple/fiedler-cooley.v - -echo -echo 'Testing...' && echo -en 'travis_fold:start:script.test\\r' -echo - -make test - -echo -echo -en 'travis_fold:end:script.test\\r' -echo - -########################################################################## diff --git a/.travis/common.sh b/.travis/common.sh deleted file mode 100644 index 8eecc4c099f..00000000000 --- a/.travis/common.sh +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/bash - -# Setup the CC / CXX from the matrix config -eval "${MATRIX_EVAL}" - -# Look for location binaries first -export PATH="$HOME/.local-bin/bin:$PATH" - -# OS X specific common setup -if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - export PATH="/usr/local/opt/ccache/libexec:$PATH" -fi - -# Parallel builds! -MAKEFLAGS="-j 2" diff --git a/.travis/deploy-after-success.sh b/.travis/deploy-after-success.sh deleted file mode 100755 index d64e95244f6..00000000000 --- a/.travis/deploy-after-success.sh +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/bash - -set -x -set -e - -# FIXME: Upload the build results somewhere... diff --git a/.travis/setup.sh b/.travis/setup.sh deleted file mode 100755 index 02879b97436..00000000000 --- a/.travis/setup.sh +++ /dev/null @@ -1,63 +0,0 @@ -#! /bin/bash - -set -e - -source .travis/common.sh - -########################################################################## - -# Output status information. -( - set +e - set -x - git status - git branch -v - git log -n 5 --graph - git log --format=oneline -n 20 --graph -) -echo -echo -en 'travis_fold:end:before_install.git\\r' -echo - -########################################################################## - -# Mac OS X specific setup. -if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - ( - echo - echo 'Setting up brew...' && echo -en 'travis_fold:start:before_install.brew\\r' - echo - brew update - brew tap Homebrew/bundle - brew bundle - brew install ccache - echo - echo -en 'travis_fold:end:before_install.brew\\r' - echo - ) -fi - -########################################################################## - -# Install iverilog -( - if [ ! -e ~/.local-bin/bin/iverilog ]; then - echo - echo 'Building iverilog...' && echo -en 'travis_fold:start:before_install.iverilog\\r' - echo - mkdir -p ~/.local-src - mkdir -p ~/.local-bin - cd ~/.local-src - git clone git://github.com/steveicarus/iverilog.git - cd iverilog - autoconf - CC=gcc CXX=g++ ./configure --prefix=$HOME/.local-bin - make - make install - echo - echo -en 'travis_fold:end:before_install.iverilog\\r' - echo - fi -) - -########################################################################## From 5488c69d2a92fc05b6d3df99ba80b69d5a1a555c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 17:37:29 +0200 Subject: [PATCH 0337/2410] Add a .mailmap file. --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000000..f3c1ba97a8a --- /dev/null +++ b/.mailmap @@ -0,0 +1,3 @@ +Marcelina Kościelnicka +Marcelina Kościelnicka +Marcelina Kościelnicka From dbfd0b61e378dd8c0e0f64205756ed7919de083c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 21:27:29 +0200 Subject: [PATCH 0338/2410] hashlib: Add a hash for bool. --- kernel/hashlib.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index a523afadd08..42fb8d3635a 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -66,6 +66,12 @@ struct hash_int_ops { } }; +template<> struct hash_ops : hash_int_ops +{ + static inline unsigned int hash(bool a) { + return a ? 1 : 0; + } +}; template<> struct hash_ops : hash_int_ops { static inline unsigned int hash(int32_t a) { From b706adb809f17ea897e8534a7ee3ae833b243d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 23 May 2021 17:20:55 +0200 Subject: [PATCH 0339/2410] opt_mem_feedback: Convert to Mem helpers. --- passes/opt/opt_mem_feedback.cc | 77 +++++++++++++--------------------- 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 75e24451468..63917c23af8 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -18,23 +18,12 @@ */ #include "kernel/yosys.h" -#include "kernel/satgen.h" #include "kernel/sigtools.h" -#include "kernel/modtools.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool memrd_cmp(RTLIL::Cell *a, RTLIL::Cell *b) -{ - return a->name < b->name; -} - -bool memwr_cmp(RTLIL::Cell *a, RTLIL::Cell *b) -{ - return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int(); -} - struct OptMemFeedbackWorker { RTLIL::Design *design; @@ -138,7 +127,7 @@ struct OptMemFeedbackWorker return conditions_logic_cache[key] = terms; } - void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) + void translate_rd_feedback_to_en(Mem &mem) { std::map>> async_rd_bits; std::map> muxtree_upstream_map; @@ -173,7 +162,7 @@ struct OptMemFeedbackWorker } if (cell->type.in(ID($memwr), ID($memrd)) && - cell->parameters.at(ID::MEMID).decode_string() == memid) + IdString(cell->parameters.at(ID::MEMID).decode_string()) == mem.memid) ignore_data_port = true; for (auto conn : cell->connections()) @@ -201,21 +190,18 @@ struct OptMemFeedbackWorker expand_non_feedback_nets.swap(new_expand_non_feedback_nets); } - for (auto cell : rd_ports) + for (auto &port : mem.rd_ports) { - if (cell->parameters.at(ID::CLK_ENABLE).as_bool()) + if (port.clk_enable) continue; - RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR)); - std::vector sig_data = sigmap(cell->getPort(ID::DATA)); - - for (int i = 0; i < int(sig_data.size()); i++) - if (non_feedback_nets.count(sig_data[i])) + for (auto &bit : port.data) + if (non_feedback_nets.count(bit)) goto not_pure_feedback_port; - async_rd_bits[sig_addr].resize(max(async_rd_bits.size(), sig_data.size())); - for (int i = 0; i < int(sig_data.size()); i++) - async_rd_bits[sig_addr][i].insert(sig_data[i]); + async_rd_bits[port.addr].resize(max(GetSize(async_rd_bits), GetSize(port.data))); + for (int i = 0; i < GetSize(port.data); i++) + async_rd_bits[port.addr][i].insert(port.data[i]); not_pure_feedback_port:; } @@ -223,35 +209,37 @@ struct OptMemFeedbackWorker if (async_rd_bits.empty()) return; - log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(memid)); + bool changed = false; + log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(mem.memid)); - for (auto cell : wr_ports) + for (int i = 0; i < GetSize(mem.wr_ports); i++) { - RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR)); - if (!async_rd_bits.count(sig_addr)) - continue; + auto &port = mem.wr_ports[i]; - log(" Analyzing write port %s.\n", log_id(cell)); + if (!async_rd_bits.count(port.addr)) + continue; - std::vector cell_data = cell->getPort(ID::DATA); - std::vector cell_en = cell->getPort(ID::EN); + log(" Analyzing write port %d.\n", i); int created_conditions = 0; - for (int i = 0; i < int(cell_data.size()); i++) - if (cell_en[i] != RTLIL::SigBit(RTLIL::State::S0)) + for (int j = 0; j < GetSize(port.data); j++) + if (port.en[j] != RTLIL::SigBit(RTLIL::State::S0)) { std::map state; std::set> conditions; - find_data_feedback(async_rd_bits.at(sig_addr).at(i), cell_data[i], state, conditions); - cell_en[i] = conditions_to_logic(conditions, cell_en[i], created_conditions); + find_data_feedback(async_rd_bits.at(port.addr).at(j), port.data[j], state, conditions); + port.en[j] = conditions_to_logic(conditions, port.en[j], created_conditions); } if (created_conditions) { log(" Added enable logic for %d different cases.\n", created_conditions); - cell->setPort(ID::EN, cell_en); + changed = true; } } + + if (changed) + mem.emit(); } // ------------- @@ -262,7 +250,7 @@ struct OptMemFeedbackWorker void operator()(RTLIL::Module* module) { - std::map, std::vector>> memindex; + std::vector memories = Mem::get_selected_memories(module); this->module = module; sigmap.set(module); @@ -272,12 +260,6 @@ struct OptMemFeedbackWorker sigmap_xmux = sigmap; for (auto cell : module->cells()) { - if (cell->type == ID($memrd)) - memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell); - - if (cell->type == ID($memwr)) - memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell); - if (cell->type == ID($mux)) { RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A)); @@ -297,11 +279,8 @@ struct OptMemFeedbackWorker } } - for (auto &it : memindex) { - std::sort(it.second.first.begin(), it.second.first.end(), memrd_cmp); - std::sort(it.second.second.begin(), it.second.second.end(), memwr_cmp); - translate_rd_feedback_to_en(it.first, it.second.first, it.second.second); - } + for (auto &mem : memories) + translate_rd_feedback_to_en(mem); } }; From 835688bf80eb9db7241c1aa767b7e97dad1c0eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 21:21:51 +0200 Subject: [PATCH 0340/2410] opt_mem_feedback: Rewrite feedback path finding logic. Fixes #2766. --- passes/opt/opt_mem_feedback.cc | 245 +++++++++++++++++---------------- tests/opt/bug2766.ys | 101 ++++++++++++++ tests/opt/opt_mem_feedback.ys | 142 +++++++++++++++++++ 3 files changed, 373 insertions(+), 115 deletions(-) create mode 100644 tests/opt/bug2766.ys create mode 100644 tests/opt/opt_mem_feedback.ys diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 63917c23af8..f186d845dd9 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -24,30 +24,52 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +// Describes found feedback path. +struct FeedbackPath { + // Which write port it is. + int wrport_idx; + // Which data bit of that write port it is. + int data_bit_idx; + // Values of all mux select signals that need to be set to select this path. + dict condition; + // The exact feedback bit used (used to match read port). + SigBit feedback_bit; + + FeedbackPath(int wrport_idx, int data_bit_idx, dict condition, SigBit feedback_bit) : wrport_idx(wrport_idx), data_bit_idx(data_bit_idx), condition(condition), feedback_bit(feedback_bit) {} +}; + struct OptMemFeedbackWorker { RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap, sigmap_xmux; - std::map> sig_to_mux; - std::map>, SigBit>, SigBit> conditions_logic_cache; + dict> sig_to_mux; + dict sig_users_count; + dict>, SigBit>, SigBit> conditions_logic_cache; // ----------------------------------------------------------------- // Converting feedbacks to async read ports to proper enable signals // ----------------------------------------------------------------- - bool find_data_feedback(const std::set &async_rd_bits, RTLIL::SigBit sig, - std::map &state, std::set> &conditions) + void find_data_feedback(const pool &async_rd_bits, RTLIL::SigBit sig, + const dict &state, + int wrport_idx, int data_bit_idx, + std::vector &paths) { if (async_rd_bits.count(sig)) { - conditions.insert(state); - return true; + paths.push_back(FeedbackPath(wrport_idx, data_bit_idx, state, sig)); + return; + } + + if (sig_users_count[sig] != 1) { + // Only descend into muxes if we're the only user. + return; } if (sig_to_mux.count(sig) == 0) - return false; + return; RTLIL::Cell *cell = sig_to_mux.at(sig).first; int bit_idx = sig_to_mux.at(sig).second; @@ -58,46 +80,32 @@ struct OptMemFeedbackWorker std::vector sig_y = sigmap(cell->getPort(ID::Y)); log_assert(sig_y.at(bit_idx) == sig); - for (int i = 0; i < int(sig_s.size()); i++) + for (int i = 0; i < GetSize(sig_s); i++) if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) { - RTLIL::SigSpec new_b = cell->getPort(ID::B); - new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->setPort(ID::B, new_b); - } - return false; + find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, wrport_idx, data_bit_idx, paths); + return; } - for (int i = 0; i < int(sig_s.size()); i++) + for (int i = 0; i < GetSize(sig_s); i++) { if (state.count(sig_s[i]) && state.at(sig_s[i]) == false) continue; - std::map new_state = state; + dict new_state = state; new_state[sig_s[i]] = true; - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) { - RTLIL::SigSpec new_b = cell->getPort(ID::B); - new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->setPort(ID::B, new_b); - } + find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, wrport_idx, data_bit_idx, paths); } - std::map new_state = state; - for (int i = 0; i < int(sig_s.size()); i++) - new_state[sig_s[i]] = false; - - if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) { - RTLIL::SigSpec new_a = cell->getPort(ID::A); - new_a.replace(bit_idx, RTLIL::State::Sx); - cell->setPort(ID::A, new_a); - } + dict new_state = state; + for (auto bit : sig_s) + new_state[bit] = false; - return false; + find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, wrport_idx, data_bit_idx, paths); } - RTLIL::SigBit conditions_to_logic(std::set> &conditions, SigBit olden, int &created_conditions) + RTLIL::SigBit conditions_to_logic(pool> &conditions, SigBit olden) { auto key = make_pair(conditions, olden); @@ -112,10 +120,9 @@ struct OptMemFeedbackWorker sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0); } terms.append(module->Ne(NEW_ID, sig1, sig2)); - created_conditions++; } - if (olden.wire != nullptr || olden != State::S1) + if (olden != State::S1) terms.append(olden); if (GetSize(terms) == 0) @@ -129,117 +136,113 @@ struct OptMemFeedbackWorker void translate_rd_feedback_to_en(Mem &mem) { - std::map>> async_rd_bits; - std::map> muxtree_upstream_map; - std::set non_feedback_nets; - - for (auto wire : module->wires()) - if (wire->port_output) { - std::vector bits = sigmap(wire); - non_feedback_nets.insert(bits.begin(), bits.end()); - } + // Look for async read ports that may be suitable for feedback paths. + dict>> async_rd_bits; - for (auto cell : module->cells()) + for (auto &port : mem.rd_ports) { - bool ignore_data_port = false; + if (port.clk_enable) + continue; - if (cell->type.in(ID($mux), ID($pmux))) - { - std::vector sig_a = sigmap(cell->getPort(ID::A)); - std::vector sig_b = sigmap(cell->getPort(ID::B)); - std::vector sig_s = sigmap(cell->getPort(ID::S)); - std::vector sig_y = sigmap(cell->getPort(ID::Y)); + SigSpec addr = sigmap_xmux(port.addr); - non_feedback_nets.insert(sig_s.begin(), sig_s.end()); + async_rd_bits[addr].resize(mem.width); + for (int i = 0; i < mem.width; i++) + async_rd_bits[addr][i].insert(sigmap(port.data[i])); + } + + if (async_rd_bits.empty()) + return; + + // Look for actual feedback paths. + std::vector paths; + + for (int i = 0; i < GetSize(mem.wr_ports); i++) + { + auto &port = mem.wr_ports[i]; - for (int i = 0; i < int(sig_y.size()); i++) { - muxtree_upstream_map[sig_y[i]].insert(sig_a[i]); - for (int j = 0; j < int(sig_s.size()); j++) - muxtree_upstream_map[sig_y[i]].insert(sig_b[i + j*sig_y.size()]); - } + SigSpec addr = sigmap_xmux(port.addr); + if (!async_rd_bits.count(addr)) continue; - } - if (cell->type.in(ID($memwr), ID($memrd)) && - IdString(cell->parameters.at(ID::MEMID).decode_string()) == mem.memid) - ignore_data_port = true; + log(" Analyzing %s.%s write port %d.\n", log_id(module), log_id(mem.memid), i); - for (auto conn : cell->connections()) + for (int j = 0; j < GetSize(port.data); j++) { - if (ignore_data_port && conn.first == ID::DATA) + if (port.en[j] == State::S0) continue; - std::vector bits = sigmap(conn.second); - non_feedback_nets.insert(bits.begin(), bits.end()); + + dict state; + + find_data_feedback(async_rd_bits.at(addr).at(j), sigmap(port.data[j]), state, i, j, paths); } } - std::set expand_non_feedback_nets = non_feedback_nets; - while (!expand_non_feedback_nets.empty()) - { - std::set new_expand_non_feedback_nets; + if (paths.empty()) + return; - for (auto &bit : expand_non_feedback_nets) - if (muxtree_upstream_map.count(bit)) - for (auto &new_bit : muxtree_upstream_map.at(bit)) - if (!non_feedback_nets.count(new_bit)) { - non_feedback_nets.insert(new_bit); - new_expand_non_feedback_nets.insert(new_bit); - } + // Now determine which read ports are actually used only for + // feedback paths, and can be removed. - expand_non_feedback_nets.swap(new_expand_non_feedback_nets); - } + dict feedback_users_count; + for (auto &path : paths) + feedback_users_count[path.feedback_bit]++; + pool feedback_ok; for (auto &port : mem.rd_ports) { if (port.clk_enable) continue; - for (auto &bit : port.data) - if (non_feedback_nets.count(bit)) - goto not_pure_feedback_port; + bool ok = true; + for (auto bit : sigmap(port.data)) + if (sig_users_count[bit] != feedback_users_count[bit]) + ok = false; - async_rd_bits[port.addr].resize(max(GetSize(async_rd_bits), GetSize(port.data))); - for (int i = 0; i < GetSize(port.data); i++) - async_rd_bits[port.addr][i].insert(port.data[i]); + if (ok) + { + // This port is going bye-bye. + for (auto bit : sigmap(port.data)) + feedback_ok.insert(bit); - not_pure_feedback_port:; + port.removed = true; + } } - if (async_rd_bits.empty()) + if (feedback_ok.empty()) return; - bool changed = false; - log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(mem.memid)); + // Prepare a feedback condition list grouped by port bits. - for (int i = 0; i < GetSize(mem.wr_ports); i++) - { - auto &port = mem.wr_ports[i]; + dict, pool>> portbit_conds; + for (auto &path : paths) + if (feedback_ok.count(path.feedback_bit)) + portbit_conds[std::make_pair(path.wrport_idx, path.data_bit_idx)].insert(path.condition); - if (!async_rd_bits.count(port.addr)) - continue; + if (portbit_conds.empty()) + return; - log(" Analyzing write port %d.\n", i); + // Okay, let's do it. - int created_conditions = 0; - for (int j = 0; j < GetSize(port.data); j++) - if (port.en[j] != RTLIL::SigBit(RTLIL::State::S0)) - { - std::map state; - std::set> conditions; - - find_data_feedback(async_rd_bits.at(port.addr).at(j), port.data[j], state, conditions); - port.en[j] = conditions_to_logic(conditions, port.en[j], created_conditions); - } - - if (created_conditions) { - log(" Added enable logic for %d different cases.\n", created_conditions); - changed = true; - } + log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", log_id(module), log_id(mem.memid)); + + for (auto &it : portbit_conds) + { + int wrport_idx = it.first.first; + int bit = it.first.second; + auto &port = mem.wr_ports[wrport_idx]; + + port.en[bit] = conditions_to_logic(it.second, port.en[bit]); + log(" Port %d bit %d: added enable logic for %d different cases.\n", wrport_idx, bit, GetSize(it.second)); } - if (changed) - mem.emit(); + mem.emit(); + + for (auto bit : feedback_ok) + module->connect(bit, State::Sx); + + design->scratchpad_set_bool("opt.did_something", true); } // ------------- @@ -258,6 +261,13 @@ struct OptMemFeedbackWorker conditions_logic_cache.clear(); sigmap_xmux = sigmap; + + for (auto wire : module->wires()) { + if (wire->port_output) + for (auto bit : sigmap(wire)) + sig_users_count[bit]++; + } + for (auto cell : module->cells()) { if (cell->type == ID($mux)) @@ -277,6 +287,11 @@ struct OptMemFeedbackWorker for (int i = 0; i < int(sig_y.size()); i++) sig_to_mux[sig_y[i]] = std::pair(cell, i); } + + for (auto &conn : cell->connections()) + if (!cell->known() || cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + sig_users_count[bit]++; } for (auto &mem : memories) @@ -292,10 +307,10 @@ struct OptMemFeedbackPass : public Pass { log("\n"); log(" opt_mem_feedback [selection]\n"); log("\n"); - log("This pass detects cases where an asynchronous read port is connected via\n"); - log("a mux tree to a write port with the same address. When such a path is\n"); - log("found, it is replaced with a new condition on an enable signal, possibly\n"); - log("allowing for removal of the read port.\n"); + log("This pass detects cases where an asynchronous read port is only connected via\n"); + log("a mux tree to a write port with the same address. When such a connection is\n"); + log("found, it is replaced with a new condition on an enable signal, allowing\n"); + log("for removal of the read port.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { diff --git a/tests/opt/bug2766.ys b/tests/opt/bug2766.ys new file mode 100644 index 00000000000..c7aa916f4ef --- /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/opt_mem_feedback.ys b/tests/opt/opt_mem_feedback.ys new file mode 100644 index 00000000000..6a68921c361 --- /dev/null +++ b/tests/opt/opt_mem_feedback.ys @@ -0,0 +1,142 @@ +# 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 +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: : From 95a39d342584fc9f98c57550aa7fba9e4652067b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 17:00:20 +0200 Subject: [PATCH 0341/2410] kernel/mem: Add priority_mask to model. This is going to be used to store arbitrary priority masks in the future. Right now, it is not supported by our cell library, so the priority_mask is computed from port order on helper construction, and discarded when emitted. However, this allows us to already convert helper-using passes to the new model. --- kernel/mem.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- kernel/mem.h | 1 + 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 4c3b333c1c3..2a51ec5d9ba 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -85,7 +85,12 @@ void Mem::emit() { wr_ports.resize(GetSize(wr_left)); // for future: handle transparency mask here - // for future: handle priority mask here + + for (auto &port : wr_ports) { + for (int i = 0; i < GetSize(wr_left); i++) + port.priority_mask[i] = port.priority_mask[wr_left[i]]; + port.priority_mask.resize(GetSize(wr_left)); + } if (packed) { if (mem) { @@ -276,6 +281,18 @@ void Mem::check() { log_assert(GetSize(port.clk) == 1); log_assert(GetSize(port.en) == width); log_assert(GetSize(port.data) == width); + log_assert(GetSize(port.priority_mask) == GetSize(wr_ports)); + for (int j = 0; j < GetSize(wr_ports); j++) { + auto &wport = wr_ports[j]; + if (port.priority_mask[j] && !wport.removed) { + log_assert(j < i); + log_assert(port.clk_enable == wport.clk_enable); + if (port.clk_enable) { + log_assert(port.clk == wport.clk); + log_assert(port.clk_polarity == wport.clk_polarity); + } + } + } } } @@ -355,6 +372,20 @@ namespace { for (auto &it : inits) res.inits.push_back(it.second); } + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } + } res.check(); return res; } @@ -412,6 +443,20 @@ namespace { mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, res.width); res.wr_ports.push_back(mwr); } + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } + } res.check(); return res; } diff --git a/kernel/mem.h b/kernel/mem.h index a2af6a183c6..af06e970af8 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -40,6 +40,7 @@ struct MemWr { dict attributes; Cell *cell; bool clk_enable, clk_polarity; + std::vector priority_mask; SigSpec clk, en, addr, data; MemWr() : removed(false), cell(nullptr) {} }; From ff9713dd86cb6390f30392580e665095055a867c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 16:48:46 +0200 Subject: [PATCH 0342/2410] kernel/mem: Add model for wide ports. Such ports cannot actually be created or used yet, this just adds the necessary plumbing in the helper. Subsequent commits will gradually add wide port support to various yosys passes. --- kernel/mem.cc | 32 ++++++++++++++++++++++++++------ kernel/mem.h | 2 ++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 2a51ec5d9ba..2285cf74d67 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -121,6 +121,8 @@ void Mem::emit() { abits = std::max(abits, GetSize(port.addr)); cell->parameters[ID::ABITS] = Const(abits); for (auto &port : rd_ports) { + // TODO: remove + log_assert(port.wide_log2 == 0); if (port.cell) { module->remove(port.cell); port.cell = nullptr; @@ -152,6 +154,8 @@ void Mem::emit() { cell->setPort(ID::RD_ADDR, rd_addr); cell->setPort(ID::RD_DATA, rd_data); for (auto &port : wr_ports) { + // TODO: remove + log_assert(port.wide_log2 == 0); if (port.cell) { module->remove(port.cell); port.cell = nullptr; @@ -206,7 +210,7 @@ void Mem::emit() { port.cell = module->addCell(NEW_ID, ID($memrd)); port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); - port.cell->parameters[ID::WIDTH] = width; + port.cell->parameters[ID::WIDTH] = width << port.wide_log2; port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; port.cell->parameters[ID::TRANSPARENT] = port.transparent; @@ -221,7 +225,7 @@ void Mem::emit() { port.cell = module->addCell(NEW_ID, ID($memwr)); port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); - port.cell->parameters[ID::WIDTH] = width; + port.cell->parameters[ID::WIDTH] = width << port.wide_log2; port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; port.cell->parameters[ID::PRIORITY] = idx++; @@ -264,23 +268,32 @@ Const Mem::get_init_data() const { } void Mem::check() { + int max_wide_log2 = 0; for (auto &port : rd_ports) { if (port.removed) continue; log_assert(GetSize(port.clk) == 1); log_assert(GetSize(port.en) == 1); - log_assert(GetSize(port.data) == width); + log_assert(GetSize(port.data) == (width << port.wide_log2)); if (!port.clk_enable) { log_assert(!port.transparent); } + for (int j = 0; j < port.wide_log2; j++) { + log_assert(port.addr[j] == State::S0); + } + max_wide_log2 = std::max(max_wide_log2, port.wide_log2); } for (int i = 0; i < GetSize(wr_ports); i++) { auto &port = wr_ports[i]; if (port.removed) continue; log_assert(GetSize(port.clk) == 1); - log_assert(GetSize(port.en) == width); - log_assert(GetSize(port.data) == width); + log_assert(GetSize(port.en) == (width << port.wide_log2)); + log_assert(GetSize(port.data) == (width << port.wide_log2)); + for (int j = 0; j < port.wide_log2; j++) { + log_assert(port.addr[j] == State::S0); + } + max_wide_log2 = std::max(max_wide_log2, port.wide_log2); log_assert(GetSize(port.priority_mask) == GetSize(wr_ports)); for (int j = 0; j < GetSize(wr_ports); j++) { auto &wport = wr_ports[j]; @@ -294,6 +307,9 @@ void Mem::check() { } } } + int mask = (1 << max_wide_log2) - 1; + log_assert(!(start_offset & mask)); + log_assert(!(size & mask)); } namespace { @@ -331,6 +347,7 @@ namespace { mrd.en = cell->getPort(ID::EN); mrd.addr = cell->getPort(ID::ADDR); mrd.data = cell->getPort(ID::DATA); + mrd.wide_log2 = ceil_log2(GetSize(mrd.data) / mem->width); res.rd_ports.push_back(mrd); } } @@ -346,6 +363,7 @@ namespace { mwr.en = cell->getPort(ID::EN); mwr.addr = cell->getPort(ID::ADDR); mwr.data = cell->getPort(ID::DATA); + mwr.wide_log2 = ceil_log2(GetSize(mwr.data) / mem->width); ports.push_back(std::make_pair(cell->parameters.at(ID::PRIORITY).as_int(), mwr)); } std::sort(ports.begin(), ports.end(), [](const std::pair &a, const std::pair &b) { return a.first < b.first; }); @@ -424,6 +442,7 @@ namespace { } for (int i = 0; i < cell->parameters.at(ID::RD_PORTS).as_int(); i++) { MemRd mrd; + mrd.wide_log2 = 0; mrd.clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE).extract(i, 1).as_bool(); mrd.clk_polarity = cell->parameters.at(ID::RD_CLK_POLARITY).extract(i, 1).as_bool(); mrd.transparent = cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool(); @@ -435,6 +454,7 @@ namespace { } for (int i = 0; i < cell->parameters.at(ID::WR_PORTS).as_int(); i++) { MemWr mwr; + mwr.wide_log2 = 0; mwr.clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE).extract(i, 1).as_bool(); mwr.clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY).extract(i, 1).as_bool(); mwr.clk = cell->getPort(ID::WR_CLK).extract(i, 1); @@ -507,7 +527,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } else { - SigSpec sig_d = module->addWire(stringf("%s$rdreg[%d]$d", memid.c_str(), idx), width); + SigSpec sig_d = module->addWire(stringf("%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); SigSpec sig_q = port.data; port.data = sig_d; c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); diff --git a/kernel/mem.h b/kernel/mem.h index af06e970af8..e0d8c277f49 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -29,6 +29,7 @@ struct MemRd { bool removed; dict attributes; Cell *cell; + int wide_log2; bool clk_enable, clk_polarity; bool transparent; SigSpec clk, en, addr, data; @@ -39,6 +40,7 @@ struct MemWr { bool removed; dict attributes; Cell *cell; + int wide_log2; bool clk_enable, clk_polarity; std::vector priority_mask; SigSpec clk, en, addr, data; From 8c1999aac1a5d8388451fab05b6c4752fbe0a031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 00:49:52 +0200 Subject: [PATCH 0343/2410] kernel/mem: Emit support for wide ports in packed mode. Since the packed cell doesn't actually support wide ports yet, we just auto-narrow them on emit. The future packed cell will add RD_WIDE_CONTINUATION and WR_WIDE_CONTINUATION parameters so the transform will be trivially reversible for proper serialization. --- kernel/mem.cc | 64 +++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 2285cf74d67..de8ae8b1be4 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -108,10 +108,8 @@ void Mem::emit() { cell->parameters[ID::WIDTH] = Const(width); cell->parameters[ID::OFFSET] = Const(start_offset); cell->parameters[ID::SIZE] = Const(size); - cell->parameters[ID::RD_PORTS] = Const(GetSize(rd_ports)); - cell->parameters[ID::WR_PORTS] = Const(GetSize(wr_ports)); - Const rd_clk_enable, rd_clk_polarity, rd_transparent; - Const wr_clk_enable, wr_clk_polarity; + Const rd_wide_continuation, rd_clk_enable, rd_clk_polarity, rd_transparent; + Const wr_wide_continuation, wr_clk_enable, wr_clk_polarity; SigSpec rd_clk, rd_en, rd_addr, rd_data; SigSpec wr_clk, wr_en, wr_addr, wr_data; int abits = 0; @@ -121,31 +119,34 @@ void Mem::emit() { abits = std::max(abits, GetSize(port.addr)); cell->parameters[ID::ABITS] = Const(abits); for (auto &port : rd_ports) { - // TODO: remove - log_assert(port.wide_log2 == 0); if (port.cell) { module->remove(port.cell); port.cell = nullptr; } - rd_clk_enable.bits.push_back(State(port.clk_enable)); - rd_clk_polarity.bits.push_back(State(port.clk_polarity)); - rd_transparent.bits.push_back(State(port.transparent)); - rd_clk.append(port.clk); - log_assert(GetSize(port.clk) == 1); - rd_en.append(port.en); - log_assert(GetSize(port.en) == 1); - SigSpec addr = port.addr; - addr.extend_u0(abits, false); - rd_addr.append(addr); - log_assert(GetSize(addr) == abits); + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + { + rd_wide_continuation.bits.push_back(State(sub != 0)); + rd_clk_enable.bits.push_back(State(port.clk_enable)); + rd_clk_polarity.bits.push_back(State(port.clk_polarity)); + rd_transparent.bits.push_back(State(port.transparent)); + rd_clk.append(port.clk); + rd_en.append(port.en); + SigSpec addr = port.addr; + addr.extend_u0(abits, false); + for (int i = 0; i < port.wide_log2; i++) + addr[i] = State(sub >> i & 1); + rd_addr.append(addr); + log_assert(GetSize(addr) == abits); + } rd_data.append(port.data); - log_assert(GetSize(port.data) == width); } if (rd_ports.empty()) { + rd_wide_continuation = State::S0; rd_clk_enable = State::S0; rd_clk_polarity = State::S0; rd_transparent = State::S0; } + cell->parameters[ID::RD_PORTS] = Const(GetSize(rd_clk)); cell->parameters[ID::RD_CLK_ENABLE] = rd_clk_enable; cell->parameters[ID::RD_CLK_POLARITY] = rd_clk_polarity; cell->parameters[ID::RD_TRANSPARENT] = rd_transparent; @@ -154,29 +155,32 @@ void Mem::emit() { cell->setPort(ID::RD_ADDR, rd_addr); cell->setPort(ID::RD_DATA, rd_data); for (auto &port : wr_ports) { - // TODO: remove - log_assert(port.wide_log2 == 0); if (port.cell) { module->remove(port.cell); port.cell = nullptr; } - wr_clk_enable.bits.push_back(State(port.clk_enable)); - wr_clk_polarity.bits.push_back(State(port.clk_polarity)); - wr_clk.append(port.clk); - log_assert(GetSize(port.clk) == 1); + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + { + wr_wide_continuation.bits.push_back(State(sub != 0)); + wr_clk_enable.bits.push_back(State(port.clk_enable)); + wr_clk_polarity.bits.push_back(State(port.clk_polarity)); + wr_clk.append(port.clk); + SigSpec addr = port.addr; + addr.extend_u0(abits, false); + for (int i = 0; i < port.wide_log2; i++) + addr[i] = State(sub >> i & 1); + wr_addr.append(addr); + log_assert(GetSize(addr) == abits); + } wr_en.append(port.en); - log_assert(GetSize(port.en) == width); - SigSpec addr = port.addr; - addr.extend_u0(abits, false); - wr_addr.append(addr); - log_assert(GetSize(addr) == abits); wr_data.append(port.data); - log_assert(GetSize(port.data) == width); } if (wr_ports.empty()) { + wr_wide_continuation = State::S0; wr_clk_enable = State::S0; wr_clk_polarity = State::S0; } + cell->parameters[ID::WR_PORTS] = Const(GetSize(wr_clk)); cell->parameters[ID::WR_CLK_ENABLE] = wr_clk_enable; cell->parameters[ID::WR_CLK_POLARITY] = wr_clk_polarity; cell->setPort(ID::WR_CLK, wr_clk); From 35ee774ea8eac9b745f93641a192341fe559fa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 00:58:17 +0200 Subject: [PATCH 0344/2410] kernel/mem: Add a Mem::narrow helper to split up wide ports. --- kernel/mem.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/mem.h | 2 ++ 2 files changed, 53 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index de8ae8b1be4..f2c8dd953b0 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -548,3 +548,54 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { return c; } + +void Mem::narrow() { + std::vector new_rd_ports; + std::vector new_wr_ports; + std::vector> new_rd_map; + std::vector> new_wr_map; + for (int i = 0; i < GetSize(rd_ports); i++) { + auto &port = rd_ports[i]; + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { + new_rd_map.push_back(std::make_pair(i, sub)); + } + } + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &port = wr_ports[i]; + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { + new_wr_map.push_back(std::make_pair(i, sub)); + } + } + for (auto &it : new_rd_map) { + MemRd &orig = rd_ports[it.first]; + MemRd port = orig; + if (it.second != 0) + port.cell = nullptr; + if (port.wide_log2) { + port.data = port.data.extract(it.second * width, width); + for (int i = 0; i < port.wide_log2; i++) + port.addr[i] = State(it.second >> i & 1); + port.wide_log2 = 0; + } + new_rd_ports.push_back(port); + } + for (auto &it : new_wr_map) { + MemWr &orig = wr_ports[it.first]; + MemWr port = orig; + if (it.second != 0) + port.cell = nullptr; + if (port.wide_log2) { + port.data = port.data.extract(it.second * width, width); + port.en = port.en.extract(it.second * width, width); + for (int i = 0; i < port.wide_log2; i++) + port.addr[i] = State(it.second >> i & 1); + port.wide_log2 = 0; + } + port.priority_mask.clear(); + for (auto &it2 : new_wr_map) + port.priority_mask.push_back(orig.priority_mask[it2.first]); + new_wr_ports.push_back(port); + } + std::swap(rd_ports, new_rd_ports); + std::swap(wr_ports, new_wr_ports); +} diff --git a/kernel/mem.h b/kernel/mem.h index e0d8c277f49..214086ac47e 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -75,6 +75,8 @@ struct Mem { static std::vector get_all_memories(Module *module); static std::vector get_selected_memories(Module *module); Cell *extract_rdff(int idx, FfInitVals *initvals); + void narrow(); + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} }; From 69bf5c81c7cf65ccb8bd035eb45137e31a68ae86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 18:18:50 +0200 Subject: [PATCH 0345/2410] Reject wide ports in some passes that will never support them. --- backends/btor/btor.cc | 13 +++++++++++-- backends/firrtl/firrtl.cc | 4 ++++ backends/smt2/smt2.cc | 6 ++++++ passes/memory/memory_bram.cc | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index bc0504d6479..999836882ee 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -728,10 +728,19 @@ struct BtorWorker log_error("Memory %s.%s has mixed async/sync write ports.\n", log_id(module), log_id(mem->memid)); - for (auto &port : mem->rd_ports) + for (auto &port : mem->rd_ports) { if (port.clk_enable) - log_error("Memory %s.%s has sync read ports.\n", + log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n", + log_id(module), log_id(mem->memid)); + if (port.wide_log2) + log_error("Memory %s.%s has wide read ports. Please use memory_narrow to convert them first.\n", + log_id(module), log_id(mem->memid)); + } + for (auto &port : mem->wr_ports) { + if (port.wide_log2) + log_error("Memory %s.%s has wide write ports. Please use memory_narrow to convert them first.\n", log_id(module), log_id(mem->memid)); + } int data_sid = get_bv_sid(mem->width); int bool_sid = get_bv_sid(1); diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index f99becacffa..dee24d0e229 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -993,6 +993,8 @@ struct FirrtlWorker if (port.clk_enable) log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + if (port.wide_log2 != 0) + log_error("Wide read port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); std::ostringstream rpe; @@ -1014,6 +1016,8 @@ struct FirrtlWorker if (!port.clk_enable) log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); + if (port.wide_log2 != 0) + log_error("Wide write port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); if (!port.clk_polarity) log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); for (int i = 1; i < GetSize(port.en); i++) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index e0f43d6865d..4dee0d4fbc9 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -715,6 +715,12 @@ struct Smt2Worker has_sync_wr = true; else has_async_wr = true; + if (port.wide_log2) + log_error("Memory %s.%s has wide write ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); + } + for (auto &port : mem->rd_ports) { + if (port.wide_log2) + log_error("Memory %s.%s has wide read ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); } if (has_async_wr && has_sync_wr) log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index c6948fdbadb..a860fc693c6 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1057,6 +1057,20 @@ void handle_memory(Mem &mem, const rules_t &rules) log(" %s=%d", it.first.c_str(), it.second); log("\n"); + for (auto &port : mem.rd_ports) { + if (port.wide_log2) { + log("Wide read ports are not supported, skipping.\n"); + return; + } + } + + for (auto &port : mem.wr_ports) { + if (port.wide_log2) { + log("Wide write ports are not supported, skipping.\n"); + return; + } + } + pool> failed_brams; dict, tuple> best_rule_cache; From 1c903d3e4742c015dc8f0b3b5d8c8c1895459822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 01:12:19 +0200 Subject: [PATCH 0346/2410] sim: Add wide port support. --- passes/sat/sim.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 2e7a92cecfd..684e00382f2 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -334,7 +334,7 @@ struct SimInstance { auto &port = mem.rd_ports[port_idx]; Const addr = get_state(port.addr); - Const data = Const(State::Sx, mem.width); + Const data = Const(State::Sx, mem.width << port.wide_log2); if (port.clk_enable) log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(mem.memid)); @@ -342,7 +342,7 @@ struct SimInstance if (addr.is_fully_def()) { int index = addr.as_int() - mem.start_offset; if (index >= 0 && index < mem.size) - data = mdb.data.extract(index*mem.width, mem.width); + data = mdb.data.extract(index*mem.width, mem.width << port.wide_log2); } set_state(port.data, data); @@ -457,7 +457,7 @@ struct SimInstance { int index = addr.as_int() - mem.start_offset; if (index >= 0 && index < mem.size) - for (int i = 0; i < mem.width; i++) + for (int i = 0; i < (mem.width << port.wide_log2); i++) if (enable[i] == State::S1 && mdb.data.bits.at(index*mem.width+i) != data[i]) { mdb.data.bits.at(index*mem.width+i) = data[i]; dirty_memories.insert(mem.memid); From c1a47307391b54442ec6caf7e4b79d0e54351639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 May 2021 16:35:25 +0200 Subject: [PATCH 0347/2410] memory_map: Add wide port support. --- passes/memory/memory_map.cc | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 57863c0b677..92bbd8c1530 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -153,11 +153,9 @@ struct MemoryMapWorker continue; } if (!port.clk_enable) { - if (port.addr.is_fully_const()) { - // FIXME: Actually we should check for port.en.is_fully_const() also and - // create a $adff cell with this ports port.en input as reset pin when port.en - // is not a simple static 1. - static_cells_map[port.addr.as_int() - mem.start_offset] = port.data; + if (port.addr.is_fully_const() && port.en.is_fully_ones()) { + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + static_cells_map[port.addr.as_int() - mem.start_offset + sub] = port.data.extract(sub * mem.width, mem.width); static_ports.insert(i); continue; } @@ -241,20 +239,20 @@ struct MemoryMapWorker std::vector rd_signals; rd_signals.push_back(port.data); - for (int j = 0; j < abits; j++) + for (int j = 0; j < abits - port.wide_log2; j++) { std::vector next_rd_signals; for (size_t k = 0; k < rd_signals.size(); k++) { RTLIL::Cell *c = module->addCell(genid(mem.memid, "$rdmux", i, "", j, "", k), ID($mux)); - c->parameters[ID::WIDTH] = mem.width; + c->parameters[ID::WIDTH] = GetSize(port.data); c->setPort(ID::Y, rd_signals[k]); c->setPort(ID::S, rd_addr.extract(abits-j-1, 1)); count_mux++; - c->setPort(ID::A, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$a"), mem.width)); - c->setPort(ID::B, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$b"), mem.width)); + c->setPort(ID::A, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$a"), GetSize(port.data))); + c->setPort(ID::B, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$b"), GetSize(port.data))); next_rd_signals.push_back(c->getPort(ID::A)); next_rd_signals.push_back(c->getPort(ID::B)); @@ -264,7 +262,7 @@ struct MemoryMapWorker } for (int j = 0; j < mem.size; j++) - module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); + module->connect(RTLIL::SigSig(rd_signals[j >> port.wide_log2].extract((j & ((1 << port.wide_log2) - 1)) * mem.width, mem.width), data_reg_out[j])); } log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); @@ -284,16 +282,19 @@ struct MemoryMapWorker if (mem.start_offset) wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem.start_offset, GetSize(wr_addr))); - RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i, GetSize(wr_addr))); + wr_addr = wr_addr.extract_end(port.wide_log2); + RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i >> port.wide_log2, GetSize(wr_addr))); + + int sub = i & ((1 << port.wide_log2) - 1); int wr_offset = 0; - while (wr_offset < port.en.size()) + while (wr_offset < mem.width) { int wr_width = 1; - RTLIL::SigSpec wr_bit = port.en.extract(wr_offset, 1); + RTLIL::SigSpec wr_bit = port.en.extract(wr_offset + sub * mem.width, 1); - while (wr_offset + wr_width < port.en.size()) { - RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width, 1); + while (wr_offset + wr_width < mem.width) { + RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width + sub * mem.width, 1); if (next_wr_bit != wr_bit) break; wr_width++; @@ -319,7 +320,7 @@ struct MemoryMapWorker RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset), ID($mux)); c->parameters[ID::WIDTH] = wr_width; c->setPort(ID::A, sig.extract(wr_offset, wr_width)); - c->setPort(ID::B, port.data.extract(wr_offset, wr_width)); + c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width)); c->setPort(ID::S, RTLIL::SigSpec(w)); w = module->addWire(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); From 9d5d5a48b14832b3cc38d78e7e1960b14269ff4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 01:52:52 +0200 Subject: [PATCH 0348/2410] opt_mem_feedback: Add wide port support. --- passes/opt/opt_mem_feedback.cc | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index f186d845dd9..90e5cea9bc2 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -144,11 +144,14 @@ struct OptMemFeedbackWorker if (port.clk_enable) continue; - SigSpec addr = sigmap_xmux(port.addr); - - async_rd_bits[addr].resize(mem.width); - for (int i = 0; i < mem.width; i++) - async_rd_bits[addr][i].insert(sigmap(port.data[i])); + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { + SigSpec addr = sigmap_xmux(port.addr); + for (int i = 0; i < port.wide_log2; i++) + addr[i] = State(sub >> i & 1); + async_rd_bits[addr].resize(mem.width); + for (int i = 0; i < mem.width; i++) + async_rd_bits[addr][i].insert(sigmap(port.data[i + sub * mem.width])); + } } if (async_rd_bits.empty()) @@ -161,21 +164,28 @@ struct OptMemFeedbackWorker { auto &port = mem.wr_ports[i]; - SigSpec addr = sigmap_xmux(port.addr); - - if (!async_rd_bits.count(addr)) - continue; - log(" Analyzing %s.%s write port %d.\n", log_id(module), log_id(mem.memid), i); - for (int j = 0; j < GetSize(port.data); j++) + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - if (port.en[j] == State::S0) + SigSpec addr = sigmap_xmux(port.addr); + for (int k = 0; k < port.wide_log2; k++) + addr[k] = State(sub >> k & 1); + + if (!async_rd_bits.count(addr)) continue; - dict state; + for (int j = 0; j < mem.width; j++) + { + int bit_idx = sub * mem.width + j; + + if (port.en[bit_idx] == State::S0) + continue; + + dict state; - find_data_feedback(async_rd_bits.at(addr).at(j), sigmap(port.data[j]), state, i, j, paths); + find_data_feedback(async_rd_bits.at(addr).at(j), sigmap(port.data[bit_idx]), state, i, bit_idx, paths); + } } } From 47f958ce4592a42e26f074c88063ac17c843ea71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 01:55:44 +0200 Subject: [PATCH 0349/2410] memory_share: Add wide port support. --- passes/memory/memory_share.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index d5a44f20c11..98637720c91 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -143,6 +143,7 @@ struct MemoryShareWorker bool cache_clk_enable = false; bool cache_clk_polarity = false; RTLIL::SigSpec cache_clk; + int cache_wide_log2 = 0; bool changed = false; @@ -152,12 +153,14 @@ struct MemoryShareWorker RTLIL::SigSpec addr = sigmap_xmux(port.addr); if (port.clk_enable != cache_clk_enable || + port.wide_log2 != cache_wide_log2 || (cache_clk_enable && (sigmap(port.clk) != cache_clk || port.clk_polarity != cache_clk_polarity))) { cache_clk_enable = port.clk_enable; cache_clk_polarity = port.clk_polarity; cache_clk = sigmap(port.clk); + cache_wide_log2 = port.wide_log2; last_port_by_addr.clear(); if (cache_clk_enable) @@ -290,18 +293,21 @@ struct MemoryShareWorker bool cache_clk_enable = false; bool cache_clk_polarity = false; RTLIL::SigSpec cache_clk; + int cache_wide_log2 = 0; for (int i = 0; i < GetSize(mem.wr_ports); i++) { auto &port = mem.wr_ports[i]; if (port.clk_enable != cache_clk_enable || + port.wide_log2 != cache_wide_log2 || (cache_clk_enable && (sigmap(port.clk) != cache_clk || port.clk_polarity != cache_clk_polarity))) { cache_clk_enable = port.clk_enable; cache_clk_polarity = port.clk_polarity; cache_clk = sigmap(port.clk); + cache_wide_log2 = port.wide_log2; } else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) considered_port_pairs.insert(i); From e0736c1622c60980ddf9b989e9c3e2acc4403135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 02:12:55 +0200 Subject: [PATCH 0350/2410] Add memory_narrow pass. --- passes/memory/Makefile.inc | 1 + passes/memory/memory_narrow.cc | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 passes/memory/memory_narrow.cc diff --git a/passes/memory/Makefile.inc b/passes/memory/Makefile.inc index e468c3a0731..5a2c4ecfc1e 100644 --- a/passes/memory/Makefile.inc +++ b/passes/memory/Makefile.inc @@ -8,4 +8,5 @@ OBJS += passes/memory/memory_bram.o OBJS += passes/memory/memory_map.o OBJS += passes/memory/memory_memx.o OBJS += passes/memory/memory_nordff.o +OBJS += passes/memory/memory_narrow.o diff --git a/passes/memory/memory_narrow.cc b/passes/memory/memory_narrow.cc new file mode 100644 index 00000000000..cf5e4346540 --- /dev/null +++ b/passes/memory/memory_narrow.cc @@ -0,0 +1,67 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina Kościelnicka + * + * 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 "kernel/mem.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct MemoryNarrowPass : public Pass { + MemoryNarrowPass() : Pass("memory_narrow", "split up wide memory ports") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" memory_narrow [options] [selection]\n"); + log("\n"); + log("This pass splits up wide memory ports into several narrow ports.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing MEMORY_NARROW pass (splitting up wide memory ports).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + for (auto &mem : Mem::get_selected_memories(module)) + { + bool wide = false; + for (auto &port : mem.rd_ports) + if (port.wide_log2) + wide = true; + for (auto &port : mem.wr_ports) + if (port.wide_log2) + wide = true; + if (wide) { + mem.narrow(); + mem.emit(); + } + } + } + } +} MemoryNarrowPass; + +PRIVATE_NAMESPACE_END From 4858721637fc5d6ae6d7e0fb0489e0cec8bb388b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 02:56:35 +0200 Subject: [PATCH 0351/2410] kernel/mem: Add emulate_priority helper. --- kernel/mem.cc | 38 ++++++++++++++++++++++++++++++++++++++ kernel/mem.h | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index f2c8dd953b0..649515e0c9b 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -599,3 +599,41 @@ void Mem::narrow() { std::swap(rd_ports, new_rd_ports); std::swap(wr_ports, new_wr_ports); } + +void Mem::emulate_priority(int idx1, int idx2) +{ + auto &port1 = wr_ports[idx1]; + auto &port2 = wr_ports[idx2]; + if (!port2.priority_mask[idx1]) + return; + int min_wide_log2 = std::min(port1.wide_log2, port2.wide_log2); + int max_wide_log2 = std::max(port1.wide_log2, port2.wide_log2); + bool wide1 = port1.wide_log2 > port2.wide_log2; + for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { + SigSpec addr1 = port1.addr; + SigSpec addr2 = port2.addr; + for (int j = min_wide_log2; j < max_wide_log2; j++) + if (wide1) + addr1[j] = State(sub >> j & 1); + else + addr2[j] = State(sub >> j & 1); + SigSpec addr_eq = module->Eq(NEW_ID, addr1, addr2); + int ewidth = width << min_wide_log2; + int sub1 = wide1 ? sub : 0; + int sub2 = wide1 ? 0 : sub; + dict, SigBit> cache; + for (int pos = 0; pos < ewidth; pos++) { + SigBit &en1 = port1.en[pos + sub1 * width]; + SigBit &en2 = port2.en[pos + sub2 * width]; + std::pair key(en1, en2); + if (cache.count(key)) { + en1 = cache[key]; + } else { + SigBit active2 = module->And(NEW_ID, addr_eq, en2); + SigBit nactive2 = module->Not(NEW_ID, active2); + en1 = cache[key] = module->And(NEW_ID, en1, nactive2); + } + } + } + port2.priority_mask[idx1] = false; +} diff --git a/kernel/mem.h b/kernel/mem.h index 214086ac47e..08befebdbf4 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -77,6 +77,12 @@ struct Mem { Cell *extract_rdff(int idx, FfInitVals *initvals); void narrow(); + // If write port idx2 currently has priority over write port idx1, + // inserts extra logic on idx1's enable signal to disable writes + // when idx2 is writing to the same address, then removes the priority + // from the priority mask. + void emulate_priority(int idx1, int idx2); + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} }; From 5628f5a88fa49c126af0149e302a8292229ab9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 15:17:29 +0200 Subject: [PATCH 0352/2410] opt_mem_feedback: Respect write port priority. --- passes/opt/opt_mem_feedback.cc | 15 +++++++++++ tests/opt/opt_mem_feedback.ys | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 90e5cea9bc2..8e93c93b924 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -237,6 +237,21 @@ struct OptMemFeedbackWorker log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", log_id(module), log_id(mem.memid)); + // If a write port has a feedback path that we're about to bypass, + // but also has priority over some other write port, the feedback + // path is not necessarily a NOP — it may overwrite the other port. + // Emulate this effect by converting the priority to soft logic + // (this will affect the other port's enable signal). + for (auto &it : portbit_conds) + { + int wrport_idx = it.first.first; + auto &port = mem.wr_ports[wrport_idx]; + + for (int i = 0; i < wrport_idx; i++) + if (port.priority_mask[i]) + mem.emulate_priority(i, wrport_idx); + } + for (auto &it : portbit_conds) { int wrport_idx = it.first.first; diff --git a/tests/opt/opt_mem_feedback.ys b/tests/opt/opt_mem_feedback.ys index 6a68921c361..56078ec278d 100644 --- a/tests/opt/opt_mem_feedback.ys +++ b/tests/opt/opt_mem_feedback.ys @@ -140,3 +140,50 @@ 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 +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : From 96c7d60304e4e9e4cb4d85924efcafa546283c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 15:34:12 +0200 Subject: [PATCH 0353/2410] memory_bram: Respect write port priority. --- passes/memory/memory_bram.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index a860fc693c6..6ec3dc2e97f 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1071,6 +1071,20 @@ void handle_memory(Mem &mem, const rules_t &rules) } } + // This pass cannot deal with write port priority — we need to emulate it, + // if present. Since priority emulation will change the enable signals, + // which in turn may change enable grouping and mapping eligibility in + // pathological cases, we need to do this before checking mapping + // eligibility. This will create priority emulation logic for all + // memories in the design regardless of whether we end up mapping them + // or not, but since we never call Mem::emit(), the new priority masks + // and enables won't be commited to the design, and this logic will be + // unused (and removed by subsequent opt_clean) for unmapped memories. + + for (int i = 0; i < GetSize(mem.wr_ports); i++) + for (int j = 0; j < i; j++) + mem.emulate_priority(j, i); + pool> failed_brams; dict, tuple> best_rule_cache; From 097de6c5f8c5170cc275b7250bf3780ae6ab3a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 15:48:52 +0200 Subject: [PATCH 0354/2410] mem/extract_rdff: Fix wire naming and wide port support. --- kernel/mem.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 649515e0c9b..f1fedf3c296 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -524,17 +524,33 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (port.transparent) { - SigSpec sig_q = module->addWire(stringf("%s$rdreg[%d]$q", memid.c_str(), idx), GetSize(port.addr)); - SigSpec sig_d = port.addr; - port.addr = sig_q; - c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); + log_assert(port.en == State::S1); + + // Do not put a register in front of constant address bits — this is both + // unnecessary and will break wide ports. + int width = 0; + for (int i = 0; i < GetSize(port.addr); i++) + if (port.addr[i].wire) + width++; + + SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width); + SigSpec sig_d; + + int pos = 0; + for (int i = 0; i < GetSize(port.addr); i++) + if (port.addr[i].wire) { + sig_d.append(port.addr[i]); + port.addr[i] = sig_q[pos++]; + } + + c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, State::S1, sig_d, sig_q, port.clk_polarity, true); } else { - SigSpec sig_d = module->addWire(stringf("%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); + SigSpec sig_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); SigSpec sig_q = port.data; port.data = sig_d; - c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); + c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); } log("Extracted %s FF from read port %d of %s.%s: %s\n", port.transparent ? "addr" : "data", From 24b880b2de1676b420f5a0bbdf3805dab38b8f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 17:18:59 +0200 Subject: [PATCH 0355/2410] kernel/mem: Add model support for read port init value and resets. Like wide port support, this is still completely unusable, and support in various passes will be gradually added later. It also has no support at all in the cell library, so attempting to create a read port with a reset or initial value will cause an assert failure for now. --- kernel/mem.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-- kernel/mem.h | 5 ++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index f1fedf3c296..6d6778b57da 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -18,6 +18,7 @@ */ #include "kernel/mem.h" +#include "kernel/ff.h" USING_YOSYS_NAMESPACE @@ -119,6 +120,10 @@ void Mem::emit() { abits = std::max(abits, GetSize(port.addr)); cell->parameters[ID::ABITS] = Const(abits); for (auto &port : rd_ports) { + // TODO: remove + log_assert(port.arst == State::S0); + log_assert(port.srst == State::S0); + log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); if (port.cell) { module->remove(port.cell); port.cell = nullptr; @@ -210,6 +215,10 @@ void Mem::emit() { mem->start_offset = start_offset; mem->size = size; for (auto &port : rd_ports) { + // TODO: remove + log_assert(port.arst == State::S0); + log_assert(port.srst == State::S0); + log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memrd)); port.cell->parameters[ID::MEMID] = memid.str(); @@ -278,9 +287,16 @@ void Mem::check() { continue; log_assert(GetSize(port.clk) == 1); log_assert(GetSize(port.en) == 1); + log_assert(GetSize(port.arst) == 1); + log_assert(GetSize(port.srst) == 1); log_assert(GetSize(port.data) == (width << port.wide_log2)); + log_assert(GetSize(port.init_value) == (width << port.wide_log2)); + log_assert(GetSize(port.arst_value) == (width << port.wide_log2)); + log_assert(GetSize(port.srst_value) == (width << port.wide_log2)); if (!port.clk_enable) { log_assert(!port.transparent); + log_assert(port.arst == State::S0); + log_assert(port.srst == State::S0); } for (int j = 0; j < port.wide_log2; j++) { log_assert(port.addr[j] == State::S0); @@ -352,6 +368,12 @@ namespace { mrd.addr = cell->getPort(ID::ADDR); mrd.data = cell->getPort(ID::DATA); mrd.wide_log2 = ceil_log2(GetSize(mrd.data) / mem->width); + mrd.ce_over_srst = false; + mrd.arst_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.srst_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.init_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.srst = State::S0; + mrd.arst = State::S0; res.rd_ports.push_back(mrd); } } @@ -454,6 +476,12 @@ namespace { mrd.en = cell->getPort(ID::RD_EN).extract(i, 1); mrd.addr = cell->getPort(ID::RD_ADDR).extract(i * abits, abits); mrd.data = cell->getPort(ID::RD_DATA).extract(i * res.width, res.width); + mrd.ce_over_srst = false; + mrd.arst_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.srst_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.init_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.srst = State::S0; + mrd.arst = State::S0; res.rd_ports.push_back(mrd); } for (int i = 0; i < cell->parameters.at(ID::WR_PORTS).as_int(); i++) { @@ -525,6 +553,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (port.transparent) { log_assert(port.en == State::S1); + log_assert(port.srst == State::S0); + log_assert(port.arst == State::S0); + log_assert(port.init_value.is_fully_undef()); // Do not put a register in front of constant address bits — this is both // unnecessary and will break wide ports. @@ -547,10 +578,38 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } else { + log_assert(port.arst == State::S0 || port.srst == State::S0); + SigSpec sig_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); - SigSpec sig_q = port.data; + IdString name = stringf("$%s$rdreg[%d]", memid.c_str(), idx); + FfData ff(initvals); + ff.width = GetSize(port.data); + ff.has_clk = true; + ff.sig_clk = port.clk; + ff.pol_clk = port.clk_polarity; + if (port.en != State::S1) { + ff.has_en = true; + ff.pol_en = true; + ff.sig_en = port.en; + } + if (port.arst != State::S0) { + ff.has_arst = true; + ff.pol_arst = true; + ff.sig_arst = port.arst; + ff.val_arst = port.arst_value; + } + if (port.srst != State::S0) { + ff.has_srst = true; + ff.pol_srst = true; + ff.sig_srst = port.srst; + ff.val_srst = port.srst_value; + ff.ce_over_srst = ff.has_en && port.ce_over_srst; + } + ff.sig_d = sig_d; + ff.sig_q = port.data; + ff.val_init = port.init_value; port.data = sig_d; - c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); + c = ff.emit(module, name); } log("Extracted %s FF from read port %d of %s.%s: %s\n", port.transparent ? "addr" : "data", @@ -558,9 +617,15 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { port.en = State::S1; port.clk = State::S0; + port.arst = State::S0; + port.srst = State::S0; port.clk_enable = false; port.clk_polarity = true; port.transparent = false; + port.ce_over_srst = false; + port.arst_value = Const(State::Sx, GetSize(port.data)); + port.srst_value = Const(State::Sx, GetSize(port.data)); + port.init_value = Const(State::Sx, GetSize(port.data)); return c; } @@ -589,6 +654,9 @@ void Mem::narrow() { port.cell = nullptr; if (port.wide_log2) { port.data = port.data.extract(it.second * width, width); + port.init_value = port.init_value.extract(it.second * width, width); + port.arst_value = port.arst_value.extract(it.second * width, width); + port.srst_value = port.srst_value.extract(it.second * width, width); for (int i = 0; i < port.wide_log2; i++) port.addr[i] = State(it.second >> i & 1); port.wide_log2 = 0; diff --git a/kernel/mem.h b/kernel/mem.h index 08befebdbf4..49b72bc353e 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -30,9 +30,10 @@ struct MemRd { dict attributes; Cell *cell; int wide_log2; - bool clk_enable, clk_polarity; + bool clk_enable, clk_polarity, ce_over_srst; + Const arst_value, srst_value, init_value; bool transparent; - SigSpec clk, en, addr, data; + SigSpec clk, en, arst, srst, addr, data; MemRd() : removed(false), cell(nullptr) {} }; From e6b078d156f8690ab06d342da9be9af02cbcc3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 18:49:17 +0200 Subject: [PATCH 0356/2410] opt_mem: Add reset/init value support. --- passes/opt/opt_mem.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 0409fb736f4..2788648ec9a 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -51,6 +51,8 @@ struct OptMemPass : public Pass { int total_count = 0; for (auto module : design->selected_modules()) { + SigMap sigmap(module); + FfInitVals initvals(&sigmap, module); for (auto &mem : Mem::get_selected_memories(module)) { bool changed = false; for (auto &port : mem.wr_ports) { @@ -65,6 +67,16 @@ struct OptMemPass : public Pass { } if (mem.wr_ports.empty() && mem.inits.empty()) { + // The whole memory array will contain + // only State::Sx, but the embedded read + // registers could have reset or init values. + // They will probably be optimized away by + // opt_dff later. + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + mem.extract_rdff(i, &initvals); + auto &port = mem.rd_ports[i]; + module->connect(port.data, Const(State::Sx, GetSize(port.data))); + } mem.remove(); total_count++; } From 3514c92dc42644d64dca2167c05096d10891de69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 20:42:34 +0200 Subject: [PATCH 0357/2410] mem/extract_rdff: Add alternate transparency handling. When extracting read register from a transparent port that has an enable, reset, or initial value, the usual trick of putting a register on the address instead of data doesn't work. In this case, create soft transparency logic instead. When transparency masks land, this will also be used to handle ports that are transparent to only a subset of write ports. --- kernel/mem.cc | 98 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 6d6778b57da..5d0a01dd2c6 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -550,13 +550,28 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { Cell *c; - if (port.transparent) - { - log_assert(port.en == State::S1); - log_assert(port.srst == State::S0); - log_assert(port.arst == State::S0); - log_assert(port.init_value.is_fully_undef()); + // There are two ways to handle rdff extraction when transparency is involved: + // + // - if all of the following conditions are true, put the FF on address input: + // + // - the port has no clock enable, no reset, and no initial value + // - the port is transparent wrt all write ports (implying they also share + // the clock domain) + // + // - otherwise, put the FF on the data output, and make bypass paths for + // all write ports wrt which this port is transparent + bool trans_use_addr = port.transparent; + + // If there are no write ports at all, we could possibly use either way; do data + // FF in this case. + if (GetSize(wr_ports) == 0) + trans_use_addr = false; + if (port.en != State::S1 || port.srst != State::S0 || port.arst != State::S0 || !port.init_value.is_fully_undef()) + trans_use_addr = false; + + if (trans_use_addr) + { // Do not put a register in front of constant address bits — this is both // unnecessary and will break wide ports. int width = 0; @@ -564,23 +579,70 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (port.addr[i].wire) width++; - SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width); - SigSpec sig_d; + if (width) { + SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width); + SigSpec sig_d; - int pos = 0; - for (int i = 0; i < GetSize(port.addr); i++) - if (port.addr[i].wire) { - sig_d.append(port.addr[i]); - port.addr[i] = sig_q[pos++]; - } + int pos = 0; + for (int i = 0; i < GetSize(port.addr); i++) + if (port.addr[i].wire) { + sig_d.append(port.addr[i]); + port.addr[i] = sig_q[pos++]; + } - c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, State::S1, sig_d, sig_q, port.clk_polarity, true); + c = module->addDff(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, sig_d, sig_q, port.clk_polarity); + } } else { log_assert(port.arst == State::S0 || port.srst == State::S0); - SigSpec sig_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); + SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data)); + SigSpec sig_d = async_d; + + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &wport = wr_ports[i]; + if (port.transparent) { + log_assert(wport.clk_enable); + log_assert(wport.clk == port.clk); + log_assert(wport.clk_enable == port.clk_enable); + int min_wide_log2 = std::min(port.wide_log2, wport.wide_log2); + int max_wide_log2 = std::max(port.wide_log2, wport.wide_log2); + bool wide_write = wport.wide_log2 > port.wide_log2; + for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { + SigSpec raddr = port.addr; + SigSpec waddr = wport.addr; + for (int j = min_wide_log2; j < max_wide_log2; j++) + if (wide_write) + waddr[j] = State(sub >> j & 1); + else + raddr[j] = State(sub >> j & 1); + SigSpec addr_eq; + if (raddr != waddr) + addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid.c_str(), idx, i, sub), raddr, waddr); + int pos = 0; + int ewidth = width << min_wide_log2; + int wsub = wide_write ? sub : 0; + int rsub = wide_write ? 0 : sub; + while (pos < ewidth) { + int epos = pos; + while (epos < ewidth && wport.en[epos + wsub * width] == wport.en[pos + wsub * width]) + epos++; + SigSpec cur = sig_d.extract(pos + rsub * width, epos-pos); + SigSpec other = wport.data.extract(pos + wsub * width, epos-pos); + SigSpec cond; + if (raddr != waddr) + cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid.c_str(), idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq); + else + cond = wport.en[pos + wsub * width]; + SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid.c_str(), idx, i, sub, pos), cur, other, cond); + sig_d.replace(pos + rsub * width, merged); + pos = epos; + } + } + } + } + IdString name = stringf("$%s$rdreg[%d]", memid.c_str(), idx); FfData ff(initvals); ff.width = GetSize(port.data); @@ -608,11 +670,11 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { ff.sig_d = sig_d; ff.sig_q = port.data; ff.val_init = port.init_value; - port.data = sig_d; + port.data = async_d; c = ff.emit(module, name); } - log("Extracted %s FF from read port %d of %s.%s: %s\n", port.transparent ? "addr" : "data", + log("Extracted %s FF from read port %d of %s.%s: %s\n", trans_use_addr ? "addr" : "data", idx, log_id(module), log_id(memid), log_id(c)); port.en = State::S1; From 15f35d6754af619accdf63030e0a5ad3085cec16 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 27 Mar 2021 15:59:48 -0400 Subject: [PATCH 0358/2410] sv: support remaining assignment operators - Add support for: *=, /=, %=, <<=, >>=, <<<=, >>>= - Unify existing support for: +=, -=, &=, |=, ^= --- frontends/verilog/verilog_lexer.l | 15 +++++-- frontends/verilog/verilog_parser.y | 68 +++++++++++++----------------- tests/simple/asgn_binop.sv | 23 ++++++++++ 3 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 tests/simple/asgn_binop.sv diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 1a6dc96fd02..f52928c77f8 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -544,11 +544,18 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { ".*" { return TOK_WILDCARD_CONNECT; } -"|=" { SV_KEYWORD(TOK_OR_ASSIGN); } -"&=" { SV_KEYWORD(TOK_AND_ASSIGN); } -"+=" { SV_KEYWORD(TOK_PLUS_ASSIGN); } +"|=" { SV_KEYWORD(TOK_BIT_OR_ASSIGN); } +"&=" { SV_KEYWORD(TOK_BIT_AND_ASSIGN); } +"+=" { SV_KEYWORD(TOK_ADD_ASSIGN); } "-=" { SV_KEYWORD(TOK_SUB_ASSIGN); } -"^=" { SV_KEYWORD(TOK_XOR_ASSIGN); } +"^=" { SV_KEYWORD(TOK_BIT_XOR_ASSIGN); } +"/=" { SV_KEYWORD(TOK_DIV_ASSIGN); } +"%=" { SV_KEYWORD(TOK_MOD_ASSIGN); } +"*=" { SV_KEYWORD(TOK_MUL_ASSIGN); } +"<<=" { SV_KEYWORD(TOK_SHL_ASSIGN); } +">>=" { SV_KEYWORD(TOK_SHR_ASSIGN); } +"<<<=" { SV_KEYWORD(TOK_SSHL_ASSIGN); } +">>>=" { SV_KEYWORD(TOK_SSHR_ASSIGN); } [-+]?[=*]> { if (!specify_mode) REJECT; diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index dd25f412f17..c2b43f45b9e 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -260,6 +260,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) bool boolean; char ch; int integer; + YOSYS_NAMESPACE_PREFIX AST::AstNodeType ast_node_type; } %token TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE @@ -272,7 +273,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR TOK_WILDCARD_CONNECT %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC -%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_PLUS_ASSIGN TOK_ALWAYS TOK_INITIAL +%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL %token TOK_ALWAYS_FF TOK_ALWAYS_COMB TOK_ALWAYS_LATCH %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT %token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC @@ -286,7 +287,9 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY %token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_UNION -%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN +%token TOK_BIT_OR_ASSIGN TOK_BIT_AND_ASSIGN TOK_BIT_XOR_ASSIGN TOK_ADD_ASSIGN +%token TOK_SUB_ASSIGN TOK_DIV_ASSIGN TOK_MOD_ASSIGN TOK_MUL_ASSIGN +%token TOK_SHL_ASSIGN TOK_SHR_ASSIGN TOK_SSHL_ASSIGN TOK_SSHR_ASSIGN %type range range_or_multirange non_opt_range non_opt_multirange %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type @@ -298,6 +301,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %type integer_atom_type %type attr case_attr %type struct_union +%type asgn_binop %type specify_target %type specify_triple specify_opt_triple @@ -2449,47 +2453,35 @@ simple_behavioral_stmt: SET_AST_NODE_LOC(node, @2, @5); append_attr(node, $1); } | - attr lvalue TOK_XOR_ASSIGN delay expr { - AstNode *xor_node = new AstNode(AST_BIT_XOR, $2->clone(), $5); - AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, xor_node); - SET_AST_NODE_LOC(xor_node, @2, @5); - SET_AST_NODE_LOC(node, @2, @5); - ast_stack.back()->children.push_back(node); - append_attr(node, $1); - } | - attr lvalue TOK_OR_ASSIGN delay expr { - AstNode *or_node = new AstNode(AST_BIT_OR, $2->clone(), $5); - SET_AST_NODE_LOC(or_node, @2, @5); - AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, or_node); - SET_AST_NODE_LOC(node, @2, @5); - ast_stack.back()->children.push_back(node); - append_attr(node, $1); - } | - attr lvalue TOK_PLUS_ASSIGN delay expr { - AstNode *add_node = new AstNode(AST_ADD, $2->clone(), $5); - AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, add_node); - SET_AST_NODE_LOC(node, @2, @5); - SET_AST_NODE_LOC(add_node, @2, @5); - ast_stack.back()->children.push_back(node); - append_attr(node, $1); - } | - attr lvalue TOK_SUB_ASSIGN delay expr { - AstNode *sub_node = new AstNode(AST_SUB, $2->clone(), $5); - AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, sub_node); - SET_AST_NODE_LOC(node, @2, @5); - SET_AST_NODE_LOC(sub_node, @2, @5); - ast_stack.back()->children.push_back(node); - append_attr(node, $1); - } | - attr lvalue TOK_AND_ASSIGN delay expr { - AstNode *and_node = new AstNode(AST_BIT_AND, $2->clone(), $5); - AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, and_node); + attr lvalue asgn_binop delay expr { + AstNode *expr_node = $5; + if ($3 == AST_SHIFT_LEFT || $3 == AST_SHIFT_RIGHT || + $3 == AST_SHIFT_SLEFT || $3 == AST_SHIFT_SRIGHT) { + expr_node = new AstNode(AST_TO_UNSIGNED, expr_node); + SET_AST_NODE_LOC(expr_node, @5, @5); + } + AstNode *op_node = new AstNode($3, $2->clone(), expr_node); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, op_node); + SET_AST_NODE_LOC(op_node, @2, @5); SET_AST_NODE_LOC(node, @2, @5); - SET_AST_NODE_LOC(and_node, @2, @5); ast_stack.back()->children.push_back(node); append_attr(node, $1); }; +asgn_binop: + TOK_BIT_OR_ASSIGN { $$ = AST_BIT_OR; } | + TOK_BIT_AND_ASSIGN { $$ = AST_BIT_AND; } | + TOK_BIT_XOR_ASSIGN { $$ = AST_BIT_XOR; } | + TOK_ADD_ASSIGN { $$ = AST_ADD; } | + TOK_SUB_ASSIGN { $$ = AST_SUB; } | + TOK_DIV_ASSIGN { $$ = AST_DIV; } | + TOK_MOD_ASSIGN { $$ = AST_MOD; } | + TOK_MUL_ASSIGN { $$ = AST_MUL; } | + TOK_SHL_ASSIGN { $$ = AST_SHIFT_LEFT; } | + TOK_SHR_ASSIGN { $$ = AST_SHIFT_RIGHT; } | + TOK_SSHL_ASSIGN { $$ = AST_SHIFT_SLEFT; } | + TOK_SSHR_ASSIGN { $$ = AST_SHIFT_SRIGHT; } ; + // this production creates the obligatory if-else shift/reduce conflict behavioral_stmt: defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl | diff --git a/tests/simple/asgn_binop.sv b/tests/simple/asgn_binop.sv new file mode 100644 index 00000000000..b134e569712 --- /dev/null +++ b/tests/simple/asgn_binop.sv @@ -0,0 +1,23 @@ +`define TEST(name, asgnop)\ + module test_``name ( \ + input logic [3:0] a, b, \ + output logic [3:0] c \ + ); \ + always @* begin \ + c = a; \ + c asgnop b; \ + end \ + endmodule + +`TEST(add, +=) +`TEST(sub, -=) +`TEST(mul, *=) +`TEST(div, /=) +`TEST(mod, %=) +`TEST(bit_and, &=) +`TEST(bit_or , |=) +`TEST(bit_xor, ^=) +`TEST(shl, <<=) +`TEST(shr, >>=) +`TEST(sshl, <<<=) +`TEST(sshr, >>>=) From 0795b3ec076d8d2c0aa0d954b707271bd2f064bf Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 25 Mar 2021 14:06:05 -0400 Subject: [PATCH 0359/2410] verilog: fix case expression sign and width handling - The case expression and case item expressions are extended to the maximum width among them, and are only interpreted as signed if all of them are signed - Add overall width and sign detection for AST_CASE - Add sign argument to genWidthRTLIL helper - Coverage for both const and non-const case statements --- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 50 ++++++++++++++++++++----- frontends/ast/simplify.cc | 9 ++++- tests/simple/case_expr_const.v | 49 +++++++++++++++++++++++++ tests/simple/case_expr_non_const.v | 59 ++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 12 deletions(-) create mode 100644 tests/simple/case_expr_const.v create mode 100644 tests/simple/case_expr_non_const.v diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 06947935382..9887d24ead1 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -291,7 +291,7 @@ namespace AST // for expressions the resulting signal vector is returned // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); - RTLIL::SigSpec genWidthRTLIL(int width, const dict *new_subst_ptr = NULL); + RTLIL::SigSpec genWidthRTLIL(int width, bool sgn, const dict *new_subst_ptr = NULL); // compare AST nodes bool operator==(const AstNode &other) const; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index ad5814f1b12..b8b9f715e8f 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -566,7 +566,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map.stdmap()); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), true, &subst_rvalue_map.stdmap()); pool lvalue_sigbits; for (int i = 0; i < GetSize(lvalue); i++) { @@ -593,9 +593,13 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { + int width_hint; + bool sign_hint; + ast->detectSignWidth(width_hint, sign_hint); + RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; set_src_attr(sw, ast); - sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); + sw->signal = ast->children[0]->genWidthRTLIL(width_hint, sign_hint, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -637,7 +641,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map.stdmap())); + current_case->compare.push_back(node->genWidthRTLIL(width_hint, sign_hint, &subst_rvalue_map.stdmap())); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -715,9 +719,9 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::MemWriteAction action; set_src_attr(&action, child); action.memid = memid; - action.address = child->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); - action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid]->width, &subst_rvalue_map.stdmap()); - action.enable = child->children[2]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); + action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap()); + action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid]->width, true, &subst_rvalue_map.stdmap()); + action.enable = child->children[2]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap()); RTLIL::Const orig_priority_mask = child->children[4]->bitsAsConst(); RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx); for (int i = 0; i < portid; i++) { @@ -954,6 +958,32 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun width_hint = max(width_hint, this_width); break; + case AST_CASE: + { + // This detects the _overall_ sign and width to be used for comparing + // the case expression with the case item expressions. The case + // expression and case item expressions are extended to the maximum + // width among them, and are only interpreted as signed if all of them + // are signed. + width_hint = -1; + sign_hint = true; + auto visit_case_expr = [&width_hint, &sign_hint] (AstNode *node) { + int sub_width_hint = -1; + bool sub_sign_hint = true; + node->detectSignWidth(sub_width_hint, sub_sign_hint); + width_hint = max(width_hint, sub_width_hint); + sign_hint &= sub_sign_hint; + }; + visit_case_expr(children[0]); + for (size_t i = 1; i < children.size(); i++) { + AstNode *child = children[i]; + for (AstNode *v : child->children) + if (v->type != AST_DEFAULT && v->type != AST_BLOCK) + visit_case_expr(v); + } + break; + } + case AST_FCALL: if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") { if (GetSize(children) == 1) { @@ -1695,7 +1725,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) SigSpec addr_sig = children[0]->genRTLIL(); cell->setPort(ID::ADDR, addr_sig); - cell->setPort(ID::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words)); + cell->setPort(ID::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words, true)); cell->parameters[ID::MEMID] = RTLIL::Const(str); cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig)); @@ -1754,7 +1784,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_ASSIGN: { RTLIL::SigSpec left = children[0]->genRTLIL(); - RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); + RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size(), true); if (left.has_const()) { RTLIL::SigSpec new_left, new_right; for (int i = 0; i < GetSize(left); i++) @@ -1979,14 +2009,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // signals must be substituted before being used as input values (used by ProcessGenerator) // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). -RTLIL::SigSpec AstNode::genWidthRTLIL(int width, const dict *new_subst_ptr) +RTLIL::SigSpec AstNode::genWidthRTLIL(int width, bool sgn, const dict *new_subst_ptr) { const dict *backup_subst_ptr = genRTLIL_subst_ptr; if (new_subst_ptr) genRTLIL_subst_ptr = new_subst_ptr; - bool sign_hint = true; + bool sign_hint = sgn; int width_hint = width; detectSignWidthWorker(width_hint, sign_hint); RTLIL::SigSpec sig = genRTLIL(width_hint, sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b9965ba99e2..305f67da82d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1185,8 +1185,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (const_fold && type == AST_CASE) { + int width_hint; + bool sign_hint; + detectSignWidth(width_hint, sign_hint); while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { } if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) { + RTLIL::Const case_expr = children[0]->bitsAsConst(width_hint, sign_hint); std::vector new_children; new_children.push_back(children[0]); for (int i = 1; i < GetSize(children); i++) { @@ -1199,7 +1203,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; while (v->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { } if (v->type == AST_CONSTANT && v->bits_only_01()) { - if (v->bits == children[0]->bits) { + RTLIL::Const case_item_expr = v->bitsAsConst(width_hint, sign_hint); + RTLIL::Const match = const_eq(case_expr, case_item_expr, sign_hint, sign_hint, 1); + log_assert(match.bits.size() == 1); + if (match.bits.front() == RTLIL::State::S1) { while (i+1 < GetSize(children)) delete children[++i]; goto keep_const_cond; diff --git a/tests/simple/case_expr_const.v b/tests/simple/case_expr_const.v new file mode 100644 index 00000000000..58267b965e8 --- /dev/null +++ b/tests/simple/case_expr_const.v @@ -0,0 +1,49 @@ +// Note: case_expr_{,non_}const.v should be modified in tandem to ensure both +// the constant and non-constant case evaluation logic is covered +module top( + // expected to output all 1s + output reg a, b, c, d, e, f, g, h +); + initial begin + case (2'b0) + 1'b0: a = 1; + default: a = 0; + endcase + case (2'sb11) + 2'sb01: b = 0; + 1'sb1: b = 1; + endcase + case (2'sb11) + 1'sb0: c = 0; + 1'sb1: c = 1; + endcase + case (2'sb11) + 1'b0: d = 0; + 1'sb1: d = 0; + default: d = 1; + endcase + case (2'b11) + 1'sb0: e = 0; + 1'sb1: e = 0; + default: e = 1; + endcase + case (1'sb1) + 1'sb0: f = 0; + 2'sb11: f = 1; + default: f = 0; + endcase + case (1'sb1) + 1'sb0: g = 0; + 3'b0: g = 0; + 2'sb11: g = 0; + default: g = 1; + endcase + case (1'sb1) + 1'sb0: h = 0; + 1'b1: h = 1; + 3'b0: h = 0; + 2'sb11: h = 0; + default: h = 0; + endcase + end +endmodule diff --git a/tests/simple/case_expr_non_const.v b/tests/simple/case_expr_non_const.v new file mode 100644 index 00000000000..7856e781c27 --- /dev/null +++ b/tests/simple/case_expr_non_const.v @@ -0,0 +1,59 @@ +// Note: case_expr_{,non_}const.v should be modified in tandem to ensure both +// the constant and non-constant case evaluation logic is covered +module top( + // expected to output all 1s + output reg a, b, c, d, e, f, g, h +); + reg x_1b0 = 1'b0; + reg x_1b1 = 1'b1; + reg signed x_1sb0 = 1'sb0; + reg signed x_1sb1 = 1'sb1; + reg [1:0] x_2b0 = 2'b0; + reg [1:0] x_2b11 = 2'b11; + reg signed [1:0] x_2sb01 = 2'sb01; + reg signed [1:0] x_2sb11 = 2'sb11; + reg [2:0] x_3b0 = 3'b0; + + initial begin + case (x_2b0) + x_1b0: a = 1; + default: a = 0; + endcase + case (x_2sb11) + x_2sb01: b = 0; + x_1sb1: b = 1; + endcase + case (x_2sb11) + x_1sb0: c = 0; + x_1sb1: c = 1; + endcase + case (x_2sb11) + x_1b0: d = 0; + x_1sb1: d = 0; + default: d = 1; + endcase + case (x_2b11) + x_1sb0: e = 0; + x_1sb1: e = 0; + default: e = 1; + endcase + case (x_1sb1) + x_1sb0: f = 0; + x_2sb11: f = 1; + default: f = 0; + endcase + case (x_1sb1) + x_1sb0: g = 0; + x_3b0: g = 0; + x_2sb11: g = 0; + default: g = 1; + endcase + case (x_1sb1) + x_1sb0: h = 0; + x_1b1: h = 1; + x_3b0: h = 0; + x_2sb11: h = 0; + default: h = 0; + endcase + end +endmodule From 18806f1ef653f29654533ee47fd8a1b0cf1d645a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 19:31:53 +0200 Subject: [PATCH 0360/2410] memory_bram: Reuse extract_rdff helper for make_outreg. Also properly skip read ports with init value or reset when not making use of make_outreg. Proper support for matching those will land later. --- passes/memory/memory_bram.cc | 61 +++++++++++++++++++++------------- tests/arch/anlogic/lutram.ys | 9 +++-- tests/arch/ecp5/lutram.ys | 8 ++--- tests/arch/intel_alm/lutram.ys | 10 +++--- tests/arch/nexus/lutram.ys | 4 +-- 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 6ec3dc2e97f..b708647665a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/mem.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -401,7 +402,7 @@ struct rules_t } }; -bool replace_memory(Mem &orig_mem, const rules_t &rules, const rules_t::bram_t &bram, const rules_t::match_t &match, dict &match_properties, int mode) +bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, const rules_t::bram_t &bram, const rules_t::match_t &match, dict &match_properties, int mode) { // We will modify ports — make a copy of the structure. Mem mem(orig_mem); @@ -727,7 +728,18 @@ grow_read_ports:; log(" Bram port %c%d.%d has no read enable input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } - skip_bram_rport_clkcheck: + if (port.arst != State::S0) { + log(" Bram port %c%d.%d has no async reset input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + goto skip_bram_rport; + } + if (port.srst != State::S0) { + log(" Bram port %c%d.%d has no sync reset input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + goto skip_bram_rport; + } + if (!port.init_value.is_fully_undef()) { + log(" Bram port %c%d.%d has no initial value support.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + goto skip_bram_rport; + } if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) { if (match.make_transp && GetSize(mem.wr_ports) <= 1) { pi.make_transp = true; @@ -750,10 +762,11 @@ grow_read_ports:; } } + skip_bram_rport_clkcheck: log(" Mapped to bram port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); pi.mapped_port = cell_port_i; - if (port.clk_enable) { + if (port.clk_enable && !pi.make_outreg) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; if (!pi.make_transp) @@ -868,6 +881,16 @@ grow_read_ports:; for (auto &other_bram : rules.brams.at(bram.name)) bram.find_variant_params(variant_params, other_bram); + // Apply make_outreg where necessary. + for (auto &pi : portinfos) { + if (pi.make_outreg) { + mem.extract_rdff(pi.mapped_port, initvals); + auto &port = mem.rd_ports[pi.mapped_port]; + pi.sig_addr = port.addr; + pi.sig_data = port.data; + } + } + // actually replace that memory cell dict> dout_cache; @@ -970,18 +993,7 @@ grow_read_ports:; } else { SigSpec bram_dout = module->addWire(NEW_ID, bram.dbits); c->setPort(stringf("\\%sDATA", pf), bram_dout); - if (pi.make_outreg && pi.make_transp) { - log(" Moving output register to address for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); - SigSpec sig_addr_q = module->addWire(NEW_ID, bram.abits); - module->addDff(NEW_ID, pi.sig_clock, sig_addr, sig_addr_q, pi.effective_clkpol); - c->setPort(stringf("\\%sADDR", pf), sig_addr_q); - } else if (pi.make_outreg) { - SigSpec bram_dout_q = module->addWire(NEW_ID, bram.dbits); - if (!pi.sig_en.empty()) - bram_dout = module->Mux(NEW_ID, bram_dout_q, bram_dout, pi.sig_en); - module->addDff(NEW_ID, pi.sig_clock, bram_dout, bram_dout_q, pi.effective_clkpol); - bram_dout = bram_dout_q; - } else if (pi.make_transp) { + if (pi.make_transp) { log(" Adding extra logic for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); SigSpec transp_en_d = module->Mux(NEW_ID, SigSpec(0, make_transp_enbits), @@ -1005,7 +1017,7 @@ grow_read_ports:; } SigSpec addr_ok_q = addr_ok; - if ((pi.clocks || pi.make_outreg) && !addr_ok.empty()) { + if (pi.clocks && !addr_ok.empty()) { addr_ok_q = module->addWire(NEW_ID); if (!pi.sig_en.empty()) addr_ok = module->Mux(NEW_ID, addr_ok_q, addr_ok, pi.sig_en); @@ -1037,7 +1049,7 @@ grow_read_ports:; return true; } -void handle_memory(Mem &mem, const rules_t &rules) +void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) { log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid)); @@ -1217,7 +1229,7 @@ void handle_memory(Mem &mem, const rules_t &rules) if (or_next_if_better && i+1 == GetSize(rules.matches) && vi+1 == GetSize(rules.brams.at(match.name))) log_error("Found 'or_next_if_better' in last match rule.\n"); - if (!replace_memory(mem, rules, bram, match, match_properties, 1)) { + if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 1)) { log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; @@ -1244,12 +1256,12 @@ void handle_memory(Mem &mem, const rules_t &rules) best_rule_cache.clear(); auto &best_bram = rules.brams.at(rules.matches.at(best_rule.first).name).at(best_rule.second); - if (!replace_memory(mem, rules, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) + if (!replace_memory(mem, rules, initvals, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", log_id(best_bram.name), best_bram.variant); return; } - if (!replace_memory(mem, rules, bram, match, match_properties, 0)) { + if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 0)) { log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; @@ -1381,9 +1393,12 @@ struct MemoryBramPass : public Pass { } extra_args(args, argidx, design); - for (auto mod : design->selected_modules()) - for (auto &mem : Mem::get_selected_memories(mod)) - handle_memory(mem, rules); + for (auto mod : design->selected_modules()) { + SigMap sigmap(mod); + FfInitVals initvals(&sigmap, mod); + for (auto &mem : Mem::get_selected_memories(mod)) + handle_memory(mem, rules, &initvals); + } } } MemoryBramPass; diff --git a/tests/arch/anlogic/lutram.ys b/tests/arch/anlogic/lutram.ys index 9ebb7544323..6dbdbdac3e8 100644 --- a/tests/arch/anlogic/lutram.ys +++ b/tests/arch/anlogic/lutram.ys @@ -13,9 +13,8 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter design -load postopt cd lutram_1w1r -select -assert-count 8 t:AL_MAP_LUT2 -select -assert-count 8 t:AL_MAP_LUT4 -select -assert-count 8 t:AL_MAP_LUT5 -select -assert-count 36 t:AL_MAP_SEQ +select -assert-count 4 t:AL_MAP_LUT3 +select -assert-count 8 t:AL_MAP_LUT6 +select -assert-count 8 t:AL_MAP_SEQ select -assert-count 8 t:EG_LOGIC_DRAM16X4 #Why not AL_LOGIC_BRAM? -select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D +select -assert-none t:AL_MAP_LUT3 t:AL_MAP_LUT6 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D diff --git a/tests/arch/ecp5/lutram.ys b/tests/arch/ecp5/lutram.ys index e1ae7abd524..9bef37c6867 100644 --- a/tests/arch/ecp5/lutram.ys +++ b/tests/arch/ecp5/lutram.ys @@ -11,9 +11,9 @@ sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs mite design -load postopt cd lutram_1w1r -select -assert-count 24 t:L6MUX21 -select -assert-count 71 t:LUT4 -select -assert-count 32 t:PFUMX +select -assert-count 8 t:L6MUX21 +select -assert-count 36 t:LUT4 +select -assert-count 16 t:PFUMX select -assert-count 8 t:TRELLIS_DPR16X4 -select -assert-count 35 t:TRELLIS_FF +select -assert-count 8 t:TRELLIS_FF select -assert-none t:L6MUX21 t:LUT4 t:PFUMX t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D diff --git a/tests/arch/intel_alm/lutram.ys b/tests/arch/intel_alm/lutram.ys index 5d33b8e12d8..9ddb1ec874e 100644 --- a/tests/arch/intel_alm/lutram.ys +++ b/tests/arch/intel_alm/lutram.ys @@ -12,11 +12,10 @@ sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs mite design -load postopt cd lutram_1w1r select -assert-count 16 t:MISTRAL_MLAB -select -assert-count 1 t:MISTRAL_NOT select -assert-count 2 t:MISTRAL_ALUT2 select -assert-count 8 t:MISTRAL_ALUT3 -select -assert-count 17 t:MISTRAL_FF -select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D +select -assert-count 8 t:MISTRAL_FF +select -assert-none t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D design -reset @@ -34,8 +33,7 @@ sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs mite design -load postopt cd lutram_1w1r select -assert-count 16 t:MISTRAL_MLAB -select -assert-count 1 t:MISTRAL_NOT select -assert-count 2 t:MISTRAL_ALUT2 select -assert-count 8 t:MISTRAL_ALUT3 -select -assert-count 17 t:MISTRAL_FF -select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D +select -assert-count 8 t:MISTRAL_FF +select -assert-none t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D diff --git a/tests/arch/nexus/lutram.ys b/tests/arch/nexus/lutram.ys index cd645f717a2..6e33431b605 100644 --- a/tests/arch/nexus/lutram.ys +++ b/tests/arch/nexus/lutram.ys @@ -13,7 +13,7 @@ design -load postopt cd lutram_1w1r stat select -assert-count 8 t:WIDEFN9 -select -assert-count 16 t:LUT4 +select -assert-count 12 t:LUT4 select -assert-count 8 t:DPR16X4 -select -assert-count 36 t:FD1P3IX +select -assert-count 8 t:FD1P3IX select -assert-none t:DPR16X4 t:FD1P3IX t:WIDEFN9 t:LUT4 t:INV t:IB t:OB t:VLO t:VHI %% t:* %D From d99fce3bc77a42563e1e270172e08ec25d58c7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 22:39:50 +0200 Subject: [PATCH 0361/2410] mem/extract_rdff: Fix "no FF made" edge case. When converting a sync transparent read port with const address to async read port, nothing at all needs to be done other than clk_enable change, and thus we have no FF cell to return. Handle this case correctly in the helper and in its users. --- kernel/mem.cc | 5 ++++- passes/memory/memory_nordff.cc | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 5d0a01dd2c6..fe88be5d7bc 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -579,7 +579,8 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (port.addr[i].wire) width++; - if (width) { + if (width) + { SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width); SigSpec sig_d; @@ -591,6 +592,8 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } c = module->addDff(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, sig_d, sig_q, port.clk_polarity); + } else { + c = nullptr; } } else diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc index 665efceb202..80f78ca77ae 100644 --- a/passes/memory/memory_nordff.cc +++ b/passes/memory/memory_nordff.cc @@ -57,9 +57,12 @@ struct MemoryNordffPass : public Pass { for (auto &mem : Mem::get_selected_memories(module)) { bool changed = false; - for (int i = 0; i < GetSize(mem.rd_ports); i++) - if (mem.extract_rdff(i, &initvals)) + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + if (mem.rd_ports[i].clk_enable) { + mem.extract_rdff(i, &initvals); changed = true; + } + } if (changed) mem.emit(); From 64ba3c384255335d61e2d07160c57fa74156cde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 22:37:03 +0200 Subject: [PATCH 0362/2410] backends/verilog: Try to preserve mem write port priorities. --- backends/verilog/verilog_backend.cc | 116 ++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 32 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index cfdc0316ad9..27a032586ad 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -594,48 +594,100 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) } } - // write ports - for (auto &port : mem.wr_ports) + // Write ports. Those are messy because we try to preserve priority, as much as we can: + // + // 1. We split all ports into several disjoint processes. + // 2. If a port has priority over another port, the two ports need to share + // a process, so that priority can be reconstructed on the other end. + // 3. We want each process to be as small as possible, to avoid extra + // priorities inferred on the other end. + pool wr_ports_done; + for (int ridx = 0; ridx < GetSize(mem.wr_ports); ridx++) { + if (wr_ports_done.count(ridx)) + continue; + + auto &root = mem.wr_ports[ridx]; + + // Start from a root. + pool wr_ports_now; + wr_ports_now.insert(ridx); + + // Transitively fill list of ports in this process by following priority edges. + while (true) { - std::ostringstream os; - dump_sigspec(os, port.clk); - clk_domain_str = stringf("%sedge %s", port.clk_polarity ? "pos" : "neg", os.str().c_str()); - if( clk_to_lof_body.count(clk_domain_str) == 0 ) - clk_to_lof_body[clk_domain_str] = std::vector(); + bool changed = false; + + for (int i = 0; i < GetSize(mem.wr_ports); i++) + for (int j = 0; j < i; j++) + if (mem.wr_ports[i].priority_mask[j]) + { + if (wr_ports_now.count(i) && !wr_ports_now.count(j)) { + wr_ports_now.insert(j); + changed = true; + } + if (!wr_ports_now.count(i) && wr_ports_now.count(j)) { + wr_ports_now.insert(i); + changed = true; + } + } + + if (!changed) + break; } - // make something like: - // always @(posedge clk) - // if (wr_en_bit) memid[w_addr][??] <= w_data[??]; - // ... - for (int i = 0; i < GetSize(port.en); i++) - { - int start_i = i, width = 1; - SigBit wen_bit = port.en[i]; - while (i+1 < GetSize(port.en) && active_sigmap(port.en[i+1]) == active_sigmap(wen_bit)) - i++, width++; + f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", root.clk_polarity ? "pos" : "neg"); + dump_sigspec(f, root.clk); + f << ") begin\n"; - if (wen_bit == State::S0) + for (int pidx = 0; pidx < GetSize(mem.wr_ports); pidx++) + { + if (!wr_ports_now.count(pidx)) continue; + wr_ports_done.insert(pidx); + + auto &port = mem.wr_ports[pidx]; + log_assert(port.clk_enable == root.clk_enable); + if (port.clk_enable) { + log_assert(port.clk == root.clk); + log_assert(port.clk_polarity == root.clk_polarity); + } - std::ostringstream os; - if (wen_bit != State::S1) + // make something like: + // always @(posedge clk) + // if (wr_en_bit) memid[w_addr][??] <= w_data[??]; + // ... + for (int i = 0; i < GetSize(port.en); i++) { - os << stringf("if ("); - dump_sigspec(os, wen_bit); - os << stringf(") "); + int start_i = i, width = 1; + SigBit wen_bit = port.en[i]; + + while (i+1 < GetSize(port.en) && active_sigmap(port.en[i+1]) == active_sigmap(wen_bit)) + i++, width++; + + if (wen_bit == State::S0) + continue; + + f << stringf("%s%s", indent.c_str(), indent.c_str()); + if (wen_bit != State::S1) + { + f << stringf("if ("); + dump_sigspec(f, wen_bit); + f << stringf(")\n"); + f << stringf("%s%s%s", indent.c_str(), indent.c_str(), indent.c_str()); + } + f << stringf("%s[", mem_id.c_str()); + dump_sigspec(f, port.addr); + if (width == GetSize(port.en)) + f << stringf("] <= "); + else + f << stringf("][%d:%d] <= ", i, start_i); + dump_sigspec(f, port.data.extract(start_i, width)); + f << stringf(";\n"); } - os << stringf("%s[", mem_id.c_str()); - dump_sigspec(os, port.addr); - if (width == GetSize(port.en)) - os << stringf("] <= "); - else - os << stringf("][%d:%d] <= ", i, start_i); - dump_sigspec(os, port.data.extract(start_i, width)); - os << stringf(";\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); } + + f << stringf("%s" "end\n", indent.c_str()); } // Output Verilog that looks something like this: // reg [..] _3_; From 57ca51be76ec4dc6eba802728ca6407520c704e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 26 May 2021 02:06:44 +0200 Subject: [PATCH 0363/2410] kernel/mem: Add prepare_wr_merge helper. --- kernel/mem.cc | 20 ++++++++++++++++++++ kernel/mem.h | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index fe88be5d7bc..77165d97fbc 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -786,3 +786,23 @@ void Mem::emulate_priority(int idx1, int idx2) } port2.priority_mask[idx1] = false; } + +void Mem::prepare_wr_merge(int idx1, int idx2) { + log_assert(idx1 < idx2); + auto &port1 = wr_ports[idx1]; + auto &port2 = wr_ports[idx2]; + // If port 2 has priority over a port before port 1, make port 1 have priority too. + for (int i = 0; i < idx1; i++) + if (port2.priority_mask[i]) + port1.priority_mask[i] = true; + // If port 2 has priority over a port after port 1, emulate it. + for (int i = idx1 + 1; i < idx2; i++) + if (port2.priority_mask[i]) + emulate_priority(i, idx2); + // If some port had priority over port 2, make it have priority over the merged port too. + for (int i = idx2 + 1; i < GetSize(wr_ports); i++) { + auto &oport = wr_ports[i]; + if (oport.priority_mask[idx2]) + oport.priority_mask[idx1] = true; + } +} diff --git a/kernel/mem.h b/kernel/mem.h index 49b72bc353e..15886877a80 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -84,6 +84,13 @@ struct Mem { // from the priority mask. void emulate_priority(int idx1, int idx2); + // Prepares for merging write port idx2 into idx1 (where idx1 < idx2). + // Specifically, takes care of priority masks: any priority relations + // that idx2 had are replicated onto idx1, unless they conflict with + // priorities already present on idx1, in which case emulate_priority + // is called. + void prepare_wr_merge(int idx1, int idx2); + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} }; From 83a218141c1a333b582c257c316ddea63e1ca519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 26 May 2021 02:49:50 +0200 Subject: [PATCH 0364/2410] kernel/mem: Add sub_addr helpers. --- kernel/mem.cc | 32 ++++++++++++-------------------- kernel/mem.h | 18 ++++++++++++++++++ passes/opt/opt_mem_feedback.cc | 8 ++------ 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 77165d97fbc..a7ee1f2d643 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -136,10 +136,8 @@ void Mem::emit() { rd_transparent.bits.push_back(State(port.transparent)); rd_clk.append(port.clk); rd_en.append(port.en); - SigSpec addr = port.addr; + SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); - for (int i = 0; i < port.wide_log2; i++) - addr[i] = State(sub >> i & 1); rd_addr.append(addr); log_assert(GetSize(addr) == abits); } @@ -170,10 +168,8 @@ void Mem::emit() { wr_clk_enable.bits.push_back(State(port.clk_enable)); wr_clk_polarity.bits.push_back(State(port.clk_polarity)); wr_clk.append(port.clk); - SigSpec addr = port.addr; + SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); - for (int i = 0; i < port.wide_log2; i++) - addr[i] = State(sub >> i & 1); wr_addr.append(addr); log_assert(GetSize(addr) == abits); } @@ -615,11 +611,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { SigSpec raddr = port.addr; SigSpec waddr = wport.addr; - for (int j = min_wide_log2; j < max_wide_log2; j++) - if (wide_write) - waddr[j] = State(sub >> j & 1); - else - raddr[j] = State(sub >> j & 1); + if (wide_write) + waddr = wport.sub_addr(sub); + else + raddr = port.sub_addr(sub); SigSpec addr_eq; if (raddr != waddr) addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid.c_str(), idx, i, sub), raddr, waddr); @@ -722,8 +717,7 @@ void Mem::narrow() { port.init_value = port.init_value.extract(it.second * width, width); port.arst_value = port.arst_value.extract(it.second * width, width); port.srst_value = port.srst_value.extract(it.second * width, width); - for (int i = 0; i < port.wide_log2; i++) - port.addr[i] = State(it.second >> i & 1); + port.addr = port.sub_addr(it.second); port.wide_log2 = 0; } new_rd_ports.push_back(port); @@ -736,8 +730,7 @@ void Mem::narrow() { if (port.wide_log2) { port.data = port.data.extract(it.second * width, width); port.en = port.en.extract(it.second * width, width); - for (int i = 0; i < port.wide_log2; i++) - port.addr[i] = State(it.second >> i & 1); + port.addr = port.sub_addr(it.second); port.wide_log2 = 0; } port.priority_mask.clear(); @@ -761,11 +754,10 @@ void Mem::emulate_priority(int idx1, int idx2) for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { SigSpec addr1 = port1.addr; SigSpec addr2 = port2.addr; - for (int j = min_wide_log2; j < max_wide_log2; j++) - if (wide1) - addr1[j] = State(sub >> j & 1); - else - addr2[j] = State(sub >> j & 1); + if (wide1) + addr1 = port1.sub_addr(sub); + else + addr2 = port2.sub_addr(sub); SigSpec addr_eq = module->Eq(NEW_ID, addr1, addr2); int ewidth = width << min_wide_log2; int sub1 = wide1 ? sub : 0; diff --git a/kernel/mem.h b/kernel/mem.h index 15886877a80..82eb0f4880c 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -34,7 +34,16 @@ struct MemRd { Const arst_value, srst_value, init_value; bool transparent; SigSpec clk, en, arst, srst, addr, data; + MemRd() : removed(false), cell(nullptr) {} + + // Returns the address of given subword index accessed by this port. + SigSpec sub_addr(int sub) { + SigSpec res = addr; + for (int i = 0; i < wide_log2; i++) + res[i] = State(sub >> i & 1); + return res; + } }; struct MemWr { @@ -45,7 +54,16 @@ struct MemWr { bool clk_enable, clk_polarity; std::vector priority_mask; SigSpec clk, en, addr, data; + MemWr() : removed(false), cell(nullptr) {} + + // Returns the address of given subword index accessed by this port. + SigSpec sub_addr(int sub) { + SigSpec res = addr; + for (int i = 0; i < wide_log2; i++) + res[i] = State(sub >> i & 1); + return res; + } }; struct MemInit { diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 8e93c93b924..1311038439f 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -145,9 +145,7 @@ struct OptMemFeedbackWorker continue; for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - SigSpec addr = sigmap_xmux(port.addr); - for (int i = 0; i < port.wide_log2; i++) - addr[i] = State(sub >> i & 1); + SigSpec addr = sigmap_xmux(port.sub_addr(sub)); async_rd_bits[addr].resize(mem.width); for (int i = 0; i < mem.width; i++) async_rd_bits[addr][i].insert(sigmap(port.data[i + sub * mem.width])); @@ -168,9 +166,7 @@ struct OptMemFeedbackWorker for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - SigSpec addr = sigmap_xmux(port.addr); - for (int k = 0; k < port.wide_log2; k++) - addr[k] = State(sub >> k & 1); + SigSpec addr = sigmap_xmux(port.sub_addr(sub)); if (!async_rd_bits.count(addr)) continue; From b019db1f373e6bfe2b55363d28b9b6828a1cca6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 26 May 2021 03:07:51 +0200 Subject: [PATCH 0365/2410] kernel/mem: Add helpers for write port widening. --- kernel/mem.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/mem.h | 11 +++++++++++ 2 files changed, 57 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index a7ee1f2d643..021e1991e5d 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -798,3 +798,49 @@ void Mem::prepare_wr_merge(int idx1, int idx2) { oport.priority_mask[idx1] = true; } } + +void Mem::widen_prep(int wide_log2) { + // Make sure start_offset and size are aligned to the port width, + // adjust if necessary. + int mask = ((1 << wide_log2) - 1); + int delta = start_offset & mask; + start_offset -= delta; + size += delta; + if (size & mask) { + size |= mask; + size++; + } +} + +void Mem::widen_wr_port(int idx, int wide_log2) { + widen_prep(wide_log2); + auto &port = wr_ports[idx]; + log_assert(port.wide_log2 <= wide_log2); + if (port.wide_log2 < wide_log2) { + SigSpec new_data, new_en; + SigSpec addr_lo = port.addr.extract(0, wide_log2); + for (int sub = 0; sub < (1 << wide_log2); sub += (1 << port.wide_log2)) + { + Const cur_addr_lo(sub, wide_log2); + if (addr_lo == cur_addr_lo) { + // Always writes to this subword. + new_data.append(port.data); + new_en.append(port.en); + } else if (addr_lo.is_fully_const()) { + // Never writes to this subword. + new_data.append(Const(State::Sx, GetSize(port.data))); + new_en.append(Const(State::S0, GetSize(port.data))); + } else { + // May or may not write to this subword. + new_data.append(port.data); + SigSpec addr_eq = module->Eq(NEW_ID, addr_lo, cur_addr_lo); + SigSpec en = module->Mux(NEW_ID, Const(State::S0, GetSize(port.data)), port.en, addr_eq); + new_en.append(en); + } + } + port.addr.replace(port.wide_log2, Const(State::S0, wide_log2 - port.wide_log2)); + port.data = new_data; + port.en = new_en; + port.wide_log2 = wide_log2; + } +} diff --git a/kernel/mem.h b/kernel/mem.h index 82eb0f4880c..b4a9cb69542 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -109,6 +109,17 @@ struct Mem { // is called. void prepare_wr_merge(int idx1, int idx2); + // Prepares the memory for widening a port to a given width. This + // involves ensuring that start_offset and size are aligned to the + // target width. + void widen_prep(int wide_log2); + + // Widens a write port up to a given width. The newly port is + // equivalent to the original, made by replicating enable/data bits + // and masking enable bits with decoders on the low part of the + // original address. + void widen_wr_port(int idx, int wide_log2); + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} }; From 1eae6025e7dccc021dcd2a6d658dae40ab02ef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 25 Oct 2020 23:01:59 +0100 Subject: [PATCH 0366/2410] memory_share: Improve same-address merging, recognize wide write ports. --- passes/memory/memory_share.cc | 281 ++++++++++------------------------ 1 file changed, 77 insertions(+), 204 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 98637720c91..bfd94a344ab 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -33,230 +33,100 @@ struct MemoryShareWorker SigMap sigmap, sigmap_xmux; ModWalker modwalker; CellTypes cone_ct; + bool flag_widen; // ------------------------------------------------------ // Consolidate write ports that write to the same address + // (or close enough to be merged to wide ports) // ------------------------------------------------------ - RTLIL::SigSpec mask_en_naive(RTLIL::SigSpec do_mask, RTLIL::SigSpec bits, RTLIL::SigSpec mask_bits) - { - // this is the naive version of the function that does not care about grouping the EN bits. - - RTLIL::SigSpec inv_mask_bits = module->Not(NEW_ID, mask_bits); - RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.size()), inv_mask_bits, do_mask); - RTLIL::SigSpec result = module->And(NEW_ID, inv_mask_bits_filtered, bits); - return result; - } - - RTLIL::SigSpec mask_en_grouped(RTLIL::SigSpec do_mask, RTLIL::SigSpec bits, RTLIL::SigSpec mask_bits) - { - // this version of the function preserves the bit grouping in the EN bits. - - std::vector v_bits = bits; - std::vector v_mask_bits = mask_bits; - - std::map, std::pair>> groups; - RTLIL::SigSpec grouped_bits, grouped_mask_bits; - - for (int i = 0; i < bits.size(); i++) { - std::pair key(v_bits[i], v_mask_bits[i]); - if (groups.count(key) == 0) { - groups[key].first = grouped_bits.size(); - grouped_bits.append(v_bits[i]); - grouped_mask_bits.append(v_mask_bits[i]); - } - groups[key].second.push_back(i); - } - - std::vector grouped_result = mask_en_naive(do_mask, grouped_bits, grouped_mask_bits); - RTLIL::SigSpec result; - - for (int i = 0; i < bits.size(); i++) { - std::pair key(v_bits[i], v_mask_bits[i]); - result.append(grouped_result.at(groups.at(key).first)); - } - - return result; - } - - void merge_en_data(RTLIL::SigSpec &merged_en, RTLIL::SigSpec &merged_data, RTLIL::SigSpec next_en, RTLIL::SigSpec next_data) - { - std::vector v_old_en = merged_en; - std::vector v_next_en = next_en; - - // The new merged_en signal is just the old merged_en signal and next_en OR'ed together. - // But of course we need to preserve the bit grouping.. - - std::map, int> groups; - std::vector grouped_old_en, grouped_next_en; - RTLIL::SigSpec new_merged_en; - - for (int i = 0; i < int(v_old_en.size()); i++) { - std::pair key(v_old_en[i], v_next_en[i]); - if (groups.count(key) == 0) { - groups[key] = grouped_old_en.size(); - grouped_old_en.push_back(key.first); - grouped_next_en.push_back(key.second); - } - } - - std::vector grouped_new_en = module->Or(NEW_ID, grouped_old_en, grouped_next_en); - - for (int i = 0; i < int(v_old_en.size()); i++) { - std::pair key(v_old_en[i], v_next_en[i]); - new_merged_en.append(grouped_new_en.at(groups.at(key))); - } - - // Create the new merged_data signal. - - RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.size()); - - RTLIL::SigSpec old_data_set = module->And(NEW_ID, merged_en, merged_data); - RTLIL::SigSpec old_data_unset = module->And(NEW_ID, merged_en, module->Not(NEW_ID, merged_data)); - - RTLIL::SigSpec new_data_set = module->And(NEW_ID, next_en, next_data); - RTLIL::SigSpec new_data_unset = module->And(NEW_ID, next_en, module->Not(NEW_ID, next_data)); - - new_merged_data = module->Or(NEW_ID, new_merged_data, old_data_set); - new_merged_data = module->And(NEW_ID, new_merged_data, module->Not(NEW_ID, old_data_unset)); - - new_merged_data = module->Or(NEW_ID, new_merged_data, new_data_set); - new_merged_data = module->And(NEW_ID, new_merged_data, module->Not(NEW_ID, new_data_unset)); - - // Update merged_* signals - - merged_en = new_merged_en; - merged_data = new_merged_data; - } - - void consolidate_wr_by_addr(Mem &mem) + bool consolidate_wr_by_addr(Mem &mem) { if (GetSize(mem.wr_ports) <= 1) - return; + return false; log("Consolidating write ports of memory %s.%s by address:\n", log_id(module), log_id(mem.memid)); - std::map last_port_by_addr; - std::vector> active_bits_on_port; - - bool cache_clk_enable = false; - bool cache_clk_polarity = false; - RTLIL::SigSpec cache_clk; - int cache_wide_log2 = 0; - bool changed = false; - for (int i = 0; i < GetSize(mem.wr_ports); i++) { - auto &port = mem.wr_ports[i]; - RTLIL::SigSpec addr = sigmap_xmux(port.addr); - - if (port.clk_enable != cache_clk_enable || - port.wide_log2 != cache_wide_log2 || - (cache_clk_enable && (sigmap(port.clk) != cache_clk || - port.clk_polarity != cache_clk_polarity))) - { - cache_clk_enable = port.clk_enable; - cache_clk_polarity = port.clk_polarity; - cache_clk = sigmap(port.clk); - cache_wide_log2 = port.wide_log2; - last_port_by_addr.clear(); - - if (cache_clk_enable) - log(" New clock domain: %s %s\n", cache_clk_polarity ? "posedge" : "negedge", log_signal(cache_clk)); - else - log(" New clock domain: unclocked\n"); - } - - log(" Port %d has addr %s.\n", i, log_signal(addr)); - - log(" Active bits: "); - std::vector en_bits = sigmap(port.en); - active_bits_on_port.push_back(std::vector(en_bits.size())); - for (int k = int(en_bits.size())-1; k >= 0; k--) { - active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; - log("%c", active_bits_on_port[i][k] ? '1' : '0'); - } - log("\n"); - - if (last_port_by_addr.count(addr)) + auto &port1 = mem.wr_ports[i]; + if (port1.removed) + continue; + if (!port1.clk_enable) + continue; + for (int j = i + 1; j < GetSize(mem.wr_ports); j++) { - int last_i = last_port_by_addr.at(addr); - log(" Merging port %d into this one.\n", last_i); - - bool found_overlapping_bits = false; - for (int k = 0; k < int(en_bits.size()); k++) { - if (active_bits_on_port[i][k] && active_bits_on_port[last_i][k]) - found_overlapping_bits = true; - active_bits_on_port[i][k] = active_bits_on_port[i][k] || active_bits_on_port[last_i][k]; - } - - // Force this ports addr input to addr directly (skip don't care muxes) - - port.addr = addr; - - // If any of the ports between `last_i' and `i' write to the same address, this - // will have priority over whatever `last_i` wrote. So we need to revisit those - // ports and mask the EN bits accordingly. - - RTLIL::SigSpec merged_en = sigmap(mem.wr_ports[last_i].en); - - for (int j = last_i+1; j < i; j++) - { - if (mem.wr_ports[j].removed) + auto &port2 = mem.wr_ports[j]; + if (port2.removed) + continue; + if (!port2.clk_enable) + continue; + if (port1.clk != port2.clk) + continue; + if (port1.clk_polarity != port2.clk_polarity) + continue; + // If the width of the ports doesn't match, they can still be + // merged by widening the narrow one. Check if the conditions + // hold for that. + int wide_log2 = std::max(port1.wide_log2, port2.wide_log2); + if (GetSize(port1.addr) <= wide_log2) + continue; + if (GetSize(port2.addr) <= wide_log2) + continue; + if (!port1.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (!port2.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) { + // Incompatible addresses after widening. Last chance — widen both + // ports by one more bit to merge them. + if (!flag_widen) + continue; + wide_log2++; + if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) + continue; + if (!port1.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (!port2.addr.extract(0, wide_log2).is_fully_const()) continue; - - for (int k = 0; k < int(en_bits.size()); k++) - if (active_bits_on_port[i][k] && active_bits_on_port[j][k]) - goto found_overlapping_bits_i_j; - - if (0) { - found_overlapping_bits_i_j: - log(" Creating collosion-detect logic for port %d.\n", j); - RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); - module->addEq(NEW_ID, addr, mem.wr_ports[j].addr, is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(mem.wr_ports[j].en)); - } } - - // Then we need to merge the (masked) EN and the DATA signals. - - RTLIL::SigSpec merged_data = mem.wr_ports[last_i].data; - if (found_overlapping_bits) { - log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(port.en), sigmap(port.data)); - } else { - RTLIL::SigSpec cell_en = sigmap(port.en); - RTLIL::SigSpec cell_data = sigmap(port.data); - for (int k = 0; k < int(en_bits.size()); k++) - if (!active_bits_on_port[last_i][k]) { - merged_en.replace(k, cell_en.extract(k, 1)); - merged_data.replace(k, cell_data.extract(k, 1)); - } + log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); + mem.prepare_wr_merge(i, j); + port1.addr = sigmap_xmux(port1.addr); + port2.addr = sigmap_xmux(port2.addr); + mem.widen_wr_port(i, wide_log2); + mem.widen_wr_port(j, wide_log2); + int pos = 0; + while (pos < GetSize(port1.data)) { + int epos = pos; + while (epos < GetSize(port1.data) && port1.en[epos] == port1.en[pos] && port2.en[epos] == port2.en[pos]) + epos++; + int width = epos - pos; + SigBit new_en; + if (port2.en[pos] == State::S0) { + new_en = port1.en[pos]; + } else if (port1.en[pos] == State::S0) { + port1.data.replace(pos, port2.data.extract(pos, width)); + new_en = port2.en[pos]; + } else { + port1.data.replace(pos, module->Mux(NEW_ID, port1.data.extract(pos, width), port2.data.extract(pos, width), port2.en[pos])); + new_en = module->Or(NEW_ID, port1.en[pos], port2.en[pos]); + } + for (int k = pos; k < epos; k++) + port1.en[k] = new_en; + pos = epos; } - - // Connect the new EN and DATA signals and remove the old write port. - - port.en = merged_en; - port.data = merged_data; - - mem.wr_ports[last_i].removed = true; changed = true; - - log(" Active bits: "); - std::vector en_bits = sigmap(port.en); - active_bits_on_port.push_back(std::vector(en_bits.size())); - for (int k = int(en_bits.size())-1; k >= 0; k--) - log("%c", active_bits_on_port[i][k] ? '1' : '0'); - log("\n"); + port2.removed = true; } - - last_port_by_addr[addr] = i; } if (changed) mem.emit(); + + return changed; } @@ -441,7 +311,7 @@ struct MemoryShareWorker // Setup and run // ------------- - MemoryShareWorker(RTLIL::Design *design) : design(design), modwalker(design) {} + MemoryShareWorker(RTLIL::Design *design, bool flag_widen) : design(design), modwalker(design), flag_widen(flag_widen) {} void operator()(RTLIL::Module* module) { @@ -465,8 +335,9 @@ struct MemoryShareWorker } } - for (auto &mem : memories) - consolidate_wr_by_addr(mem); + for (auto &mem : memories) { + while (consolidate_wr_by_addr(mem)); + } cone_ct.setup_internals(); cone_ct.cell_types.erase(ID($mul)); @@ -515,8 +386,10 @@ struct MemorySharePass : public Pass { } void execute(std::vector args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n"); + // TODO: expose when wide ports are actually supported. + bool flag_widen = false; extra_args(args, 1, design); - MemoryShareWorker msw(design); + MemoryShareWorker msw(design, flag_widen); for (auto module : design->selected_modules()) msw(module); From aabe1c382e635040d16b6a29c7e2741e8e9d7adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 26 May 2021 01:18:29 +0200 Subject: [PATCH 0367/2410] backends/verilog: Add wide port support. --- backends/verilog/verilog_backend.cc | 131 +++++++++++++++++++--------- 1 file changed, 88 insertions(+), 43 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 27a032586ad..95ad69c814d 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -541,19 +541,36 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) // assign r_data = temp_id; std::string temp_id = next_auto_id(); lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id.c_str()) ); + + bool has_en = port.en != State::S1; + + if (has_en) { std::ostringstream os; - if (port.en != RTLIL::SigBit(true)) - { - os << stringf("if ("); - dump_sigspec(os, port.en); - os << stringf(") "); - } - os << stringf("%s <= %s[", temp_id.c_str(), mem_id.c_str()); - dump_sigspec(os, port.addr); + os << stringf("if ("); + dump_sigspec(os, port.en); + os << stringf(") begin\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + } + + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + { + SigSpec addr = port.sub_addr(sub); + std::ostringstream os; + if (has_en) + os << indent; + os << temp_id; + if (port.wide_log2) + os << stringf("[%d:%d]", (sub + 1) * mem.width - 1, sub * mem.width); + os << stringf(" <= %s[", mem_id.c_str()); + dump_sigspec(os, addr); os << stringf("];\n"); clk_to_lof_body[clk_domain_str].push_back(os.str()); } + + if (has_en) + clk_to_lof_body[clk_domain_str].push_back("end\n"); + { std::ostringstream os; dump_sigspec(os, port.data); @@ -569,28 +586,48 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) // temp_id <= r_addr; // assign r_data = array_reg[temp_id]; std::string temp_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.addr.size() - 1, temp_id.c_str()) ); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.addr.size() - 1 - port.wide_log2, temp_id.c_str()) ); { std::ostringstream os; - dump_sigspec(os, port.addr); + dump_sigspec(os, port.addr.extract_end(port.wide_log2)); std::string line = stringf("%s <= %s;\n", temp_id.c_str(), os.str().c_str()); clk_to_lof_body[clk_domain_str].push_back(line); } + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { std::ostringstream os; - dump_sigspec(os, port.data); - std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), temp_id.c_str()); - clk_to_lof_body[""].push_back(line); + os << "assign "; + dump_sigspec(os, port.data.extract(sub * mem.width, mem.width)); + os << stringf(" = %s[", mem_id.c_str());; + if (port.wide_log2) { + Const addr_lo; + for (int i = 0; i < port.wide_log2; i++) + addr_lo.bits.push_back(State(sub >> i & 1)); + os << "{"; + os << temp_id; + os << ", "; + dump_const(os, addr_lo); + os << "}"; + } else { + os << temp_id; + } + os << "];\n"; + clk_to_lof_body[""].push_back(os.str()); } } } else { // for non-clocked read-ports make something like: // assign r_data = array_reg[r_addr]; - std::ostringstream os, os2; - dump_sigspec(os, port.data); - dump_sigspec(os2, port.addr); - std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), os2.str().c_str()); - clk_to_lof_body[""].push_back(line); + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + { + SigSpec addr = port.sub_addr(sub); + + std::ostringstream os, os2; + dump_sigspec(os, port.data.extract(sub * mem.width, mem.width)); + dump_sigspec(os2, addr); + std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), os2.str().c_str()); + clk_to_lof_body[""].push_back(line); + } } } @@ -636,9 +673,13 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) break; } - f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", root.clk_polarity ? "pos" : "neg"); - dump_sigspec(f, root.clk); - f << ") begin\n"; + if (root.clk_enable) { + f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", root.clk_polarity ? "pos" : "neg"); + dump_sigspec(f, root.clk); + f << ") begin\n"; + } else { + f << stringf("%s" "always%s begin\n", indent.c_str(), systemverilog ? "_latch" : " @*"); + } for (int pidx = 0; pidx < GetSize(mem.wr_ports); pidx++) { @@ -657,33 +698,37 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) // always @(posedge clk) // if (wr_en_bit) memid[w_addr][??] <= w_data[??]; // ... - for (int i = 0; i < GetSize(port.en); i++) + for (int sub = 0; sub < (1 << port.wide_log2); sub++) { - int start_i = i, width = 1; - SigBit wen_bit = port.en[i]; + SigSpec addr = port.sub_addr(sub); + for (int i = 0; i < mem.width; i++) + { + int start_i = i, width = 1; + SigBit wen_bit = port.en[sub * mem.width + i]; - while (i+1 < GetSize(port.en) && active_sigmap(port.en[i+1]) == active_sigmap(wen_bit)) - i++, width++; + while (i+1 < mem.width && active_sigmap(port.en[sub * mem.width + i+1]) == active_sigmap(wen_bit)) + i++, width++; - if (wen_bit == State::S0) - continue; + if (wen_bit == State::S0) + continue; - f << stringf("%s%s", indent.c_str(), indent.c_str()); - if (wen_bit != State::S1) - { - f << stringf("if ("); - dump_sigspec(f, wen_bit); - f << stringf(")\n"); - f << stringf("%s%s%s", indent.c_str(), indent.c_str(), indent.c_str()); + f << stringf("%s%s", indent.c_str(), indent.c_str()); + if (wen_bit != State::S1) + { + f << stringf("if ("); + dump_sigspec(f, wen_bit); + f << stringf(")\n"); + f << stringf("%s%s%s", indent.c_str(), indent.c_str(), indent.c_str()); + } + f << stringf("%s[", mem_id.c_str()); + dump_sigspec(f, addr); + if (width == GetSize(port.en)) + f << stringf("] <= "); + else + f << stringf("][%d:%d] <= ", i, start_i); + dump_sigspec(f, port.data.extract(sub * mem.width + start_i, width)); + f << stringf(";\n"); } - f << stringf("%s[", mem_id.c_str()); - dump_sigspec(f, port.addr); - if (width == GetSize(port.en)) - f << stringf("] <= "); - else - f << stringf("][%d:%d] <= ", i, start_i); - dump_sigspec(f, port.data.extract(start_i, width)); - f << stringf(";\n"); } } From 055ba748bcf8c77bff15bda0de49c0b4b3722bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 17:50:59 +0200 Subject: [PATCH 0368/2410] backends/verilog: Add support for memory read port reset and init value. --- backends/verilog/verilog_backend.cc | 90 ++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 95ad69c814d..0dc7113bd16 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -515,6 +515,8 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) // create a map : "edge clk" -> expressions within that clock domain dict> clk_to_lof_body; + dict clk_to_arst_cond; + dict> clk_to_arst_body; clk_to_lof_body[""] = std::vector(); std::string clk_domain_str; // create a list of reg declarations @@ -529,8 +531,12 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) std::ostringstream os; dump_sigspec(os, port.clk); clk_domain_str = stringf("%sedge %s", port.clk_polarity ? "pos" : "neg", os.str().c_str()); - if( clk_to_lof_body.count(clk_domain_str) == 0 ) - clk_to_lof_body[clk_domain_str] = std::vector(); + if (port.arst != State::S0) { + std::ostringstream os2; + dump_sigspec(os2, port.arst); + clk_domain_str += stringf(", posedge %s", os2.str().c_str()); + clk_to_arst_cond[clk_domain_str] = os2.str(); + } } if (!port.transparent) { @@ -542,22 +548,51 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) std::string temp_id = next_auto_id(); lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id.c_str()) ); - bool has_en = port.en != State::S1; + bool has_indent = false; - if (has_en) - { + if (port.arst != State::S0) { + std::ostringstream os; + os << stringf("%s <= ", temp_id.c_str()); + dump_sigspec(os, port.arst_value); + os << ";\n"; + clk_to_arst_body[clk_domain_str].push_back(os.str()); + } + + if (port.srst != State::S0 && !port.ce_over_srst) { + std::ostringstream os; + os << stringf("if ("); + dump_sigspec(os, port.srst); + os << stringf(")\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + std::ostringstream os2; + os2 << stringf("%s" "%s <= ", indent.c_str(), temp_id.c_str()); + dump_sigspec(os2, port.srst_value); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + std::ostringstream os3; + if (port.en == State::S1) { + os3 << "else begin\n"; + } else { + os3 << "else if ("; + dump_sigspec(os3, port.en); + os3 << ") begin\n"; + } + clk_to_lof_body[clk_domain_str].push_back(os3.str()); + has_indent = true; + } else if (port.en != State::S1) { std::ostringstream os; os << stringf("if ("); dump_sigspec(os, port.en); os << stringf(") begin\n"); clk_to_lof_body[clk_domain_str].push_back(os.str()); + has_indent = true; } for (int sub = 0; sub < (1 << port.wide_log2); sub++) { SigSpec addr = port.sub_addr(sub); std::ostringstream os; - if (has_en) + if (has_indent) os << indent; os << temp_id; if (port.wide_log2) @@ -568,9 +603,35 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) clk_to_lof_body[clk_domain_str].push_back(os.str()); } - if (has_en) + if (port.srst != State::S0 && port.ce_over_srst) + { + std::ostringstream os; + if (has_indent) + os << indent; + os << stringf("if ("); + dump_sigspec(os, port.srst); + os << stringf(")\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + std::ostringstream os2; + if (has_indent) + os2 << indent; + os2 << stringf("%s" "%s <= ", indent.c_str(), temp_id.c_str()); + dump_sigspec(os2, port.srst_value); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + } + + if (has_indent) clk_to_lof_body[clk_domain_str].push_back("end\n"); + if (!port.init_value.is_fully_undef()) + { + std::ostringstream os; + dump_sigspec(os, port.init_value); + std::string line = stringf("initial %s = %s;\n", temp_id.c_str(), os.str().c_str()); + clk_to_lof_body[""].push_back(line); + } + { std::ostringstream os; dump_sigspec(os, port.data); @@ -765,8 +826,19 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) if( clk_domain != "") { f << stringf("%s" "always%s @(%s) begin\n", indent.c_str(), systemverilog ? "_ff" : "", clk_domain.c_str()); - for(auto &line : lof_lines) - f << stringf("%s%s" "%s", indent.c_str(), indent.c_str(), line.c_str()); + bool has_arst = clk_to_arst_cond.count(clk_domain) != 0; + if (has_arst) { + f << stringf("%s%s" "if (%s) begin\n", indent.c_str(), indent.c_str(), clk_to_arst_cond[clk_domain].c_str()); + for(auto &line : clk_to_arst_body[clk_domain]) + f << stringf("%s%s%s" "%s", indent.c_str(), indent.c_str(), indent.c_str(), line.c_str()); + f << stringf("%s%s" "end else begin\n", indent.c_str(), indent.c_str()); + for(auto &line : lof_lines) + f << stringf("%s%s%s" "%s", indent.c_str(), indent.c_str(), indent.c_str(), line.c_str()); + f << stringf("%s%s" "end\n", indent.c_str(), indent.c_str()); + } else { + for(auto &line : lof_lines) + f << stringf("%s%s" "%s", indent.c_str(), indent.c_str(), line.c_str()); + } f << stringf("%s" "end\n", indent.c_str()); } else From cbf6b719fe85ce8544f9bb0796711f3f45638862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 23:43:25 +0200 Subject: [PATCH 0369/2410] Make a few passes auto-call Mem::narrow instead of rejecting wide ports. This essentially adds wide port support for free in passes that don't have a usefully better way of handling wide ports than just breaking them up to narrow ports, avoiding "please run memory_narrow" annoyance. --- backends/btor/btor.cc | 12 +++--------- backends/firrtl/firrtl.cc | 6 ++---- backends/smt2/smt2.cc | 7 +------ kernel/mem.cc | 3 +++ passes/memory/memory_bram.cc | 15 +-------------- 5 files changed, 10 insertions(+), 33 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 999836882ee..a7e32bc5c43 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -732,14 +732,6 @@ struct BtorWorker if (port.clk_enable) log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n", log_id(module), log_id(mem->memid)); - if (port.wide_log2) - log_error("Memory %s.%s has wide read ports. Please use memory_narrow to convert them first.\n", - log_id(module), log_id(mem->memid)); - } - for (auto &port : mem->wr_ports) { - if (port.wide_log2) - log_error("Memory %s.%s has wide write ports. Please use memory_narrow to convert them first.\n", - log_id(module), log_id(mem->memid)); } int data_sid = get_bv_sid(mem->width); @@ -1089,8 +1081,10 @@ struct BtorWorker memories = Mem::get_all_memories(module); dict mem_dict; - for (auto &mem : memories) + for (auto &mem : memories) { + mem.narrow(); mem_dict[mem.memid] = &mem; + } for (auto cell : module->cells()) if (cell->is_mem_cell()) mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index dee24d0e229..86b1bbdf695 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -542,6 +542,8 @@ struct FirrtlWorker vector port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs; std::vector memories = Mem::get_all_memories(module); + for (auto &mem : memories) + mem.narrow(); for (auto wire : module->wires()) { @@ -993,8 +995,6 @@ struct FirrtlWorker if (port.clk_enable) log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); - if (port.wide_log2 != 0) - log_error("Wide read port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); std::ostringstream rpe; @@ -1016,8 +1016,6 @@ struct FirrtlWorker if (!port.clk_enable) log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); - if (port.wide_log2 != 0) - log_error("Wide write port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); if (!port.clk_polarity) log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); for (int i = 1; i < GetSize(port.en); i++) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 4dee0d4fbc9..7f6779c7de1 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -124,6 +124,7 @@ struct Smt2Worker memories = Mem::get_all_memories(module); for (auto &mem : memories) { + mem.narrow(); mem_dict[mem.memid] = &mem; for (auto &port : mem.wr_ports) { @@ -715,12 +716,6 @@ struct Smt2Worker has_sync_wr = true; else has_async_wr = true; - if (port.wide_log2) - log_error("Memory %s.%s has wide write ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); - } - for (auto &port : mem->rd_ports) { - if (port.wide_log2) - log_error("Memory %s.%s has wide read ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); } if (has_async_wr && has_sync_wr) log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); diff --git a/kernel/mem.cc b/kernel/mem.cc index 021e1991e5d..848dc9f3a95 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -691,6 +691,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } void Mem::narrow() { + // NOTE: several passes depend on this function not modifying + // the design at all until (and unless) emit() is called. + // Be careful to preserve this. std::vector new_rd_ports; std::vector new_wr_ports; std::vector> new_rd_map; diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index b708647665a..c1476669d4e 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1052,6 +1052,7 @@ grow_read_ports:; void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) { log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid)); + mem.narrow(); bool cell_init = !mem.inits.empty(); @@ -1069,20 +1070,6 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) log(" %s=%d", it.first.c_str(), it.second); log("\n"); - for (auto &port : mem.rd_ports) { - if (port.wide_log2) { - log("Wide read ports are not supported, skipping.\n"); - return; - } - } - - for (auto &port : mem.wr_ports) { - if (port.wide_log2) { - log("Wide write ports are not supported, skipping.\n"); - return; - } - } - // This pass cannot deal with write port priority — we need to emulate it, // if present. Since priority emulation will change the enable signals, // which in turn may change enable grouping and mapping eligibility in From 2d10caabbc083cdb615ee2035916505758e4944f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 26 Oct 2020 03:20:57 +0100 Subject: [PATCH 0370/2410] memory_share: Improve sat-based port sharing. --- passes/memory/memory_share.cc | 268 +++++++++++++++++++--------------- 1 file changed, 151 insertions(+), 117 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index bfd94a344ab..19afeb72dd7 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -139,13 +139,9 @@ struct MemoryShareWorker if (GetSize(mem.wr_ports) <= 1) return; - ezSatPtr ez; - SatGen satgen(ez.get(), &modwalker.sigmap); + // Get a list of ports that have any chance of being mergeable. - // find list of considered ports and port pairs - - std::set considered_ports; - std::set considered_port_pairs; + pool eligible_ports; for (int i = 0; i < GetSize(mem.wr_ports); i++) { auto &port = mem.wr_ports[i]; @@ -154,152 +150,190 @@ struct MemoryShareWorker if (bit == RTLIL::State::S1) goto port_is_always_active; if (modwalker.has_drivers(bits)) - considered_ports.insert(i); + eligible_ports.insert(i); port_is_always_active:; } + if (eligible_ports.size() <= 1) + return; + log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", log_id(module), log_id(mem.memid)); - bool cache_clk_enable = false; - bool cache_clk_polarity = false; - RTLIL::SigSpec cache_clk; - int cache_wide_log2 = 0; + // Group eligible ports by clock domain and width. + pool checked_ports; + std::vector> groups; for (int i = 0; i < GetSize(mem.wr_ports); i++) { - auto &port = mem.wr_ports[i]; + auto &port1 = mem.wr_ports[i]; + if (!eligible_ports.count(i)) + continue; + if (checked_ports.count(i)) + continue; - if (port.clk_enable != cache_clk_enable || - port.wide_log2 != cache_wide_log2 || - (cache_clk_enable && (sigmap(port.clk) != cache_clk || - port.clk_polarity != cache_clk_polarity))) + + std::vector group; + group.push_back(i); + + for (int j = i + 1; j < GetSize(mem.wr_ports); j++) { - cache_clk_enable = port.clk_enable; - cache_clk_polarity = port.clk_polarity; - cache_clk = sigmap(port.clk); - cache_wide_log2 = port.wide_log2; + auto &port2 = mem.wr_ports[j]; + if (!eligible_ports.count(j)) + continue; + if (checked_ports.count(j)) + continue; + if (port1.clk_enable != port2.clk_enable) + continue; + if (port1.clk_enable) { + if (port1.clk != port2.clk) + continue; + if (port1.clk_polarity != port2.clk_polarity) + continue; + } + if (port1.wide_log2 != port2.wide_log2) + continue; + group.push_back(j); } - else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) - considered_port_pairs.insert(i); - - if (cache_clk_enable) - log(" Port %d on %s %s: %s\n", i, - cache_clk_polarity ? "posedge" : "negedge", log_signal(cache_clk), - considered_ports.count(i) ? "considered" : "not considered"); - else - log(" Port %d unclocked: %s\n", i, - considered_ports.count(i) ? "considered" : "not considered"); - } - if (considered_port_pairs.size() < 1) { - log(" No two subsequent ports in same clock domain considered -> nothing to consolidate.\n"); - return; - } + for (auto j : group) + checked_ports.insert(j); - // create SAT representation of common input cone of all considered EN signals - - pool one_hot_wires; - std::set sat_cells; - std::set bits_queue; - std::map port_to_sat_variable; + if (group.size() <= 1) + continue; - for (int i = 0; i < GetSize(mem.wr_ports); i++) - if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) - { - RTLIL::SigSpec sig = modwalker.sigmap(mem.wr_ports[i].en); - port_to_sat_variable[i] = ez->expression(ez->OpOr, satgen.importSigSpec(sig)); + groups.push_back(group); + } - std::vector bits = sig; - bits_queue.insert(bits.begin(), bits.end()); + bool changed = false; + for (auto &group : groups) { + auto &some_port = mem.wr_ports[group[0]]; + string ports; + for (auto idx : group) { + if (idx != group[0]) + ports += ", "; + ports += std::to_string(idx); + } + if (!some_port.clk_enable) { + log(" Checking unclocked group, width %d: ports %s.\n", mem.width << some_port.wide_log2, ports.c_str()); + } else { + log(" Checking group clocked with %sedge %s, width %d: ports %s.\n", some_port.clk_polarity ? "pos" : "neg", log_signal(some_port.clk), mem.width << some_port.wide_log2, ports.c_str()); } - while (!bits_queue.empty()) - { - for (auto bit : bits_queue) - if (bit.wire && bit.wire->get_bool_attribute(ID::onehot)) - one_hot_wires.insert(bit.wire); - - pool portbits; - modwalker.get_drivers(portbits, bits_queue); - bits_queue.clear(); - - for (auto &pbit : portbits) - if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { - pool &cell_inputs = modwalker.cell_inputs[pbit.cell]; - bits_queue.insert(cell_inputs.begin(), cell_inputs.end()); - sat_cells.insert(pbit.cell); - } - } + // Okay, time to actually run the SAT solver. - for (auto wire : one_hot_wires) { - log(" Adding one-hot constraint for wire %s.\n", log_id(wire)); - vector ez_wire_bits = satgen.importSigSpec(wire); - for (int i : ez_wire_bits) - for (int j : ez_wire_bits) - if (i != j) ez->assume(ez->NOT(i), j); - } + ezSatPtr ez; + SatGen satgen(ez.get(), &modwalker.sigmap); - log(" Common input cone for all EN signals: %d cells.\n", int(sat_cells.size())); + // create SAT representation of common input cone of all considered EN signals - for (auto cell : sat_cells) - satgen.importCell(cell); + pool one_hot_wires; + std::set sat_cells; + std::set bits_queue; + dict port_to_sat_variable; - log(" Size of unconstrained SAT problem: %d variables, %d clauses\n", ez->numCnfVariables(), ez->numCnfClauses()); + for (auto idx : group) { + RTLIL::SigSpec sig = modwalker.sigmap(mem.wr_ports[idx].en); + port_to_sat_variable[idx] = ez->expression(ez->OpOr, satgen.importSigSpec(sig)); - // merge subsequent ports if possible + std::vector bits = sig; + bits_queue.insert(bits.begin(), bits.end()); + } - bool changed = false; - for (int i = 0; i < GetSize(mem.wr_ports); i++) - { - if (!considered_port_pairs.count(i)) - continue; + while (!bits_queue.empty()) + { + for (auto bit : bits_queue) + if (bit.wire && bit.wire->get_bool_attribute(ID::onehot)) + one_hot_wires.insert(bit.wire); + + pool portbits; + modwalker.get_drivers(portbits, bits_queue); + bits_queue.clear(); + + for (auto &pbit : portbits) + if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { + pool &cell_inputs = modwalker.cell_inputs[pbit.cell]; + bits_queue.insert(cell_inputs.begin(), cell_inputs.end()); + sat_cells.insert(pbit.cell); + } + } - if (ez->solve(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i))) { - log(" According to SAT solver sharing of port %d with port %d is not possible.\n", i-1, i); - continue; + for (auto wire : one_hot_wires) { + log(" Adding one-hot constraint for wire %s.\n", log_id(wire)); + vector ez_wire_bits = satgen.importSigSpec(wire); + for (int i : ez_wire_bits) + for (int j : ez_wire_bits) + if (i != j) ez->assume(ez->NOT(i), j); } - log(" Merging port %d into port %d.\n", i-1, i); - port_to_sat_variable.at(i) = ez->OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); + log(" Common input cone for all EN signals: %d cells.\n", int(sat_cells.size())); - RTLIL::SigSpec last_addr = mem.wr_ports[i-1].addr; - RTLIL::SigSpec last_data = mem.wr_ports[i-1].data; - std::vector last_en = modwalker.sigmap(mem.wr_ports[i-1].en); + for (auto cell : sat_cells) + satgen.importCell(cell); - RTLIL::SigSpec this_addr = mem.wr_ports[i].addr; - RTLIL::SigSpec this_data = mem.wr_ports[i].data; - std::vector this_en = modwalker.sigmap(mem.wr_ports[i].en); + log(" Size of unconstrained SAT problem: %d variables, %d clauses\n", ez->numCnfVariables(), ez->numCnfClauses()); - RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); + // now try merging the ports. - if (GetSize(last_addr) < GetSize(this_addr)) - last_addr.extend_u0(GetSize(this_addr)); - else - this_addr.extend_u0(GetSize(last_addr)); + for (int ii = 0; ii < GetSize(group); ii++) { + int idx1 = group[ii]; + auto &port1 = mem.wr_ports[idx1]; + if (port1.removed) + continue; + for (int jj = ii + 1; jj < GetSize(group); jj++) { + int idx2 = group[jj]; + auto &port2 = mem.wr_ports[idx2]; + if (port2.removed) + continue; - mem.wr_ports[i].addr = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); - mem.wr_ports[i].data = module->Mux(NEW_ID, last_data, this_data, this_en_active); + if (ez->solve(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2))) { + log(" According to SAT solver sharing of port %d with port %d is not possible.\n", idx1, idx2); + continue; + } + + log(" Merging port %d into port %d.\n", idx2, idx1); + mem.prepare_wr_merge(idx1, idx2); + port_to_sat_variable.at(idx1) = ez->OR(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2)); + + RTLIL::SigSpec last_addr = port1.addr; + RTLIL::SigSpec last_data = port1.data; + std::vector last_en = modwalker.sigmap(port1.en); + + RTLIL::SigSpec this_addr = port2.addr; + RTLIL::SigSpec this_data = port2.data; + std::vector this_en = modwalker.sigmap(port2.en); + + RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); + + if (GetSize(last_addr) < GetSize(this_addr)) + last_addr.extend_u0(GetSize(this_addr)); + else + this_addr.extend_u0(GetSize(last_addr)); + + port1.addr = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); + port1.data = module->Mux(NEW_ID, last_data, this_data, this_en_active); + + std::map, int> groups_en; + RTLIL::SigSpec grouped_last_en, grouped_this_en, en; + RTLIL::Wire *grouped_en = module->addWire(NEW_ID, 0); + + for (int j = 0; j < int(this_en.size()); j++) { + std::pair key(last_en[j], this_en[j]); + if (!groups_en.count(key)) { + grouped_last_en.append(last_en[j]); + grouped_this_en.append(this_en[j]); + groups_en[key] = grouped_en->width; + grouped_en->width++; + } + en.append(RTLIL::SigSpec(grouped_en, groups_en[key])); + } - std::map, int> groups_en; - RTLIL::SigSpec grouped_last_en, grouped_this_en, en; - RTLIL::Wire *grouped_en = module->addWire(NEW_ID, 0); + module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); + port1.en = en; - for (int j = 0; j < int(this_en.size()); j++) { - std::pair key(last_en[j], this_en[j]); - if (!groups_en.count(key)) { - grouped_last_en.append(last_en[j]); - grouped_this_en.append(this_en[j]); - groups_en[key] = grouped_en->width; - grouped_en->width++; + port2.removed = true; + changed = true; } - en.append(RTLIL::SigSpec(grouped_en, groups_en[key])); } - - module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - mem.wr_ports[i].en = en; - - mem.wr_ports[i-1].removed = true; - changed = true; } if (changed) From 82f5829aba108be4a3786e7a237fd7bcebe61eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 26 Oct 2020 00:44:37 +0100 Subject: [PATCH 0371/2410] memory_share: Add read port merging. This is mostly meant for wide port recognition, but may also happen to merge some ports with compatible initial/reset values (eg. 0 vs x). --- passes/memory/memory_share.cc | 140 ++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 19afeb72dd7..7a063e318d2 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -36,6 +36,145 @@ struct MemoryShareWorker bool flag_widen; + // -------------------------------------------------- + // Consolidate read ports that read the same address + // (or close enough to be merged to wide ports) + // -------------------------------------------------- + + // A simple function to detect ports that couldn't possibly collide + // because of opposite const address bits (simplistic, but enough + // to fix problems with inferring wide ports). + bool rdwr_can_collide(Mem &mem, int ridx, int widx) { + auto &rport = mem.rd_ports[ridx]; + auto &wport = mem.wr_ports[widx]; + for (int i = std::max(rport.wide_log2, wport.wide_log2); i < GetSize(rport.addr) && i < GetSize(wport.addr); i++) { + if (rport.addr[i] == State::S1 && wport.addr[i] == State::S0) + return false; + if (rport.addr[i] == State::S0 && wport.addr[i] == State::S1) + return false; + } + return true; + } + + bool merge_rst_value(Mem &mem, Const &res, int wide_log2, const Const &src1, int sub1, const Const &src2, int sub2) { + res = Const(State::Sx, mem.width << wide_log2); + for (int i = 0; i < GetSize(src1); i++) + res[i + sub1 * mem.width] = src1[i]; + for (int i = 0; i < GetSize(src2); i++) { + if (src2[i] == State::Sx) + continue; + auto &dst = res[i + sub2 * mem.width]; + if (dst == src2[i]) + continue; + if (dst != State::Sx) + return false; + dst = src2[i]; + } + return true; + } + + bool consolidate_rd_by_addr(Mem &mem) + { + if (GetSize(mem.rd_ports) <= 1) + return false; + + log("Consolidating read ports of memory %s.%s by address:\n", log_id(module), log_id(mem.memid)); + + bool changed = false; + for (int i = 0; i < GetSize(mem.rd_ports); i++) + { + auto &port1 = mem.rd_ports[i]; + if (port1.removed) + continue; + for (int j = i + 1; j < GetSize(mem.rd_ports); j++) + { + auto &port2 = mem.rd_ports[j]; + if (port2.removed) + continue; + if (port1.clk_enable != port2.clk_enable) + continue; + if (port1.clk_enable) { + if (port1.clk != port2.clk) + continue; + if (port1.clk_polarity != port2.clk_polarity) + continue; + } + if (port1.en != port2.en) + continue; + if (port1.arst != port2.arst) + continue; + if (port1.srst != port2.srst) + continue; + if (port1.ce_over_srst != port2.ce_over_srst) + continue; + if (port1.transparent != port2.transparent) + continue; + // If the width of the ports doesn't match, they can still be + // merged by widening the narrow one. Check if the conditions + // hold for that. + int wide_log2 = std::max(port1.wide_log2, port2.wide_log2); + if (GetSize(port1.addr) <= wide_log2) + continue; + if (GetSize(port2.addr) <= wide_log2) + continue; + if (!port1.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (!port2.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) { + // Incompatible addresses after widening. Last chance — widen both + // ports by one more bit to merge them. + if (!flag_widen) + continue; + wide_log2++; + if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) + continue; + if (!port1.addr.extract(0, wide_log2).is_fully_const()) + continue; + if (!port2.addr.extract(0, wide_log2).is_fully_const()) + continue; + } + // Combine init/reset values. + SigSpec sub1_c = port1.addr.extract(0, wide_log2); + log_assert(sub1_c.is_fully_const()); + int sub1 = sub1_c.as_int(); + SigSpec sub2_c = port2.addr.extract(0, wide_log2); + log_assert(sub2_c.is_fully_const()); + int sub2 = sub2_c.as_int(); + Const init_value, arst_value, srst_value; + if (!merge_rst_value(mem, init_value, wide_log2, port1.init_value, sub1, port2.init_value, sub2)) + continue; + if (!merge_rst_value(mem, arst_value, wide_log2, port1.arst_value, sub1, port2.arst_value, sub2)) + continue; + if (!merge_rst_value(mem, srst_value, wide_log2, port1.srst_value, sub1, port2.srst_value, sub2)) + continue; + { + log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); + mem.widen_prep(wide_log2); + SigSpec new_data = module->addWire(NEW_ID, mem.width << wide_log2); + module->connect(port1.data, new_data.extract(sub1 * mem.width, mem.width << port1.wide_log2)); + module->connect(port2.data, new_data.extract(sub2 * mem.width, mem.width << port2.wide_log2)); + port1.addr = sigmap_xmux(port1.addr); + for (int k = 0; k < wide_log2; k++) + port1.addr[k] = State::S0; + port1.init_value = init_value; + port1.arst_value = arst_value; + port1.srst_value = srst_value; + port1.wide_log2 = wide_log2; + port1.data = new_data; + port2.removed = true; + changed = true; + } + } + } + + if (changed) + mem.emit(); + + return changed; + } + + // ------------------------------------------------------ // Consolidate write ports that write to the same address // (or close enough to be merged to wide ports) @@ -370,6 +509,7 @@ struct MemoryShareWorker } for (auto &mem : memories) { + while (consolidate_rd_by_addr(mem)); while (consolidate_wr_by_addr(mem)); } From 13b901bf1c5ac7d25ea061fc129d944ea0317150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 31 May 2021 15:53:18 +0200 Subject: [PATCH 0372/2410] memory_map: Improve start_offset handling. Fixes #2775. --- passes/memory/memory_map.cc | 66 ++++++++++------------ tests/opt/memory_map_offset.ys | 100 +++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 35 deletions(-) create mode 100644 tests/opt/memory_map_offset.ys diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 92bbd8c1530..b5ebf012ecc 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -155,7 +155,7 @@ struct MemoryMapWorker if (!port.clk_enable) { if (port.addr.is_fully_const() && port.en.is_fully_ones()) { for (int sub = 0; sub < (1 << port.wide_log2); sub++) - static_cells_map[port.addr.as_int() - mem.start_offset + sub] = port.data.extract(sub * mem.width, mem.width); + static_cells_map[port.addr.as_int() + sub] = port.data.extract(sub * mem.width, mem.width); static_ports.insert(i); continue; } @@ -176,22 +176,24 @@ struct MemoryMapWorker log("Mapping memory %s in module %s:\n", mem.memid.c_str(), module->name.c_str()); - std::vector data_reg_in; - std::vector data_reg_out; + int abits = ceil_log2(mem.size); + std::vector data_reg_in(1 << abits); + std::vector data_reg_out(1 << abits); int count_static = 0; for (int i = 0; i < mem.size; i++) { - if (static_cells_map.count(i) > 0) + int addr = i + mem.start_offset; + int idx = addr & ((1 << abits) - 1); + if (static_cells_map.count(addr) > 0) { - data_reg_in.push_back(RTLIL::SigSpec(RTLIL::State::Sz, mem.width)); - data_reg_out.push_back(static_cells_map[i]); + data_reg_out[idx] = static_cells_map[addr]; count_static++; } else { - RTLIL::Cell *c = module->addCell(genid(mem.memid, "", i), ID($dff)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "", addr), ID($dff)); c->parameters[ID::WIDTH] = mem.width; if (GetSize(refclock) != 0) { c->parameters[ID::CLK_POLARITY] = RTLIL::Const(refclock_pol); @@ -201,13 +203,13 @@ struct MemoryMapWorker c->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::S0)); } - RTLIL::Wire *w_in = module->addWire(genid(mem.memid, "", i, "$d"), mem.width); - data_reg_in.push_back(RTLIL::SigSpec(w_in)); - c->setPort(ID::D, data_reg_in.back()); + RTLIL::Wire *w_in = module->addWire(genid(mem.memid, "", addr, "$d"), mem.width); + data_reg_in[idx] = w_in; + c->setPort(ID::D, w_in); - std::string w_out_name = stringf("%s[%d]", mem.memid.c_str(), i); + std::string w_out_name = stringf("%s[%d]", mem.memid.c_str(), addr); if (module->wires_.count(w_out_name) > 0) - w_out_name = genid(mem.memid, "", i, "$q"); + w_out_name = genid(mem.memid, "", addr, "$q"); RTLIL::Wire *w_out = module->addWire(w_out_name, mem.width); SigSpec w_init = init_data.extract(i*mem.width, mem.width); @@ -215,8 +217,8 @@ struct MemoryMapWorker if (!w_init.is_fully_undef()) w_out->attributes[ID::init] = w_init.as_const(); - data_reg_out.push_back(RTLIL::SigSpec(w_out)); - c->setPort(ID::Q, data_reg_out.back()); + data_reg_out[idx] = w_out; + c->setPort(ID::Q, w_out); } } @@ -224,7 +226,6 @@ struct MemoryMapWorker int count_dff = 0, count_mux = 0, count_wrmux = 0; - int abits = ceil_log2(mem.size); for (int i = 0; i < GetSize(mem.rd_ports); i++) { auto &port = mem.rd_ports[i]; @@ -233,9 +234,6 @@ struct MemoryMapWorker RTLIL::SigSpec rd_addr = port.addr; rd_addr.extend_u0(abits, false); - if (mem.start_offset) - rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem.start_offset, abits)); - std::vector rd_signals; rd_signals.push_back(port.data); @@ -261,31 +259,29 @@ struct MemoryMapWorker next_rd_signals.swap(rd_signals); } - for (int j = 0; j < mem.size; j++) - module->connect(RTLIL::SigSig(rd_signals[j >> port.wide_log2].extract((j & ((1 << port.wide_log2) - 1)) * mem.width, mem.width), data_reg_out[j])); + for (int j = 0; j < (1 << abits); j++) + if (data_reg_out[j] != SigSpec()) + module->connect(RTLIL::SigSig(rd_signals[j >> port.wide_log2].extract((j & ((1 << port.wide_log2) - 1)) * mem.width, mem.width), data_reg_out[j])); } log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); for (int i = 0; i < mem.size; i++) { - if (static_cells_map.count(i) > 0) + int addr = i + mem.start_offset; + int idx = addr & ((1 << abits) - 1); + if (static_cells_map.count(addr) > 0) continue; - RTLIL::SigSpec sig = data_reg_out[i]; + RTLIL::SigSpec sig = data_reg_out[idx]; for (int j = 0; j < GetSize(mem.wr_ports); j++) { auto &port = mem.wr_ports[j]; - RTLIL::SigSpec wr_addr = port.addr; - - if (mem.start_offset) - wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem.start_offset, GetSize(wr_addr))); - - wr_addr = wr_addr.extract_end(port.wide_log2); - RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i >> port.wide_log2, GetSize(wr_addr))); + RTLIL::SigSpec wr_addr = port.addr.extract_end(port.wide_log2); + RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(addr >> port.wide_log2, GetSize(wr_addr))); - int sub = i & ((1 << port.wide_log2) - 1); + int sub = addr & ((1 << port.wide_log2) - 1); int wr_offset = 0; while (wr_offset < mem.width) @@ -304,7 +300,7 @@ struct MemoryMapWorker if (wr_bit != State::S1) { - RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", i, "", j, "", wr_offset), ID($and)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and)); c->parameters[ID::A_SIGNED] = RTLIL::Const(0); c->parameters[ID::B_SIGNED] = RTLIL::Const(0); c->parameters[ID::A_WIDTH] = RTLIL::Const(1); @@ -313,17 +309,17 @@ struct MemoryMapWorker c->setPort(ID::A, w); c->setPort(ID::B, wr_bit); - w = module->addWire(genid(mem.memid, "$wren", i, "", j, "", wr_offset, "$y")); + w = module->addWire(genid(mem.memid, "$wren", addr, "", j, "", wr_offset, "$y")); c->setPort(ID::Y, RTLIL::SigSpec(w)); } - RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset), ID($mux)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux)); c->parameters[ID::WIDTH] = wr_width; c->setPort(ID::A, sig.extract(wr_offset, wr_width)); c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width)); c->setPort(ID::S, RTLIL::SigSpec(w)); - w = module->addWire(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); + w = module->addWire(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset, "$y"), wr_width); c->setPort(ID::Y, w); sig.replace(wr_offset, w); @@ -332,7 +328,7 @@ struct MemoryMapWorker } } - module->connect(RTLIL::SigSig(data_reg_in[i], sig)); + module->connect(RTLIL::SigSig(data_reg_in[idx], sig)); } log(" write interface: %d write mux blocks.\n", count_wrmux); diff --git a/tests/opt/memory_map_offset.ys b/tests/opt/memory_map_offset.ys new file mode 100644 index 00000000000..06969922d64 --- /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 From 6d5d8457883e5de8df58997d95373d3433b781bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 1 Jun 2021 01:48:35 +0200 Subject: [PATCH 0373/2410] kernel/mem: Recognize some deprecated memory port configs. Transparency is meaningless for asynchronous ports, so we assume transparent == false to simplify the code in this case. Likewise, enable is meaningless, and we assume it is const-1. However, turns out that nMigen emits the former, and Verilog frontend emits the latter, so squash these issues when ingesting a $memrd cell. Fixes #2811. --- kernel/mem.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index 848dc9f3a95..82942d9be86 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -291,6 +291,7 @@ void Mem::check() { log_assert(GetSize(port.srst_value) == (width << port.wide_log2)); if (!port.clk_enable) { log_assert(!port.transparent); + log_assert(port.en == State::S1); log_assert(port.arst == State::S0); log_assert(port.srst == State::S0); } @@ -370,6 +371,15 @@ namespace { mrd.init_value = Const(State::Sx, mem->width << mrd.wide_log2); mrd.srst = State::S0; mrd.arst = State::S0; + if (!mrd.clk_enable) { + // Fix some patterns that we'll allow for backwards compatibility, + // but don't want to see moving forwards: async transparent + // ports (inherently meaningless) and async ports without + // const 1 tied to EN bit (which may mean a latch in the future). + mrd.transparent = false; + if (mrd.en == State::Sx) + mrd.en = State::S1; + } res.rd_ports.push_back(mrd); } } From 8cfed1a97957e4c096d1e0a0304d978bcb27e116 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 27 May 2021 16:47:02 -0400 Subject: [PATCH 0374/2410] sv: support tasks and functions within packages --- frontends/ast/ast.cc | 20 ++++++++++++++++++++ frontends/ast/simplify.cc | 2 +- frontends/verilog/verilog_parser.y | 2 +- tests/verilog/package_task_func.sv | 30 ++++++++++++++++++++++++++++++ tests/verilog/package_task_func.ys | 4 ++++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/verilog/package_task_func.sv create mode 100644 tests/verilog/package_task_func.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e5cc941104..7e53713e3e5 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1196,6 +1196,25 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN design->add(current_module); } +// renames identifiers in tasks and functions within a package +static void rename_in_package_stmts(AstNode *pkg) +{ + std::unordered_set idents; + for (AstNode *item : pkg->children) + idents.insert(item->str); + std::function rename = + [&rename, &idents, pkg](AstNode *node) { + for (AstNode *child : node->children) { + if (idents.count(child->str)) + child->str = pkg->str + "::" + child->str.substr(1); + rename(child); + } + }; + for (AstNode *item : pkg->children) + if (item->type == AST_FUNCTION || item->type == AST_TASK) + rename(item); +} + // create AstModule instances for all modules in the AST tree and add them to 'design' void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire) @@ -1284,6 +1303,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump else if (child->type == AST_PACKAGE) { // process enum/other declarations child->simplify(true, false, false, 1, -1, false, false); + rename_in_package_stmts(child); design->verilog_packages.push_back(child->clone()); current_scope.clear(); } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 305f67da82d..517647afbf0 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -875,7 +875,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; // these nodes appear at the top level in a package and can define names - if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF) { + if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF || node->type == AST_FUNCTION || node->type == AST_TASK) { current_scope[node->str] = node; } if (node->type == AST_ENUM) { diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index c2b43f45b9e..93ddbec9187 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -593,7 +593,7 @@ package_body: package_body package_body_stmt | %empty; package_body_stmt: - typedef_decl | localparam_decl | param_decl; + typedef_decl | localparam_decl | param_decl | task_func_decl; interface: TOK_INTERFACE { diff --git a/tests/verilog/package_task_func.sv b/tests/verilog/package_task_func.sv new file mode 100644 index 00000000000..2df7a52052a --- /dev/null +++ b/tests/verilog/package_task_func.sv @@ -0,0 +1,30 @@ +package P; + localparam Y = 2; + localparam X = Y + 1; + task t; + output integer x; + x = Y; + endtask + function automatic integer f; + input integer i; + f = i * X; + endfunction + function automatic integer g; + input integer i; + g = i == 0 ? 1 : Y * g(i - 1); + endfunction + localparam Z = g(4); +endpackage + +module top; + integer a; + initial P::t(a); + integer b = P::f(3); + integer c = P::g(3); + integer d = P::Z; + + assert property (a == 2); + assert property (b == 9); + assert property (c == 8); + assert property (d == 16); +endmodule diff --git a/tests/verilog/package_task_func.ys b/tests/verilog/package_task_func.ys new file mode 100644 index 00000000000..c94cc2acb26 --- /dev/null +++ b/tests/verilog/package_task_func.ys @@ -0,0 +1,4 @@ +read_verilog -sv package_task_func.sv +proc +opt -full +sat -verify -seq 1 -prove-asserts -show-all From e65ed3f228bd0e26248eaaeabdcea507379d757a Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 8 Jun 2021 00:20:55 +0200 Subject: [PATCH 0375/2410] Add claire deadname stuff to .mailmap Signed-off-by: Claire Xenia Wolf --- .mailmap | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.mailmap b/.mailmap index f3c1ba97a8a..78afe1b6cc9 100644 --- a/.mailmap +++ b/.mailmap @@ -1,3 +1,7 @@ Marcelina Kościelnicka Marcelina Kościelnicka Marcelina Kościelnicka +Claire Xenia Wolf +Claire Xenia Wolf +Claire Xenia Wolf +Claire Xenia Wolf From 72787f52fc31954e4b7dc3dc34d86705fc4e9dd1 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 8 Jun 2021 00:39:36 +0200 Subject: [PATCH 0376/2410] Fixing old e-mail addresses and deadnames s/((Claire|Xen|Xenia|Clifford)\s+)+(Wolf|Xen)\s+<(claire|clifford)@(symbioticeda.com|clifford.at|yosyshq.com)>/Claire Xenia Wolf /gi; s/((Nina|Nak|N\.)\s+)+Engelhardt\s+/N. Engelhardt /gi; s/((David)\s+)+Shah\s+<(dave|david)@(symbioticeda.com|yosyshq.com|ds0.me)>/David Shah /gi; s/((Miodrag)\s+)+Milanovic\s+<(miodrag|micko)@(symbioticeda.com|yosyshq.com)>/Miodrag Milanovic /gi; s,https?://www.clifford.at/yosys/,http://yosyshq.net/yosys/,g; --- COPYING | 2 +- Makefile | 2 +- README.md | 10 +++++----- backends/aiger/aiger.cc | 2 +- backends/aiger/xaiger.cc | 2 +- backends/blif/blif.cc | 2 +- backends/btor/btor.cc | 4 ++-- backends/edif/edif.cc | 2 +- backends/firrtl/firrtl.cc | 2 +- backends/intersynth/intersynth.cc | 2 +- backends/json/json.cc | 2 +- backends/protobuf/protobuf.cc | 2 +- backends/rtlil/rtlil_backend.cc | 2 +- backends/rtlil/rtlil_backend.h | 2 +- backends/simplec/simplec.cc | 2 +- backends/smt2/smt2.cc | 2 +- backends/smt2/smtbmc.py | 2 +- backends/smt2/smtio.py | 2 +- backends/smv/smv.cc | 2 +- backends/spice/spice.cc | 2 +- backends/table/table.cc | 2 +- backends/verilog/verilog_backend.cc | 2 +- frontends/aiger/aigerparse.cc | 2 +- frontends/aiger/aigerparse.h | 2 +- frontends/ast/ast.cc | 2 +- frontends/ast/ast.h | 2 +- frontends/ast/dpicall.cc | 2 +- frontends/ast/genrtlil.cc | 2 +- frontends/ast/simplify.cc | 2 +- frontends/blif/blifparse.cc | 2 +- frontends/blif/blifparse.h | 2 +- frontends/json/jsonparse.cc | 2 +- frontends/liberty/liberty.cc | 2 +- frontends/rtlil/rtlil_frontend.cc | 2 +- frontends/rtlil/rtlil_frontend.h | 2 +- frontends/rtlil/rtlil_lexer.l | 2 +- frontends/rtlil/rtlil_parser.y | 2 +- frontends/verific/verific.cc | 2 +- frontends/verific/verific.h | 2 +- frontends/verific/verificsva.cc | 2 +- frontends/verilog/const2ast.cc | 2 +- frontends/verilog/preproc.cc | 2 +- frontends/verilog/preproc.h | 2 +- frontends/verilog/verilog_frontend.cc | 2 +- frontends/verilog/verilog_frontend.h | 2 +- frontends/verilog/verilog_lexer.l | 2 +- frontends/verilog/verilog_parser.y | 2 +- guidelines/CodeOfConduct | 5 ++--- guidelines/Windows | 4 ++-- kernel/bitpattern.h | 2 +- kernel/calc.cc | 2 +- kernel/cellaigs.cc | 2 +- kernel/cellaigs.h | 2 +- kernel/celledges.cc | 2 +- kernel/celledges.h | 2 +- kernel/celltypes.h | 2 +- kernel/consteval.h | 2 +- kernel/cost.h | 2 +- kernel/driver.cc | 2 +- kernel/hashlib.h | 2 +- kernel/log.cc | 2 +- kernel/log.h | 2 +- kernel/macc.h | 2 +- kernel/modtools.h | 2 +- kernel/register.cc | 2 +- kernel/register.h | 2 +- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 2 +- kernel/satgen.cc | 2 +- kernel/satgen.h | 2 +- kernel/sigtools.h | 2 +- kernel/timinginfo.h | 2 +- kernel/utils.h | 2 +- kernel/yosys.cc | 4 ++-- kernel/yosys.h | 2 +- libs/bigint/README | 2 +- libs/ezsat/README | 2 +- libs/ezsat/demo_bit.cc | 2 +- libs/ezsat/demo_cmp.cc | 2 +- libs/ezsat/demo_vec.cc | 2 +- libs/ezsat/ezminisat.cc | 2 +- libs/ezsat/ezminisat.h | 2 +- libs/ezsat/ezsat.cc | 2 +- libs/ezsat/ezsat.h | 2 +- libs/ezsat/puzzle3d.cc | 2 +- libs/ezsat/testbench.cc | 2 +- libs/subcircuit/README | 2 +- libs/subcircuit/subcircuit.cc | 2 +- libs/subcircuit/subcircuit.h | 2 +- manual/APPNOTE_010_Verilog_to_BLIF.tex | 2 +- manual/APPNOTE_011_Design_Investigation.tex | 2 +- manual/APPNOTE_012_Verilog_to_BTOR.tex | 2 +- manual/CHAPTER_StateOfTheArt/simlib_yosys.v | 2 +- manual/PRESENTATION_ExAdv.tex | 2 +- manual/PRESENTATION_ExOth.tex | 2 +- manual/PRESENTATION_ExSyn.tex | 2 +- manual/PRESENTATION_Intro.tex | 8 ++++---- manual/PRESENTATION_Prog.tex | 2 +- manual/presentation.tex | 2 +- misc/create_vcxsrc.sh | 4 ++-- misc/py_wrap_generator.py | 4 ++-- passes/cmds/add.cc | 2 +- passes/cmds/autoname.cc | 2 +- passes/cmds/blackbox.cc | 2 +- passes/cmds/check.cc | 2 +- passes/cmds/chformal.cc | 2 +- passes/cmds/chtype.cc | 2 +- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 2 +- passes/cmds/copy.cc | 2 +- passes/cmds/cover.cc | 2 +- passes/cmds/delete.cc | 2 +- passes/cmds/design.cc | 2 +- passes/cmds/edgetypes.cc | 2 +- passes/cmds/exec.cc | 2 +- passes/cmds/logcmd.cc | 2 +- passes/cmds/logger.cc | 2 +- passes/cmds/ltp.cc | 2 +- passes/cmds/plugin.cc | 2 +- passes/cmds/portlist.cc | 2 +- passes/cmds/qwp.cc | 2 +- passes/cmds/rename.cc | 2 +- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/scratchpad.cc | 4 ++-- passes/cmds/select.cc | 2 +- passes/cmds/setattr.cc | 2 +- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 2 +- passes/cmds/splice.cc | 2 +- passes/cmds/splitnets.cc | 2 +- passes/cmds/stat.cc | 2 +- passes/cmds/tee.cc | 2 +- passes/cmds/torder.cc | 2 +- passes/cmds/trace.cc | 2 +- passes/cmds/write_file.cc | 2 +- passes/equiv/equiv_add.cc | 2 +- passes/equiv/equiv_induct.cc | 2 +- passes/equiv/equiv_make.cc | 2 +- passes/equiv/equiv_mark.cc | 2 +- passes/equiv/equiv_miter.cc | 2 +- passes/equiv/equiv_purge.cc | 2 +- passes/equiv/equiv_remove.cc | 2 +- passes/equiv/equiv_simple.cc | 2 +- passes/equiv/equiv_status.cc | 2 +- passes/equiv/equiv_struct.cc | 2 +- passes/fsm/fsm.cc | 2 +- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_expand.cc | 2 +- passes/fsm/fsm_export.cc | 2 +- passes/fsm/fsm_extract.cc | 2 +- passes/fsm/fsm_info.cc | 2 +- passes/fsm/fsm_map.cc | 2 +- passes/fsm/fsm_opt.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- passes/fsm/fsmdata.h | 2 +- passes/hierarchy/hierarchy.cc | 2 +- passes/hierarchy/submod.cc | 2 +- passes/hierarchy/uniquify.cc | 2 +- passes/memory/memory.cc | 2 +- passes/memory/memory_bram.cc | 2 +- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_memx.cc | 2 +- passes/memory/memory_nordff.cc | 2 +- passes/memory/memory_share.cc | 2 +- passes/memory/memory_unpack.cc | 2 +- passes/opt/muxpack.cc | 2 +- passes/opt/opt.cc | 2 +- passes/opt/opt_clean.cc | 2 +- passes/opt/opt_demorgan.cc | 2 +- passes/opt/opt_dff.cc | 2 +- passes/opt/opt_expr.cc | 2 +- passes/opt/opt_lut_ins.cc | 2 +- passes/opt/opt_mem.cc | 2 +- passes/opt/opt_mem_feedback.cc | 2 +- passes/opt/opt_merge.cc | 2 +- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_reduce.cc | 2 +- passes/opt/opt_share.cc | 2 +- passes/opt/pmux2shiftx.cc | 2 +- passes/opt/rmports.cc | 2 +- passes/opt/share.cc | 2 +- passes/opt/wreduce.cc | 2 +- passes/pmgen/generate.h | 2 +- passes/pmgen/ice40_dsp.cc | 2 +- passes/pmgen/ice40_wrapcarry.cc | 2 +- passes/pmgen/peepopt.cc | 2 +- passes/pmgen/test_pmgen.cc | 2 +- passes/pmgen/xilinx_dsp.cc | 2 +- passes/pmgen/xilinx_srl.cc | 2 +- passes/proc/proc.cc | 2 +- passes/proc/proc_arst.cc | 2 +- passes/proc/proc_clean.cc | 2 +- passes/proc/proc_dff.cc | 2 +- passes/proc/proc_dlatch.cc | 2 +- passes/proc/proc_init.cc | 2 +- passes/proc/proc_mux.cc | 2 +- passes/proc/proc_rmdead.cc | 2 +- passes/sat/assertpmux.cc | 2 +- passes/sat/async2sync.cc | 2 +- passes/sat/clk2fflogic.cc | 2 +- passes/sat/cutpoint.cc | 2 +- passes/sat/eval.cc | 4 ++-- passes/sat/expose.cc | 2 +- passes/sat/fmcombine.cc | 2 +- passes/sat/fminit.cc | 2 +- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 2 +- passes/sat/mutate.cc | 2 +- passes/sat/sat.cc | 2 +- passes/sat/sim.cc | 2 +- passes/sat/supercover.cc | 2 +- passes/techmap/abc.cc | 2 +- passes/techmap/abc9.cc | 2 +- passes/techmap/abc9_exe.cc | 2 +- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/aigmap.cc | 2 +- passes/techmap/alumacc.cc | 2 +- passes/techmap/attrmap.cc | 2 +- passes/techmap/attrmvcp.cc | 2 +- passes/techmap/clkbufmap.cc | 2 +- passes/techmap/deminout.cc | 2 +- passes/techmap/dffinit.cc | 2 +- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/extract.cc | 2 +- passes/techmap/extract_counter.cc | 2 +- passes/techmap/extract_fa.cc | 2 +- passes/techmap/extractinv.cc | 2 +- passes/techmap/flatten.cc | 2 +- passes/techmap/hilomap.cc | 2 +- passes/techmap/insbuf.cc | 2 +- passes/techmap/iopadmap.cc | 2 +- passes/techmap/libparse.cc | 2 +- passes/techmap/libparse.h | 2 +- passes/techmap/lut2mux.cc | 2 +- passes/techmap/maccmap.cc | 2 +- passes/techmap/muxcover.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- passes/techmap/pmuxtree.cc | 2 +- passes/techmap/shregmap.cc | 2 +- passes/techmap/simplemap.cc | 2 +- passes/techmap/simplemap.h | 2 +- passes/techmap/techmap.cc | 2 +- passes/techmap/tribuf.cc | 2 +- passes/techmap/zinit.cc | 2 +- passes/tests/test_abcloop.cc | 2 +- passes/tests/test_autotb.cc | 2 +- passes/tests/test_cell.cc | 2 +- techlibs/achronix/speedster22i/cells_arith.v | 2 +- techlibs/achronix/speedster22i/cells_map.v | 2 +- techlibs/achronix/speedster22i/cells_sim.v | 2 +- techlibs/achronix/synth_achronix.cc | 2 +- techlibs/anlogic/anlogic_eqn.cc | 2 +- techlibs/anlogic/anlogic_fixcarry.cc | 2 +- techlibs/anlogic/arith_map.v | 4 ++-- techlibs/anlogic/synth_anlogic.cc | 4 ++-- techlibs/common/mul2dsp.v | 4 ++-- techlibs/common/prep.cc | 2 +- techlibs/common/simcells.v | 2 +- techlibs/common/simlib.v | 2 +- techlibs/common/synth.cc | 2 +- techlibs/common/techmap.v | 2 +- techlibs/easic/synth_easic.cc | 2 +- techlibs/ecp5/arith_map.v | 2 +- techlibs/ecp5/ecp5_gsr.cc | 4 ++-- techlibs/ecp5/synth_ecp5.cc | 2 +- techlibs/efinix/arith_map.v | 4 ++-- techlibs/efinix/efinix_fixcarry.cc | 2 +- techlibs/efinix/synth_efinix.cc | 4 ++-- techlibs/gowin/arith_map.v | 2 +- techlibs/gowin/synth_gowin.cc | 2 +- techlibs/greenpak4/greenpak4_dffinv.cc | 2 +- techlibs/greenpak4/synth_greenpak4.cc | 2 +- techlibs/ice40/arith_map.v | 2 +- techlibs/ice40/ice40_braminit.cc | 2 +- techlibs/ice40/ice40_opt.cc | 2 +- techlibs/ice40/synth_ice40.cc | 2 +- techlibs/intel/common/altpll_bb.v | 2 +- techlibs/intel/common/m9k_bb.v | 2 +- techlibs/intel/cyclone10lp/cells_arith.v | 2 +- techlibs/intel/cyclone10lp/cells_map.v | 2 +- techlibs/intel/cyclone10lp/cells_sim.v | 2 +- techlibs/intel/cycloneiv/cells_arith.v | 2 +- techlibs/intel/cycloneiv/cells_map.v | 2 +- techlibs/intel/cycloneiv/cells_sim.v | 2 +- techlibs/intel/cycloneive/arith_map.v | 2 +- techlibs/intel/cycloneive/cells_map.v | 2 +- techlibs/intel/cycloneive/cells_sim.v | 2 +- techlibs/intel/max10/cells_arith.v | 2 +- techlibs/intel/max10/cells_map.v | 2 +- techlibs/intel/max10/cells_sim.v | 2 +- techlibs/intel/synth_intel.cc | 2 +- techlibs/intel_alm/cyclonev/cells_sim.v | 2 +- techlibs/intel_alm/synth_intel_alm.cc | 2 +- techlibs/nexus/arith_map.v | 2 +- techlibs/sf2/arith_map.v | 2 +- techlibs/sf2/synth_sf2.cc | 2 +- techlibs/xilinx/abc9_model.v | 2 +- techlibs/xilinx/arith_map.v | 2 +- techlibs/xilinx/cells_map.v | 2 +- techlibs/xilinx/cells_sim.v | 2 +- techlibs/xilinx/ff_map.v | 2 +- techlibs/xilinx/lut_map.v | 2 +- techlibs/xilinx/mux_map.v | 2 +- techlibs/xilinx/synth_xilinx.cc | 2 +- techlibs/xilinx/xilinx_dffopt.cc | 2 +- tests/vloghtb/run-test.sh | 2 +- 309 files changed, 330 insertions(+), 331 deletions(-) diff --git a/COPYING b/COPYING index 7cd2464cd6f..e8b123be234 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ ISC License -Copyright (C) 2012 - 2020 Claire Wolf +Copyright (C) 2012 - 2020 Claire Xenia Wolf Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/Makefile b/Makefile index b35a11d531c..596fad2e1d7 100644 --- a/Makefile +++ b/Makefile @@ -956,7 +956,7 @@ ifeq ($(ENABLE_ABC),1) cp -r $(PROGRAM_PREFIX)yosys-abc.exe abc/lib/x86/pthreadVC2.dll yosys-win32-mxebin-$(YOSYS_VER)/ endif echo -en 'This is Yosys $(YOSYS_VER) for Win32.\r\n' > yosys-win32-mxebin-$(YOSYS_VER)/readme.txt - echo -en 'Documentation at http://www.clifford.at/yosys/.\r\n' >> yosys-win32-mxebin-$(YOSYS_VER)/readme.txt + echo -en 'Documentation at http://yosyshq.net/yosys/.\r\n' >> yosys-win32-mxebin-$(YOSYS_VER)/readme.txt zip -r yosys-win32-mxebin-$(YOSYS_VER).zip yosys-win32-mxebin-$(YOSYS_VER)/ endif diff --git a/README.md b/README.md index 74b6170b17f..09e46a80883 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ``` yosys -- Yosys Open SYnthesis Suite -Copyright (C) 2012 - 2020 Claire Wolf +Copyright (C) 2012 - 2020 Claire Xenia Wolf Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -38,11 +38,11 @@ Web Site and Other Resources ============================ More information and documentation can be found on the Yosys web site: -- http://www.clifford.at/yosys/ +- http://yosyshq.net/yosys/ The "Documentation" page on the web site contains links to more resources, including a manual that even describes some of the Yosys internals: -- http://www.clifford.at/yosys/documentation.html +- http://yosyshq.net/yosys/documentation.html The directory `guidelines` contains additional information for people interested in using the Yosys C++ APIs. @@ -92,7 +92,7 @@ For Cygwin use the following command to install all prerequisites, or select the There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well as a source distribution for Visual Studio. Visit the Yosys download page for -more information: http://www.clifford.at/yosys/download.html +more information: http://yosyshq.net/yosys/download.html To configure the build system to use a specific compiler, use one of @@ -568,7 +568,7 @@ Building the documentation ========================== Note that there is no need to build the manual if you just want to read it. -Simply download the PDF from http://www.clifford.at/yosys/documentation.html +Simply download the PDF from http://yosyshq.net/yosys/documentation.html instead. On Ubuntu, texlive needs these packages to be able to build the manual: diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 476b30488d2..35935b847e0 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 65ccc748f54..66955d88e9d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 08881904256..ba29d90907f 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index a7e32bc5c43..6370b53bd2c 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +18,7 @@ */ // [[CITE]] Btor2 , BtorMC and Boolector 3.0 -// Aina Niemetz, Mathias Preiner, Clifford Wolf, Armin Biere +// Aina Niemetz, Mathias Preiner, C. Wolf, Armin Biere // Computer Aided Verification - 30th International Conference, CAV 2018 // https://cs.stanford.edu/people/niemetz/publication/2018/niemetzpreinerwolfbiere-cav18/ diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index e0013238c83..37010844432 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 86b1bbdf695..7abe584c9cc 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index a6b36de6cba..758a8792bbd 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/json/json.cc b/backends/json/json.cc index b7e51f1e8a2..4aa8046d602 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/protobuf/protobuf.cc b/backends/protobuf/protobuf.cc index f6623a38268..384ce2e8e10 100644 --- a/backends/protobuf/protobuf.cc +++ b/backends/protobuf/protobuf.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index 0846208ba48..a6e45b2f2e9 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/rtlil/rtlil_backend.h b/backends/rtlil/rtlil_backend.h index 77eea353ca9..35829729c56 100644 --- a/backends/rtlil/rtlil_backend.h +++ b/backends/rtlil/rtlil_backend.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc index 3adeaa6c02b..e283dcf7c17 100644 --- a/backends/simplec/simplec.cc +++ b/backends/simplec/simplec.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 7f6779c7de1..f4482794279 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index da5a7f57ed8..be27a3d097c 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -2,7 +2,7 @@ # # yosys -- Yosys Open SYnthesis Suite # -# Copyright (C) 2012 Clifford Wolf +# Copyright (C) 2012 Claire Xenia Wolf # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 516091011d7..97eb1c5374e 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -1,7 +1,7 @@ # # yosys -- Yosys Open SYnthesis Suite # -# Copyright (C) 2012 Clifford Wolf +# Copyright (C) 2012 Claire Xenia Wolf # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index e41582fea4a..f4723d2a675 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index ca5c680c9b8..f260276eb93 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/table/table.cc b/backends/table/table.cc index 77642ccbdf2..2bf64e7b1c6 100644 --- a/backends/table/table.cc +++ b/backends/table/table.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 0dc7113bd16..800865414dd 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 463c5965b94..cb19b8413a5 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h index 251a24977e2..81b9559474f 100644 --- a/frontends/aiger/aigerparse.h +++ b/frontends/aiger/aigerparse.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e53713e3e5..f33b7678560 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 Ruben Undheim * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 9887d24ead1..bb9f42a0529 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index 948c9083c61..12a7e1183f7 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b8b9f715e8f..902fbb01b0b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 517647afbf0..38ca5e063fc 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 52b46c228e9..19844bda6e2 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/blif/blifparse.h b/frontends/blif/blifparse.h index 2b84cb795f0..d7a3c96b1fc 100644 --- a/frontends/blif/blifparse.h +++ b/frontends/blif/blifparse.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index cbfa038a184..50c25abdadb 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index f77d7da5601..abf8de4d1ba 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 00c34175e12..5f85ca2b88b 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/rtlil/rtlil_frontend.h b/frontends/rtlil/rtlil_frontend.h index a420778b042..18926060545 100644 --- a/frontends/rtlil/rtlil_frontend.h +++ b/frontends/rtlil/rtlil_frontend.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l index 897ebf66784..e164132167a 100644 --- a/frontends/rtlil/rtlil_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 7a8f508bf13..0e6eacf8846 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 7aa3ebcbb81..97930924807 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index f168a25887f..f79d8042ad0 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 1f5da1b1d95..1bbdcf0167f 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 230dfadbfb2..a4dfbc7ec7c 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 568224da241..4b9ebe0aa3d 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/preproc.h b/frontends/verilog/preproc.h index 673d633c0b6..e1048156c3c 100644 --- a/frontends/verilog/preproc.h +++ b/frontends/verilog/preproc.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 84ac73e910f..ad0bb9ff721 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index aa78810388c..30f1c11802a 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index f52928c77f8..b29e625d648 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 93ddbec9187..10d904dbde4 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/guidelines/CodeOfConduct b/guidelines/CodeOfConduct index 4f779977bbe..92decd3b6a5 100644 --- a/guidelines/CodeOfConduct +++ b/guidelines/CodeOfConduct @@ -55,9 +55,8 @@ further defined and clarified by project maintainers. Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at clifford@clifford.at (and/or -cliffordvienna@gmail.com if you think your mail to the other address got -stuck in the spam filter). All complaints will be reviewed and investigated and +reported by contacting the project team at contact@yosyshq.com and/or +claire@clairexen.net. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement diff --git a/guidelines/Windows b/guidelines/Windows index 3bd86f3ec5c..16ba57c9da2 100644 --- a/guidelines/Windows +++ b/guidelines/Windows @@ -54,7 +54,7 @@ As root (or other user with write access to /usr/local/src): Then as regular user in some directory where you build stuff: - git clone https://github.com/cliffordwolf/yosys.git yosys-win32 + git clone https://github.com/YosysHQ/yosys.git yosys-win32 cd yosys-win32 make config-mxe - make -j$(nproc) mxebin \ No newline at end of file + make -j$(nproc) mxebin diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 894a95ed1ff..7a8eb39f9f2 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/calc.cc b/kernel/calc.cc index d54ccbc10c8..1e6410f7dbf 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 2c82b1bca78..292af3f51b0 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/cellaigs.h b/kernel/cellaigs.h index 1417a614c9e..8f6d69ba62b 100644 --- a/kernel/cellaigs.h +++ b/kernel/cellaigs.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 314e7c77e76..af07d26b316 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/celledges.h b/kernel/celledges.h index d105e4009d1..d5e374f050c 100644 --- a/kernel/celledges.h +++ b/kernel/celledges.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 944cb301ab2..2918b90395d 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/consteval.h b/kernel/consteval.h index ff8cf86d62b..3edfc490cea 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/cost.h b/kernel/cost.h index ea2a4c1f028..b81420af756 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/driver.cc b/kernel/driver.cc index b55f0283709..2cd1f473cc0 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 42fb8d3635a..0c9f2528715 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -6,7 +6,7 @@ // means. // ------------------------------------------------------- -// Written by Clifford Wolf in 2014 +// Written by Claire Xenia Wolf in 2014 // ------------------------------------------------------- #ifndef HASHLIB_H diff --git a/kernel/log.cc b/kernel/log.cc index 41e91119e97..8d3bdd15be3 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/log.h b/kernel/log.h index 3d93f5bcd14..ea14028dd1f 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/macc.h b/kernel/macc.h index d216e6772e1..e4e1ebf52ab 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/modtools.h b/kernel/modtools.h index 3af5367b177..bd393b5d580 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/register.cc b/kernel/register.cc index 34735a60854..226963fdaa7 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/register.h b/kernel/register.h index 5cd8490824b..15750af2a40 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f9ae947b634..1d41ba81a74 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 2f06690d1f5..6ecca7370fa 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/satgen.cc b/kernel/satgen.cc index 2a54e78ec23..7ad56c1179c 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/satgen.h b/kernel/satgen.h index cf2db733f87..da2cec2223c 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/sigtools.h b/kernel/sigtools.h index c631fa481da..4ea43d74364 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h index eba3386d6f2..9d88ac027cc 100644 --- a/kernel/timinginfo.h +++ b/kernel/timinginfo.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * (C) 2020 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/kernel/utils.h b/kernel/utils.h index 8942905fe35..d37f045ff7c 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/yosys.cc b/kernel/yosys.cc index dcaf364e929..efc42952915 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -137,7 +137,7 @@ void yosys_banner() log(" | |\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); log(" | |\n"); - log(" | Copyright (C) 2012 - 2020 Claire Wolf |\n"); + log(" | Copyright (C) 2012 - 2020 Claire Xenia Wolf |\n"); log(" | |\n"); log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); log(" | purpose with or without fee is hereby granted, provided that the above |\n"); diff --git a/kernel/yosys.h b/kernel/yosys.h index e93d09cd41b..120311a6f6e 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -1,7 +1,7 @@ /* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/bigint/README b/libs/bigint/README index e1842381e72..c6e9bdba617 100644 --- a/libs/bigint/README +++ b/libs/bigint/README @@ -1,5 +1,5 @@ -Note by Clifford Wolf: +Note by Claire Wolf: This version of bigint was downloaded at 2012-08-29 from https://mattmccutchen.net/bigint/bigint-2010.04.30.tar.bz2 diff --git a/libs/ezsat/README b/libs/ezsat/README index c6745e6cf0f..db0a18a4e22 100644 --- a/libs/ezsat/README +++ b/libs/ezsat/README @@ -4,7 +4,7 @@ * The ezSAT C++11 library * * * * A simple frontend to SAT solvers with bindings to MiniSAT. * - * by Clifford Wolf * + * by Claire Xenia Wolf * * * ************************************************************************** diff --git a/libs/ezsat/demo_bit.cc b/libs/ezsat/demo_bit.cc index c7b11246cdf..b4b68970181 100644 --- a/libs/ezsat/demo_bit.cc +++ b/libs/ezsat/demo_bit.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/demo_cmp.cc b/libs/ezsat/demo_cmp.cc index 8d7ceb2b4b7..7b927c66402 100644 --- a/libs/ezsat/demo_cmp.cc +++ b/libs/ezsat/demo_cmp.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/demo_vec.cc b/libs/ezsat/demo_vec.cc index eb8d75997fb..a13430d5570 100644 --- a/libs/ezsat/demo_vec.cc +++ b/libs/ezsat/demo_vec.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index ac4defac386..30df625cbb7 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index 3a34c13c898..92a91d744a2 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 8c666ca1f97..3b089ccca9d 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 85b13685f3e..7f3bdf68dd0 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/puzzle3d.cc b/libs/ezsat/puzzle3d.cc index 59f840f9ec0..d39def6c6c8 100644 --- a/libs/ezsat/puzzle3d.cc +++ b/libs/ezsat/puzzle3d.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/ezsat/testbench.cc b/libs/ezsat/testbench.cc index d6dc41fa944..f5a91f3fb68 100644 --- a/libs/ezsat/testbench.cc +++ b/libs/ezsat/testbench.cc @@ -1,7 +1,7 @@ /* * ezSAT -- A simple and easy to use CNF generator for SAT solvers * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/subcircuit/README b/libs/subcircuit/README index ecaa987db0a..de85cdfea7e 100644 --- a/libs/subcircuit/README +++ b/libs/subcircuit/README @@ -4,7 +4,7 @@ * The SubCircuit C++11 library * * * * An implementation of a modified Ullmann Subgraph Isomorphism Algorithm * - * for coarse grain logic networks. by Clifford Wolf * + * for coarse grain logic networks. by Claire Xenia Wolf * * * ************************************************************************** diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index 4068dc09aa6..f38da3fcc57 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -2,7 +2,7 @@ * SubCircuit -- An implementation of the Ullmann Subgraph Isomorphism * algorithm for coarse grain logic networks * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/subcircuit/subcircuit.h b/libs/subcircuit/subcircuit.h index 8368efab138..f2a28ecd26d 100644 --- a/libs/subcircuit/subcircuit.h +++ b/libs/subcircuit/subcircuit.h @@ -2,7 +2,7 @@ * SubCircuit -- An implementation of the Ullmann Subgraph Isomorphism * algorithm for coarse grain logic networks * - * Copyright (C) 2013 Clifford Wolf + * Copyright (C) 2013 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/manual/APPNOTE_010_Verilog_to_BLIF.tex b/manual/APPNOTE_010_Verilog_to_BLIF.tex index 0ecdf619422..5b1c0c359aa 100644 --- a/manual/APPNOTE_010_Verilog_to_BLIF.tex +++ b/manual/APPNOTE_010_Verilog_to_BLIF.tex @@ -438,7 +438,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. \\ -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \bibitem{bigsim} yosys-bigsim, a collection of real-world Verilog designs for regression testing purposes. \\ diff --git a/manual/APPNOTE_011_Design_Investigation.tex b/manual/APPNOTE_011_Design_Investigation.tex index 9780c78336c..33df79f6128 100644 --- a/manual/APPNOTE_011_Design_Investigation.tex +++ b/manual/APPNOTE_011_Design_Investigation.tex @@ -1042,7 +1042,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \bibitem{graphviz} Graphviz - Graph Visualization Software. diff --git a/manual/APPNOTE_012_Verilog_to_BTOR.tex b/manual/APPNOTE_012_Verilog_to_BTOR.tex index 1bc2778760e..ebaa3e420b0 100644 --- a/manual/APPNOTE_012_Verilog_to_BTOR.tex +++ b/manual/APPNOTE_012_Verilog_to_BTOR.tex @@ -411,7 +411,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. \\ -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \bibitem{boolector} Robert Brummayer and Armin Biere, Boolector: An Efficient SMT Solver for Bit-Vectors and Arrays\\ diff --git a/manual/CHAPTER_StateOfTheArt/simlib_yosys.v b/manual/CHAPTER_StateOfTheArt/simlib_yosys.v index 454c9a83f37..ec209fa0227 100644 --- a/manual/CHAPTER_StateOfTheArt/simlib_yosys.v +++ b/manual/CHAPTER_StateOfTheArt/simlib_yosys.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index ef8f64cec11..1cb99e8fa07 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -890,7 +890,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index 73f8bea2e5c..ddac5c72fa5 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -221,7 +221,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index 655720ebc64..11f205f1fdd 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -509,7 +509,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index af561d01b67..2b1fd9d1062 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -476,7 +476,7 @@ \subsection{Yosys Commands} \begin{itemize} \item Use ``{\tt help}'' for a command list and ``{\tt help \it command}'' for details. \item Or run ``{\tt yosys -H}'' or ``{\tt yosys -h \it command}''. -\item Or go to \url{http://www.clifford.at/yosys/documentation.html}. +\item Or go to \url{http://yosyshq.net/yosys/documentation.html}. \end{itemize} \bigskip @@ -913,11 +913,11 @@ \subsection{Documentation, Downloads, Contacts} \begin{frame}{\subsecname} \begin{itemize} \item Website: \\ -\smallskip\hskip1cm\url{http://www.clifford.at/yosys/} +\smallskip\hskip1cm\url{http://yosyshq.net/yosys/} \bigskip \item Manual, Command Reference, Application Notes: \\ -\smallskip\hskip1cm\url{http://www.clifford.at/yosys/documentation.html} +\smallskip\hskip1cm\url{http://yosyshq.net/yosys/documentation.html} \bigskip \item Instead of a mailing list we have a SubReddit: \\ @@ -950,7 +950,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 3b61361aff4..aeb9b137ca2 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -590,7 +590,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://www.clifford.at/yosys/} +\url{http://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/presentation.tex b/manual/presentation.tex index 63b963bbdd5..08e40939446 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -81,7 +81,7 @@ \title{Yosys Open SYnthesis Suite} \author{Clifford Wolf} -\institute{http://www.clifford.at/yosys/} +\institute{http://yosyshq.net/yosys/} \usetheme{Madrid} \usecolortheme{seagull} diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 924d2722e4d..2bf282427ad 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -6,7 +6,7 @@ yosysver="$2" gitsha="$3" rm -rf YosysVS-Tpl-v2.zip YosysVS -wget http://www.clifford.at/yosys/nogit/YosysVS-Tpl-v2.zip +wget http://yosyshq.net/yosys/nogit/YosysVS-Tpl-v2.zip unzip YosysVS-Tpl-v2.zip rm -f YosysVS-Tpl-v2.zip @@ -35,7 +35,7 @@ Want to use a git working copy for the yosys source code? Open "Git Bash" in this directory and run: mv yosys yosys.bak - git clone https://github.com/cliffordwolf/yosys.git yosys + git clone https://github.com/YosysHQ/yosys.git yosys cd yosys git checkout -B master $(git rev-parse HEAD | cut -c1-10) unzip ../genfiles.zip diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 2de3c1f99f8..4d9a6011326 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -1,7 +1,7 @@ # # yosys -- Yosys Open SYnthesis Suite # -# Copyright (C) 2012 Clifford Wolf +# Copyright (C) 2012 Claire Xenia Wolf # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -2243,7 +2243,7 @@ def gen_wrappers(filename, debug_level_ = 0): """/* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index a2f4a91000f..c0951725403 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 28d4012c443..bd4e4a0cad0 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index fca91852c35..43670efaf24 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index b502b078871..ee0f0a58fae 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index a1b3fbef792..d813a449c17 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc index b894f334cff..6f9ca9a450d 100644 --- a/passes/cmds/chtype.cc +++ b/passes/cmds/chtype.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index d85ea9ad561..1bd52aab258 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 9235dda2b47..dbe23ccf19b 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index c351065f35e..e3fb3a0e6a5 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 0867e3b4f25..1db3e2ca055 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 2855f0cdc1b..48a2179b13e 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 2d7ba1fef06..169f7cc4add 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/edgetypes.cc b/passes/cmds/edgetypes.cc index 37c4204002e..5b53f50ccbb 100644 --- a/passes/cmds/edgetypes.cc +++ b/passes/cmds/edgetypes.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc index 951fa53fc44..f00629a02f1 100644 --- a/passes/cmds/exec.cc +++ b/passes/cmds/exec.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 - 2020 Claire Wolf + * Copyright (C) 2012 - 2020 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/logcmd.cc b/passes/cmds/logcmd.cc index 12c43ecec59..f1702400dc2 100644 --- a/passes/cmds/logcmd.cc +++ b/passes/cmds/logcmd.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index 6a9ed603665..d06939c2e59 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2020 Miodrag Milanovic + * Copyright (C) 2020 Miodrag Milanovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/ltp.cc b/passes/cmds/ltp.cc index 39ec432c263..22bdaab4423 100644 --- a/passes/cmds/ltp.cc +++ b/passes/cmds/ltp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index a94769bcd29..3a1ae2850b5 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/portlist.cc b/passes/cmds/portlist.cc index 97f4bfd9992..03048422d4c 100644 --- a/passes/cmds/portlist.cc +++ b/passes/cmds/portlist.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index cf0f6d0dea6..2da61244110 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index f8fe715c8e2..1d08fc5145c 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index a70dd308602..017600a46f7 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 7aa9a484f32..81881832cd7 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 9369f531299..015eb97e7f3 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf - * 2019 Nina Engelhardt + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 N. Engelhardt * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index b4f3994a224..bb7b78cfed5 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 3a94209d407..710fa9ab400 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index cf8d766196c..a078b0b1c97 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index a389c317934..750fe0e1048 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 0f63b91c574..4ad0d2b2500 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index fff8a0d3efa..927cefca32d 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 0d84c73db37..422810526cc 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index 60689fc825a..7a1f4a36b5d 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 30e76081e45..9fc7f2e9cd3 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index 10742c3706c..4005427767f 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc index 3d898a5efef..ea9b3f5566e 100644 --- a/passes/cmds/write_file.cc +++ b/passes/cmds/write_file.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/equiv/equiv_add.cc b/passes/equiv/equiv_add.cc index 2abbb59bbb0..1bcd4a88710 100644 --- a/passes/equiv/equiv_add.cc +++ b/passes/equiv/equiv_add.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index 5f14416da1c..8d882ae8326 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 6923ae3d01f..7ef2827bfbc 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_mark.cc b/passes/equiv/equiv_mark.cc index a722b5ed634..97a2a38ddbc 100644 --- a/passes/equiv/equiv_mark.cc +++ b/passes/equiv/equiv_mark.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc index e028f806acf..6acfe85a972 100644 --- a/passes/equiv/equiv_miter.cc +++ b/passes/equiv/equiv_miter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_purge.cc b/passes/equiv/equiv_purge.cc index a43ecec5a93..5b0696d9ba4 100644 --- a/passes/equiv/equiv_purge.cc +++ b/passes/equiv/equiv_purge.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_remove.cc b/passes/equiv/equiv_remove.cc index 89442308b41..5d1823e12a1 100644 --- a/passes/equiv/equiv_remove.cc +++ b/passes/equiv/equiv_remove.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 8d9e870da44..7621341a7c3 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_status.cc b/passes/equiv/equiv_status.cc index 2db44ea908b..b221be27c0e 100644 --- a/passes/equiv/equiv_status.cc +++ b/passes/equiv/equiv_status.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc index 9784225db20..39604994a15 100644 --- a/passes/equiv/equiv_struct.cc +++ b/passes/equiv/equiv_struct.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index 21d352407f7..0c5e624dc7c 100644 --- a/passes/fsm/fsm.cc +++ b/passes/fsm/fsm.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 97c575ba76e..a2d38a0bd60 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index d6b492af542..239f17f3621 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index be6702d7e13..65dda12674c 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2012 Martin Schmölzer * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 082973153fa..62a9d309efb 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index da0982bb9e3..ff3714021b8 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index a30d407f071..df31dbb7a28 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 5fc1fb3bb25..f2eb06760b2 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index d4a704270c9..3dc29b5a0bc 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 47398b558ed..4ba3b4e4f5d 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 3372687e187..2ea0d4061d9 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 Ruben Undheim * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index b2826cbff85..845dc850fa6 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index 3f9443a63f0..e9322d359f7 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index 57e43694334..29e140ba998 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index c1476669d4e..7b3df8eecc2 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index ede6ca6a19d..bf3bb34f8b0 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 3248d4e9f79..5cfb3f48a4e 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index b5ebf012ecc..ca1ca483d0e 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 11bbe75cce3..7edc26caaa2 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc index 80f78ca77ae..3253c8f6080 100644 --- a/passes/memory/memory_nordff.cc +++ b/passes/memory/memory_nordff.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 7a063e318d2..846583c2ca2 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 16b57d9c3f5..422d6fe1543 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index aa5f8243744..b5e151098dd 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 4b052d9a220..c3e418c075d 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c66f4530834..699fd4f80ca 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index f0fa86f42ba..1464c4177cd 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2017 Clifford Wolf + * Copyright (C) 2017 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index c87ac3163e5..94d6d544366 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2020 Marcelina Kościelnicka * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index e36e4419d2a..84f07c8a976 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index bb40e1e552c..99043ef7ea9 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 2788648ec9a..edadf2c7b11 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 1311038439f..9e04772b4e3 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 9086943dcb4..f27277574e2 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 67b283e11e4..8ef54cdda0d 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 28de9ceb6e8..15b2772c755 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 62a478673cb..ba85df975f9 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Bogdan Vukobratovic * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index f3b1fd377aa..90ddf8dd718 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 99a2a61c826..9fa9f5c2df9 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/share.cc b/passes/opt/share.cc index f7848e01d78..88c4dee8bf9 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index a216f36d4fd..0cdabcc1a88 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/generate.h b/passes/pmgen/generate.h index 354583de510..85e2087746a 100644 --- a/passes/pmgen/generate.h +++ b/passes/pmgen/generate.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index c46f5d58ff2..24134b1fb1f 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index e234906ad03..c936d02dc75 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc index a9c62fcf651..9a497c91441 100644 --- a/passes/pmgen/peepopt.cc +++ b/passes/pmgen/peepopt.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 7b2938ddffc..beff59778ac 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index cf7703d362a..72b4522d81b 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/pmgen/xilinx_srl.cc b/passes/pmgen/xilinx_srl.cc index 1410850c749..a66a06586cc 100644 --- a/passes/pmgen/xilinx_srl.cc +++ b/passes/pmgen/xilinx_srl.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * (C) 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/proc/proc.cc b/passes/proc/proc.cc index 2151b0ce7f6..2dfc30e8722 100644 --- a/passes/proc/proc.cc +++ b/passes/proc/proc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index d1bfbc647bc..f0168295714 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 9e0b671f4c4..76d4cf51b48 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 2b6ca8449c8..da2a14c82f8 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index 03d072cf4c4..8340e143197 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index b705251ddce..841bce400d5 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index d20f345343b..b209057fe86 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index ee91637ca2a..d49fd7ed31d 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index f31b7880487..abdcb224096 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index 3fa5a614c6e..a2b51677e06 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index cbf7c5435e9..06208397216 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 6fc267d51ee..bca6a5ec629 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 085e7c5b840..056115031be 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +18,7 @@ */ // [[CITE]] VlogHammer Verilog Regression Test Suite -// http://www.clifford.at/yosys/vloghammer.html +// http://yosyshq.net/yosys/vloghammer.html #include "kernel/register.h" #include "kernel/celltypes.h" diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 2c65821cfd8..e7ec29ee408 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index cb49edac3c2..e15bdf6a83d 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/fminit.cc b/passes/sat/fminit.cc index c72e62548d8..5f4ec006877 100644 --- a/passes/sat/fminit.cc +++ b/passes/sat/fminit.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index f87b85da913..52e80f667b0 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index fe4a819f329..37efadfbd06 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index 95e0e094425..42eb0c6d078 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 9fdac6147ea..df2725b3c39 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 684e00382f2..630e1aaa1ac 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/sat/supercover.cc b/passes/sat/supercover.cc index aacc044fb11..38dbd3cf942 100644 --- a/passes/sat/supercover.cc +++ b/passes/sat/supercover.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index d5286f4e9ab..49a0fad77f9 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 0fef4a9f26c..207a280fc1b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * (C) 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index b916b049d07..a66e95e2179 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index edb52901012..4b5def5eb92 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index ce151c7f3d2..4836ebe3484 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index b16e9750e73..e4e70004c0f 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/attrmap.cc b/passes/techmap/attrmap.cc index 8643543c8ce..96e65ff2e9a 100644 --- a/passes/techmap/attrmap.cc +++ b/passes/techmap/attrmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/attrmvcp.cc b/passes/techmap/attrmvcp.cc index b3202c587f7..65b63daf1df 100644 --- a/passes/techmap/attrmvcp.cc +++ b/passes/techmap/attrmvcp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index 1cbd12e3d2c..a7b96a9c6e9 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2019 Marcelina Kościelnicka * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 9a23cb90e35..5245331f8af 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 44af043db07..9cfe55947ba 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 78a6f1c0d57..252baae9a02 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index f5966fac0f8..eb6b3b858aa 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 56b2ea5841b..9c814af231b 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2017 Clifford Wolf + * Copyright (C) 2017 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 3fcff01c307..aabe43ac289 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc index 11463380cc8..48d9600fa72 100644 --- a/passes/techmap/extractinv.cc +++ b/passes/techmap/extractinv.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2019 Marcelina Kościelnicka * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 35257273ce6..616fee3f5e8 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index b808a8d8e6f..c1b94722159 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/insbuf.cc b/passes/techmap/insbuf.cc index a3b5b698d5d..68c22c317ed 100644 --- a/passes/techmap/insbuf.cc +++ b/passes/techmap/insbuf.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index e8530a0347d..45fa5f226da 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 349ccc11505..990d5594317 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index c9ebd06c58e..77e305f0b87 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index f56eff3e5f7..ef76e0deb5d 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 43f2d97f590..2235bdef9fa 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 24109b579bd..a90d8198578 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index e1ebfcad8a9..0167891571f 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index b937d3fb01c..ff6bb549bdf 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index b971068f72a..9281829700f 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index b9d337da455..b65224c717e 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/simplemap.h b/passes/techmap/simplemap.h index 5091050a11d..03a8fb36f89 100644 --- a/passes/techmap/simplemap.h +++ b/passes/techmap/simplemap.h @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 1f9a89aec95..a69a6d460cc 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 79ddb4bd7de..f92b4cdb010 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index e3b4ae57309..7c5b73c90d5 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/tests/test_abcloop.cc b/passes/tests/test_abcloop.cc index ac31e36f120..9e7adaab1ea 100644 --- a/passes/tests/test_abcloop.cc +++ b/passes/tests/test_abcloop.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index 4ab46014d90..404d1e48da5 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 616981f32d4..4e437e409ab 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/achronix/speedster22i/cells_arith.v b/techlibs/achronix/speedster22i/cells_arith.v index 8529706a7dd..ac78ff66017 100644 --- a/techlibs/achronix/speedster22i/cells_arith.v +++ b/techlibs/achronix/speedster22i/cells_arith.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/achronix/speedster22i/cells_map.v b/techlibs/achronix/speedster22i/cells_map.v index a19e53f4997..04288baa7a1 100644 --- a/techlibs/achronix/speedster22i/cells_map.v +++ b/techlibs/achronix/speedster22i/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/achronix/speedster22i/cells_sim.v b/techlibs/achronix/speedster22i/cells_sim.v index a0c60b4be05..6c87adb947a 100644 --- a/techlibs/achronix/speedster22i/cells_sim.v +++ b/techlibs/achronix/speedster22i/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index a31cbfc1416..9a0a7a3b57b 100644 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/anlogic/anlogic_eqn.cc b/techlibs/anlogic/anlogic_eqn.cc index e5fbc186f39..4004b9f17ed 100644 --- a/techlibs/anlogic/anlogic_eqn.cc +++ b/techlibs/anlogic/anlogic_eqn.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2018 Miodrag Milanovic + * Copyright (C) 2018 Miodrag Milanovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc index c7dfe3c0540..e8d061b9317 100644 --- a/techlibs/anlogic/anlogic_fixcarry.cc +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2019 Miodrag Milanovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index 23e190bcb87..f0cec490902 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2018 Miodrag Milanovic - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2018 Miodrag Milanovic + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 604ca81ad8c..039cae00e73 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2018 Miodrag Milanovic - * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Miodrag Milanovic + * Copyright (C) 2018 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/mul2dsp.v b/techlibs/common/mul2dsp.v index f22f47b4a54..69d70b948e3 100644 --- a/techlibs/common/mul2dsp.v +++ b/techlibs/common/mul2dsp.v @@ -1,9 +1,9 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung - * 2019 David Shah + * 2019 David Shah * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index 132d6aec202..c354956bcf4 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 27ef442327c..7d9bebe2af0 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 5c9efad2751..42a355c2dd8 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 89d6e530e37..79e5933e096 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 2ab28e6e680..d3dc85f2480 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc index 9b78b44af60..50526a9ea30 100644 --- a/techlibs/easic/synth_easic.cc +++ b/techlibs/easic/synth_easic.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ecp5/arith_map.v b/techlibs/ecp5/arith_map.v index ffd42469cef..0e56a18bdc1 100644 --- a/techlibs/ecp5/arith_map.v +++ b/techlibs/ecp5/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 David Shah * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/ecp5/ecp5_gsr.cc index 18d99cfb25f..a676548f20b 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/ecp5/ecp5_gsr.cc @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf - * Copyright (C) 2019 David Shah + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2019 David Shah * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 482e7a1400b..b30884ba39e 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 David Shah * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index 4dac360b964..6bda0505c6c 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2018 Miodrag Milanovic - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2018 Miodrag Milanovic + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc index 486b8e89cf0..c61fa79b8a4 100644 --- a/techlibs/efinix/efinix_fixcarry.cc +++ b/techlibs/efinix/efinix_fixcarry.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2019 Miodrag Milanovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 613063e34c4..ace56bee928 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2019 Miodrag Milanovic - * Copyright (C) 2019 Clifford Wolf + * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2019 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v index 42aaba8700a..b504e5bd84a 100644 --- a/techlibs/gowin/arith_map.v +++ b/techlibs/gowin/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 David Shah * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 55a6bb66ce1..c97bd595ca7 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc index b8797bc1993..a77711e01ce 100644 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ b/techlibs/greenpak4/greenpak4_dffinv.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index 26d913ab33b..a9f7db679ee 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index 3950e882be7..087220ec2b8 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc index e5d1f7e2475..95586074027 100644 --- a/techlibs/ice40/ice40_braminit.cc +++ b/techlibs/ice40/ice40_braminit.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index d2860790451..b13d3301856 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index ea038d325ac..67118752d32 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/common/altpll_bb.v b/techlibs/intel/common/altpll_bb.v index d2e6a3643b6..d649e06c60a 100644 --- a/techlibs/intel/common/altpll_bb.v +++ b/techlibs/intel/common/altpll_bb.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/common/m9k_bb.v b/techlibs/intel/common/m9k_bb.v index 4bb230642f6..551d5cc0c18 100644 --- a/techlibs/intel/common/m9k_bb.v +++ b/techlibs/intel/common/m9k_bb.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cyclone10lp/cells_arith.v b/techlibs/intel/cyclone10lp/cells_arith.v index d8c46e865b6..d0d98814577 100644 --- a/techlibs/intel/cyclone10lp/cells_arith.v +++ b/techlibs/intel/cyclone10lp/cells_arith.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cyclone10lp/cells_map.v b/techlibs/intel/cyclone10lp/cells_map.v index 22907b14428..1341793df8b 100644 --- a/techlibs/intel/cyclone10lp/cells_map.v +++ b/techlibs/intel/cyclone10lp/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cyclone10lp/cells_sim.v b/techlibs/intel/cyclone10lp/cells_sim.v index f5a8aee2bcb..ab99589925e 100644 --- a/techlibs/intel/cyclone10lp/cells_sim.v +++ b/techlibs/intel/cyclone10lp/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneiv/cells_arith.v b/techlibs/intel/cycloneiv/cells_arith.v index f7bc3cd6599..1241e89fe84 100644 --- a/techlibs/intel/cycloneiv/cells_arith.v +++ b/techlibs/intel/cycloneiv/cells_arith.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneiv/cells_map.v b/techlibs/intel/cycloneiv/cells_map.v index 41afd94be87..59f50bddbe2 100644 --- a/techlibs/intel/cycloneiv/cells_map.v +++ b/techlibs/intel/cycloneiv/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneiv/cells_sim.v b/techlibs/intel/cycloneiv/cells_sim.v index 2af2ab990fb..f3c8fbe03c1 100644 --- a/techlibs/intel/cycloneiv/cells_sim.v +++ b/techlibs/intel/cycloneiv/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneive/arith_map.v b/techlibs/intel/cycloneive/arith_map.v index a755e10db73..f31baf1e1d4 100644 --- a/techlibs/intel/cycloneive/arith_map.v +++ b/techlibs/intel/cycloneive/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneive/cells_map.v b/techlibs/intel/cycloneive/cells_map.v index 6d7f36ec573..646530d161a 100644 --- a/techlibs/intel/cycloneive/cells_map.v +++ b/techlibs/intel/cycloneive/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/cycloneive/cells_sim.v b/techlibs/intel/cycloneive/cells_sim.v index f17b86fdf8a..9f4cb9a2e79 100644 --- a/techlibs/intel/cycloneive/cells_sim.v +++ b/techlibs/intel/cycloneive/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/max10/cells_arith.v b/techlibs/intel/max10/cells_arith.v index 8529706a7dd..ac78ff66017 100644 --- a/techlibs/intel/max10/cells_arith.v +++ b/techlibs/intel/max10/cells_arith.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/max10/cells_map.v b/techlibs/intel/max10/cells_map.v index 8f198daefa9..6fefcd5d05d 100644 --- a/techlibs/intel/max10/cells_map.v +++ b/techlibs/intel/max10/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/max10/cells_sim.v b/techlibs/intel/max10/cells_sim.v index 98673596b35..7705fa27a06 100644 --- a/techlibs/intel/max10/cells_sim.v +++ b/techlibs/intel/max10/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 1d8e660a085..166c8184314 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel_alm/cyclonev/cells_sim.v b/techlibs/intel_alm/cyclonev/cells_sim.v index d0a9d9179a2..14bb756cf4d 100644 --- a/techlibs/intel_alm/cyclonev/cells_sim.v +++ b/techlibs/intel_alm/cyclonev/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index d0e84aabd21..385fc26b6b7 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Claire Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2019 Dan Ravensloft * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index ce14a15eaa1..ce81a96de83 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Claire Xen + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2018 David Shah * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/sf2/arith_map.v b/techlibs/sf2/arith_map.v index 462d3ce50be..f16b1abb812 100644 --- a/techlibs/sf2/arith_map.v +++ b/techlibs/sf2/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 22cc4a1ae52..8d78a6097a0 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index db44ff00b81..3958a2bf0f9 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index 63be7563e8e..1282f564cfe 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index ec4635ac69c..e8386e2e0cc 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index a079f1c95f2..ee5a89e2272 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v index 45d202294e5..2079fd99a48 100644 --- a/techlibs/xilinx/ff_map.v +++ b/techlibs/xilinx/ff_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/xilinx/lut_map.v b/techlibs/xilinx/lut_map.v index 2ab6075f150..30d7d8014ec 100644 --- a/techlibs/xilinx/lut_map.v +++ b/techlibs/xilinx/lut_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/xilinx/mux_map.v b/techlibs/xilinx/mux_map.v index bb31d21ec7c..f4983449177 100644 --- a/techlibs/xilinx/mux_map.v +++ b/techlibs/xilinx/mux_map.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 1fd2d4f8bca..28672fb2ea8 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * (C) 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index 598f1b216a1..677082916f5 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index ad99226e7c4..9e22d1b7409 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -3,7 +3,7 @@ set -ex rm -rf Makefile refdat rtl scripts spec -wget -N http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 +wget -N http://yosyshq.net/yosys/nogit/vloghammer_tb.tar.bz2 tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean From d9f11bb7a631ad309b9328d33b2f41a4987b6222 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 8 Jun 2021 12:06:32 -0400 Subject: [PATCH 0377/2410] autoname: simple perf optimizations --- passes/cmds/autoname.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 28d4012c443..addd8d29ac3 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -22,25 +22,20 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -int autoname_worker(Module *module) +int autoname_worker(Module *module, const dict& wire_score) { dict> proposed_cell_names; dict> proposed_wire_names; - dict wire_score; int best_score = -1; - for (auto cell : module->selected_cells()) - for (auto &conn : cell->connections()) - for (auto bit : conn.second) - if (bit.wire != nullptr) - wire_score[bit.wire]++; - for (auto cell : module->selected_cells()) { if (cell->name[0] == '$') { for (auto &conn : cell->connections()) { - string suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first)); + string suffix; for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] != '$') { + if (suffix.empty()) + suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first)); IdString new_name(bit.wire->name.str() + suffix); int score = wire_score.at(bit.wire); if (cell->output(conn.first)) score = 0; @@ -54,9 +49,11 @@ int autoname_worker(Module *module) } } else { for (auto &conn : cell->connections()) { - string suffix = stringf("_%s", log_id(conn.first)); + string suffix; for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) { + if (suffix.empty()) + suffix = stringf("_%s", log_id(conn.first)); IdString new_name(cell->name.str() + suffix); int score = wire_score.at(bit.wire); if (cell->output(conn.first)) score = 0; @@ -118,10 +115,17 @@ struct AutonamePass : public Pass { for (auto module : design->selected_modules()) { + dict wire_score; + for (auto cell : module->selected_cells()) + for (auto &conn : cell->connections()) + for (auto bit : conn.second) + if (bit.wire != nullptr) + wire_score[bit.wire]++; + int count = 0, iter = 0; while (1) { iter++; - int n = autoname_worker(module); + int n = autoname_worker(module, wire_score); if (!n) break; count += n; } From c79fbfe0a130f1a2979413174c3e5688433bafe3 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 26 May 2021 18:22:31 -0400 Subject: [PATCH 0378/2410] mem2reg: tolerate out of bounds constant accesses This brings the mem2reg behavior in line with the nomem2reg behavior. --- frontends/ast/simplify.cc | 47 ++++++++++++++++++++++++++---- tests/simple/mem2reg_bounds_tern.v | 19 ++++++++++++ tests/verilog/mem_bounds.sv | 27 +++++++++++++++++ tests/verilog/mem_bounds.ys | 6 ++++ 4 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 tests/simple/mem2reg_bounds_tern.v create mode 100644 tests/verilog/mem_bounds.sv create mode 100644 tests/verilog/mem_bounds.ys diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 517647afbf0..44b11da7405 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1762,7 +1762,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // split memory access with bit select to individual statements - if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue) + if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue && stage == 2) { if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n"); @@ -4501,11 +4501,48 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, if (children[0]->children[0]->type == AST_CONSTANT) { int id = children[0]->children[0]->integer; - str = stringf("%s[%d]", str.c_str(), id); + int left = id2ast->children[1]->children[0]->integer; + int right = id2ast->children[1]->children[1]->integer; + bool valid_const_access = + (left <= id && id <= right) || + (right <= id && id <= left); + if (valid_const_access) + { + str = stringf("%s[%d]", str.c_str(), id); + delete_children(); + range_valid = false; + id2ast = NULL; + } + else + { + int width; + if (bit_part_sel) + { + bit_part_sel->dumpAst(nullptr, "? "); + if (bit_part_sel->children.size() == 1) + width = 0; + else + width = bit_part_sel->children[0]->integer - + bit_part_sel->children[1]->integer; + delete bit_part_sel; + bit_part_sel = nullptr; + } + else + { + width = id2ast->children[0]->children[0]->integer - + id2ast->children[0]->children[1]->integer; + } + width = abs(width) + 1; - delete_children(); - range_valid = false; - id2ast = NULL; + delete_children(); + + std::vector x_bits; + for (int i = 0; i < width; i++) + x_bits.push_back(RTLIL::State::Sx); + AstNode *constant = AstNode::mkconst_bits(x_bits, false); + constant->cloneInto(this); + delete constant; + } } else { diff --git a/tests/simple/mem2reg_bounds_tern.v b/tests/simple/mem2reg_bounds_tern.v new file mode 100644 index 00000000000..89d6dd3e88a --- /dev/null +++ b/tests/simple/mem2reg_bounds_tern.v @@ -0,0 +1,19 @@ +module top( + input clk, + input wire [1:0] sel, + input wire [7:0] base, + output reg [7:0] line +); + reg [0:7] mem [0:2]; + + generate + genvar i; + for (i = 0; i < 4; i = i + 1) begin : gen + always @(posedge clk) + mem[i] <= i == 0 ? base : mem[i - 1] + 1; + end + endgenerate + + always @(posedge clk) + line = mem[sel]; +endmodule diff --git a/tests/verilog/mem_bounds.sv b/tests/verilog/mem_bounds.sv new file mode 100644 index 00000000000..7fb2fb042bd --- /dev/null +++ b/tests/verilog/mem_bounds.sv @@ -0,0 +1,27 @@ +module top; + reg [0:7] mem [0:2]; + + initial mem[1] = '1; + wire [31:0] a, b, c, d; + assign a = mem[1]; + assign b = mem[-1]; + assign c = mem[-1][0]; + assign d = mem[-1][0:1]; + + always @* begin + + assert ($countbits(a, '0) == 24); + assert ($countbits(a, '1) == 8); + assert ($countbits(a, 'x) == 0); + + assert ($countbits(b, '0) == 24); + assert ($countbits(b, 'x) == 8); + + assert ($countbits(c, '0) == 31); + assert ($countbits(c, 'x) == 1); + + assert ($countbits(d, '0) == 30); + assert ($countbits(d, 'x) == 2); + + end +endmodule diff --git a/tests/verilog/mem_bounds.ys b/tests/verilog/mem_bounds.ys new file mode 100644 index 00000000000..42623ad097b --- /dev/null +++ b/tests/verilog/mem_bounds.ys @@ -0,0 +1,6 @@ +read_verilog -sv -mem2reg mem_bounds.sv +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all -enable_undef From 2e697f5655455fd8ce5fec40b94683a11ade24e8 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 5 Jun 2021 16:21:09 -0400 Subject: [PATCH 0379/2410] verilog: check for module scope identifiers during width detection The recent fix for case expression width detection causes the width of the expressions to be queried before they are simplified. Because the logic supporting module scope identifiers only existed in simplify, looking them up would fail during width detection. This moves the logic to a common helper used in both simplify() and detectSignWidthWorker(). --- frontends/ast/ast.h | 3 +++ frontends/ast/genrtlil.cc | 11 +++++++++-- frontends/ast/simplify.cc | 29 ++++++++++++++++++----------- tests/simple/module_scope_case.v | 11 +++++++++++ 4 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 tests/simple/module_scope_case.v diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 9887d24ead1..b6b15b73882 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -326,6 +326,9 @@ namespace AST // helpers for locations std::string loc_string() const; + + // Helper for looking up identifiers which are prefixed with the current module name + std::string try_pop_module_prefix() const; }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b8b9f715e8f..e886844be1c 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -767,8 +767,15 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_IDENTIFIER: id_ast = id2ast; - if (id_ast == NULL && current_scope.count(str)) - id_ast = current_scope.at(str); + if (!id_ast) { + if (current_scope.count(str)) + id_ast = current_scope[str]; + else { + std::string alt = try_pop_module_prefix(); + if (current_scope.count(alt)) + id_ast = current_scope[alt]; + } + } if (!id_ast) log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str()); if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 44b11da7405..cd27a720a9d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1698,17 +1698,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; - size_t pos = str.find('.', 1); - if (str[0] == '\\' && pos != std::string::npos) { - std::string new_str = "\\" + str.substr(pos + 1); - if (current_scope.count(new_str)) { - std::string prefix = str.substr(0, pos); - auto it = current_scope_ast->attributes.find(ID::hdlname); - if ((it != current_scope_ast->attributes.end() && it->second->str == prefix) - || prefix == current_scope_ast->str) - str = new_str; - } - } + str = try_pop_module_prefix(); for (auto node : current_scope_ast->children) { //log("looking at mod scope child %s\n", type2str(node->type).c_str()); switch (node->type) { @@ -5124,4 +5114,21 @@ std::pair AstNode::get_tern_choice() return {choice, not_choice}; } +std::string AstNode::try_pop_module_prefix() const +{ + AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + size_t pos = str.find('.', 1); + if (str[0] == '\\' && pos != std::string::npos) { + std::string new_str = "\\" + str.substr(pos + 1); + if (current_scope.count(new_str)) { + std::string prefix = str.substr(0, pos); + auto it = current_scope_ast->attributes.find(ID::hdlname); + if ((it != current_scope_ast->attributes.end() && it->second->str == prefix) + || prefix == current_scope_ast->str) + return new_str; + } + } + return str; +} + YOSYS_NAMESPACE_END diff --git a/tests/simple/module_scope_case.v b/tests/simple/module_scope_case.v new file mode 100644 index 00000000000..1472b6912a2 --- /dev/null +++ b/tests/simple/module_scope_case.v @@ -0,0 +1,11 @@ +module top( + input wire x, + output reg y +); + always @* begin + case (top.x) + 1: top.y = 0; + 0: top.y = 1; + endcase + end +endmodule From 92e705cb51d8c8f6d9f1550ed103b677a2447c93 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:16:33 +0200 Subject: [PATCH 0380/2410] Fix files with CRLF line endings --- techlibs/common/mul2dsp.v | 636 +++++++++++----------- techlibs/intel_alm/common/bram_m20k_map.v | 62 +-- tests/arch/common/counter.v | 22 +- tests/arch/common/fsm.v | 102 ++-- tests/arch/common/shifter.v | 22 +- 5 files changed, 422 insertions(+), 422 deletions(-) diff --git a/techlibs/common/mul2dsp.v b/techlibs/common/mul2dsp.v index 69d70b948e3..ca2b3c5cf50 100644 --- a/techlibs/common/mul2dsp.v +++ b/techlibs/common/mul2dsp.v @@ -1,318 +1,318 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * 2019 Eddie Hung - * 2019 David Shah - * - * 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. - * - * --- - * - * Tech-mapping rules for decomposing arbitrarily-sized $mul cells - * into an equivalent collection of smaller `DSP_NAME cells (with the - * same interface as $mul) no larger than `DSP_[AB]_MAXWIDTH, attached - * to $shl and $add cells. - * - */ - -`ifndef DSP_A_MAXWIDTH -$fatal(1, "Macro DSP_A_MAXWIDTH must be defined"); -`endif -`ifndef DSP_B_MAXWIDTH -$fatal(1, "Macro DSP_B_MAXWIDTH must be defined"); -`endif -`ifndef DSP_B_MAXWIDTH -$fatal(1, "Macro DSP_B_MAXWIDTH must be defined"); -`endif -`ifndef DSP_A_MAXWIDTH_PARTIAL -`define DSP_A_MAXWIDTH_PARTIAL `DSP_A_MAXWIDTH -`endif -`ifndef DSP_B_MAXWIDTH_PARTIAL -`define DSP_B_MAXWIDTH_PARTIAL `DSP_B_MAXWIDTH -`endif - -`ifndef DSP_NAME -$fatal(1, "Macro DSP_NAME must be defined"); -`endif - -`define MAX(a,b) (a > b ? a : b) -`define MIN(a,b) (a < b ? a : b) - -(* techmap_celltype = "$mul $__mul" *) -module _80_mul (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] Y; - - parameter _TECHMAP_CELLTYPE_ = ""; - - generate - if (0) begin end -`ifdef DSP_A_MINWIDTH - else if (A_WIDTH < `DSP_A_MINWIDTH) - wire _TECHMAP_FAIL_ = 1; -`endif -`ifdef DSP_B_MINWIDTH - else if (B_WIDTH < `DSP_B_MINWIDTH) - wire _TECHMAP_FAIL_ = 1; -`endif -`ifdef DSP_Y_MINWIDTH - else if (Y_WIDTH < `DSP_Y_MINWIDTH) - wire _TECHMAP_FAIL_ = 1; -`endif -`ifdef DSP_SIGNEDONLY - else if (_TECHMAP_CELLTYPE_ == "$mul" && !A_SIGNED && !B_SIGNED) - \$mul #( - .A_SIGNED(1), - .B_SIGNED(1), - .A_WIDTH(A_WIDTH + 1), - .B_WIDTH(B_WIDTH + 1), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A({1'b0, A}), - .B({1'b0, B}), - .Y(Y) - ); -`endif - else if (_TECHMAP_CELLTYPE_ == "$mul" && A_WIDTH < B_WIDTH) - \$mul #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(B), - .B(A), - .Y(Y) - ); - else begin - wire [1023:0] _TECHMAP_DO_ = "proc; clean"; - -`ifdef DSP_SIGNEDONLY - localparam sign_headroom = 1; -`else - localparam sign_headroom = 0; -`endif - - genvar i; - if (A_WIDTH > `DSP_A_MAXWIDTH) begin - localparam n = (A_WIDTH-`DSP_A_MAXWIDTH+`DSP_A_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_A_MAXWIDTH_PARTIAL-sign_headroom); - localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH_PARTIAL); - localparam last_A_WIDTH = A_WIDTH-n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom); - localparam last_Y_WIDTH = B_WIDTH+last_A_WIDTH; - if (A_SIGNED && B_SIGNED) begin : blk - (* force_downto *) - wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; - (* force_downto *) - wire signed [last_Y_WIDTH-1:0] last_partial; - (* force_downto *) - wire signed [Y_WIDTH-1:0] partial_sum [n:0]; - end - else begin : blk - (* force_downto *) - wire [partial_Y_WIDTH-1:0] partial [n-1:0]; - (* force_downto *) - wire [last_Y_WIDTH-1:0] last_partial; - (* force_downto *) - wire [Y_WIDTH-1:0] partial_sum [n:0]; - end - - for (i = 0; i < n; i=i+1) begin:sliceA - \$__mul #( - .A_SIGNED(sign_headroom), - .B_SIGNED(B_SIGNED), - .A_WIDTH(`DSP_A_MAXWIDTH_PARTIAL), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(partial_Y_WIDTH) - ) mul ( - .A({{sign_headroom{1'b0}}, A[i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_A_MAXWIDTH_PARTIAL-sign_headroom]}), - .B(B), - .Y(blk.partial[i]) - ); - // TODO: Currently a 'cascade' approach to summing the partial - // products is taken here, but a more efficient 'binary - // reduction' approach also exists... - if (i == 0) - assign blk.partial_sum[i] = blk.partial[i]; - else - assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; - end - - \$__mul #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(last_A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(last_Y_WIDTH) - ) sliceA.last ( - .A(A[A_WIDTH-1 -: last_A_WIDTH]), - .B(B), - .Y(blk.last_partial) - ); - assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; - assign Y = blk.partial_sum[n]; - end - else if (B_WIDTH > `DSP_B_MAXWIDTH) begin - localparam n = (B_WIDTH-`DSP_B_MAXWIDTH+`DSP_B_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); - localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH_PARTIAL); - localparam last_B_WIDTH = B_WIDTH-n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); - localparam last_Y_WIDTH = A_WIDTH+last_B_WIDTH; - if (A_SIGNED && B_SIGNED) begin : blk - (* force_downto *) - wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; - (* force_downto *) - wire signed [last_Y_WIDTH-1:0] last_partial; - (* force_downto *) - wire signed [Y_WIDTH-1:0] partial_sum [n:0]; - end - else begin : blk - (* force_downto *) - wire [partial_Y_WIDTH-1:0] partial [n-1:0]; - (* force_downto *) - wire [last_Y_WIDTH-1:0] last_partial; - (* force_downto *) - wire [Y_WIDTH-1:0] partial_sum [n:0]; - end - - for (i = 0; i < n; i=i+1) begin:sliceB - \$__mul #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(sign_headroom), - .A_WIDTH(A_WIDTH), - .B_WIDTH(`DSP_B_MAXWIDTH_PARTIAL), - .Y_WIDTH(partial_Y_WIDTH) - ) mul ( - .A(A), - .B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_B_MAXWIDTH_PARTIAL-sign_headroom]}), - .Y(blk.partial[i]) - ); - // TODO: Currently a 'cascade' approach to summing the partial - // products is taken here, but a more efficient 'binary - // reduction' approach also exists... - if (i == 0) - assign blk.partial_sum[i] = blk.partial[i]; - else - assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; - end - - \$__mul #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(last_B_WIDTH), - .Y_WIDTH(last_Y_WIDTH) - ) mul_sliceB_last ( - .A(A), - .B(B[B_WIDTH-1 -: last_B_WIDTH]), - .Y(blk.last_partial) - ); - assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; - assign Y = blk.partial_sum[n]; - end - else begin - if (A_SIGNED) begin : blkA - wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A); - end - else begin : blkA - wire [`DSP_A_MAXWIDTH-1:0] Aext = A; - end - if (B_SIGNED) begin : blkB - wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B); - end - else begin : blkB - wire [`DSP_B_MAXWIDTH-1:0] Bext = B; - end - - `DSP_NAME #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(`DSP_A_MAXWIDTH), - .B_WIDTH(`DSP_B_MAXWIDTH), - .Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)), - ) _TECHMAP_REPLACE_ ( - .A(blkA.Aext), - .B(blkB.Bext), - .Y(Y) - ); - end - end - endgenerate -endmodule - -(* techmap_celltype = "$mul $__mul" *) -module _90_soft_mul (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] Y; - - // Indirection necessary since mapping - // back to $mul will cause recursion - generate - if (A_SIGNED && !B_SIGNED) - \$__soft_mul #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(1), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH+1), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(A), - .B({1'b0,B}), - .Y(Y) - ); - else if (!A_SIGNED && B_SIGNED) - \$__soft_mul #( - .A_SIGNED(1), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH+1), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A({1'b0,A}), - .B(B), - .Y(Y) - ); - else - \$__soft_mul #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(A), - .B(B), - .Y(Y) - ); - endgenerate -endmodule +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 Eddie Hung + * 2019 gatecat + * + * 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. + * + * --- + * + * Tech-mapping rules for decomposing arbitrarily-sized $mul cells + * into an equivalent collection of smaller `DSP_NAME cells (with the + * same interface as $mul) no larger than `DSP_[AB]_MAXWIDTH, attached + * to $shl and $add cells. + * + */ + +`ifndef DSP_A_MAXWIDTH +$fatal(1, "Macro DSP_A_MAXWIDTH must be defined"); +`endif +`ifndef DSP_B_MAXWIDTH +$fatal(1, "Macro DSP_B_MAXWIDTH must be defined"); +`endif +`ifndef DSP_B_MAXWIDTH +$fatal(1, "Macro DSP_B_MAXWIDTH must be defined"); +`endif +`ifndef DSP_A_MAXWIDTH_PARTIAL +`define DSP_A_MAXWIDTH_PARTIAL `DSP_A_MAXWIDTH +`endif +`ifndef DSP_B_MAXWIDTH_PARTIAL +`define DSP_B_MAXWIDTH_PARTIAL `DSP_B_MAXWIDTH +`endif + +`ifndef DSP_NAME +$fatal(1, "Macro DSP_NAME must be defined"); +`endif + +`define MAX(a,b) (a > b ? a : b) +`define MIN(a,b) (a < b ? a : b) + +(* techmap_celltype = "$mul $__mul" *) +module _80_mul (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + parameter _TECHMAP_CELLTYPE_ = ""; + + generate + if (0) begin end +`ifdef DSP_A_MINWIDTH + else if (A_WIDTH < `DSP_A_MINWIDTH) + wire _TECHMAP_FAIL_ = 1; +`endif +`ifdef DSP_B_MINWIDTH + else if (B_WIDTH < `DSP_B_MINWIDTH) + wire _TECHMAP_FAIL_ = 1; +`endif +`ifdef DSP_Y_MINWIDTH + else if (Y_WIDTH < `DSP_Y_MINWIDTH) + wire _TECHMAP_FAIL_ = 1; +`endif +`ifdef DSP_SIGNEDONLY + else if (_TECHMAP_CELLTYPE_ == "$mul" && !A_SIGNED && !B_SIGNED) + \$mul #( + .A_SIGNED(1), + .B_SIGNED(1), + .A_WIDTH(A_WIDTH + 1), + .B_WIDTH(B_WIDTH + 1), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A({1'b0, A}), + .B({1'b0, B}), + .Y(Y) + ); +`endif + else if (_TECHMAP_CELLTYPE_ == "$mul" && A_WIDTH < B_WIDTH) + \$mul #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(B), + .B(A), + .Y(Y) + ); + else begin + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + +`ifdef DSP_SIGNEDONLY + localparam sign_headroom = 1; +`else + localparam sign_headroom = 0; +`endif + + genvar i; + if (A_WIDTH > `DSP_A_MAXWIDTH) begin + localparam n = (A_WIDTH-`DSP_A_MAXWIDTH+`DSP_A_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_A_MAXWIDTH_PARTIAL-sign_headroom); + localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH_PARTIAL); + localparam last_A_WIDTH = A_WIDTH-n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom); + localparam last_Y_WIDTH = B_WIDTH+last_A_WIDTH; + if (A_SIGNED && B_SIGNED) begin : blk + (* force_downto *) + wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; + (* force_downto *) + wire signed [last_Y_WIDTH-1:0] last_partial; + (* force_downto *) + wire signed [Y_WIDTH-1:0] partial_sum [n:0]; + end + else begin : blk + (* force_downto *) + wire [partial_Y_WIDTH-1:0] partial [n-1:0]; + (* force_downto *) + wire [last_Y_WIDTH-1:0] last_partial; + (* force_downto *) + wire [Y_WIDTH-1:0] partial_sum [n:0]; + end + + for (i = 0; i < n; i=i+1) begin:sliceA + \$__mul #( + .A_SIGNED(sign_headroom), + .B_SIGNED(B_SIGNED), + .A_WIDTH(`DSP_A_MAXWIDTH_PARTIAL), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(partial_Y_WIDTH) + ) mul ( + .A({{sign_headroom{1'b0}}, A[i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_A_MAXWIDTH_PARTIAL-sign_headroom]}), + .B(B), + .Y(blk.partial[i]) + ); + // TODO: Currently a 'cascade' approach to summing the partial + // products is taken here, but a more efficient 'binary + // reduction' approach also exists... + if (i == 0) + assign blk.partial_sum[i] = blk.partial[i]; + else + assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; + end + + \$__mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(last_A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(last_Y_WIDTH) + ) sliceA.last ( + .A(A[A_WIDTH-1 -: last_A_WIDTH]), + .B(B), + .Y(blk.last_partial) + ); + assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; + assign Y = blk.partial_sum[n]; + end + else if (B_WIDTH > `DSP_B_MAXWIDTH) begin + localparam n = (B_WIDTH-`DSP_B_MAXWIDTH+`DSP_B_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); + localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH_PARTIAL); + localparam last_B_WIDTH = B_WIDTH-n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom); + localparam last_Y_WIDTH = A_WIDTH+last_B_WIDTH; + if (A_SIGNED && B_SIGNED) begin : blk + (* force_downto *) + wire signed [partial_Y_WIDTH-1:0] partial [n-1:0]; + (* force_downto *) + wire signed [last_Y_WIDTH-1:0] last_partial; + (* force_downto *) + wire signed [Y_WIDTH-1:0] partial_sum [n:0]; + end + else begin : blk + (* force_downto *) + wire [partial_Y_WIDTH-1:0] partial [n-1:0]; + (* force_downto *) + wire [last_Y_WIDTH-1:0] last_partial; + (* force_downto *) + wire [Y_WIDTH-1:0] partial_sum [n:0]; + end + + for (i = 0; i < n; i=i+1) begin:sliceB + \$__mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(sign_headroom), + .A_WIDTH(A_WIDTH), + .B_WIDTH(`DSP_B_MAXWIDTH_PARTIAL), + .Y_WIDTH(partial_Y_WIDTH) + ) mul ( + .A(A), + .B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_B_MAXWIDTH_PARTIAL-sign_headroom]}), + .Y(blk.partial[i]) + ); + // TODO: Currently a 'cascade' approach to summing the partial + // products is taken here, but a more efficient 'binary + // reduction' approach also exists... + if (i == 0) + assign blk.partial_sum[i] = blk.partial[i]; + else + assign blk.partial_sum[i] = (blk.partial[i] << (* mul2dsp *) i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[i-1]; + end + + \$__mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(last_B_WIDTH), + .Y_WIDTH(last_Y_WIDTH) + ) mul_sliceB_last ( + .A(A), + .B(B[B_WIDTH-1 -: last_B_WIDTH]), + .Y(blk.last_partial) + ); + assign blk.partial_sum[n] = (blk.last_partial << (* mul2dsp *) n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) blk.partial_sum[n-1]; + assign Y = blk.partial_sum[n]; + end + else begin + if (A_SIGNED) begin : blkA + wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A); + end + else begin : blkA + wire [`DSP_A_MAXWIDTH-1:0] Aext = A; + end + if (B_SIGNED) begin : blkB + wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B); + end + else begin : blkB + wire [`DSP_B_MAXWIDTH-1:0] Bext = B; + end + + `DSP_NAME #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(`DSP_A_MAXWIDTH), + .B_WIDTH(`DSP_B_MAXWIDTH), + .Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)), + ) _TECHMAP_REPLACE_ ( + .A(blkA.Aext), + .B(blkB.Bext), + .Y(Y) + ); + end + end + endgenerate +endmodule + +(* techmap_celltype = "$mul $__mul" *) +module _90_soft_mul (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + // Indirection necessary since mapping + // back to $mul will cause recursion + generate + if (A_SIGNED && !B_SIGNED) + \$__soft_mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(1), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH+1), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(A), + .B({1'b0,B}), + .Y(Y) + ); + else if (!A_SIGNED && B_SIGNED) + \$__soft_mul #( + .A_SIGNED(1), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH+1), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A({1'b0,A}), + .B(B), + .Y(Y) + ); + else + \$__soft_mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(A), + .B(B), + .Y(Y) + ); + endgenerate +endmodule diff --git a/techlibs/intel_alm/common/bram_m20k_map.v b/techlibs/intel_alm/common/bram_m20k_map.v index 92f41310f67..15739d66a2e 100644 --- a/techlibs/intel_alm/common/bram_m20k_map.v +++ b/techlibs/intel_alm/common/bram_m20k_map.v @@ -1,31 +1,31 @@ -module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - -parameter CFG_ABITS = 10; -parameter CFG_DBITS = 20; -parameter CFG_ENABLE_A = 1; -parameter CFG_ENABLE_B = 1; - -input CLK1; -input [CFG_ABITS-1:0] A1ADDR, B1ADDR; -input [CFG_DBITS-1:0] A1DATA; -output [CFG_DBITS-1:0] B1DATA; -input [CFG_ENABLE_A-1:0] A1EN, B1EN; - -altsyncram #( - .operation_mode("dual_port"), - .ram_block_type("m20k"), - .widthad_a(CFG_ABITS), - .width_a(CFG_DBITS), - .widthad_b(CFG_ABITS), - .width_b(CFG_DBITS), -) _TECHMAP_REPLACE_ ( - .address_a(A1ADDR), - .data_a(A1DATA), - .wren_a(A1EN), - .address_b(B1ADDR), - .q_b(B1DATA), - .clock0(CLK1), - .clock1(CLK1) -); - -endmodule +module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + +parameter CFG_ABITS = 10; +parameter CFG_DBITS = 20; +parameter CFG_ENABLE_A = 1; +parameter CFG_ENABLE_B = 1; + +input CLK1; +input [CFG_ABITS-1:0] A1ADDR, B1ADDR; +input [CFG_DBITS-1:0] A1DATA; +output [CFG_DBITS-1:0] B1DATA; +input [CFG_ENABLE_A-1:0] A1EN, B1EN; + +altsyncram #( + .operation_mode("dual_port"), + .ram_block_type("m20k"), + .widthad_a(CFG_ABITS), + .width_a(CFG_DBITS), + .widthad_b(CFG_ABITS), + .width_b(CFG_DBITS), +) _TECHMAP_REPLACE_ ( + .address_a(A1ADDR), + .data_a(A1DATA), + .wren_a(A1EN), + .address_b(B1ADDR), + .q_b(B1DATA), + .clock0(CLK1), + .clock1(CLK1) +); + +endmodule diff --git a/tests/arch/common/counter.v b/tests/arch/common/counter.v index 9746fd70131..1e0a13dc95a 100644 --- a/tests/arch/common/counter.v +++ b/tests/arch/common/counter.v @@ -1,11 +1,11 @@ -module top ( out, clk, reset ); - output [7:0] out; - input clk, reset; - reg [7:0] out; - - always @(posedge clk, posedge reset) - if (reset) - out <= 8'b0; - else - out <= out + 1; -endmodule +module top ( out, clk, reset ); + output [7:0] out; + input clk, reset; + reg [7:0] out; + + always @(posedge clk, posedge reset) + if (reset) + out <= 8'b0; + else + out <= out + 1; +endmodule diff --git a/tests/arch/common/fsm.v b/tests/arch/common/fsm.v index 9d3fbb64aef..cf1c21a582a 100644 --- a/tests/arch/common/fsm.v +++ b/tests/arch/common/fsm.v @@ -1,51 +1,51 @@ - module fsm ( clock, reset, req_0, req_1, gnt_0, gnt_1 ); - input clock,reset,req_0,req_1; - output gnt_0,gnt_1; - wire clock,reset,req_0,req_1; - reg gnt_0,gnt_1; - - parameter SIZE = 3; - parameter IDLE = 3'b001; - parameter GNT0 = 3'b010; - parameter GNT1 = 3'b100; - parameter GNT2 = 3'b101; - - reg [SIZE-1:0] state; - reg [SIZE-1:0] next_state; - - always @ (posedge clock) - begin : FSM - if (reset == 1'b1) begin - state <= #1 IDLE; - gnt_0 <= 0; - gnt_1 <= 0; - end - else - case(state) - IDLE : if (req_0 == 1'b1) begin - state <= #1 GNT0; - gnt_0 <= 1; - end else if (req_1 == 1'b1) begin - gnt_1 <= 1; - state <= #1 GNT0; - end else begin - state <= #1 IDLE; - end - GNT0 : if (req_0 == 1'b1) begin - state <= #1 GNT0; - end else begin - gnt_0 <= 0; - state <= #1 IDLE; - end - GNT1 : if (req_1 == 1'b1) begin - state <= #1 GNT2; - gnt_1 <= req_0; - end - GNT2 : if (req_0 == 1'b1) begin - state <= #1 GNT1; - gnt_1 <= req_1; - end - default : state <= #1 IDLE; - endcase - end -endmodule + module fsm ( clock, reset, req_0, req_1, gnt_0, gnt_1 ); + input clock,reset,req_0,req_1; + output gnt_0,gnt_1; + wire clock,reset,req_0,req_1; + reg gnt_0,gnt_1; + + parameter SIZE = 3; + parameter IDLE = 3'b001; + parameter GNT0 = 3'b010; + parameter GNT1 = 3'b100; + parameter GNT2 = 3'b101; + + reg [SIZE-1:0] state; + reg [SIZE-1:0] next_state; + + always @ (posedge clock) + begin : FSM + if (reset == 1'b1) begin + state <= #1 IDLE; + gnt_0 <= 0; + gnt_1 <= 0; + end + else + case(state) + IDLE : if (req_0 == 1'b1) begin + state <= #1 GNT0; + gnt_0 <= 1; + end else if (req_1 == 1'b1) begin + gnt_1 <= 1; + state <= #1 GNT0; + end else begin + state <= #1 IDLE; + end + GNT0 : if (req_0 == 1'b1) begin + state <= #1 GNT0; + end else begin + gnt_0 <= 0; + state <= #1 IDLE; + end + GNT1 : if (req_1 == 1'b1) begin + state <= #1 GNT2; + gnt_1 <= req_0; + end + GNT2 : if (req_0 == 1'b1) begin + state <= #1 GNT1; + gnt_1 <= req_1; + end + default : state <= #1 IDLE; + endcase + end +endmodule diff --git a/tests/arch/common/shifter.v b/tests/arch/common/shifter.v index cace3b5889a..3030608abb2 100644 --- a/tests/arch/common/shifter.v +++ b/tests/arch/common/shifter.v @@ -1,11 +1,11 @@ -module top(out, clk, in); - output [7:0] out; - input signed clk, in; - reg signed [7:0] out = 0; - - always @(posedge clk) - begin - out <= out >> 1; - out[7] <= in; - end -endmodule +module top(out, clk, in); + output [7:0] out; + input signed clk, in; + reg signed [7:0] out = 0; + + always @(posedge clk) + begin + out <= out >> 1; + out[7] <= in; + end +endmodule From 0ada13cbe2f8e3c8568bc7e6731be9edb4c46e47 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:16:56 +0200 Subject: [PATCH 0381/2410] Use HTTPS for website links, gatecat email git ls-tree -r --name-only HEAD | xargs sed -i -rf ~/fixemails.sed s/((Claire|Xen|Xenia|Clifford)\s+)+(Wolf|Xen)\s+<(claire|clifford)@(symbioticeda.com|clifford.at|yosyshq.com)>/Claire Xenia Wolf /gi; s/((Nina|Nak|N\.)\s+)+Engelhardt\s+/N. Engelhardt /gi; s/((David)\s+)+(Shah|gatecat)\s+<(dave|david|gatecat)@(symbioticeda.com|yosyshq.com|ds0.me)>/gatecat /gi; s/((Miodrag)\s+)+Milanovic\s+<(miodrag|micko)@(symbioticeda.com|yosyshq.com)>/Miodrag Milanovic /gi; s,https?://www.clifford.at/yosys/|http://yosyshq.net/yosys/,https://yosyshq.net/yosys/,g; --- Makefile | 2 +- README.md | 8 ++++---- manual/APPNOTE_010_Verilog_to_BLIF.tex | 2 +- manual/APPNOTE_011_Design_Investigation.tex | 2 +- manual/APPNOTE_012_Verilog_to_BTOR.tex | 2 +- manual/PRESENTATION_ExAdv.tex | 2 +- manual/PRESENTATION_ExOth.tex | 2 +- manual/PRESENTATION_ExSyn.tex | 2 +- manual/PRESENTATION_Intro.tex | 8 ++++---- manual/PRESENTATION_Prog.tex | 2 +- manual/presentation.tex | 2 +- misc/create_vcxsrc.sh | 2 +- passes/sat/eval.cc | 2 +- techlibs/ecp5/arith_map.v | 2 +- techlibs/ecp5/ecp5_gsr.cc | 2 +- techlibs/ecp5/synth_ecp5.cc | 2 +- techlibs/gowin/arith_map.v | 2 +- techlibs/nexus/arith_map.v | 2 +- techlibs/nexus/synth_nexus.cc | 2 +- tests/vloghtb/run-test.sh | 2 +- 20 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 596fad2e1d7..07ebed642d4 100644 --- a/Makefile +++ b/Makefile @@ -956,7 +956,7 @@ ifeq ($(ENABLE_ABC),1) cp -r $(PROGRAM_PREFIX)yosys-abc.exe abc/lib/x86/pthreadVC2.dll yosys-win32-mxebin-$(YOSYS_VER)/ endif echo -en 'This is Yosys $(YOSYS_VER) for Win32.\r\n' > yosys-win32-mxebin-$(YOSYS_VER)/readme.txt - echo -en 'Documentation at http://yosyshq.net/yosys/.\r\n' >> yosys-win32-mxebin-$(YOSYS_VER)/readme.txt + echo -en 'Documentation at https://yosyshq.net/yosys/.\r\n' >> yosys-win32-mxebin-$(YOSYS_VER)/readme.txt zip -r yosys-win32-mxebin-$(YOSYS_VER).zip yosys-win32-mxebin-$(YOSYS_VER)/ endif diff --git a/README.md b/README.md index 09e46a80883..ab656352a9e 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,11 @@ Web Site and Other Resources ============================ More information and documentation can be found on the Yosys web site: -- http://yosyshq.net/yosys/ +- https://yosyshq.net/yosys/ The "Documentation" page on the web site contains links to more resources, including a manual that even describes some of the Yosys internals: -- http://yosyshq.net/yosys/documentation.html +- https://yosyshq.net/yosys/documentation.html The directory `guidelines` contains additional information for people interested in using the Yosys C++ APIs. @@ -92,7 +92,7 @@ For Cygwin use the following command to install all prerequisites, or select the There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well as a source distribution for Visual Studio. Visit the Yosys download page for -more information: http://yosyshq.net/yosys/download.html +more information: https://yosyshq.net/yosys/download.html To configure the build system to use a specific compiler, use one of @@ -568,7 +568,7 @@ Building the documentation ========================== Note that there is no need to build the manual if you just want to read it. -Simply download the PDF from http://yosyshq.net/yosys/documentation.html +Simply download the PDF from https://yosyshq.net/yosys/documentation.html instead. On Ubuntu, texlive needs these packages to be able to build the manual: diff --git a/manual/APPNOTE_010_Verilog_to_BLIF.tex b/manual/APPNOTE_010_Verilog_to_BLIF.tex index 5b1c0c359aa..0d0d3e5cd5d 100644 --- a/manual/APPNOTE_010_Verilog_to_BLIF.tex +++ b/manual/APPNOTE_010_Verilog_to_BLIF.tex @@ -438,7 +438,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. \\ -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \bibitem{bigsim} yosys-bigsim, a collection of real-world Verilog designs for regression testing purposes. \\ diff --git a/manual/APPNOTE_011_Design_Investigation.tex b/manual/APPNOTE_011_Design_Investigation.tex index 33df79f6128..dc228430177 100644 --- a/manual/APPNOTE_011_Design_Investigation.tex +++ b/manual/APPNOTE_011_Design_Investigation.tex @@ -1042,7 +1042,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \bibitem{graphviz} Graphviz - Graph Visualization Software. diff --git a/manual/APPNOTE_012_Verilog_to_BTOR.tex b/manual/APPNOTE_012_Verilog_to_BTOR.tex index ebaa3e420b0..a96e26503f4 100644 --- a/manual/APPNOTE_012_Verilog_to_BTOR.tex +++ b/manual/APPNOTE_012_Verilog_to_BTOR.tex @@ -411,7 +411,7 @@ \section{Conclusion} \bibitem{yosys} Clifford Wolf. The Yosys Open SYnthesis Suite. \\ -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \bibitem{boolector} Robert Brummayer and Armin Biere, Boolector: An Efficient SMT Solver for Bit-Vectors and Arrays\\ diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 1cb99e8fa07..6a426ff2b1f 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -890,7 +890,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index ddac5c72fa5..3f5113e3cf4 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -221,7 +221,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index 11f205f1fdd..d7cfdc6f2fc 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -509,7 +509,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 2b1fd9d1062..22048bc3d30 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -476,7 +476,7 @@ \subsection{Yosys Commands} \begin{itemize} \item Use ``{\tt help}'' for a command list and ``{\tt help \it command}'' for details. \item Or run ``{\tt yosys -H}'' or ``{\tt yosys -h \it command}''. -\item Or go to \url{http://yosyshq.net/yosys/documentation.html}. +\item Or go to \url{https://yosyshq.net/yosys/documentation.html}. \end{itemize} \bigskip @@ -913,11 +913,11 @@ \subsection{Documentation, Downloads, Contacts} \begin{frame}{\subsecname} \begin{itemize} \item Website: \\ -\smallskip\hskip1cm\url{http://yosyshq.net/yosys/} +\smallskip\hskip1cm\url{https://yosyshq.net/yosys/} \bigskip \item Manual, Command Reference, Application Notes: \\ -\smallskip\hskip1cm\url{http://yosyshq.net/yosys/documentation.html} +\smallskip\hskip1cm\url{https://yosyshq.net/yosys/documentation.html} \bigskip \item Instead of a mailing list we have a SubReddit: \\ @@ -950,7 +950,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index aeb9b137ca2..b0390cb9977 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -590,7 +590,7 @@ \subsection{Summary} \bigskip \bigskip \begin{center} -\url{http://yosyshq.net/yosys/} +\url{https://yosyshq.net/yosys/} \end{center} \end{frame} diff --git a/manual/presentation.tex b/manual/presentation.tex index 08e40939446..ea8e37bc9db 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -81,7 +81,7 @@ \title{Yosys Open SYnthesis Suite} \author{Clifford Wolf} -\institute{http://yosyshq.net/yosys/} +\institute{https://yosyshq.net/yosys/} \usetheme{Madrid} \usecolortheme{seagull} diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 2bf282427ad..dc4ac13e0b9 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -6,7 +6,7 @@ yosysver="$2" gitsha="$3" rm -rf YosysVS-Tpl-v2.zip YosysVS -wget http://yosyshq.net/yosys/nogit/YosysVS-Tpl-v2.zip +wget https://yosyshq.net/yosys/nogit/YosysVS-Tpl-v2.zip unzip YosysVS-Tpl-v2.zip rm -f YosysVS-Tpl-v2.zip diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 056115031be..05879426e63 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -18,7 +18,7 @@ */ // [[CITE]] VlogHammer Verilog Regression Test Suite -// http://yosyshq.net/yosys/vloghammer.html +// https://yosyshq.net/yosys/vloghammer.html #include "kernel/register.h" #include "kernel/celltypes.h" diff --git a/techlibs/ecp5/arith_map.v b/techlibs/ecp5/arith_map.v index 0e56a18bdc1..9334785ae19 100644 --- a/techlibs/ecp5/arith_map.v +++ b/techlibs/ecp5/arith_map.v @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 David Shah + * Copyright (C) 2018 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/ecp5/ecp5_gsr.cc index a676548f20b..62b231aab3b 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/ecp5/ecp5_gsr.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2019 David Shah + * Copyright (C) 2019 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index b30884ba39e..2df9a1f8765 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 David Shah + * Copyright (C) 2018 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v index b504e5bd84a..2d48fa752a2 100644 --- a/techlibs/gowin/arith_map.v +++ b/techlibs/gowin/arith_map.v @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 David Shah + * Copyright (C) 2018 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index ce81a96de83..9a1fedfc81a 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 David Shah + * Copyright (C) 2018 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 9134b6e2a81..d725546cc5a 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2020 David Shah + * Copyright (C) 2020 gatecat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index 9e22d1b7409..3c068961991 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -3,7 +3,7 @@ set -ex rm -rf Makefile refdat rtl scripts spec -wget -N http://yosyshq.net/yosys/nogit/vloghammer_tb.tar.bz2 +wget -N https://yosyshq.net/yosys/nogit/vloghammer_tb.tar.bz2 tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean From a734face3a200a6704342e61466ca85fc0c732b0 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:33:41 +0200 Subject: [PATCH 0382/2410] More deadname stuff --- manual/APPNOTE_010_Verilog_to_BLIF.tex | 6 +++--- manual/APPNOTE_011_Design_Investigation.tex | 4 ++-- manual/APPNOTE_012_Verilog_to_BTOR.tex | 4 ++-- manual/CHAPTER_Auxlibs.tex | 4 ++-- manual/PRESENTATION_Intro.tex | 6 +++--- manual/literature.bib | 8 ++++---- manual/manual.tex | 4 ++-- manual/presentation.tex | 4 ++-- manual/weblinks.bib | 12 ++++++------ tests/simple/vloghammer.v | 2 +- 10 files changed, 27 insertions(+), 27 deletions(-) diff --git a/manual/APPNOTE_010_Verilog_to_BLIF.tex b/manual/APPNOTE_010_Verilog_to_BLIF.tex index 0d0d3e5cd5d..16254d593db 100644 --- a/manual/APPNOTE_010_Verilog_to_BLIF.tex +++ b/manual/APPNOTE_010_Verilog_to_BLIF.tex @@ -52,7 +52,7 @@ \begin{document} \title{Yosys Application Note 010: \\ Converting Verilog to BLIF} -\author{Clifford Wolf \\ November 2013} +\author{Claire Xenia Wolf \\ November 2013} \maketitle \begin{abstract} @@ -437,12 +437,12 @@ \section{Conclusion} \begin{thebibliography}{9} \bibitem{yosys} -Clifford Wolf. The Yosys Open SYnthesis Suite. \\ +Claire Xenia Wolf. The Yosys Open SYnthesis Suite. \\ \url{https://yosyshq.net/yosys/} \bibitem{bigsim} yosys-bigsim, a collection of real-world Verilog designs for regression testing purposes. \\ -\url{https://github.com/cliffordwolf/yosys-bigsim} +\url{https://github.com/YosysHQ/yosys-bigsim} \bibitem{navre} Sebastien Bourdeauducq. Navr\'e AVR clone (8-bit RISC). \\ diff --git a/manual/APPNOTE_011_Design_Investigation.tex b/manual/APPNOTE_011_Design_Investigation.tex index dc228430177..881212fe93e 100644 --- a/manual/APPNOTE_011_Design_Investigation.tex +++ b/manual/APPNOTE_011_Design_Investigation.tex @@ -54,7 +54,7 @@ \begin{document} \title{Yosys Application Note 011: \\ Interactive Design Investigation} -\author{Clifford Wolf \\ Original Version December 2013} +\author{Claire Xenia Wolf \\ Original Version December 2013} \maketitle \begin{abstract} @@ -1041,7 +1041,7 @@ \section{Conclusion} \begin{thebibliography}{9} \bibitem{yosys} -Clifford Wolf. The Yosys Open SYnthesis Suite. +Claire Xenia Wolf. The Yosys Open SYnthesis Suite. \url{https://yosyshq.net/yosys/} \bibitem{graphviz} diff --git a/manual/APPNOTE_012_Verilog_to_BTOR.tex b/manual/APPNOTE_012_Verilog_to_BTOR.tex index a96e26503f4..aabdc63c41f 100644 --- a/manual/APPNOTE_012_Verilog_to_BTOR.tex +++ b/manual/APPNOTE_012_Verilog_to_BTOR.tex @@ -52,7 +52,7 @@ \begin{document} \title{Yosys Application Note 012: \\ Converting Verilog to BTOR} -\author{Ahmed Irfan and Clifford Wolf \\ April 2015} +\author{Ahmed Irfan and Claire Xenia Wolf \\ April 2015} \maketitle \begin{abstract} @@ -410,7 +410,7 @@ \section{Conclusion} \begin{thebibliography}{9} \bibitem{yosys} -Clifford Wolf. The Yosys Open SYnthesis Suite. \\ +Claire Xenia Wolf. The Yosys Open SYnthesis Suite. \\ \url{https://yosyshq.net/yosys/} \bibitem{boolector} diff --git a/manual/CHAPTER_Auxlibs.tex b/manual/CHAPTER_Auxlibs.tex index 440ea13754c..b3041078fbc 100644 --- a/manual/CHAPTER_Auxlibs.tex +++ b/manual/CHAPTER_Auxlibs.tex @@ -22,7 +22,7 @@ \section{SubCircuit} \label{sec:SubCircuit} The files in {\tt libs/subcircuit} provide a library for solving the subcircuit -isomorphism problem. It is written by Clifford Wolf and based on the Ullmann +isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph Isomorphism Algorithm \cite{UllmannSubgraphIsomorphism}. It is used by the {\tt extract} pass (see {\tt help extract} or Sec.~\ref{cmd:extract}). @@ -30,6 +30,6 @@ \section{ezSAT} The files in {\tt libs/ezsat} provide a library for simplifying generating CNF formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT -library is written by Clifford Wolf. It is used by the {\tt sat} pass (see +library is written by C. Wolf. It is used by the {\tt sat} pass (see {\tt help sat} or Sec.~\ref{cmd:sat}). diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 22048bc3d30..1c3b79fa034 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -260,7 +260,7 @@ \subsection{Example Project} \end{itemize} \vfill Direct link to the files: \\ \footnotesize -\url{https://github.com/cliffordwolf/yosys/tree/master/manual/PRESENTATION_Intro} +\url{https://github.com/YosysHQ/yosys/tree/master/manual/PRESENTATION_Intro} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -806,7 +806,7 @@ \subsection{Projects (that I know of) using Yosys} \begin{itemize} \item Ongoing PhD project on coarse grain synthesis \\ {\setlength{\parindent}{0.5cm}\footnotesize -Johann Glaser and Clifford Wolf. Methodology and Example-Driven Interconnect +Johann Glaser and C. Wolf. Methodology and Example-Driven Interconnect Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable Architectures. In Jan Haase, editor, \it Models, Methods, and Tools for Complex Chip Design. Lecture Notes in Electrical Engineering. Volume 265, 2014, pp @@ -925,7 +925,7 @@ \subsection{Documentation, Downloads, Contacts} \bigskip \item Direct link to the source code: \\ -\smallskip\hskip1cm\url{https://github.com/cliffordwolf/yosys} +\smallskip\hskip1cm\url{https://github.com/YosysHQ/yosys} \end{itemize} \end{frame} diff --git a/manual/literature.bib b/manual/literature.bib index 372e882ac21..86652eb462b 100644 --- a/manual/literature.bib +++ b/manual/literature.bib @@ -1,7 +1,7 @@ @inproceedings{intersynth, title={Example-driven interconnect synthesis for heterogeneous coarse-grain reconfigurable logic}, - author={Clifford Wolf and Johann Glaser and Florian Schupfer and Jan Haase and Christoph Grimm}, + author={C. Wolf and Johann Glaser and Florian Schupfer and Jan Haase and Christoph Grimm}, booktitle={FDL Proceeding of the 2012 Forum on Specification and Design Languages}, pages={194--201}, year={2012} @@ -9,7 +9,7 @@ @inproceedings{intersynth @incollection{intersynthFdlBookChapter, title={Methodology and Example-Driven Interconnect Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable Architectures}, - author={Johann Glaser and Clifford Wolf}, + author={Johann Glaser and C. Wolf}, booktitle={Advances in Models, Methods, and Tools for Complex Chip Design --- Selected contributions from FDL'12}, editor={Jan Haase}, publisher={Springer}, @@ -18,14 +18,14 @@ @incollection{intersynthFdlBookChapter } @unpublished{BACC, - author = {Clifford Wolf}, + author = {C. Wolf}, title = {Design and Implementation of the Yosys Open SYnthesis Suite}, note = {Bachelor Thesis, Vienna University of Technology}, year = {2013} } @unpublished{VerilogFossEval, - author = {Clifford Wolf}, + author = {C. Wolf}, title = {Evaluation of Open Source Verilog Synthesis Tools for Feature-Completeness and Extensibility}, note = {Unpublished Student Research Paper, Vienna University of Technology}, year = {2012} diff --git a/manual/manual.tex b/manual/manual.tex index dac8b1000fc..1914df9893a 100644 --- a/manual/manual.tex +++ b/manual/manual.tex @@ -51,7 +51,7 @@ % Hyperlinks \usepackage[colorlinks,hyperindex,plainpages=false,% pdftitle={Yosys Manual},% -pdfauthor={Clifford Wolf},% +pdfauthor={Claire Xenia Wolf},% %pdfkeywords={keyword},% pdfpagelabels,% pagebackref,% @@ -137,7 +137,7 @@ \bf\Huge Yosys Manual \bigskip -\large Clifford Wolf +\large Claire Xenia Wolf \end{center} \vfil\null diff --git a/manual/presentation.tex b/manual/presentation.tex index ea8e37bc9db..7aba33c8b31 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -80,7 +80,7 @@ \end{centering}} \title{Yosys Open SYnthesis Suite} -\author{Clifford Wolf} +\author{Claire Xenia Wolf} \institute{https://yosyshq.net/yosys/} \usetheme{Madrid} @@ -124,7 +124,7 @@ \section{Abstract} \section{About me} \begin{frame}{About me} -Hi! I'm Clifford Wolf. +Hi! I'm Claire Xenia Wolf. \bigskip I like writing open source software. For example: diff --git a/manual/weblinks.bib b/manual/weblinks.bib index d5f83315dcf..23ddbc38b99 100644 --- a/manual/weblinks.bib +++ b/manual/weblinks.bib @@ -1,20 +1,20 @@ @misc{YosysGit, - author = {Clifford Wolf}, + author = {Claire Xenia Wolf}, title = {{Yosys Open SYnthesis Suite (YOSYS)}}, - note = {\url{http://github.com/cliffordwolf/yosys}} + note = {\url{http://github.com/YosysHQ/yosys}} } @misc{YosysTestsGit, - author = {Clifford Wolf}, + author = {Claire Xenia Wolf}, title = {{Yosys Test Bench}}, - note = {\url{http://github.com/cliffordwolf/yosys-tests}} + note = {\url{http://github.com/YosysHQ/yosys-tests}} } @misc{VlogHammer, - author = {Clifford Wolf}, + author = {Claire Xenia Wolf}, title = {{VlogHammer Verilog Synthesis Regression Tests}}, - note = {\url{http://github.com/cliffordwolf/VlogHammer}} + note = {\url{http://github.com/YosysHQ/VlogHammer}} } @misc{Icarus, diff --git a/tests/simple/vloghammer.v b/tests/simple/vloghammer.v index 3bb3cf992ad..5fcedbff11f 100644 --- a/tests/simple/vloghammer.v +++ b/tests/simple/vloghammer.v @@ -1,6 +1,6 @@ // test cases found using vloghammer -// https://github.com/cliffordwolf/VlogHammer +// https://github.com/YosysHQ/VlogHammer module test01(a, y); input [7:0] a; From 06b99950ed295bde34063190641c71b28fde8e1f Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:39:12 +0200 Subject: [PATCH 0383/2410] Fix icestorm links Signed-off-by: Claire Xenia Wolf --- techlibs/ice40/abc9_model.v | 42 +- techlibs/ice40/cells_sim.v | 990 ++++++++++++++++++------------------ 2 files changed, 516 insertions(+), 516 deletions(-) diff --git a/techlibs/ice40/abc9_model.v b/techlibs/ice40/abc9_model.v index 84923d381fa..3e3ca94a697 100644 --- a/techlibs/ice40/abc9_model.v +++ b/techlibs/ice40/abc9_model.v @@ -28,57 +28,57 @@ module \$__ICE40_CARRY_WRAPPER ( ); `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79 (CI => CO) = (126, 105); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80 (I0 => O) = (449, 386); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82 (A => CO) = (259, 245); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83 (A => O) = (400, 379); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85 (B => CO) = (231, 133); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86 (B => O) = (379, 351); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88 (I3 => O) = (316, 288); (CI => O) = (316, 288); endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79 (CI => CO) = (186, 155); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80 (I0 => O) = (662, 569); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82 (A => CO) = (382, 362); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83 (A => O) = (589, 558); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85 (B => CO) = (341, 196); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86 (B => O) = (558, 517); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88 (I3 => O) = (465, 423); (CI => O) = (465, 423); endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91 (CI => CO) = (278, 278); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92 (I0 => O) = (1245, 1285); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94 (A => CO) = (675, 662); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95 (A => O) = (1179, 1232); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97 (B => CO) = (609, 358); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98 (B => O) = (1179, 1205); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100 (I3 => O) = (861, 874); (CI => O) = (861, 874); endspecify diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index bde3c1a87ed..0f28e227015 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -188,37 +188,37 @@ module SB_LUT4 ( assign O = I0 ? s1[1] : s1[0]; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80 (I0 => O) = (449, 386); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83 (I1 => O) = (400, 379); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86 (I2 => O) = (379, 351); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88 (I3 => O) = (316, 288); endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80 (I0 => O) = (662, 569); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83 (I1 => O) = (589, 558); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86 (I2 => O) = (558, 517); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88 (I3 => O) = (465, 423); endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92 (I0 => O) = (1245, 1285); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95 (I1 => O) = (1179, 1232); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98 (I2 => O) = (1179, 1205); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100 (I3 => O) = (861, 874); endspecify `endif @@ -229,31 +229,31 @@ module SB_CARRY (output CO, input I0, I1, CI); assign CO = (I0 && I1) || ((I0 || I1) && CI); `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79 (CI => CO) = (126, 105); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82 (I0 => CO) = (259, 245); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85 (I1 => CO) = (231, 133); endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79 (CI => CO) = (186, 155); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82 (I0 => CO) = (382, 362); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85 (I0 => CO) = (341, 196); endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91 (CI => CO) = (278, 278); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94 (I0 => CO) = (675, 662); - // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97 + // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97 (I0 => CO) = (609, 358); endspecify `endif @@ -270,28 +270,28 @@ module SB_DFF ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 (posedge C => (Q : D)) = 1391; endspecify `endif @@ -307,34 +307,34 @@ module SB_DFFE ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E) (posedge C => (Q : D)) = 1391; endspecify `endif @@ -352,36 +352,36 @@ module SB_DFFSR ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(R, posedge C, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if ( R) (posedge C => (Q : 1'b0)) = 540; if (!R) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(R, posedge C, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if ( R) (posedge C => (Q : 1'b0)) = 796; if (!R) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(R, posedge C, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if ( R) (posedge C => (Q : 1'b0)) = 1391; if (!R) (posedge C => (Q : D)) = 1391; endspecify @@ -400,12 +400,12 @@ module SB_DFFR ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge R, posedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 599; `else @@ -413,18 +413,18 @@ module SB_DFFR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (!R) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge R, posedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 883; `else @@ -432,18 +432,18 @@ module SB_DFFR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (!R) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge R, posedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 1589; `else @@ -451,7 +451,7 @@ module SB_DFFR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (!R) (posedge C => (Q : D)) = 1391; endspecify `endif @@ -469,36 +469,36 @@ module SB_DFFSS ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(S, posedge C, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if ( S) (posedge C => (Q : 1'b1)) = 540; if (!S) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(S, posedge C, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if ( S) (posedge C => (Q : 1'b1)) = 796; if (!S) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(S, posedge C, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if ( S) (posedge C => (Q : 1'b1)) = 1391; if (!S) (posedge C => (Q : D)) = 1391; endspecify @@ -517,12 +517,12 @@ module SB_DFFS ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge S, posedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 599; `else @@ -530,18 +530,18 @@ module SB_DFFS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (!S) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge S, posedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 883; `else @@ -549,18 +549,18 @@ module SB_DFFS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (!S) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge S, posedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 1589; `else @@ -568,7 +568,7 @@ module SB_DFFS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (!S) (posedge C => (Q : D)) = 1391; endspecify `endif @@ -588,42 +588,42 @@ module SB_DFFESR ( end `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C &&& E && !R, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(R, posedge C &&& E, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && R) (posedge C => (Q : 1'b0)) = 540; if (E && !R) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E && !R, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(R, posedge C &&& E, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && R) (posedge C => (Q : 1'b0)) = 796; if (E && !R) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(R, posedge C &&& E, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && R) (posedge C => (Q : 1'b0)) = 1391; if (E && !R) (posedge C => (Q : D)) = 1391; endspecify @@ -642,14 +642,14 @@ module SB_DFFER ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge R, posedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 599; `else @@ -657,20 +657,20 @@ module SB_DFFER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && !R) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge R, posedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 883; `else @@ -678,20 +678,20 @@ module SB_DFFER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && !R) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge R, posedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 1589; `else @@ -699,7 +699,7 @@ module SB_DFFER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && !R) (posedge C => (Q : D)) = 1391; endspecify `endif @@ -719,42 +719,42 @@ module SB_DFFESS ( end `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C &&& E && !S, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(S, posedge C &&& E, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && S) (posedge C => (Q : 1'b1)) = 540; if (E && !S) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E && !S, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(S, posedge C &&& E, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && S) (posedge C => (Q : 1'b1)) = 796; if (E && !S) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(S, posedge C &&& E, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && S) (posedge C => (Q : 1'b1)) = 1391; if (E && !S) (posedge C => (Q : D)) = 1391; endspecify @@ -773,14 +773,14 @@ module SB_DFFES ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, posedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(posedge S, posedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 599; `else @@ -788,20 +788,20 @@ module SB_DFFES ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && !S) (posedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(posedge S, posedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 883; `else @@ -809,20 +809,20 @@ module SB_DFFES ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && !S) (posedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, posedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(posedge S, posedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 1589; `else @@ -830,7 +830,7 @@ module SB_DFFES ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && !S) (posedge C => (Q : D)) = 1391; endspecify `endif @@ -847,28 +847,28 @@ module SB_DFFN ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 (negedge C => (Q : D)) = 1391; endspecify `endif @@ -884,34 +884,34 @@ module SB_DFFNE ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E) (negedge C => (Q : D)) = 1391; endspecify `endif @@ -929,36 +929,36 @@ module SB_DFFNSR ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(R, negedge C, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if ( R) (negedge C => (Q : 1'b0)) = 540; if (!R) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(R, negedge C, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if ( R) (negedge C => (Q : 1'b0)) = 796; if (!R) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(R, negedge C, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if ( R) (negedge C => (Q : 1'b0)) = 1391; if (!R) (negedge C => (Q : D)) = 1391; endspecify @@ -977,12 +977,12 @@ module SB_DFFNR ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge R, negedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 599; `else @@ -990,18 +990,18 @@ module SB_DFFNR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (!R) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge R, negedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 883; `else @@ -1009,18 +1009,18 @@ module SB_DFFNR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (!R) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge R, negedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 1589; `else @@ -1028,7 +1028,7 @@ module SB_DFFNR ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (!R) (negedge C => (Q : D)) = 1391; endspecify `endif @@ -1046,36 +1046,36 @@ module SB_DFFNSS ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(S, negedge C, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if ( S) (negedge C => (Q : 1'b1)) = 540; if (!S) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(S, negedge C, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if ( S) (negedge C => (Q : 1'b1)) = 796; if (!S) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(S, negedge C, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if ( S) (negedge C => (Q : 1'b1)) = 1391; if (!S) (negedge C => (Q : D)) = 1391; endspecify @@ -1094,12 +1094,12 @@ module SB_DFFNS ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge S, negedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 599; `else @@ -1107,18 +1107,18 @@ module SB_DFFNS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (!S) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge S, negedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 883; `else @@ -1126,18 +1126,18 @@ module SB_DFFNS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (!S) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge S, negedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 1589; `else @@ -1145,7 +1145,7 @@ module SB_DFFNS ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (!S) (negedge C => (Q : D)) = 1391; endspecify `endif @@ -1165,42 +1165,42 @@ module SB_DFFNESR ( end `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C &&& E && !R, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(R, negedge C &&& E, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && R) (negedge C => (Q : 1'b0)) = 540; if (E && !R) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E && !R, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(R, negedge C &&& E, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && R) (negedge C => (Q : 1'b0)) = 796; if (E && !R) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(R, negedge C &&& E, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && R) (negedge C => (Q : 1'b0)) = 1391; if (E && !R) (negedge C => (Q : D)) = 1391; endspecify @@ -1219,14 +1219,14 @@ module SB_DFFNER ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(R, negedge C, 2160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 599; `else @@ -1234,20 +1234,20 @@ module SB_DFFNER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && !R) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(R, negedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 883; `else @@ -1255,20 +1255,20 @@ module SB_DFFNER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && !R) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge R, negedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge R => (Q : 1'b0)) = 1589; `else @@ -1276,7 +1276,7 @@ module SB_DFFNER ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && !R) (negedge C => (Q : D)) = 1391; endspecify `endif @@ -1296,42 +1296,42 @@ module SB_DFFNESS ( end `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C &&& E && !S, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setup(S, negedge C &&& E, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && S) (negedge C => (Q : 1'b1)) = 540; if (E && !S) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E && !S, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setup(S, negedge C &&& E, 299); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && S) (negedge C => (Q : 1'b1)) = 796; if (E && !S) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setup(S, negedge C &&& E, 530); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && S) (negedge C => (Q : 1'b1)) = 1391; if (E && !S) (negedge C => (Q : D)) = 1391; endspecify @@ -1350,14 +1350,14 @@ module SB_DFFNES ( Q <= D; `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 $setup(D, negedge C &&& E, 470 - 449); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63 $setup(negedge S, negedge C, 160); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 599; `else @@ -1366,20 +1366,20 @@ module SB_DFFNES ( // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 if (E && !S) (negedge C => (Q : D)) = 540; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, 693 - 662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63 $setup(negedge S, negedge C, 235); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 883; `else @@ -1387,20 +1387,20 @@ module SB_DFFNES ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 if (E && !S) (negedge C => (Q : D)) = 796; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 - // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // minus https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setup(E, negedge C, 0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75 $setup(negedge S, negedge C, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103 `ifndef YOSYS (posedge S => (Q : 1'b1)) = 1589; `else @@ -1408,7 +1408,7 @@ module SB_DFFNES ( // but for facilitating a bypass box, let's pretend it's // a simple path `endif - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 if (E && !S) (negedge C => (Q : D)) = 1391; endspecify `endif @@ -1589,67 +1589,67 @@ module SB_RAM40_4K ( `endif `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 $setup(MASK, posedge WCLK &&& WE && WCLKE, 274); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 $setup(RCLKE, posedge RCLK, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 $setup(RE, posedge RCLK, 98); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 224); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 $setup(WCLKE, posedge WCLK, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 161); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLK, 133); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 (posedge RCLK => (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 $setup(MASK, posedge WCLK &&& WE && WCLKE, 403); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 300); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 $setup(RCLKE, posedge RCLK, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 $setup(RE, posedge RCLK, 145); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 331); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 $setup(WCLKE, posedge WCLK, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 238); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLK, 196); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 (posedge RCLK => (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 $setup(MASK, posedge WCLK &&& WE && WCLKE, 517); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 384); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 $setup(RCLKE, posedge RCLK, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 $setup(RE, posedge RCLK, 185); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 $setup(WCLKE, posedge WCLK, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 305); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLK, 252); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 (posedge RCLK => (RDATA : 16'bx)) = 1179; endspecify `endif @@ -1725,67 +1725,67 @@ module SB_RAM40_4KNR ( ); `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 $setup(MASK, posedge WCLK &&& WE && WCLKE, 274); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 $setup(RCLKE, posedge RCLKN, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 $setup(RE, posedge RCLKN, 98); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 224); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 $setup(WCLKE, posedge WCLK, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 161); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLK, 133); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 (posedge RCLKN => (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 $setup(MASK, posedge WCLK &&& WE && WCLKE, 403); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 300); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 $setup(RCLKE, posedge RCLKN, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 $setup(RE, posedge RCLKN, 145); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 331); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 $setup(WCLKE, posedge WCLK, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 238); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLK, 196); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 (posedge RCLKN => (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 $setup(MASK, posedge WCLK &&& WE && WCLKE, 517); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 384); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 $setup(RCLKE, posedge RCLKN, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 $setup(RE, posedge RCLKN, 185); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 $setup(WADDR, posedge WCLK &&& WE && WCLKE, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 $setup(WCLKE, posedge WCLK, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 $setup(WDATA, posedge WCLK &&& WE && WCLKE, 305); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLK, 252); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 (posedge RCLKN => (RDATA : 16'bx)) = 1179; endspecify `endif @@ -1861,67 +1861,67 @@ module SB_RAM40_4KNW ( ); `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 274); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 $setup(RCLKE, posedge RCLK, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 $setup(RE, posedge RCLK, 98); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 224); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 $setup(WCLKE, posedge WCLKN, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 161); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLKN, 133); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 (posedge RCLK => (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 403); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 300); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 $setup(RCLKE, posedge RCLK, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 $setup(RE, posedge RCLK, 145); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 331); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 $setup(WCLKE, posedge WCLKN, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 238); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLKN, 196); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 (posedge RCLK => (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 517); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 $setup(RADDR, posedge RCLK &&& RE && RCLKE, 384); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 $setup(RCLKE, posedge RCLK, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 $setup(RE, posedge RCLK, 185); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 $setup(WCLKE, posedge WCLKN, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 305); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLKN, 252); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 (posedge RCLK => (RDATA : 16'bx)) = 1179; endspecify `endif @@ -1997,67 +1997,67 @@ module SB_RAM40_4KNRNW ( ); `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 274); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 203); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370 $setup(RCLKE, posedge RCLKN, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371 $setup(RE, posedge RCLKN, 98); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 224); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383 $setup(WCLKE, posedge WCLKN, 267); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 161); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLKN, 133); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 (posedge RCLKN => (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 403); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 300); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370 $setup(RCLKE, posedge RCLKN, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371 $setup(RE, posedge RCLKN, 145); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 331); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383 $setup(WCLKE, posedge WCLKN, 393); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 238); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLKN, 196); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 (posedge RCLKN => (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983 $setup(MASK, posedge WCLKN &&& WE && WCLKE, 517); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994 $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 384); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995 $setup(RCLKE, posedge RCLKN, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996 $setup(RE, posedge RCLKN, 185); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007 $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008 $setup(WCLKE, posedge WCLKN, 503); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024 $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 305); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLKN, 252); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 (posedge RCLKN => (RDATA : 16'bx)) = 1179; endspecify `endif @@ -2159,63 +2159,63 @@ endspecify `endif `ifdef ICE40_HX specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L79 (CIN => COUT) = (101:112:126, 85:94:105); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80 (I0 => O) = (361:399:449, 310:343:386); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L81 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L81 (I0 => LO) = (293:324:365, 310:343:386); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L82 (I1 => COUT) = (209:231:259, 197:218:245); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L83 (I1 => O) = (321:355:400, 304:337:379); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L84 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L84 (I1 => LO) = (259:287:323, 304:337:379); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L85 (I2 => COUT) = (186:206:231, 107:118:133); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L86 (I2 => O) = (304:337:379, 282:312:351); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L87 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L87 (I2 => LO) = (254:281:316, 231:256:288); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L88 (I3 => O) = (254:281:316, 231:256:288); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L89 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L89 (I3 => LO) = (214:237:267, 220:243:274); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90 (posedge CLK => (O : 1'bx)) = (434:480:540, 434:480:540); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91-L92 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91-L92 (SR => O) = (482:535:599, 482:533:599); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74 $setuphold(posedge CLK, posedge I0, 378:418:470, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L68 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L68 $setuphold(posedge CLK, negedge I0, 321:355:400, 0:0:0); $setuphold(negedge CLK, posedge I0, 378:418:470, 0:0:0); $setuphold(negedge CLK, negedge I0, 321:355:400, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L75 $setuphold(posedge CLK, posedge I1, 321:355:400, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L69 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L69 $setuphold(posedge CLK, negedge I1, 304:337:379, 0:0:0); $setuphold(negedge CLK, posedge I1, 321:355:400, 0:0:0); $setuphold(negedge CLK, negedge I1, 304:337:379, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L76 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L76 $setuphold(posedge CLK, posedge I2, 299:330:372, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L70 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L70 $setuphold(posedge CLK, negedge I2, 259:287:323, 0:0:0); $setuphold(negedge CLK, posedge I2, 299:330:372, 0:0:0); $setuphold(negedge CLK, negedge I2, 259:287:323, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L77 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L77 $setuphold(posedge CLK, posedge I3, 220:243:274, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L71 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L71 $setuphold(posedge CLK, negedge I3, 175:183:217, 0:0:0); $setuphold(negedge CLK, posedge I3, 220:243:274, 0:0:0); $setuphold(negedge CLK, negedge I3, 175:183:217, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73 $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L67 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L67 $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78 $setuphold(posedge CLK, posedge SR, 163:181:203, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L72 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L72 $setuphold(posedge CLK, negedge SR, 113:125:140, 0:0:0); $setuphold(negedge CLK, posedge SR, 163:181:203, 0:0:0); $setuphold(negedge CLK, negedge SR, 113:125:140, 0:0:0); @@ -2223,63 +2223,63 @@ endspecify `endif `ifdef ICE40_LP specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L79 (CIN => COUT) = (118:153:186, 98:128:155); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80 (I0 => O) = (419:545:662, 360:468:569); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L81 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L81 (I0 => LO) = (340:442:538, 360:468:569); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L82 (I1 => COUT) = (242:315:382, 229:298:362); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L83 (I1 => O) = (372:485:589, 353:459:558); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L84 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L84 (I1 => LO) = (301:391:475, 353:459:558); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L85 (I2 => COUT) = (216:281:341, 124:162:196); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86 (I2 => O) = (353:459:558, 327:425:517); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L87 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L87 (I2 => LO) = (288:374:455, 321:417:507); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L88 (I3 => O) = (294:383:465, 268:349:424); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L89 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L89 (I3 => LO) = (249:323:393, 255:332:403); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90 (posedge CLK => (O : 1'bx)) = (504:655:796, 504:655:796); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91-L92 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91-L92 (SR => O) = (559:726:883, 559:726:883); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74 $setuphold(posedge CLK, posedge I0, 438:570:693, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L68 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L68 $setuphold(posedge CLK, negedge I0, 373:485:589, 0:0:0); $setuphold(negedge CLK, posedge I0, 438:570:693, 0:0:0); $setuphold(negedge CLK, negedge I0, 373:485:589, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L75 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L75 $setuphold(posedge CLK, posedge I1, 373:485:589, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L69 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L69 $setuphold(posedge CLK, negedge I1, 353:459:558, 0:0:0); $setuphold(negedge CLK, posedge I1, 373:485:589, 0:0:0); $setuphold(negedge CLK, negedge I1, 353:459:558, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L76 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L76 $setuphold(posedge CLK, posedge I2, 347:451:548, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L70 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L70 $setuphold(posedge CLK, negedge I2, 301:391:475, 0:0:0); $setuphold(negedge CLK, posedge I2, 347:451:548, 0:0:0); $setuphold(negedge CLK, negedge I2, 301:391:475, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L77 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L77 $setuphold(posedge CLK, posedge I3, 255:332:403, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L71 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L71 $setuphold(posedge CLK, negedge I3, 203:264:320, 0:0:0); $setuphold(negedge CLK, posedge I3, 255:332:403, 0:0:0); $setuphold(negedge CLK, negedge I3, 203:264:320, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73 $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L67 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L67 $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78 $setuphold(posedge CLK, posedge SR, 190:247:300, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L72 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L72 $setuphold(posedge CLK, negedge SR, 131:170:207, 0:0:0); $setuphold(negedge CLK, posedge SR, 190:247:300, 0:0:0); $setuphold(negedge CLK, negedge SR, 131:170:207, 0:0:0); @@ -2287,63 +2287,63 @@ endspecify `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L91 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L91 (CIN => COUT) = (103:181:278, 103:181:278); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L92 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L92 (I0 => O) = (462:808:1255, 477:834:1285); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L93 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L93 (I0 => LO) = (315:550:848, 334:585:901); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L94 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L94 (I1 => COUT) = (251:438:675, 246:430:662); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L95 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L95 (I1 => O) = (438:765:1179, 457:799:1232); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L96 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L96 (I1 => LO) = (275:481:742, 329:576:887); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L97 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L97 (I2 => COUT) = (226:395:609, 133:232:358); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L98 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L98 (I2 => O) = (438:765:1179, 447:782:1205); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L99 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L99 (I2 => LO) = (261:456:702, 290:507:781); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L100 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L100 (I3 => O) = (320:559:861, 226:370:874); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L101 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L101 (I3 => LO) = (216:378:583, 226:395:609); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102 (posedge CLK => (O : 1'bx)) = (516:903:1391, 516:903:1391); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103-104 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103-104 (SR => O) = (420:734:1131, 590:1032:1589); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86 $setuphold(posedge CLK, posedge I0, 457:799:1232, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L80 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L80 $setuphold(posedge CLK, negedge I0, 393:688:1060, 0:0:0); $setuphold(negedge CLK, posedge I0, 457:799:1232, 0:0:0); $setuphold(negedge CLK, negedge I0, 393:688:1060, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L87 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L87 $setuphold(posedge CLK, posedge I1, 393:688:1060, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L81 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L81 $setuphold(posedge CLK, negedge I1, 373:653:1007, 0:0:0); $setuphold(negedge CLK, posedge I1, 393:688:1060, 0:0:0); $setuphold(negedge CLK, negedge I1, 373:653:1007, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L88 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L88 $setuphold(posedge CLK, posedge I2, 364:636:980, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L82 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L82 $setuphold(posedge CLK, negedge I2, 320:559:861, 0:0:0); $setuphold(negedge CLK, posedge I2, 364:636:980, 0:0:0); $setuphold(negedge CLK, negedge I2, 320:559:861, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L89 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L89 $setuphold(posedge CLK, posedge I3, 279:473:728, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L83 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L83 $setuphold(posedge CLK, negedge I3, 216:378:583, 0:0:0); $setuphold(negedge CLK, posedge I3, 279:473:728, 0:0:0); $setuphold(negedge CLK, negedge I3, 216:378:583, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L85 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L85 $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L79 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L79 $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90 $setuphold(posedge CLK, posedge SR, 197:344:530, 0:0:0); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L84 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L84 $setuphold(posedge CLK, negedge SR, 143:249:384, 0:0:0); $setuphold(negedge CLK, posedge SR, 197:344:530, 0:0:0); $setuphold(negedge CLK, negedge SR, 131:170:207, 0:0:0); @@ -2570,23 +2570,23 @@ module SB_SPRAM256KA ( `endif `ifdef ICE40_U specify - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13169-L13182 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13169-L13182 $setup(posedge ADDRESS, posedge CLOCK, 268); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13183 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13183 $setup(CHIPSELECT, posedge CLOCK, 404); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13184-L13199 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13184-L13199 $setup(DATAIN, posedge CLOCK, 143); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13200-L13203 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13200-L13203 $setup(MASKWREN, posedge CLOCK, 143); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167 //$setup(negedge SLEEP, posedge CLOCK, 41505); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167 //$setup(negedge STANDBY, posedge CLOCK, 1715); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13206 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13206 $setup(WREN, posedge CLOCK, 289); - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207-L13222 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207-L13222 (posedge CLOCK => (DATAOUT : 16'bx)) = 1821; - // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13223-L13238 + // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13223-L13238 (posedge SLEEP => (DATAOUT : 16'b0)) = 1099; endspecify `endif From 0ff4fb1eb35bfba5b7a936401b58deb21776c81a Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:40:33 +0200 Subject: [PATCH 0384/2410] More deadname stuff Signed-off-by: Claire Xenia Wolf --- tests/various/muxpack.v | 4 ++-- tests/various/muxpack.ys | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v index 33ece1f1673..752f9ba48eb 100644 --- a/tests/various/muxpack.v +++ b/tests/various/muxpack.v @@ -154,7 +154,7 @@ always @* o <= i[4*W+:W]; endmodule -module cliffordwolf_nonexclusive_select ( +module clairexen_nonexclusive_select ( input wire x, y, z, input wire a, b, c, d, output reg o @@ -167,7 +167,7 @@ module cliffordwolf_nonexclusive_select ( end endmodule -module cliffordwolf_freduce ( +module clairexen_freduce ( input wire [1:0] s, input wire a, b, c, d, output reg [3:0] o diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index 3e90419af4c..d73fc44b4ff 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -167,7 +167,7 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter design -load read -hierarchy -top cliffordwolf_nonexclusive_select +hierarchy -top clairexen_nonexclusive_select prep design -save gold muxpack @@ -182,7 +182,7 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter #design -load read -#hierarchy -top cliffordwolf_freduce +#hierarchy -top clairexen_freduce #prep #design -save gold #proc; opt; freduce; opt From 2d95a7da9cd2e8cf1854215241c5df7d67ca0c1e Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:42:52 +0200 Subject: [PATCH 0385/2410] Intersynth URL Signed-off-by: Claire Xenia Wolf --- backends/intersynth/intersynth.cc | 2 +- manual/command-reference-manual.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 758a8792bbd..59173c4a2d4 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -68,7 +68,7 @@ struct IntersynthBackend : public Backend { log(" only write selected modules. modules must be selected entirely or\n"); log(" not at all.\n"); log("\n"); - log("http://www.clifford.at/intersynth/\n"); + log("http://bygone.clairexen.net/intersynth/\n"); log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index a3264b4cd93..960078cc770 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -6999,7 +6999,7 @@ \section{write\_intersynth -- write design to InterSynth netlist file} only write selected modules. modules must be selected entirely or not at all. -http://www.clifford.at/intersynth/ +http://bygone.clairexen.net/intersynth/ \end{lstlisting} \section{write\_json -- write design to a JSON file} From 588137cd082849cfa3dee92a01ac4ee91f6ed946 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 9 Jun 2021 12:44:37 +0200 Subject: [PATCH 0386/2410] Fix deadname SVN links Signed-off-by: Claire Xenia Wolf --- passes/techmap/extract_fa.cc | 2 +- passes/techmap/libparse.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index aabe43ac289..117fdd54cf6 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -33,7 +33,7 @@ struct ExtractFaConfig int maxbreadth = 6; }; -// http://svn.clifford.at/handicraft/2016/bindec/bindec.c +// http://svn.clairexen.net/handicraft/2016/bindec/bindec.c int bindec(unsigned char v) { int r = v & 1; diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 990d5594317..3d0ebaea366 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -384,7 +384,7 @@ void LibertyParser::error(const std::string &str) exit(1); } -/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/ +/**** BEGIN: http://svn.clairexen.net/tools/trunk/examples/check.h ****/ #define CHECK_NV(result, check) \ do { \ @@ -405,7 +405,7 @@ void LibertyParser::error(const std::string &str) } \ } while(0) -/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/ +/**** END: http://svn.clairexen.net/tools/trunk/examples/check.h ****/ LibertyAst *find_non_null(LibertyAst *node, const char *name) { From 12b3a9765dafeb8766265c82dee9e06435343e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 9 Jun 2021 16:14:16 +0200 Subject: [PATCH 0387/2410] opt_expr: Optimize div/mod by const 1. Turns out the code for div by a power of 2 is already almost capable of optimizing this to a shift-by-0 or and-with-0, which will be further folded into nothingness; let's beef it up to handle div by 1 as well. Fixes #2820. --- passes/opt/opt_expr.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 84f07c8a976..0230a5c402f 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1648,7 +1648,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } - for (int i = 1; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) + for (int i = 0; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) if (b_val == (1 << i)) { if (cell->type.in(ID($div), ID($divfloor))) @@ -1672,7 +1672,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons // Truncating division is the same as flooring division, except when // the result is negative and there is a remainder - then trunc = floor + 1 - if (is_truncating && a_signed) { + if (is_truncating && a_signed && i != 0) { Wire *flooring = module->addWire(NEW_ID, sig_y.size()); cell->setPort(ID::Y, flooring); @@ -1698,7 +1698,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons std::vector new_b = RTLIL::SigSpec(State::S1, i); - if (b_signed) + if (b_signed || i == 0) new_b.push_back(State::S0); cell->type = ID($and); @@ -1707,7 +1707,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons // truncating modulo has the same masked bits as flooring modulo, but // the sign bits are those of A (except when R=0) - if (is_truncating && a_signed) { + if (is_truncating && a_signed && i != 0) { Wire *flooring = module->addWire(NEW_ID, sig_y.size()); cell->setPort(ID::Y, flooring); SigSpec truncating = SigSpec(flooring).extract(0, i); From 1667ad658b3aefd3b5418dace6403d3990029fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 9 Jun 2021 18:41:57 +0200 Subject: [PATCH 0388/2410] opt_expr: Fix mul/div/mod by POT patterns to support >= 32 bits. The previous code, in addition to being needlessly limitted to 32 bits in the first place, also had UB for the 31th bit (doing 1 << 31). --- kernel/rtlil.cc | 33 +++++++ kernel/rtlil.h | 2 + passes/opt/opt_expr.cc | 207 +++++++++++++++++------------------------ 3 files changed, 120 insertions(+), 122 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1d41ba81a74..a756218f3b6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -363,6 +363,26 @@ bool RTLIL::Const::is_fully_undef() const return true; } +bool RTLIL::Const::is_onehot(int *pos) const +{ + cover("kernel.rtlil.const.is_onehot"); + + bool found = false; + for (int i = 0; i < GetSize(*this); i++) { + auto &bit = bits[i]; + if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) + return false; + if (bit == RTLIL::State::S1) { + if (found) + return false; + if (pos) + *pos = i; + found = true; + } + } + return found; +} + bool RTLIL::AttrObject::has_attribute(RTLIL::IdString id) const { return attributes.count(id); @@ -4211,6 +4231,19 @@ bool RTLIL::SigSpec::has_marked_bits() const return false; } +bool RTLIL::SigSpec::is_onehot(int *pos) const +{ + cover("kernel.rtlil.sigspec.is_onehot"); + + pack(); + if (!is_fully_const()) + return false; + log_assert(GetSize(chunks_) <= 1); + if (width_) + return RTLIL::Const(chunks_[0].data).is_onehot(pos); + return false; +} + bool RTLIL::SigSpec::as_bool() const { cover("kernel.rtlil.sigspec.as_bool"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6ecca7370fa..d876d7831e3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -662,6 +662,7 @@ struct RTLIL::Const bool is_fully_ones() const; bool is_fully_def() const; bool is_fully_undef() const; + bool is_onehot(int *pos = nullptr) const; inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const { RTLIL::Const ret; @@ -934,6 +935,7 @@ struct RTLIL::SigSpec bool is_fully_undef() const; bool has_const() const; bool has_marked_bits() const; + bool is_onehot(int *pos = nullptr) const; bool as_bool() const; int as_int(bool is_signed = false) const; diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 0230a5c402f..709cb6020d2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -393,29 +393,6 @@ int get_highest_hot_index(RTLIL::SigSpec signal) return -1; } -// if the signal has only one bit set, return the index of that bit. -// otherwise return -1 -int get_onehot_bit_index(RTLIL::SigSpec signal) -{ - int bit_index = -1; - - for (int i = 0; i < GetSize(signal); i++) - { - if (signal[i] == RTLIL::State::S0) - continue; - - if (signal[i] != RTLIL::State::S1) - return -1; - - if (bit_index != -1) - return -1; - - bit_index = i; - } - - return bit_index; -} - void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv) { if (!design->selected(module)) @@ -1526,14 +1503,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y)); - if (sig_b.is_fully_const() && sig_b.size() <= 32) + if (sig_b.is_fully_const()) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; - if (sig_a.is_fully_def() && sig_a.size() <= 32) + if (sig_a.is_fully_def()) { - int a_val = sig_a.as_int(); - - if (a_val == 0) + if (sig_a.is_fully_zero()) { cover("opt.opt_expr.mul_shift.zero"); @@ -1547,37 +1522,34 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } - for (int i = 1; i < (a_signed ? sig_a.size()-1 : sig_a.size()); i++) - if (a_val == (1 << i)) - { - if (swapped_ab) - cover("opt.opt_expr.mul_shift.swapped"); - else - cover("opt.opt_expr.mul_shift.unswapped"); - - log_debug("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", - a_val, cell->name.c_str(), module->name.c_str(), i); + int exp; + if (sig_a.is_onehot(&exp) && !(a_signed && exp == GetSize(sig_a) - 1)) + { + if (swapped_ab) + cover("opt.opt_expr.mul_shift.swapped"); + else + cover("opt.opt_expr.mul_shift.unswapped"); - if (!swapped_ab) { - cell->setPort(ID::A, cell->getPort(ID::B)); - cell->parameters.at(ID::A_WIDTH) = cell->parameters.at(ID::B_WIDTH); - cell->parameters.at(ID::A_SIGNED) = cell->parameters.at(ID::B_SIGNED); - } + log_debug("Replacing multiply-by-%s cell `%s' in module `%s' with shift-by-%d.\n", + log_signal(sig_a), cell->name.c_str(), module->name.c_str(), exp); - std::vector new_b = RTLIL::SigSpec(i, 6); + if (!swapped_ab) { + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->parameters.at(ID::A_WIDTH) = cell->parameters.at(ID::B_WIDTH); + cell->parameters.at(ID::A_SIGNED) = cell->parameters.at(ID::B_SIGNED); + } - while (GetSize(new_b) > 1 && new_b.back() == RTLIL::State::S0) - new_b.pop_back(); + Const new_b = exp; - cell->type = ID($shl); - cell->parameters[ID::B_WIDTH] = GetSize(new_b); - cell->parameters[ID::B_SIGNED] = false; - cell->setPort(ID::B, new_b); - cell->check(); + cell->type = ID($shl); + cell->parameters[ID::B_WIDTH] = GetSize(new_b); + cell->parameters[ID::B_SIGNED] = false; + cell->setPort(ID::B, new_b); + cell->check(); - did_something = true; - goto next_cell; - } + did_something = true; + goto next_cell; + } } sig_a = assign_map(cell->getPort(ID::A)); @@ -1622,7 +1594,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (!keepdc && cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) + if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { bool a_signed = cell->parameters[ID::A_SIGNED].as_bool(); bool b_signed = cell->parameters[ID::B_SIGNED].as_bool(); @@ -1630,11 +1602,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons SigSpec sig_b = assign_map(cell->getPort(ID::B)); SigSpec sig_y = assign_map(cell->getPort(ID::Y)); - if (sig_b.is_fully_def() && sig_b.size() <= 32) + if (sig_b.is_fully_def()) { - int b_val = sig_b.as_int(); - - if (b_val == 0) + if (sig_b.is_fully_zero()) { cover("opt.opt_expr.divmod_zero"); @@ -1648,86 +1618,79 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } - for (int i = 0; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) - if (b_val == (1 << i)) + int exp; + if (!keepdc && sig_b.is_onehot(&exp) && !(b_signed && exp == GetSize(sig_b) - 1)) + { + if (cell->type.in(ID($div), ID($divfloor))) { - if (cell->type.in(ID($div), ID($divfloor))) - { - cover("opt.opt_expr.div_shift"); - - bool is_truncating = cell->type == ID($div); - log_debug("Replacing %s-divide-by-%d cell `%s' in module `%s' with shift-by-%d.\n", - is_truncating ? "truncating" : "flooring", - b_val, cell->name.c_str(), module->name.c_str(), i); + cover("opt.opt_expr.div_shift"); - std::vector new_b = RTLIL::SigSpec(i, 6); + bool is_truncating = cell->type == ID($div); + log_debug("Replacing %s-divide-by-%s cell `%s' in module `%s' with shift-by-%d.\n", + is_truncating ? "truncating" : "flooring", + log_signal(sig_b), cell->name.c_str(), module->name.c_str(), exp); - while (GetSize(new_b) > 1 && new_b.back() == RTLIL::State::S0) - new_b.pop_back(); + Const new_b = exp; - cell->type = ID($sshr); - cell->parameters[ID::B_WIDTH] = GetSize(new_b); - cell->parameters[ID::B_SIGNED] = false; - cell->setPort(ID::B, new_b); + cell->type = ID($sshr); + cell->parameters[ID::B_WIDTH] = GetSize(new_b); + cell->parameters[ID::B_SIGNED] = false; + cell->setPort(ID::B, new_b); - // Truncating division is the same as flooring division, except when - // the result is negative and there is a remainder - then trunc = floor + 1 - if (is_truncating && a_signed && i != 0) { - Wire *flooring = module->addWire(NEW_ID, sig_y.size()); - cell->setPort(ID::Y, flooring); - - Wire *result_neg = module->addWire(NEW_ID); - module->addXor(NEW_ID, sig_a[sig_a.size()-1], sig_b[sig_b.size()-1], result_neg); - Wire *rem_nonzero = module->addWire(NEW_ID); - module->addReduceOr(NEW_ID, sig_a.extract(0, i), rem_nonzero); - Wire *should_add = module->addWire(NEW_ID); - module->addAnd(NEW_ID, result_neg, rem_nonzero, should_add); - module->addAdd(NEW_ID, flooring, should_add, sig_y); - } + // Truncating division is the same as flooring division, except when + // the result is negative and there is a remainder - then trunc = floor + 1 + if (is_truncating && a_signed && GetSize(sig_a) != 0 && exp != 0) { + Wire *flooring = module->addWire(NEW_ID, sig_y.size()); + cell->setPort(ID::Y, flooring); - cell->check(); + SigSpec a_sign = sig_a[sig_a.size()-1]; + SigSpec rem_nonzero = module->ReduceOr(NEW_ID, sig_a.extract(0, exp)); + SigSpec should_add = module->And(NEW_ID, a_sign, rem_nonzero); + module->addAdd(NEW_ID, flooring, should_add, sig_y); } - else if (cell->type.in(ID($mod), ID($modfloor))) + + cell->check(); + } + else if (cell->type.in(ID($mod), ID($modfloor))) + { + cover("opt.opt_expr.mod_mask"); + + bool is_truncating = cell->type == ID($mod); + log_debug("Replacing %s-modulo-by-%s cell `%s' in module `%s' with bitmask.\n", + is_truncating ? "truncating" : "flooring", + log_signal(sig_b), cell->name.c_str(), module->name.c_str()); + + // truncating modulo has the same masked bits as flooring modulo, but + // the sign bits are those of A (except when R=0) + if (is_truncating && a_signed && GetSize(sig_a) != 0 && exp != 0) { - cover("opt.opt_expr.mod_mask"); + module->remove(cell); + SigSpec truncating = sig_a.extract(0, exp); - bool is_truncating = cell->type == ID($mod); - log_debug("Replacing %s-modulo-by-%d cell `%s' in module `%s' with bitmask.\n", - is_truncating ? "truncating" : "flooring", - b_val, cell->name.c_str(), module->name.c_str()); + SigSpec a_sign = sig_a[sig_a.size()-1]; + SigSpec rem_nonzero = module->ReduceOr(NEW_ID, sig_a.extract(0, exp)); + SigSpec extend_bit = module->And(NEW_ID, a_sign, rem_nonzero); - std::vector new_b = RTLIL::SigSpec(State::S1, i); + truncating.append(extend_bit); + module->addPos(NEW_ID, truncating, sig_y, true); + } + else + { + std::vector new_b = RTLIL::SigSpec(State::S1, exp); - if (b_signed || i == 0) + if (b_signed || exp == 0) new_b.push_back(State::S0); cell->type = ID($and); cell->parameters[ID::B_WIDTH] = GetSize(new_b); cell->setPort(ID::B, new_b); - - // truncating modulo has the same masked bits as flooring modulo, but - // the sign bits are those of A (except when R=0) - if (is_truncating && a_signed && i != 0) { - Wire *flooring = module->addWire(NEW_ID, sig_y.size()); - cell->setPort(ID::Y, flooring); - SigSpec truncating = SigSpec(flooring).extract(0, i); - - Wire *rem_nonzero = module->addWire(NEW_ID); - module->addReduceOr(NEW_ID, truncating, rem_nonzero); - SigSpec a_sign = sig_a[sig_a.size()-1]; - Wire *extend_bit = module->addWire(NEW_ID); - module->addAnd(NEW_ID, a_sign, rem_nonzero, extend_bit); - - truncating.append(extend_bit); - module->addPos(NEW_ID, truncating, sig_y, true); - } - cell->check(); } - - did_something = true; - goto next_cell; } + + did_something = true; + goto next_cell; + } } } @@ -1957,8 +1920,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons replace = true; } - int const_bit_hot = get_onehot_bit_index(const_sig); - if (const_bit_hot >= 0 && const_bit_hot < var_width) + int const_bit_hot; + if (const_sig.is_onehot(&const_bit_hot) && const_bit_hot < var_width) { RTLIL::SigSpec var_high_sig(RTLIL::State::S0, var_width - const_bit_hot); for (int i = const_bit_hot; i < var_width; i++) { From 6a6d049f1cb6a96eb2af83441a0fb156efbd9cc3 Mon Sep 17 00:00:00 2001 From: gatecat Date: Fri, 11 Jun 2021 11:11:12 +0100 Subject: [PATCH 0389/2410] opt_muxtree: Update port_off and port_idx even for constant bits Signed-off-by: gatecat --- passes/opt/opt_muxtree.cc | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 8ef54cdda0d..100b1b4954e 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -372,29 +372,28 @@ struct OptMuxtreeWorker int port_idx = 0, port_off = 0; vector bits = sig2bits(sig, false); for (int i = 0; i < GetSize(bits); i++) { - if (bits[i] < 0) - continue; - if (knowledge.known_inactive.at(bits[i])) { - sig[i] = State::S0; - did_something = true; - } else - if (knowledge.known_active.at(bits[i])) { - sig[i] = State::S1; - did_something = true; - } - if (width) { - if (ctrl_bits.count(bits[i])) { - sig[i] = ctrl_bits.at(bits[i]) == port_idx ? State::S1 : State::S0; + if (bits[i] >= 0) { + if (knowledge.known_inactive.at(bits[i])) { + sig[i] = State::S0; + did_something = true; + } else + if (knowledge.known_active.at(bits[i])) { + sig[i] = State::S1; did_something = true; } - if (++port_off == width) - port_idx++, port_off=0; - } else { if (ctrl_bits.count(bits[i])) { - sig[i] = State::S0; + if (width) { + sig[i] = ctrl_bits.at(bits[i]) == port_idx ? State::S1 : State::S0; + } else { + sig[i] = State::S0; + } did_something = true; } } + if (width) { + if (++port_off == width) + port_idx++, port_off=0; + } } if (did_something) { From 438bcc68c0859057e4d3f521d1c865d2a9d90e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 11 Jun 2021 12:19:21 +0200 Subject: [PATCH 0390/2410] Add regression test for #2824. --- tests/opt/bug2824.ys | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/opt/bug2824.ys diff --git a/tests/opt/bug2824.ys b/tests/opt/bug2824.ys new file mode 100644 index 00000000000..9d0d1e9e55c --- /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 From 801ecc0e1d75f092981361632265edce67130a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 14 Jun 2021 16:28:10 +0200 Subject: [PATCH 0391/2410] verilog: Squash a memory leak. That was added in ecc22f7fedfa639482dbc55a05709da85116a60f --- frontends/verilog/verilog_frontend.cc | 12 ++++-------- frontends/verilog/verilog_frontend.h | 2 +- frontends/verilog/verilog_lexer.l | 2 +- frontends/verilog/verilog_parser.y | 17 ++++++++--------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index ad0bb9ff721..9b277c6b977 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -482,18 +482,18 @@ struct VerilogFrontend : public Frontend { // make package typedefs available to parser add_package_types(pkg_user_types, design->verilog_packages); - UserTypeMap *global_types_map = new UserTypeMap(); + UserTypeMap global_types_map; for (auto def : design->verilog_globals) { if (def->type == AST::AST_TYPEDEF) { - (*global_types_map)[def->str] = def; + global_types_map[def->str] = def; } } log_assert(user_type_stack.empty()); // use previous global typedefs as bottom level of user type stack - user_type_stack.push_back(global_types_map); + user_type_stack.push_back(std::move(global_types_map)); // add a new empty type map to allow overriding existing global definitions - user_type_stack.push_back(new UserTypeMap()); + user_type_stack.push_back(UserTypeMap()); frontend_verilog_yyset_lineno(1); frontend_verilog_yyrestart(NULL); @@ -519,10 +519,6 @@ struct VerilogFrontend : public Frontend { // only the previous and new global type maps remain log_assert(user_type_stack.size() == 2); - for (auto it : user_type_stack) { - // the global typedefs have to remain valid for future invocations, so just drop the map without deleting values - delete it; - } user_type_stack.clear(); delete current_ast; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 30f1c11802a..8454e7999e7 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -47,7 +47,7 @@ namespace VERILOG_FRONTEND // names of locally typedef'ed types in a stack typedef std::map UserTypeMap; - extern std::vector user_type_stack; + extern std::vector user_type_stack; // names of package typedef'ed types extern dict pkg_user_types; diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index b29e625d648..55e8b48b9a9 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -103,7 +103,7 @@ static bool isUserType(std::string &s) { // check current scope then outer scopes for a name for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) { - if ((*it)->count(s) > 0) { + if (it->count(s) > 0) { return true; } } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 10d904dbde4..3f4bf5bfd93 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -54,7 +54,7 @@ namespace VERILOG_FRONTEND { dict *attr_list, default_attr_list; std::stack *> attr_list_stack; dict *albuf; - std::vector user_type_stack; + std::vector user_type_stack; dict pkg_user_types; std::vector ast_stack; struct AstNode *astbuf1, *astbuf2, *astbuf3; @@ -132,8 +132,8 @@ static void addTypedefNode(std::string *name, AstNode *node) log_assert(node); auto *tnode = new AstNode(AST_TYPEDEF, node); tnode->str = *name; - auto user_types = user_type_stack.back(); - (*user_types)[*name] = tnode; + auto &user_types = user_type_stack.back(); + user_types[*name] = tnode; if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) { // typedef inside a package so we need the qualified name auto qname = current_ast_mod->str + "::" + (*name).substr(1); @@ -145,8 +145,7 @@ static void addTypedefNode(std::string *name, AstNode *node) static void enterTypeScope() { - auto user_types = new UserTypeMap(); - user_type_stack.push_back(user_types); + user_type_stack.push_back(UserTypeMap()); } static void exitTypeScope() @@ -157,17 +156,17 @@ static void exitTypeScope() static bool isInLocalScope(const std::string *name) { // tests if a name was declared in the current block scope - auto user_types = user_type_stack.back(); - return (user_types->count(*name) > 0); + auto &user_types = user_type_stack.back(); + return (user_types.count(*name) > 0); } static AstNode *getTypeDefinitionNode(std::string type_name) { // check current scope then outer scopes for a name for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) { - if ((*it)->count(type_name) > 0) { + if (it->count(type_name) > 0) { // return the definition nodes from the typedef statement - auto typedef_node = (**it)[type_name]; + auto typedef_node = (*it)[type_name]; log_assert(typedef_node->type == AST_TYPEDEF); return typedef_node->children[0]; } From 081111714eed9cbc3dacac766cad85de30e98073 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 20 Apr 2020 15:58:30 +0100 Subject: [PATCH 0392/2410] Simplify some RTLIL destructors No change in behaviour, but use range-based for loops instead of iterators. --- kernel/rtlil.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a756218f3b6..b7bef723ff3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -571,8 +571,8 @@ RTLIL::Design::Design() RTLIL::Design::~Design() { - for (auto it = modules_.begin(); it != modules_.end(); ++it) - delete it->second; + for (auto &pr : modules_) + delete pr.second; for (auto n : verilog_packages) delete n; for (auto n : verilog_globals) @@ -864,14 +864,14 @@ RTLIL::Module::Module() RTLIL::Module::~Module() { - for (auto it = wires_.begin(); it != wires_.end(); ++it) - delete it->second; - for (auto it = memories.begin(); it != memories.end(); ++it) - delete it->second; - for (auto it = cells_.begin(); it != cells_.end(); ++it) - delete it->second; - for (auto it = processes.begin(); it != processes.end(); ++it) - delete it->second; + for (auto &pr : wires_) + delete pr.second; + for (auto &pr : memories) + delete pr.second; + for (auto &pr : cells_) + delete pr.second; + for (auto &pr : processes) + delete pr.second; #ifdef WITH_PYTHON RTLIL::Module::get_all_modules()->erase(hashidx_); #endif From b516c681fe6c06fb089fe1e1bc081ffeb56c7949 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 14 Jun 2021 11:59:01 -0400 Subject: [PATCH 0393/2410] macos: fix leak in proc_self_dirname() --- kernel/yosys.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index efc42952915..cb6fdc2f49d 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -797,7 +797,9 @@ std::string proc_self_dirname() path = (char *) realloc((void *) path, buflen); while (buflen > 0 && path[buflen-1] != '/') buflen--; - return std::string(path, buflen); + std::string str(path, buflen); + free(path); + return str; } #elif defined(_WIN32) std::string proc_self_dirname() From 9ca5a91724e114ebb8c04be8edfc0f2f5e8073a9 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Wed, 17 Mar 2021 00:08:43 +0100 Subject: [PATCH 0394/2410] ast: fix error condition causing assert to fail type2str returns a string that doesn't start with $ or \, so it can't be assigned to an IdString. --- frontends/ast/genrtlil.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 52e0574864e..6b119b7fff9 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -2006,8 +2006,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) default: for (auto f : log_files) current_ast_mod->dumpAst(f, "verilog-ast> "); - type_name = type2str(type); - log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str()); + log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type2str(type).c_str()); } return RTLIL::SigSpec(); From 091295a5a533c44a4ad20d297fdad1ec2a77903c Mon Sep 17 00:00:00 2001 From: Xiretza Date: Tue, 16 Mar 2021 16:43:03 +0100 Subject: [PATCH 0395/2410] verilog: fix leaking ASTNodes --- frontends/ast/simplify.cc | 5 +++++ frontends/verilog/verilog_parser.y | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 500288de01f..8ef681069bf 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2303,6 +2303,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; + delete left_at_zero_ast; + delete right_at_zero_ast; } bool use_case_method = false; @@ -3534,6 +3536,8 @@ skip_dynamic_range_lvalue_expansion:; // convert purely constant arguments into localparams if (child->is_input && child->type == AST_WIRE && arg->type == AST_CONSTANT && node_contains_assignment_to(decl, child)) { wire->type = AST_LOCALPARAM; + if (wire->attributes.count(ID::nosync)) + delete wire->attributes.at(ID::nosync); wire->attributes.erase(ID::nosync); wire->children.insert(wire->children.begin(), arg->clone()); // args without a range implicitly have width 1 @@ -3557,6 +3561,7 @@ skip_dynamic_range_lvalue_expansion:; } // updates the sizing while (wire->simplify(true, false, false, 1, -1, false, false)) { } + delete arg; continue; } AstNode *wire_id = new AstNode(AST_IDENTIFIER); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 3f4bf5bfd93..4e601b51d35 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -503,18 +503,19 @@ optional_comma: module_arg_opt_assignment: '=' expr { if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) { - AstNode *wire = new AstNode(AST_IDENTIFIER); - wire->str = ast_stack.back()->children.back()->str; if (ast_stack.back()->children.back()->is_input) { AstNode *n = ast_stack.back()->children.back(); if (n->attributes.count(ID::defaultvalue)) delete n->attributes.at(ID::defaultvalue); n->attributes[ID::defaultvalue] = $2; - } else - if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic) - ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2)))); - else - ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2)); + } else { + AstNode *wire = new AstNode(AST_IDENTIFIER); + wire->str = ast_stack.back()->children.back()->str; + if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic) + ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2)))); + else + ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2)); + } } else frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value."); } | @@ -1158,6 +1159,8 @@ specify_item: cell->children.back()->str = "\\DST"; delete $1; + delete limit; + delete limit2; }; specify_opt_triple: From 62a42c317c41590b654f59851b4730c89bfcd7ae Mon Sep 17 00:00:00 2001 From: Xiretza Date: Wed, 17 Mar 2021 00:14:27 +0100 Subject: [PATCH 0396/2410] ast: delete wires and localparams after finishing const evaluation --- frontends/ast/simplify.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8ef681069bf..f8530642341 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -4774,6 +4774,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) { std::map backup_scope = current_scope; std::map variables; + std::vector to_delete; AstNode *block = new AstNode(AST_BLOCK); AstNode *result = nullptr; @@ -4831,6 +4832,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) current_scope[stmt->str] = stmt; block->children.erase(block->children.begin()); + to_delete.push_back(stmt); continue; } @@ -4843,6 +4845,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) current_scope[stmt->str] = stmt; block->children.erase(block->children.begin()); + to_delete.push_back(stmt); continue; } @@ -5038,6 +5041,11 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) delete block; current_scope = backup_scope; + for (auto it : to_delete) { + delete it; + } + to_delete.clear(); + return result; } From b57e47fad8b4ecd5438ee49c618fc8978a4bb058 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 18 Mar 2021 10:38:36 +0100 Subject: [PATCH 0397/2410] verilog: fix wildcard port connections leaking memory --- frontends/verilog/verilog_parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 4e601b51d35..7d750ea28de 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2084,6 +2084,7 @@ cell_port: if (!sv_mode) frontend_verilog_yyerror("Wildcard port connections are only supported in SystemVerilog mode."); astbuf2->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(1, false); + free_attr($1); }; always_comb_or_latch: From c6681508f1a2e35d41e8fc6f1f5dec41972ef6fd Mon Sep 17 00:00:00 2001 From: Xiretza Date: Thu, 18 Mar 2021 21:52:06 +0100 Subject: [PATCH 0398/2410] verilog: fix leaking of type names in parser --- frontends/verilog/verilog_parser.y | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 7d750ea28de..1a76d0dea0b 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -692,6 +692,7 @@ wire_type_token: astbuf3->is_custom_type = true; astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); astbuf3->children.back()->str = *$1; + delete $1; } | TOK_WOR { astbuf3->is_wor = true; @@ -1458,6 +1459,7 @@ param_type: astbuf1->is_custom_type = true; astbuf1->children.push_back(new AstNode(AST_WIRETYPE)); astbuf1->children.back()->str = *$1; + delete $1; }; param_decl: From c0d8da20d58d13ae5bb169ce587f05fbb851a8d0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 16 Jun 2021 11:21:44 +0200 Subject: [PATCH 0399/2410] Support command files in Verific --- frontends/verific/verific.cc | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 97930924807..3e91673ac6b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2084,6 +2084,11 @@ struct VerificPass : public Pass { log("Load the specified VHDL files into Verific.\n"); log("\n"); log("\n"); + log(" verific {-f|-F} \n"); + log("\n"); + log("Load and execute the specified command file.\n"); + log("\n"); + log("\n"); log(" verific [-work ] {-sv|-vhdl|...} \n"); log("\n"); log("Load the specified Verilog/SystemVerilog/VHDL file into the specified library.\n"); @@ -2407,6 +2412,25 @@ struct VerificPass : public Pass { break; } + if (GetSize(args) > argidx && (args[argidx] == "-f" || args[argidx] == "-F")) + { + unsigned verilog_mode = veri_file::VERILOG_95; // default recommended by Verific + + Verific::veri_file::f_file_flags flags = (args[argidx] == "-f") ? veri_file::F_FILE_NONE : veri_file::F_FILE_CAPITAL; + Array *file_names = veri_file::ProcessFFile(args[++argidx].c_str(), flags, verilog_mode); + + veri_file::DefineMacro("VERIFIC"); + + if (!veri_file::AnalyzeMultipleFiles(file_names, verilog_mode, work.c_str(), veri_file::MFCU)) { + verific_error_msg.clear(); + log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); + } + + delete file_names; + verific_import_pending = true; + goto check_error; + } + if (GetSize(args) > argidx && (args[argidx] == "-vlog95" || args[argidx] == "-vlog2k" || args[argidx] == "-sv2005" || args[argidx] == "-sv2009" || args[argidx] == "-sv2012" || args[argidx] == "-sv" || args[argidx] == "-formal")) { @@ -2963,6 +2987,11 @@ struct ReadPass : public Pass { log("Load the specified VHDL files. (Requires Verific.)\n"); log("\n"); log("\n"); + log(" read {-f|-F} \n"); + log("\n"); + log("Load and execute the specified command file. (Requires Verific.)\n"); + log("\n"); + log("\n"); log(" read -define [=]..\n"); log("\n"); log("Set global Verilog/SystemVerilog defines.\n"); @@ -3049,6 +3078,16 @@ struct ReadPass : public Pass { return; } + if (args[1] == "-f" || args[1] == "-F") { + if (use_verific) { + args[0] = "verific"; + Pass::call(design, args); + } else { + cmd_error(args, 1, "This version of Yosys is built without Verific support.\n"); + } + return; + } + if (args[1] == "-define") { if (use_verific) { args[0] = "verific"; From 1d88bea18b5a536935cdef2c5ca77e01b4daf8ac Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 16 Jun 2021 12:34:36 +0100 Subject: [PATCH 0400/2410] pyosys: Clear SIGINT handler after Python loads Signed-off-by: gatecat --- kernel/yosys.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index cb6fdc2f49d..f543447bdb5 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -71,6 +71,7 @@ #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -540,6 +541,7 @@ void yosys_setup() PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); Py_Initialize(); PyRun_SimpleString("import sys"); + signal(SIGINT, SIG_DFL); #endif Pass::init_register(); From 092f0cb01e91b65d5ecc7c8e45f0eefa30b8c205 Mon Sep 17 00:00:00 2001 From: Ashton Snelgrove Date: Wed, 16 Jun 2021 13:47:47 -0600 Subject: [PATCH 0401/2410] Include blif reader header in public facing extension header files. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 07ebed642d4..cce059395bf 100644 --- a/Makefile +++ b/Makefile @@ -608,6 +608,7 @@ $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) $(eval $(call add_include_file,frontends/ast/ast.h)) +$(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd.h)) From f2c2d73f36d7aaef90ded549143d1ee0c4d4a9f5 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 14 Jun 2021 15:32:01 -0400 Subject: [PATCH 0402/2410] sv: fix up end label checking - disallow [gen]blocks with an end label but not begin label - check validity of module end label - fix memory leak of package name and end label - fix memory leak of module end label --- frontends/verilog/verilog_parser.y | 25 +++++++++++++------ tests/simple/matching_end_labels.sv | 29 ++++++++++++++++++++++ tests/verilog/block_end_label_only.ys | 9 +++++++ tests/verilog/block_end_label_wrong.ys | 9 +++++++ tests/verilog/gen_block_end_label_only.ys | 9 +++++++ tests/verilog/gen_block_end_label_wrong.ys | 9 +++++++ tests/verilog/module_end_label.ys | 15 +++++++++++ 7 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 tests/simple/matching_end_labels.sv create mode 100644 tests/verilog/block_end_label_only.ys create mode 100644 tests/verilog/block_end_label_wrong.ys create mode 100644 tests/verilog/gen_block_end_label_only.ys create mode 100644 tests/verilog/gen_block_end_label_wrong.ys create mode 100644 tests/verilog/module_end_label.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 1a76d0dea0b..120a8bca3cc 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -235,6 +235,16 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) node->children.push_back(rangeNode); } +static void checkLabelsMatch(const char *element, const std::string *before, const std::string *after) +{ + if (!before && after) + frontend_verilog_yyerror("%s missing where end label (%s) was given.", + element, after->c_str() + 1); + if (before && after && *before != *after) + frontend_verilog_yyerror("%s (%s) and end label (%s) don't match.", + element, before->c_str() + 1, after->c_str() + 1); +} + %} %define api.prefix {frontend_verilog_yy} @@ -457,7 +467,6 @@ module: port_counter = 0; mod->str = *$4; append_attr(mod, $1); - delete $4; } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE opt_label { if (port_stubs.size() != 0) frontend_verilog_yyerror("Missing details for module port `%s'.", @@ -465,7 +474,10 @@ module: SET_AST_NODE_LOC(ast_stack.back(), @2, @$); ast_stack.pop_back(); log_assert(ast_stack.size() == 1); + checkLabelsMatch("Module name", $4, $11); current_ast_mod = NULL; + delete $4; + delete $11; exitTypeScope(); }; @@ -583,9 +595,10 @@ package: append_attr(mod, $1); } ';' package_body TOK_ENDPACKAGE opt_label { ast_stack.pop_back(); - if ($4 != NULL && $9 != NULL && *$4 != *$9) - frontend_verilog_yyerror("Package name (%s) and end label (%s) don't match.", $4->c_str()+1, $9->c_str()+1); + checkLabelsMatch("Package name", $4, $9); current_ast_mod = NULL; + delete $4; + delete $9; exitTypeScope(); }; @@ -2526,8 +2539,7 @@ behavioral_stmt: node->str = *$4; } behavioral_stmt_list TOK_END opt_label { exitTypeScope(); - if ($4 != NULL && $8 != NULL && *$4 != *$8) - frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1); + checkLabelsMatch("Begin label", $4, $8); AstNode *node = ast_stack.back(); // In SystemVerilog, unnamed blocks with block item declarations // create an implicit hierarchy scope @@ -2863,8 +2875,7 @@ gen_block: ast_stack.push_back(node); } module_gen_body TOK_END opt_label { exitTypeScope(); - if ($3 != NULL && $7 != NULL && *$3 != *$7) - frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1); + checkLabelsMatch("Begin label", $3, $7); delete $3; delete $7; SET_AST_NODE_LOC(ast_stack.back(), @1, @7); diff --git a/tests/simple/matching_end_labels.sv b/tests/simple/matching_end_labels.sv new file mode 100644 index 00000000000..09182ebcf4f --- /dev/null +++ b/tests/simple/matching_end_labels.sv @@ -0,0 +1,29 @@ +module top( + output reg [7:0] + out1, out2, out3, out4 +); + initial begin + begin : blk1 + reg x; + x = 1; + end + out1 = blk1.x; + begin : blk2 + reg x; + x = 2; + end : blk2 + out2 = blk2.x; + end + if (1) begin + if (1) begin : blk3 + reg x; + assign x = 3; + end + assign out3 = blk3.x; + if (1) begin : blk4 + reg x; + assign x = 4; + end : blk4 + assign out4 = blk4.x; + end +endmodule diff --git a/tests/verilog/block_end_label_only.ys b/tests/verilog/block_end_label_only.ys new file mode 100644 index 00000000000..5db1c787947 --- /dev/null +++ b/tests/verilog/block_end_label_only.ys @@ -0,0 +1,9 @@ +logger -expect error "Begin label missing where end label \(incorrect_name\) was given\." 1 +read_verilog -sv < Date: Tue, 26 May 2020 17:46:10 +0100 Subject: [PATCH 0403/2410] Move interface expansion in hierarchy.cc into a helper class There should be no functional change, but this splits up the control flow across functions, using class fields to hold the state that's being tracked. The result should be a bit easier to read. This is part of work to add bind support, but I'm doing some refactoring in the hierarchy pass to make the code a bit easier to work with. The idea is that (eventually) the IFExpander object will hold all the logic for expanding interfaces, and then other code can do bind insertion. --- passes/hierarchy/hierarchy.cc | 289 ++++++++++++++++++++++------------ 1 file changed, 189 insertions(+), 100 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 2ea0d4061d9..dadae04a46d 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -156,6 +156,168 @@ std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { return basicType; } +// A helper struct for expanding a module's interface connections in expand_module +struct IFExpander +{ + IFExpander (RTLIL::Design &design, RTLIL::Module &m) + : module(m), has_interfaces_not_found(false) + { + // Keep track of all derived interfaces available in the current + // module in 'interfaces_in_module': + for (auto cell : module.cells()) { + if(!cell->get_bool_attribute(ID::is_interface)) + continue; + + interfaces_in_module[cell->name] = design.module(cell->type); + } + } + + RTLIL::Module &module; + dict interfaces_in_module; + + bool has_interfaces_not_found; + std::vector connections_to_remove; + std::vector connections_to_add_name; + std::vector connections_to_add_signal; + dict interfaces_to_add_to_submodule; + dict modports_used_in_submodule; + + // Reset the per-cell state + void start_cell() + { + has_interfaces_not_found = false; + connections_to_remove.clear(); + connections_to_add_name.clear(); + connections_to_add_signal.clear(); + interfaces_to_add_to_submodule.clear(); + modports_used_in_submodule.clear(); + } + + // Set has_interfaces_not_found if there are pending interfaces that + // haven't been found yet (and might be found in the future). Print a + // warning if we've already gone over all the cells in the module. + void on_missing_interface(RTLIL::IdString interface_name) + { + // If there are cells that haven't yet been processed, maybe + // we'll find this interface in the future. + if (module.get_bool_attribute(ID::cells_not_processed)) { + has_interfaces_not_found = true; + return; + } + + // Otherwise, we have already gone over all cells in this + // module and the interface has still not been found. Warn + // about it and don't set has_interfaces_not_found (to avoid a + // loop). + log_warning("Could not find interface instance for `%s' in `%s'\n", + log_id(interface_name), log_id(&module)); + } + + // Handle an interface connection from the module + void on_interface(RTLIL::Module &submodule, + RTLIL::IdString conn_name, + const RTLIL::SigSpec &conn_signals) + { + // Check if the connected wire is a potential interface in the parent module + std::string interface_name_str = conn_signals.bits()[0].wire->name.str(); + // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name + interface_name_str.replace(0,23,""); + interface_name_str = "\\" + interface_name_str; + RTLIL::IdString interface_name = interface_name_str; + + // If 'interfaces' in the cell have not be been handled yet, we aren't + // ready to derive the sub-module either + if (!module.get_bool_attribute(ID::interfaces_replaced_in_module)) { + on_missing_interface(interface_name); + return; + } + + // Check if the interface instance is present in module. Interface + // instances may either have the plain name or the name appended with + // '_inst_from_top_dummy'. Check for both of them here + int nexactmatch = interfaces_in_module.count(interface_name) > 0; + std::string interface_name_str2 = interface_name_str + "_inst_from_top_dummy"; + RTLIL::IdString interface_name2 = interface_name_str2; + int nmatch2 = interfaces_in_module.count(interface_name2) > 0; + + // If we can't find either name, this is a missing interface. + if (! (nexactmatch || nmatch2)) { + on_missing_interface(interface_name); + return; + } + + if (nexactmatch != 0) // Choose the one with the plain name if it exists + interface_name2 = interface_name; + + RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2); + + // Go over all wires in interface, and add replacements to lists. + for (auto mod_wire : mod_replace_ports->wires()) { + std::string signal_name1 = conn_name.str() + "." + log_id(mod_wire->name); + std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire); + connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); + if(module.wire(signal_name2) == nullptr) { + log_error("Could not find signal '%s' in '%s'\n", + signal_name2.c_str(), log_id(module.name)); + } + else { + RTLIL::Wire *wire_in_parent = module.wire(signal_name2); + connections_to_add_signal.push_back(wire_in_parent); + } + } + connections_to_remove.push_back(conn_name); + interfaces_to_add_to_submodule[conn_name] = interfaces_in_module.at(interface_name2); + + // Find if the sub-module has set a modport for the current interface + // connection. Add any modports to a dict which will be passed to + // AstModule::derive + string modport_name = submodule.wire(conn_name)->get_string_attribute(ID::interface_modport); + if (!modport_name.empty()) { + modports_used_in_submodule[conn_name] = "\\" + modport_name; + } + } + + // Handle a single connection from the module, making a note to expand + // it if it's an interface connection. + void on_connection(RTLIL::Module &submodule, + RTLIL::IdString conn_name, + const RTLIL::SigSpec &conn_signals) + { + // Check if the connection is present as an interface in the sub-module's port list + const RTLIL::Wire *wire = submodule.wire(conn_name); + if (!wire || !wire->get_bool_attribute(ID::is_interface)) + return; + + // If the connection looks like an interface, handle it. + const auto &bits = conn_signals.bits(); + if (bits.size() == 1 && bits[0].wire->get_bool_attribute(ID::is_interface)) + on_interface(submodule, conn_name, conn_signals); + } + + // Iterate over the connections in a cell, tracking any interface + // connections + void visit_connections(const RTLIL::Cell &cell, + RTLIL::Module &submodule) + { + for (const auto &conn : cell.connections()) { + on_connection(submodule, conn.first, conn.second); + } + } + + // Add/remove connections to the cell as necessary, replacing any SV + // interface port connection with the individual signal connections. + void rewrite_interface_connections(RTLIL::Cell &cell) const + { + for(unsigned int i=0;i &libdirs) { bool did_something = false; @@ -173,23 +335,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } - // Always keep track of all derived interfaces available in the current module in 'interfaces_in_module': - dict interfaces_in_module; - for (auto cell : module->cells()) - { - if(cell->get_bool_attribute(ID::is_interface)) { - RTLIL::Module *intf_module = design->module(cell->type); - interfaces_in_module[cell->name] = intf_module; - } - } + IFExpander if_expander(*design, *module); for (auto cell : module->cells()) { - bool has_interfaces_not_found = false; - - std::vector connections_to_remove; - std::vector connections_to_add_name; - std::vector connections_to_add_signal; + if_expander.start_cell(); if (cell->type.begins_with("$array:")) { int pos[3]; @@ -202,10 +352,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check array_cells[cell] = std::pair(idx, num); cell->type = cell->type.substr(pos_type + 1); } - dict interfaces_to_add_to_submodule; - dict modports_used_in_submodule; - if (design->module(cell->type) == nullptr) + RTLIL::Module *mod = design->module(cell->type); + if (mod == nullptr) { if (design->module("$abstract" + cell->type.str()) != nullptr) { @@ -243,77 +392,15 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check continue; loaded_module: - if (design->module(cell->type) == nullptr) + mod = design->module(cell->type); + if (mod == nullptr) log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); did_something = true; } else { - RTLIL::Module *mod = design->module(cell->type); - - // Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to - // some lists, so that the ports for sub-modules can be replaced further down: - for (auto &conn : cell->connections()) { - if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute(ID::is_interface)) { // Check if the connection is present as an interface in the sub-module's port list - if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute(ID::is_interface)) { // Check if the connected wire is a potential interface in the parent module - std::string interface_name_str = conn.second.bits()[0].wire->name.str(); - interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name - interface_name_str = "\\" + interface_name_str; - RTLIL::IdString interface_name = interface_name_str; - bool not_found_interface = false; - if(module->get_bool_attribute(ID::interfaces_replaced_in_module)) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either - // Check if the interface instance is present in module: - // Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'. - // Check for both of them here - int nexactmatch = interfaces_in_module.count(interface_name) > 0; - std::string interface_name_str2 = interface_name_str + "_inst_from_top_dummy"; - RTLIL::IdString interface_name2 = interface_name_str2; - int nmatch2 = interfaces_in_module.count(interface_name2) > 0; - if (nexactmatch > 0 || nmatch2 > 0) { - if (nexactmatch != 0) // Choose the one with the plain name if it exists - interface_name2 = interface_name; - RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2); - for (auto mod_wire : mod_replace_ports->wires()) { // Go over all wires in interface, and add replacements to lists. - std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire->name); - std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire); - connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); - if(module->wire(signal_name2) == nullptr) { - log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name)); - } - else { - RTLIL::Wire *wire_in_parent = module->wire(signal_name2); - connections_to_add_signal.push_back(wire_in_parent); - } - } - connections_to_remove.push_back(conn.first); - interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name2); - - // Find if the sub-module has set a modport for the current - // interface connection. Add any modports to a dict which will - // be passed to AstModule::derive - string modport_name = mod->wire(conn.first)->get_string_attribute(ID::interface_modport); - if (!modport_name.empty()) { - modports_used_in_submodule[conn.first] = "\\" + modport_name; - } - } - else not_found_interface = true; - } - else not_found_interface = true; - // If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found" - // which will delay the expansion of this cell: - if (not_found_interface) { - // If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error: - if(!(module->get_bool_attribute(ID::cells_not_processed))) { - log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module)); - } - else { - // Only set has_interfaces_not_found if it would be possible to find them, since otherwiser we will end up in an infinite loop: - has_interfaces_not_found = true; - } - } - } - } - } - // + // Go over all connections and check if any of them are SV + // interfaces. + if_expander.visit_connections(*cell, *mod); if (flag_check || flag_simcheck) { @@ -340,9 +427,13 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } - RTLIL::Module *mod = design->module(cell->type); - if (design->module(cell->type)->get_blackbox_attribute()) { + // If we make it out of the if/else block above without leaving + // this iteration, mod will equal design->module(cell->type) and + // will be non-null. + log_assert(mod); + + if (mod->get_blackbox_attribute()) { if (flag_simcheck) log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); @@ -350,23 +441,18 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } // If interface instances not yet found, skip cell for now, and say we did something, so that we will return back here: - if(has_interfaces_not_found) { + if(if_expander.has_interfaces_not_found) { did_something = true; // waiting for interfaces to be handled continue; } - // Do the actual replacements of the SV interface port connection with the individual signal connections: - for(unsigned int i=0;iconnections_[connections_to_add_name[i]] = connections_to_add_signal[i]; - } - // Remove the connection for the interface itself: - for(unsigned int i=0;iconnections_.erase(connections_to_remove[i]); - } + if_expander.rewrite_interface_connections(*cell); // If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type // for the cell: - if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute(ID::module_not_derived)))) { + if (cell->parameters.size() == 0 && + (if_expander.interfaces_to_add_to_submodule.size() == 0 || + !(cell->get_bool_attribute(ID::module_not_derived)))) { // If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:", // so that the signals of the interface are added to the parent module. if (mod->get_bool_attribute(ID::is_interface)) { @@ -375,7 +461,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check continue; } - cell->type = mod->derive(design, cell->parameters, interfaces_to_add_to_submodule, modports_used_in_submodule); + cell->type = mod->derive(design, + cell->parameters, + if_expander.interfaces_to_add_to_submodule, + if_expander.modports_used_in_submodule); cell->parameters.clear(); did_something = true; @@ -386,7 +475,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check if (mod->get_bool_attribute(ID::is_interface) && cell->get_bool_attribute(ID::module_not_derived)) { cell->set_bool_attribute(ID::is_interface); RTLIL::Module *derived_module = design->module(cell->type); - interfaces_in_module[cell->name] = derived_module; + if_expander.interfaces_in_module[cell->name] = derived_module; did_something = true; } // We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell) @@ -399,8 +488,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // If any interface instances or interface ports were found in the module, we need to rederive it completely: - if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) { - module->reprocess_module(design, interfaces_in_module); + if ((if_expander.interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) { + module->reprocess_module(design, if_expander.interfaces_in_module); return did_something; } From 02b4e675495d045308a2af9f2b75bf224e0c7be5 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 19 Jun 2021 02:59:57 +0000 Subject: [PATCH 0404/2410] Fix WASI build after commit 1d88bea1. --- kernel/yosys.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f543447bdb5..39d6a1ec148 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -67,11 +67,11 @@ # define INIT_MODULE initlibyosys extern "C" void INIT_MODULE(); #endif +#include #endif #include #include -#include YOSYS_NAMESPACE_BEGIN From 0dbb05a75e1bb92c194ce6305fee02bf2e5e0470 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 5 Jul 2021 09:16:54 +0200 Subject: [PATCH 0405/2410] Add additional help --- frontends/verific/verific.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 3e91673ac6b..9e99af68063 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2088,6 +2088,27 @@ struct VerificPass : public Pass { log("\n"); log("Load and execute the specified command file.\n"); log("\n"); + log("Command file parser supports following commands:\n"); + log(" +define - defines macro\n"); + log(" -u - upper case all identifier (makes Verilog parser case insensitive)\n"); + log(" -v - register library name (file)\n"); + log(" -y - register library name (directory)\n"); + log(" +incdir - specify include dir\n"); + log(" +libext - specify library extension\n"); + log(" +liborder - add library in ordered list\n"); + log(" +librescan - unresolved modules will be always searched starting with the first\n"); + log(" library specified by -y/-v options.\n"); + log(" -f/-file - nested -f option\n"); + log(" -F - nested -F option\n"); + log("\n"); + log(" parse mode:\n"); + log(" -ams\n"); + log(" +systemverilogext\n"); + log(" +v2k\n"); + log(" +verilog1995ext\n"); + log(" +verilog2001ext\n"); + log(" -sverilog\n"); + log("\n"); log("\n"); log(" verific [-work ] {-sv|-vhdl|...} \n"); log("\n"); @@ -2990,6 +3011,7 @@ struct ReadPass : public Pass { log(" read {-f|-F} \n"); log("\n"); log("Load and execute the specified command file. (Requires Verific.)\n"); + log("Check verific command for more information about supported commands in file.\n"); log("\n"); log("\n"); log(" read -define [=]..\n"); From 18f4ae482cfa82fdb0474c2aa843e2bfe726ba56 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 14 Jun 2021 08:55:22 +0200 Subject: [PATCH 0406/2410] Makefile: clean up PYOSYS configuration --- Makefile | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index cce059395bf..77c4486877e 100644 --- a/Makefile +++ b/Makefile @@ -354,53 +354,29 @@ TARGETS += libyosys.so endif ifeq ($(ENABLE_PYOSYS),1) - -#Detect name of boost_python library. Some distros usbe boost_python-py, other boost_python, some only use the major version number, some a concatenation of major and minor version numbers -ifeq ($(OS), Darwin) +# Detect name of boost_python library. Some distros use boost_python-py, other boost_python, some only use the major version number, some a concatenation of major and minor version numbers +CHECK_BOOST_PYTHON = (echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -l$(1) - > /dev/null 2>&1 && echo "-l$(1)") BOOST_PYTHON_LIB ?= $(shell \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(shell $(PYTHON_CONFIG) --ldflags) -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - echo ""; fi; fi; fi; fi;) -else -BOOST_PYTHON_LIB ?= $(shell \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \ - if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_CONFIG) --libs` -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \ - echo ""; fi; fi; fi; fi;) -endif + $(call CHECK_BOOST_PYTHON,boost_python-py$(subst .,,$(PYTHON_VERSION))) || \ + $(call CHECK_BOOST_PYTHON,boost_python-py$(PYTHON_MAJOR_VERSION)) || \ + $(call CHECK_BOOST_PYTHON,boost_python$(subst .,,$(PYTHON_VERSION))) || \ + $(call CHECK_BOOST_PYTHON,boost_python$(PYTHON_MAJOR_VERSION)) \ +) ifeq ($(BOOST_PYTHON_LIB),) $(error BOOST_PYTHON_LIB could not be detected. Please define manually) endif -ifeq ($(OS), Darwin) -ifeq ($(PYTHON_MAJOR_VERSION),3) -LDLIBS += $(shell $(PYTHON_CONFIG) --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON -else -LDLIBS += $(shell $(PYTHON_CONFIG) --ldflags) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON -endif -else -ifeq ($(PYTHON_MAJOR_VERSION),3) LDLIBS += $(shell $(PYTHON_CONFIG) --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem +# python-config --ldflags includes LDLIBS for some reason +LDFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags)) CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON -else -LDLIBS += $(shell $(PYTHON_CONFIG) --libs) $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON -endif -endif -ifeq ($(ENABLE_PYOSYS),1) PY_WRAPPER_FILE = kernel/python_wrappers OBJS += $(PY_WRAPPER_FILE).o PY_GEN_SCRIPT= py_wrap_generator PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()") -endif -endif +endif # ENABLE_PYOSYS ifeq ($(ENABLE_READLINE),1) CXXFLAGS += -DYOSYS_ENABLE_READLINE From 9c31ecfab8a39513676656699982a3e7860a9ad6 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 14 Jun 2021 11:35:38 +0200 Subject: [PATCH 0407/2410] Makefile: don't bake DESTDIR into libyosys DT_SONAME DESTDIR is only used as a temporary destination for installed files before they are packaged into an archive; the "real" installed location is determined by PREFIX/{BIN,LIB,DAT}DIR. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 77c4486877e..aaf0398cc51 100644 --- a/Makefile +++ b/Makefile @@ -676,9 +676,9 @@ $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) ifeq ($(OS), Darwin) - $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(DESTDIR)$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) + $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) else - $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(DESTDIR)$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) + $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) endif %.o: %.cc From ef68c2762c77ea682aa0ae4dec1d51c5ee06d591 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 14 Jun 2021 12:16:19 +0200 Subject: [PATCH 0408/2410] Makefile: pass PRETTY=0 to ABC --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index aaf0398cc51..28bf12c64cc 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ bumpversion: ABCREV = 4f5f73d ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc -ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 +ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 VERBOSE=$(Q) # set ABCEXTERNAL = to use an external ABC instance # Note: The in-tree ABC (yosys-abc) will not be installed when ABCEXTERNAL is set. From a189284a28d33e383538f9bd0ec3d58bd3cf5cee Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 14 Jun 2021 13:54:47 +0200 Subject: [PATCH 0409/2410] Makefile: use git/make -C instead of cd --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 28bf12c64cc..0311607aa76 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDLIBS += -lrt endif YOSYS_VER := 0.9+4081 -GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) +GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o bumpversion: @@ -726,7 +726,7 @@ ifneq ($(ABCREV),default) $(Q) if test -d abc/.hg; then \ echo 'REEBE: NOP qverpgbel vf n ut jbexvat pbcl! Erzbir nop/ naq er-eha "znxr".' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - $(Q) if ( cd abc 2> /dev/null && ! git diff-index --quiet HEAD; ); then \ + $(Q) if test -d abc && ! git -C abc diff-index --quiet HEAD; then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi # set a variable so the test fails if git fails to run - when comparing outputs directly, empty string would match empty string @@ -738,7 +738,7 @@ ifneq ($(ABCREV),default) fi endif $(Q) rm -f abc/abc-[0-9a-f]* - $(Q) cd abc && $(MAKE) $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc-$(ABCREV)",PROG="abc-$(ABCREV)$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc-$(ABCREV).a) + $(Q) $(MAKE) -C abc $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc-$(ABCREV)",PROG="abc-$(ABCREV)$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc-$(ABCREV).a) ifeq ($(ABCREV),default) .PHONY: abc/abc-$(ABCREV)$(EXE) From 75e5500d4d3a9f37d14e94304bb7b90762ac13e8 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Tue, 16 Mar 2021 16:41:31 +0100 Subject: [PATCH 0410/2410] Makefile: allow running multiple sanitizers at once --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 0311607aa76..d585512a536 100644 --- a/Makefile +++ b/Makefile @@ -193,14 +193,14 @@ ifneq ($(SANITIZER),) $(info [Clang Sanitizer] $(SANITIZER)) CXXFLAGS += -g -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=$(SANITIZER) LDFLAGS += -g -fsanitize=$(SANITIZER) -ifeq ($(SANITIZER),address) +ifneq ($(findstring address,$(SANITIZER)),) ENABLE_COVER := 0 endif -ifeq ($(SANITIZER),memory) +ifneq ($(findstring memory,$(SANITIZER)),) CXXFLAGS += -fPIE -fsanitize-memory-track-origins LDFLAGS += -fPIE -fsanitize-memory-track-origins endif -ifeq ($(SANITIZER),cfi) +ifneq ($(findstring cfi,$(SANITIZER)),) CXXFLAGS += -flto LDFLAGS += -flto endif From 2b8f1633ce7800b4f0315f0206fd0bf9fba5237c Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 6 Jul 2021 11:46:45 +0100 Subject: [PATCH 0411/2410] ecp5: Add DCSC blackbox Signed-off-by: gatecat --- techlibs/ecp5/cells_bb.v | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v index c4cedfe3612..c9a6e52321e 100644 --- a/techlibs/ecp5/cells_bb.v +++ b/techlibs/ecp5/cells_bb.v @@ -369,6 +369,16 @@ module DCCA( ); endmodule +(* blackbox *) +module DCSC( + input CLK1, CLK0, + input SEL1, SEL0, + input MODESEL, + output DCSOUT +); + parameter DCSMODE = "POS"; +endmodule + (* blackbox *) (* keep *) module DCUA( input CH0_HDINP, CH1_HDINP, CH0_HDINN, CH1_HDINN, From 4446cfa524cf06e84add450214f64b2de6e199c3 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 17 Jun 2021 15:59:59 -0400 Subject: [PATCH 0412/2410] sv: fix a few struct and enum memory leaks --- frontends/ast/simplify.cc | 7 +++++++ frontends/verilog/verilog_parser.y | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index f8530642341..695fc429dd2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -331,6 +331,8 @@ static int size_packed_struct(AstNode *snode, int base_offset) } } // range nodes are now redundant + for (AstNode *child : node->children) + delete child; node->children.clear(); } else if (node->children.size() == 1 && node->children[0]->type == AST_MULTIRANGE) { @@ -345,6 +347,8 @@ static int size_packed_struct(AstNode *snode, int base_offset) save_struct_array_width(node, width); width *= array_count; // range nodes are now redundant + for (AstNode *child : node->children) + delete child; node->children.clear(); } else if (node->range_left < 0) { @@ -5052,6 +5056,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) void AstNode::allocateDefaultEnumValues() { log_assert(type==AST_ENUM); + log_assert(children.size() > 0); + if (children.front()->attributes.count(ID::enum_base_type)) + return; // already elaborated int last_enum_int = -1; for (auto node : children) { log_assert(node->type==AST_ENUM_ITEM); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 120a8bca3cc..9558b0e873c 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1711,10 +1711,12 @@ member_type_token: delete astbuf1; astbuf1 = template_node; } - | struct_union { + | { + delete astbuf1; + } struct_union { // stash state on ast_stack ast_stack.push_back(astbuf2); - astbuf2 = $1; + astbuf2 = $2; } struct_body { astbuf1 = astbuf2; // recover state From 7a5ac909858c22f2daf2f7ca63869c554dc3b9b5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 9 Jul 2021 09:02:27 +0200 Subject: [PATCH 0413/2410] Update to latest Verific with extensions for initial assertions --- Makefile | 2 +- frontends/verific/verific.cc | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index d585512a536..42569ecd870 100644 --- a/Makefile +++ b/Makefile @@ -498,7 +498,7 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree +VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree extensions CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC ifeq ($(OS), Darwin) LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)) -lz diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 9e99af68063..997a8e826e4 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -50,15 +50,13 @@ USING_YOSYS_NAMESPACE #include "VhdlUnits.h" #include "VeriLibrary.h" -#if defined(YOSYSHQ_VERIFIC_INITSTATE) || defined(YOSYSHQ_VERIFIC_TEMPLATES) || defined(YOSYSHQ_VERIFIC_FORMALAPPS) -#include "VeriExtensions.h" -#endif +#include "InitialAssertions.h" #ifndef YOSYSHQ_VERIFIC_API_VERSION # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210103 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210602 # error "Please update your version of YosysHQ flavored Verific." #endif @@ -1474,9 +1472,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se continue; } -#ifdef YOSYSHQ_VERIFIC_INITSTATE if (inst->Type() == PRIM_YOSYSHQ_INITSTATE) { + if (verific_verbose) + log(" adding YosysHQ init state\n"); SigBit initstate = module->Initstate(new_verific_id(inst)); SigBit sig_o = net_map_at(inst->GetOutput()); module->connect(sig_o, initstate); @@ -1484,7 +1483,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se if (!mode_keep) continue; } -#endif + if (!mode_keep && verific_sva_prims.count(inst->Type())) { if (verific_verbose) log(" skipping SVA cell in non k-mode\n"); @@ -1962,10 +1961,8 @@ void verific_import(Design *design, const std::map &par for (const auto &i : parameters) verific_params.Insert(i.first.c_str(), i.second.c_str()); -#ifdef YOSYSHQ_VERIFIC_INITSTATE - InitialAssertionRewriter rw; - rw.RegisterCallBack(); -#endif + InitialAssertions::Rewrite("work"); + if (top.empty()) { netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, &verific_params); } @@ -2850,10 +2847,8 @@ struct VerificPass : public Pass { std::set top_mod_names; -#ifdef YOSYSHQ_VERIFIC_INITSTATE - InitialAssertionRewriter rw; - rw.RegisterCallBack(); -#endif + InitialAssertions::Rewrite(work); + if (mode_all) { log("Running hier_tree::ElaborateAll().\n"); From 726fabd65e51c7a15a2a2dc24d3b99426ef43ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 10 Jul 2021 20:46:48 +0200 Subject: [PATCH 0414/2410] ice40: Fix LUT input indices in opt_lut -dlogic (again). Fixes #2061. --- techlibs/ice40/synth_ice40.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 67118752d32..3c84ea42620 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -399,7 +399,7 @@ struct SynthIce40Pass : public ScriptPass run("ice40_wrapcarry -unwrap"); run("techmap -map +/ice40/ff_map.v"); run("clean"); - run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0"); + run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3"); } if (check_label("map_cells")) From 009940f56ca71cc8655a13a514371eb5757b96ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 11 Jul 2021 23:57:53 +0200 Subject: [PATCH 0415/2410] rtlil: Make Process handling more uniform with Cell and Wire. - add a backlink to module from Process - make constructor and destructor protected, expose Module functions to add and remove processes --- frontends/ast/genrtlil.cc | 4 +--- frontends/rtlil/rtlil_parser.y | 4 +--- kernel/rtlil.cc | 32 +++++++++++++++++++++++++++++++- kernel/rtlil.h | 16 ++++++++++++++-- kernel/yosys.h | 3 +++ passes/cmds/bugpoint.cc | 9 ++++----- passes/cmds/delete.cc | 10 ++++------ passes/proc/proc_clean.cc | 9 ++++----- 8 files changed, 62 insertions(+), 25 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6b119b7fff9..e6f7b30c1f2 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -319,16 +319,14 @@ struct AST_INTERNAL::ProcessGenerator LookaheadRewriter la_rewriter(always); // generate process and simple root case - proc = new RTLIL::Process; + proc = current_module->addProcess(stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++)); set_src_attr(proc, always); - proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); proc->attributes[attr.first] = attr.second->asAttrConst(); } - current_module->processes[proc->name] = proc; current_case = &proc->root_case; // create initial temporary signal for all output registers diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 0e6eacf8846..67aeb10e02c 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -283,10 +283,8 @@ proc_stmt: TOK_PROCESS TOK_ID EOL { if (current_module->processes.count($2) != 0) rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of process %s.", $2).c_str()); - current_process = new RTLIL::Process; - current_process->name = $2; + current_process = current_module->addProcess($2); current_process->attributes = attrbuf; - current_module->processes[$2] = current_process; switch_stack.clear(); switch_stack.push_back(¤t_process->root_case.switches); case_stack.clear(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b7bef723ff3..21ee15ac548 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1839,6 +1839,14 @@ void RTLIL::Module::add(RTLIL::Cell *cell) cell->module = this; } +void RTLIL::Module::add(RTLIL::Process *process) +{ + log_assert(!process->name.empty()); + log_assert(count_id(process->name) == 0); + processes[process->name] = process; + process->module = this; +} + void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); @@ -1895,6 +1903,13 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) delete cell; } +void RTLIL::Module::remove(RTLIL::Process *process) +{ + log_assert(processes.count(process->name) != 0); + processes.erase(process->name); + delete process; +} + void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) { log_assert(wires_[wire->name] == wire); @@ -2120,11 +2135,19 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memor return mem; } +RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name) +{ + RTLIL::Process *proc = new RTLIL::Process; + proc->name = name; + add(proc); + return proc; +} + RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other) { RTLIL::Process *proc = other->clone(); proc->name = name; - processes[name] = proc; + add(proc); return proc; } @@ -2920,6 +2943,13 @@ RTLIL::Memory::Memory() #endif } +RTLIL::Process::Process() : module(nullptr) +{ + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; +} + RTLIL::Cell::Cell() : module(nullptr) { static unsigned int hashidx_count = 123456789; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d876d7831e3..dc0d5234b98 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1129,6 +1129,7 @@ struct RTLIL::Module : public RTLIL::AttrObject protected: void add(RTLIL::Wire *wire); void add(RTLIL::Cell *cell); + void add(RTLIL::Process *process); public: RTLIL::Design *design; @@ -1209,6 +1210,7 @@ struct RTLIL::Module : public RTLIL::AttrObject // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const pool &wires); void remove(RTLIL::Cell *cell); + void remove(RTLIL::Process *process); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); void rename(RTLIL::Cell *cell, RTLIL::IdString new_name); @@ -1228,6 +1230,7 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other); + RTLIL::Process *addProcess(RTLIL::IdString name); RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other); // The add* methods create a cell and return the created cell. All signals must exist in advance. @@ -1581,12 +1584,21 @@ struct RTLIL::SyncRule struct RTLIL::Process : public RTLIL::AttrObject { + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + +protected: + // use module->addProcess() and module->remove() to create or destroy processes + friend struct RTLIL::Module; + Process(); + ~Process(); + +public: RTLIL::IdString name; + RTLIL::Module *module; RTLIL::CaseRule root_case; std::vector syncs; - ~Process(); - template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); RTLIL::Process *clone() const; diff --git a/kernel/yosys.h b/kernel/yosys.h index 120311a6f6e..013c3308fd8 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -222,6 +222,7 @@ namespace RTLIL { struct Wire; struct Cell; struct Memory; + struct Process; struct Module; struct Design; struct Monitor; @@ -245,6 +246,7 @@ namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; @@ -253,6 +255,7 @@ namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index c782d9a3858..16ac5b6a7ef 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -275,7 +275,7 @@ struct BugpointPass : public Pass { if (mod->get_blackbox_attribute()) continue; - RTLIL::IdString removed_process; + RTLIL::Process *removed_process = nullptr; for (auto process : mod->processes) { if (process.second->get_bool_attribute(ID::bugpoint_keep)) @@ -284,13 +284,12 @@ struct BugpointPass : public Pass { if (index++ == seed) { log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); - removed_process = process.first; + removed_process = process.second; break; } } - if (!removed_process.empty()) { - delete mod->processes[removed_process]; - mod->processes.erase(removed_process); + if (removed_process) { + mod->remove(removed_process); return design_copy; } } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 48a2179b13e..e341f29d601 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -90,7 +90,7 @@ struct DeletePass : public Pass { pool delete_wires; pool delete_cells; - pool delete_procs; + pool delete_procs; pool delete_mems; for (auto wire : module->selected_wires()) @@ -110,7 +110,7 @@ struct DeletePass : public Pass { for (auto &it : module->processes) if (design->selected(module, it.second)) - delete_procs.insert(it.first); + delete_procs.insert(it.second); for (auto &it : delete_mems) { delete module->memories.at(it); @@ -120,10 +120,8 @@ struct DeletePass : public Pass { for (auto &it : delete_cells) module->remove(it); - for (auto &it : delete_procs) { - delete module->processes.at(it); - module->processes.erase(it); - } + for (auto &it : delete_procs) + module->remove(it); module->remove(delete_wires); diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 76d4cf51b48..45872907bd8 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -209,7 +209,7 @@ struct ProcCleanPass : public Pass { extra_args(args, argidx, design); for (auto mod : design->modules()) { - std::vector delme; + std::vector delme; if (!design->selected(mod)) continue; for (auto &proc_it : mod->processes) { @@ -220,12 +220,11 @@ struct ProcCleanPass : public Pass { proc_it.second->root_case.actions.size() == 0) { if (!quiet) log("Removing empty process `%s.%s'.\n", log_id(mod), proc_it.second->name.c_str()); - delme.push_back(proc_it.first); + delme.push_back(proc_it.second); } } - for (auto &id : delme) { - delete mod->processes[id]; - mod->processes.erase(id); + for (auto proc : delme) { + mod->remove(proc); } } From c86a79bf0b6c58aaf747e5b01de7bef5a3c7db42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 02:11:54 +0200 Subject: [PATCH 0416/2410] kernel/mem: Make the Mem helpers inherit from AttrObject. --- kernel/mem.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kernel/mem.h b/kernel/mem.h index b4a9cb69542..2b92dff8372 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -25,9 +25,8 @@ YOSYS_NAMESPACE_BEGIN -struct MemRd { +struct MemRd : RTLIL::AttrObject { bool removed; - dict attributes; Cell *cell; int wide_log2; bool clk_enable, clk_polarity, ce_over_srst; @@ -46,9 +45,8 @@ struct MemRd { } }; -struct MemWr { +struct MemWr : RTLIL::AttrObject { bool removed; - dict attributes; Cell *cell; int wide_log2; bool clk_enable, clk_polarity; @@ -66,18 +64,16 @@ struct MemWr { } }; -struct MemInit { - dict attributes; +struct MemInit : RTLIL::AttrObject { Cell *cell; Const addr; Const data; MemInit() : cell(nullptr) {} }; -struct Mem { +struct Mem : RTLIL::AttrObject { Module *module; IdString memid; - dict attributes; bool packed; RTLIL::Memory *mem; Cell *cell; From 7f12820b26905521ab149d50f1c1cf4019d5cf2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 06:26:13 +0200 Subject: [PATCH 0417/2410] kernel/mem: Commit new values of attributes in emit. --- kernel/mem.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index 82942d9be86..8d77c36431e 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -210,6 +210,7 @@ void Mem::emit() { mem->width = width; mem->start_offset = start_offset; mem->size = size; + mem->attributes = attributes; for (auto &port : rd_ports) { // TODO: remove log_assert(port.arst == State::S0); @@ -217,6 +218,7 @@ void Mem::emit() { log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memrd)); + port.cell->attributes = port.attributes; port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); port.cell->parameters[ID::WIDTH] = width << port.wide_log2; @@ -232,6 +234,7 @@ void Mem::emit() { for (auto &port : wr_ports) { if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memwr)); + port.cell->attributes = port.attributes; port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); port.cell->parameters[ID::WIDTH] = width << port.wide_log2; @@ -247,6 +250,7 @@ void Mem::emit() { for (auto &init : inits) { if (!init.cell) init.cell = module->addCell(NEW_ID, ID($meminit)); + init.cell->attributes = init.attributes; init.cell->parameters[ID::MEMID] = memid.str(); init.cell->parameters[ID::ABITS] = GetSize(init.addr); init.cell->parameters[ID::WIDTH] = width; From d5c9595668c33b72a59644b56693ef781733adb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 10 Jul 2021 03:55:51 +0200 Subject: [PATCH 0418/2410] cxxrtl: Convert to Mem helpers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This *only* does conversion, but doesn't add any new functionality — support for memory read port init/reset is still upcoming. --- backends/cxxrtl/cxxrtl_backend.cc | 482 +++++++++++++++++------------- 1 file changed, 276 insertions(+), 206 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 0071bda7f65..e6941fda1b9 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -216,7 +216,7 @@ bool is_internal_cell(RTLIL::IdString type) bool is_effectful_cell(RTLIL::IdString type) { - return type == ID($memwr) || type.isPublic(); + return type.isPublic(); } bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) @@ -274,12 +274,16 @@ struct FlowGraph { CELL_EVAL, PROCESS_SYNC, PROCESS_CASE, + MEM_RDPORT, + MEM_WRPORTS, }; Type type; RTLIL::SigSig connect = {}; - const RTLIL::Cell *cell = NULL; - const RTLIL::Process *process = NULL; + const RTLIL::Cell *cell = nullptr; + const RTLIL::Process *process = nullptr; + const Mem *mem = nullptr; + int portidx; }; std::vector nodes; @@ -414,7 +418,7 @@ struct FlowGraph { if (cell->output(conn.first)) { if (is_inlinable_cell(cell->type)) add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/true); - else if (is_ff_cell(cell->type) || (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool())) + else if (is_ff_cell(cell->type)) add_defs(node, conn.second, /*is_ff=*/true, /*inlinable=*/false); else if (is_internal_cell(cell->type)) add_defs(node, conn.second, /*is_ff=*/false, /*inlinable=*/false); @@ -502,6 +506,49 @@ struct FlowGraph { add_case_rule_defs_uses(node, &process->root_case); return node; } + + // Memories + void add_node(const Mem *mem) { + for (int i = 0; i < GetSize(mem->rd_ports); i++) { + auto &port = mem->rd_ports[i]; + Node *node = new Node; + node->type = Node::Type::MEM_RDPORT; + node->mem = mem; + node->portidx = i; + nodes.push_back(node); + add_defs(node, port.data, /*is_ff=*/port.clk_enable, /*inlinable=*/false); + add_uses(node, port.clk); + add_uses(node, port.en); + add_uses(node, port.arst); + add_uses(node, port.srst); + add_uses(node, port.addr); + if (port.transparent && port.clk_enable) { + // Our implementation of transparent read ports reads en, addr and data from every write port + // in the same domain. + for (auto &wrport : mem->wr_ports) { + if (wrport.clk_enable && wrport.clk == port.clk && wrport.clk_polarity == port.clk_polarity) { + add_uses(node, wrport.en); + add_uses(node, wrport.addr); + add_uses(node, wrport.data); + } + } + // Also we read the address twice in this case (prevent inlining). + add_uses(node, port.addr); + } + } + if (!mem->wr_ports.empty()) { + Node *node = new Node; + node->type = Node::Type::MEM_WRPORTS; + node->mem = mem; + nodes.push_back(node); + for (auto &port : mem->wr_ports) { + add_uses(node, port.clk); + add_uses(node, port.en); + add_uses(node, port.addr); + add_uses(node, port.data); + } + } + } }; std::vector split_by(const std::string &str, const std::string &sep) @@ -637,10 +684,9 @@ struct CxxrtlWorker { int temporary = 0; dict sigmaps; + dict> mod_memories; pool edge_wires; dict edge_types; - pool writable_memories; - dict> transparent_for; dict> schedule, debug_schedule; dict wire_types, debug_wire_types; dict bit_has_state; @@ -724,9 +770,9 @@ struct CxxrtlWorker { return mangle_module_name(module->name, /*is_blackbox=*/module->get_bool_attribute(ID(cxxrtl_blackbox))); } - std::string mangle(const RTLIL::Memory *memory) + std::string mangle(const Mem *mem) { - return mangle_memory_name(memory->name); + return mangle_memory_name(mem->memid); } std::string mangle(const RTLIL::Cell *cell) @@ -1216,114 +1262,6 @@ struct CxxrtlWorker { dump_sigspec_rhs(cell->getPort(ID::CLR)); f << (cell->getParam(ID::CLR_POLARITY).as_bool() ? "" : ".bit_not()") << ");\n"; } - // Memory ports - } else if (cell->type.in(ID($memrd), ID($memwr))) { - if (cell->getParam(ID::CLK_ENABLE).as_bool()) { - log_assert(!for_debug); - RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; - clk_bit = sigmaps[clk_bit.wire->module](clk_bit); - if (clk_bit.wire) { - f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") - << mangle(clk_bit) << ") {\n"; - } else { - f << indent << "if (false) {\n"; - } - inc_indent(); - } - RTLIL::Memory *memory = cell->module->memories[cell->getParam(ID::MEMID).decode_string()]; - std::string valid_index_temp = fresh_temporary(); - f << indent << "auto " << valid_index_temp << " = memory_index("; - // Almost all non-elidable cells cannot appear in debug_eval(), but $memrd is an exception; asynchronous - // memory read ports can. - dump_sigspec_rhs(cell->getPort(ID::ADDR), for_debug); - f << ", " << memory->start_offset << ", " << memory->size << ");\n"; - if (cell->type == ID($memrd)) { - bool has_enable = cell->getParam(ID::CLK_ENABLE).as_bool() && !cell->getPort(ID::EN).is_fully_ones(); - if (has_enable) { - f << indent << "if ("; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ") {\n"; - inc_indent(); - } - // The generated code has two bounds checks; one in an assertion, and another that guards the read. - // This is done so that the code does not invoke undefined behavior under any conditions, but nevertheless - // loudly crashes if an illegal condition is encountered. The assert may be turned off with -DCXXRTL_NDEBUG - // not only for release builds, but also to make sure the simulator (which is presumably embedded in some - // larger program) will never crash the code that calls into it. - // - // If assertions are disabled, out of bounds reads are defined to return zero. - f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds read\");\n"; - f << indent << "if(" << valid_index_temp << ".valid) {\n"; - inc_indent(); - if (writable_memories[memory]) { - std::string lhs_temp = fresh_temporary(); - f << indent << "value<" << memory->width << "> " << lhs_temp << " = " - << mangle(memory) << "[" << valid_index_temp << ".index];\n"; - std::vector memwr_cells(transparent_for[cell].begin(), transparent_for[cell].end()); - if (!memwr_cells.empty()) { - std::string addr_temp = fresh_temporary(); - f << indent << "const value<" << cell->getPort(ID::ADDR).size() << "> &" << addr_temp << " = "; - dump_sigspec_rhs(cell->getPort(ID::ADDR)); - f << ";\n"; - std::sort(memwr_cells.begin(), memwr_cells.end(), - [](const RTLIL::Cell *a, const RTLIL::Cell *b) { - return a->getParam(ID::PRIORITY).as_int() < b->getParam(ID::PRIORITY).as_int(); - }); - for (auto memwr_cell : memwr_cells) { - f << indent << "if (" << addr_temp << " == "; - dump_sigspec_rhs(memwr_cell->getPort(ID::ADDR)); - f << ") {\n"; - inc_indent(); - f << indent << lhs_temp << " = " << lhs_temp; - f << ".update("; - dump_sigspec_rhs(memwr_cell->getPort(ID::DATA)); - f << ", "; - dump_sigspec_rhs(memwr_cell->getPort(ID::EN)); - f << ");\n"; - dec_indent(); - f << indent << "}\n"; - } - } - f << indent; - dump_sigspec_lhs(cell->getPort(ID::DATA)); - f << " = " << lhs_temp << ";\n"; - } else { - f << indent; - dump_sigspec_lhs(cell->getPort(ID::DATA)); - f << " = " << mangle(memory) << "[" << valid_index_temp << ".index];\n"; - } - dec_indent(); - f << indent << "} else {\n"; - inc_indent(); - f << indent; - dump_sigspec_lhs(cell->getPort(ID::DATA)); - f << " = value<" << memory->width << "> {};\n"; - dec_indent(); - f << indent << "}\n"; - if (has_enable) { - dec_indent(); - f << indent << "}\n"; - } - } else /*if (cell->type == ID($memwr))*/ { - log_assert(writable_memories[memory]); - // See above for rationale of having both the assert and the condition. - // - // If assertions are disabled, out of bounds writes are defined to do nothing. - f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds write\");\n"; - f << indent << "if (" << valid_index_temp << ".valid) {\n"; - inc_indent(); - f << indent << mangle(memory) << ".update(" << valid_index_temp << ".index, "; - dump_sigspec_rhs(cell->getPort(ID::DATA)); - f << ", "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ", " << cell->getParam(ID::PRIORITY).as_int() << ");\n"; - dec_indent(); - f << indent << "}\n"; - } - if (cell->getParam(ID::CLK_ENABLE).as_bool()) { - dec_indent(); - f << indent << "}\n"; - } // Internal cells } else if (is_internal_cell(cell->type)) { log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str()); @@ -1567,6 +1505,161 @@ struct CxxrtlWorker { } } + void dump_mem_rdport(const Mem *mem, int portidx, bool for_debug = false) + { + auto &port = mem->rd_ports[portidx]; + dump_attrs(&port); + f << indent << "// memory " << mem->memid.str() << " read port " << portidx << "\n"; + if (port.clk_enable) { + log_assert(!for_debug); + RTLIL::SigBit clk_bit = port.clk[0]; + clk_bit = sigmaps[clk_bit.wire->module](clk_bit); + if (clk_bit.wire) { + f << indent << "if (" << (port.clk_polarity ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } + inc_indent(); + } + std::vector inlined_cells_addr; + collect_sigspec_rhs(port.addr, for_debug, inlined_cells_addr); + if (!inlined_cells_addr.empty()) + dump_inlined_cells(inlined_cells_addr); + std::string valid_index_temp = fresh_temporary(); + f << indent << "auto " << valid_index_temp << " = memory_index("; + // Almost all non-elidable cells cannot appear in debug_eval(), but $memrd is an exception; asynchronous + // memory read ports can. + dump_sigspec_rhs(port.addr, for_debug); + f << ", " << mem->start_offset << ", " << mem->size << ");\n"; + bool has_enable = port.clk_enable && !port.en.is_fully_ones(); + if (has_enable) { + std::vector inlined_cells_en; + collect_sigspec_rhs(port.en, for_debug, inlined_cells_en); + if (!inlined_cells_en.empty()) + dump_inlined_cells(inlined_cells_en); + f << indent << "if ("; + dump_sigspec_rhs(port.en); + f << ") {\n"; + inc_indent(); + } + // The generated code has two bounds checks; one in an assertion, and another that guards the read. + // This is done so that the code does not invoke undefined behavior under any conditions, but nevertheless + // loudly crashes if an illegal condition is encountered. The assert may be turned off with -DCXXRTL_NDEBUG + // not only for release builds, but also to make sure the simulator (which is presumably embedded in some + // larger program) will never crash the code that calls into it. + // + // If assertions are disabled, out of bounds reads are defined to return zero. + f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds read\");\n"; + f << indent << "if(" << valid_index_temp << ".valid) {\n"; + inc_indent(); + if (!mem->wr_ports.empty()) { + std::string lhs_temp = fresh_temporary(); + f << indent << "value<" << mem->width << "> " << lhs_temp << " = " + << mangle(mem) << "[" << valid_index_temp << ".index];\n"; + if (port.transparent && port.clk_enable) { + std::string addr_temp = fresh_temporary(); + f << indent << "const value<" << port.addr.size() << "> &" << addr_temp << " = "; + dump_sigspec_rhs(port.addr); + f << ";\n"; + for (auto &wrport : mem->wr_ports) { + if (!wrport.clk_enable) + continue; + if (wrport.clk != port.clk) + continue; + if (wrport.clk_polarity != port.clk_polarity) + continue; + f << indent << "if (" << addr_temp << " == "; + dump_sigspec_rhs(wrport.addr); + f << ") {\n"; + inc_indent(); + f << indent << lhs_temp << " = " << lhs_temp; + f << ".update("; + dump_sigspec_rhs(wrport.data); + f << ", "; + dump_sigspec_rhs(wrport.en); + f << ");\n"; + dec_indent(); + f << indent << "}\n"; + } + } + f << indent; + dump_sigspec_lhs(port.data); + f << " = " << lhs_temp << ";\n"; + } else { + f << indent; + dump_sigspec_lhs(port.data); + f << " = " << mangle(mem) << "[" << valid_index_temp << ".index];\n"; + } + dec_indent(); + f << indent << "} else {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(port.data); + f << " = value<" << mem->width << "> {};\n"; + dec_indent(); + f << indent << "}\n"; + if (has_enable) { + dec_indent(); + f << indent << "}\n"; + } + if (port.clk_enable) { + dec_indent(); + f << indent << "}\n"; + } + } + + void dump_mem_wrports(const Mem *mem, bool for_debug = false) + { + log_assert(!for_debug); + for (int portidx = 0; portidx < GetSize(mem->wr_ports); portidx++) { + auto &port = mem->wr_ports[portidx]; + dump_attrs(&port); + f << indent << "// memory " << mem->memid.str() << " write port " << portidx << "\n"; + if (port.clk_enable) { + RTLIL::SigBit clk_bit = port.clk[0]; + clk_bit = sigmaps[clk_bit.wire->module](clk_bit); + if (clk_bit.wire) { + f << indent << "if (" << (port.clk_polarity ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } + inc_indent(); + } + std::vector inlined_cells_addr; + collect_sigspec_rhs(port.addr, for_debug, inlined_cells_addr); + if (!inlined_cells_addr.empty()) + dump_inlined_cells(inlined_cells_addr); + std::string valid_index_temp = fresh_temporary(); + f << indent << "auto " << valid_index_temp << " = memory_index("; + dump_sigspec_rhs(port.addr); + f << ", " << mem->start_offset << ", " << mem->size << ");\n"; + // See above for rationale of having both the assert and the condition. + // + // If assertions are disabled, out of bounds writes are defined to do nothing. + f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds write\");\n"; + f << indent << "if (" << valid_index_temp << ".valid) {\n"; + inc_indent(); + std::vector inlined_cells; + collect_sigspec_rhs(port.data, for_debug, inlined_cells); + collect_sigspec_rhs(port.en, for_debug, inlined_cells); + if (!inlined_cells.empty()) + dump_inlined_cells(inlined_cells); + f << indent << mangle(mem) << ".update(" << valid_index_temp << ".index, "; + dump_sigspec_rhs(port.data); + f << ", "; + dump_sigspec_rhs(port.en); + f << ", " << portidx << ");\n"; + dec_indent(); + f << indent << "}\n"; + if (port.clk_enable) { + dec_indent(); + f << indent << "}\n"; + } + } + } + void dump_wire(const RTLIL::Wire *wire, bool is_local) { const auto &wire_type = wire_types[wire]; @@ -1650,41 +1743,28 @@ struct CxxrtlWorker { f << "value<" << wire->width << "> " << mangle(wire) << ";\n"; } - void dump_memory(RTLIL::Module *module, const RTLIL::Memory *memory) + void dump_memory(Mem *mem) { - vector init_cells; - for (auto cell : module->cells()) - if (cell->type == ID($meminit) && cell->getParam(ID::MEMID).decode_string() == memory->name.str()) - init_cells.push_back(cell); - - std::sort(init_cells.begin(), init_cells.end(), [](const RTLIL::Cell *a, const RTLIL::Cell *b) { - int a_addr = a->getPort(ID::ADDR).as_int(), b_addr = b->getPort(ID::ADDR).as_int(); - int a_prio = a->getParam(ID::PRIORITY).as_int(), b_prio = b->getParam(ID::PRIORITY).as_int(); - return a_prio > b_prio || (a_prio == b_prio && a_addr < b_addr); - }); - - dump_attrs(memory); - f << indent << "memory<" << memory->width << "> " << mangle(memory) - << " { " << memory->size << "u"; - if (init_cells.empty()) { + dump_attrs(mem); + f << indent << "memory<" << mem->width << "> " << mangle(mem) + << " { " << mem->size << "u"; + if (!GetSize(mem->inits)) { f << " };\n"; } else { f << ",\n"; inc_indent(); - for (auto cell : init_cells) { - dump_attrs(cell); - RTLIL::Const data = cell->getPort(ID::DATA).as_const(); - size_t width = cell->getParam(ID::WIDTH).as_int(); - size_t words = cell->getParam(ID::WORDS).as_int(); - f << indent << "memory<" << memory->width << ">::init<" << words << "> { " - << stringf("%#x", cell->getPort(ID::ADDR).as_int()) << ", {"; + for (auto &init : mem->inits) { + dump_attrs(&init); + int words = GetSize(init.data) / mem->width; + f << indent << "memory<" << mem->width << ">::init<" << words << "> { " + << stringf("%#x", init.addr.as_int()) << ", {"; inc_indent(); - for (size_t n = 0; n < words; n++) { + for (int n = 0; n < words; n++) { if (n % 4 == 0) f << "\n" << indent; else f << " "; - dump_const(data, width, n * width, /*fixed_width=*/true); + dump_const(init.data, mem->width, n * mem->width, /*fixed_width=*/true); f << ","; } dec_indent(); @@ -1735,6 +1815,12 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::PROCESS_SYNC: dump_process_syncs(node.process); break; + case FlowGraph::Node::Type::MEM_RDPORT: + dump_mem_rdport(node.mem, node.portidx); + break; + case FlowGraph::Node::Type::MEM_WRPORTS: + dump_mem_wrports(node.mem); + break; } } } @@ -1764,6 +1850,12 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::PROCESS_SYNC: dump_process_syncs(node.process, /*for_debug=*/true); break; + case FlowGraph::Node::Type::MEM_RDPORT: + dump_mem_rdport(node.mem, node.portidx, /*for_debug=*/true); + break; + case FlowGraph::Node::Type::MEM_WRPORTS: + dump_mem_wrports(node.mem, /*for_debug=*/true); + break; default: log_abort(); } @@ -1783,10 +1875,10 @@ struct CxxrtlWorker { f << indent << "if (" << mangle(wire) << ".commit()) changed = true;\n"; } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { - for (auto memory : module->memories) { - if (!writable_memories[memory.second]) + for (auto &mem : mod_memories[module]) { + if (!GetSize(mem.wr_ports)) continue; - f << indent << "if (" << mangle(memory.second) << ".commit()) changed = true;\n"; + f << indent << "if (" << mangle(&mem) << ".commit()) changed = true;\n"; } for (auto cell : module->cells()) { if (is_internal_cell(cell->type)) @@ -1928,12 +2020,12 @@ struct CxxrtlWorker { } } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { - for (auto &memory_it : module->memories) { - if (!memory_it.first.isPublic()) + for (auto &mem : mod_memories[module]) { + if (!mem.memid.isPublic()) continue; - f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(memory_it.second)); - f << ", debug_item(" << mangle(memory_it.second) << ", "; - f << memory_it.second->start_offset << "));\n"; + f << indent << "items.add(path + " << escape_cxx_string(mem.packed ? get_hdl_name(mem.cell) : get_hdl_name(mem.mem)); + f << ", debug_item(" << mangle(&mem) << ", "; + f << mem.start_offset << "));\n"; } for (auto cell : module->cells()) { if (is_internal_cell(cell->type)) @@ -2048,8 +2140,8 @@ struct CxxrtlWorker { for (auto wire : module->wires()) dump_debug_wire(wire, /*is_local=*/false); bool has_memories = false; - for (auto memory : module->memories) { - dump_memory(module, memory.second); + for (auto &mem : mod_memories[module]) { + dump_memory(&mem); has_memories = true; } if (has_memories) @@ -2313,6 +2405,11 @@ struct CxxrtlWorker { SigMap &sigmap = sigmaps[module]; sigmap.set(module); + std::vector &memories = mod_memories[module]; + memories = Mem::get_all_memories(module); + for (auto &mem : memories) + mem.narrow(); + if (module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto port : module->ports) { RTLIL::Wire *wire = module->wire(port); @@ -2357,13 +2454,13 @@ struct CxxrtlWorker { for (auto conn : module->connections()) flow.add_node(conn); - dict memrw_cell_nodes; - dict, - pool> memwr_per_domain; for (auto cell : module->cells()) { if (!cell->known()) log_cmd_error("Unknown cell `%s'.\n", log_id(cell->type)); + if (cell->is_mem_cell()) + continue; + RTLIL::Module *cell_module = design->module(cell->type); if (cell_module && cell_module->get_blackbox_attribute() && @@ -2375,7 +2472,7 @@ struct CxxrtlWorker { cell_module->get_bool_attribute(ID(cxxrtl_template))) blackbox_specializations[cell_module].insert(template_args(cell)); - FlowGraph::Node *node = flow.add_node(cell); + flow.add_node(cell); // Various DFF cells are treated like posedge/negedge processes, see above for details. if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { @@ -2383,43 +2480,23 @@ struct CxxrtlWorker { register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } - // Similar for memory port cells. - if (cell->type.in(ID($memrd), ID($memwr))) { - if (cell->getParam(ID::CLK_ENABLE).as_bool()) { - if (is_valid_clock(cell->getPort(ID::CLK))) - register_edge_signal(sigmap, cell->getPort(ID::CLK), - cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); - } - memrw_cell_nodes[cell] = node; - } - // Optimize access to read-only memories. - if (cell->type == ID($memwr)) - writable_memories.insert(module->memories[cell->getParam(ID::MEMID).decode_string()]); - // Collect groups of memory write ports in the same domain. - if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK))) { - RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; - const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; - memwr_per_domain[{clk_bit, memory}].insert(cell); - } - // Handling of packed memories is delegated to the `memory_unpack` pass, so we can rely on the presence - // of RTLIL memory objects and $memrd/$memwr/$meminit cells. - if (cell->type.in(ID($mem))) - log_assert(false); } - for (auto cell : module->cells()) { - // Collect groups of memory write ports read by every transparent read port. - if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK)) && - cell->getParam(ID::TRANSPARENT).as_bool()) { - RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0]; - const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()]; - for (auto memwr_cell : memwr_per_domain[{clk_bit, memory}]) { - transparent_for[cell].insert(memwr_cell); - // Our implementation of transparent $memrd cells reads \EN, \ADDR and \DATA from every $memwr cell - // in the same domain, which isn't directly visible in the netlist. Add these uses explicitly. - flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID::EN)); - flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID::ADDR)); - flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID::DATA)); - } + + for (auto &mem : memories) { + flow.add_node(&mem); + + // Clocked memory cells are treated like posedge/negedge processes as well. + for (auto &port : mem.rd_ports) { + if (port.clk_enable) + if (is_valid_clock(port.clk)) + register_edge_signal(sigmap, port.clk, + port.clk_polarity ? RTLIL::STp : RTLIL::STn); + } + for (auto &port : mem.wr_ports) { + if (port.clk_enable) + if (is_valid_clock(port.clk)) + register_edge_signal(sigmap, port.clk, + port.clk_polarity ? RTLIL::STp : RTLIL::STn); } } @@ -2518,6 +2595,8 @@ struct CxxrtlWorker { for (auto node : flow.nodes) { if (node->type == FlowGraph::Node::Type::CELL_EVAL && is_effectful_cell(node->cell->type)) worklist.insert(node); // node has effects + else if (node->type == FlowGraph::Node::Type::MEM_WRPORTS) + worklist.insert(node); // node is memory write else if (flow.node_sync_defs.count(node)) worklist.insert(node); // node is a flip-flop else if (flow.node_comb_defs.count(node)) { @@ -2747,9 +2826,9 @@ struct CxxrtlWorker { } } - void check_design(RTLIL::Design *design, bool &has_top, bool &has_sync_init, bool &has_packed_mem) + void check_design(RTLIL::Design *design, bool &has_top, bool &has_sync_init) { - has_sync_init = has_packed_mem = has_top = false; + has_sync_init = has_top = false; for (auto module : design->modules()) { if (module->get_blackbox_attribute() && !module->has_attribute(ID(cxxrtl_blackbox))) @@ -2768,20 +2847,15 @@ struct CxxrtlWorker { for (auto sync : proc.second->syncs) if (sync->type == RTLIL::STi) has_sync_init = true; - - // The Mem constructor also checks for well-formedness of $meminit cells, if any. - for (auto &mem : Mem::get_all_memories(module)) - if (mem.packed) - has_packed_mem = true; } } void prepare_design(RTLIL::Design *design) { bool did_anything = false; - bool has_top, has_sync_init, has_packed_mem; + bool has_top, has_sync_init; log_push(); - check_design(design, has_top, has_sync_init, has_packed_mem); + check_design(design, has_top, has_sync_init); if (run_hierarchy && !has_top) { Pass::call(design, "hierarchy -auto-top"); did_anything = true; @@ -2801,14 +2875,10 @@ struct CxxrtlWorker { Pass::call(design, "proc_init"); did_anything = true; } - if (has_packed_mem) { - Pass::call(design, "memory_unpack"); - did_anything = true; - } // Recheck the design if it was modified. if (did_anything) - check_design(design, has_top, has_sync_init, has_packed_mem); - log_assert(!has_sync_init && !has_packed_mem); + check_design(design, has_top, has_sync_init); + log_assert(!has_sync_init); log_pop(); if (did_anything) log_spacer(); From be5cf296997a203cdf195d7355426fa4cd187b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 10 Jul 2021 14:33:16 +0200 Subject: [PATCH 0419/2410] cxxrtl: Add support for mem read port initial data. --- backends/cxxrtl/cxxrtl_backend.cc | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index e6941fda1b9..b312878c341 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -686,6 +686,7 @@ struct CxxrtlWorker { dict sigmaps; dict> mod_memories; pool edge_wires; + dict wire_init; dict edge_types; dict> schedule, debug_schedule; dict wire_types, debug_wire_types; @@ -1681,17 +1682,17 @@ struct CxxrtlWorker { f << "<" << wire->width << ">"; } f << " " << mangle(wire); - if (wire->has_attribute(ID::init)) { + if (wire_init.count(wire)) { f << " "; - dump_const_init(wire->attributes.at(ID::init)); + dump_const_init(wire_init.at(wire)); } f << ";\n"; if (edge_wires[wire]) { if (!wire_type.is_buffered()) { f << indent << "value<" << wire->width << "> prev_" << mangle(wire); - if (wire->has_attribute(ID::init)) { + if (wire_init.count(wire)) { f << " "; - dump_const_init(wire->attributes.at(ID::init)); + dump_const_init(wire_init.at(wire)); } f << ";\n"; } @@ -2447,6 +2448,10 @@ struct CxxrtlWorker { continue; } + for (auto wire : module->wires()) + if (wire->has_attribute(ID::init)) + wire_init[wire] = wire->attributes.at(ID::init); + // Construct a flow graph where each node is a basic computational operation generally corresponding // to a fragment of the RTLIL netlist. FlowGraph flow; @@ -2491,6 +2496,19 @@ struct CxxrtlWorker { if (is_valid_clock(port.clk)) register_edge_signal(sigmap, port.clk, port.clk_polarity ? RTLIL::STp : RTLIL::STn); + // For read ports, also move initial value to wire_init (if any). + for (int i = 0; i < GetSize(port.data); i++) { + if (port.init_value[i] != State::Sx) { + SigBit bit = port.data[i]; + if (bit.wire) { + auto &init = wire_init[bit.wire]; + if (init == RTLIL::Const()) { + init = RTLIL::Const(State::Sx, GetSize(bit.wire)); + } + init[bit.offset] = port.init_value[i]; + } + } + } } for (auto &port : mem.wr_ports) { if (port.clk_enable) From af7fa62251b101266bf8419ab69e510fe5bc7e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 10 Jul 2021 23:47:01 +0200 Subject: [PATCH 0420/2410] cxxrtl: Add support for memory read port reset. --- backends/cxxrtl/cxxrtl_backend.cc | 42 ++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index b312878c341..2c93c8ad551 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1600,7 +1600,29 @@ struct CxxrtlWorker { f << " = value<" << mem->width << "> {};\n"; dec_indent(); f << indent << "}\n"; - if (has_enable) { + if (has_enable && !port.ce_over_srst) { + dec_indent(); + f << indent << "}\n"; + } + if (port.srst != State::S0) { + // Synchronous reset + std::vector inlined_cells_srst; + collect_sigspec_rhs(port.srst, for_debug, inlined_cells_srst); + if (!inlined_cells_srst.empty()) + dump_inlined_cells(inlined_cells_srst); + f << indent << "if ("; + dump_sigspec_rhs(port.srst); + f << " == value<1> {1u}) {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(port.data); + f << " = "; + dump_const(port.srst_value); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } + if (has_enable && port.ce_over_srst) { dec_indent(); f << indent << "}\n"; } @@ -1608,6 +1630,24 @@ struct CxxrtlWorker { dec_indent(); f << indent << "}\n"; } + if (port.arst != State::S0) { + // Asynchronous reset + std::vector inlined_cells_arst; + collect_sigspec_rhs(port.arst, for_debug, inlined_cells_arst); + if (!inlined_cells_arst.empty()) + dump_inlined_cells(inlined_cells_arst); + f << indent << "if ("; + dump_sigspec_rhs(port.arst); + f << " == value<1> {1u}) {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(port.data); + f << " = "; + dump_const(port.arst_value); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } } void dump_mem_wrports(const Mem *mem, bool for_debug = false) From 37506d737cb651cd7da56e4d298df4c6f0eb616d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 01:00:57 +0200 Subject: [PATCH 0421/2410] cxxrtl: Support memory writes in processes. --- backends/cxxrtl/cxxrtl_backend.cc | 61 ++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 2c93c8ad551..ddb954073e6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -226,6 +226,14 @@ bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) return cell_module->get_bool_attribute(ID(cxxrtl_blackbox)); } +bool is_memwr_process(const RTLIL::Process *process) +{ + for (auto sync : process->syncs) + if (!sync->mem_write_actions.empty()) + return true; + return false; +} + enum class CxxrtlPortType { UNKNOWN = 0, // or mixed comb/sync COMB = 1, @@ -481,14 +489,20 @@ struct FlowGraph { void add_sync_rules_defs_uses(Node *node, const RTLIL::Process *process) { - for (auto sync : process->syncs) - for (auto action : sync->actions) { + for (auto sync : process->syncs) { + for (auto &action : sync->actions) { if (sync->type == RTLIL::STp || sync->type == RTLIL::STn || sync->type == RTLIL::STe) - add_defs(node, action.first, /*is_ff=*/true, /*inlinable=*/false); + add_defs(node, action.first, /*is_ff=*/true, /*inlinable=*/false); else add_defs(node, action.first, /*is_ff=*/false, /*inlinable=*/false); add_uses(node, action.second); } + for (auto &memwr : sync->mem_write_actions) { + add_uses(node, memwr.address); + add_uses(node, memwr.data); + add_uses(node, memwr.enable); + } + } } Node *add_node(const RTLIL::Process *process) @@ -685,6 +699,7 @@ struct CxxrtlWorker { dict sigmaps; dict> mod_memories; + pool> writable_memories; pool edge_wires; dict wire_init; dict edge_types; @@ -776,6 +791,11 @@ struct CxxrtlWorker { return mangle_memory_name(mem->memid); } + std::string mangle(const RTLIL::Memory *memory) + { + return mangle_memory_name(memory->name); + } + std::string mangle(const RTLIL::Cell *cell) { return mangle_cell_name(cell->name); @@ -1498,8 +1518,28 @@ struct CxxrtlWorker { } f << ") {\n"; inc_indent(); - for (auto action : sync->actions) + for (auto &action : sync->actions) dump_assign(action, for_debug); + for (auto &memwr : sync->mem_write_actions) { + RTLIL::Memory *memory = proc->module->memories.at(memwr.memid); + std::string valid_index_temp = fresh_temporary(); + f << indent << "auto " << valid_index_temp << " = memory_index("; + dump_sigspec_rhs(memwr.address); + f << ", " << memory->start_offset << ", " << memory->size << ");\n"; + // See below for rationale of having both the assert and the condition. + // + // If assertions are disabled, out of bounds writes are defined to do nothing. + f << indent << "CXXRTL_ASSERT(" << valid_index_temp << ".valid && \"out of bounds write\");\n"; + f << indent << "if (" << valid_index_temp << ".valid) {\n"; + inc_indent(); + f << indent << mangle(memory) << ".update(" << valid_index_temp << ".index, "; + dump_sigspec_rhs(memwr.data); + f << ", "; + dump_sigspec_rhs(memwr.enable); + f << ");\n"; + dec_indent(); + f << indent << "}\n"; + } dec_indent(); f << indent << "}\n"; } @@ -1917,7 +1957,7 @@ struct CxxrtlWorker { } if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto &mem : mod_memories[module]) { - if (!GetSize(mem.wr_ports)) + if (!writable_memories.count({module, mem.memid})) continue; f << indent << "if (" << mangle(&mem) << ".commit()) changed = true;\n"; } @@ -2556,12 +2596,15 @@ struct CxxrtlWorker { register_edge_signal(sigmap, port.clk, port.clk_polarity ? RTLIL::STp : RTLIL::STn); } + + if (!mem.wr_ports.empty()) + writable_memories.insert({module, mem.memid}); } for (auto proc : module->processes) { flow.add_node(proc.second); - for (auto sync : proc.second->syncs) + for (auto sync : proc.second->syncs) { switch (sync->type) { // Edge-type sync rules require pre-registration. case RTLIL::STp: @@ -2584,6 +2627,10 @@ struct CxxrtlWorker { case RTLIL::STi: log_assert(false); } + for (auto &memwr : sync->mem_write_actions) { + writable_memories.insert({module, memwr.memid}); + } + } } // Construct a linear order of the flow graph that minimizes the amount of feedback arcs. A flow graph @@ -2655,6 +2702,8 @@ struct CxxrtlWorker { worklist.insert(node); // node has effects else if (node->type == FlowGraph::Node::Type::MEM_WRPORTS) worklist.insert(node); // node is memory write + else if (node->type == FlowGraph::Node::Type::PROCESS_SYNC && is_memwr_process(node->process)) + worklist.insert(node); // node is memory write else if (flow.node_sync_defs.count(node)) worklist.insert(node); // node is a flip-flop else if (flow.node_comb_defs.count(node)) { From 6d7d9ab077a7eac125ed6eb0170437216e64efcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 17:40:12 +0200 Subject: [PATCH 0422/2410] kernel/mem: Add documentation for more helper functions. --- kernel/mem.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/kernel/mem.h b/kernel/mem.h index 2b92dff8372..c4575167c4f 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -82,14 +82,48 @@ struct Mem : RTLIL::AttrObject { std::vector rd_ports; std::vector wr_ports; + // Removes this memory from the module. The data in helper structures + // is unaffected except for the cell/mem fields. void remove(); + + // Commits all changes in helper structures into the module — ports and + // inits marked as removed are actually removed, new ports/inits create + // new cells, modified port/inits are commited into their existing + // cells. Note that this reindexes the ports and inits array (actually + // removing the ports/inits marked as removed). void emit(); + + // Marks all inits as removed. void clear_inits(); + + // Checks consistency of this memory and all its ports/inits, using + // log_assert. void check(); + + // Gathers all initialization data into a single big const covering + // the whole memory. For all non-initialized bits, Sx will be returned. Const get_init_data() const; + + // Constructs and returns the helper structures for all memories + // in a module. static std::vector get_all_memories(Module *module); + + // Constructs and returns the helper structures for all selected + // memories in a module. static std::vector get_selected_memories(Module *module); + + // Converts a synchronous read port into an asynchronous one by + // extracting the data (or, in some rare cases, address) register + // into a separate cell, together with any soft-transparency + // logic necessary to preserve its semantics. Returns the created + // register cell, if any. Note that in some rare cases this function + // may succeed and perform a conversion without creating a new + // register — a nullptr result doesn't imply nothing was done. Cell *extract_rdff(int idx, FfInitVals *initvals); + + // Splits all wide ports in this memory into equivalent narrow ones. + // This function performs no modifications at all to the actual + // netlist unless and until emit() is called. void narrow(); // If write port idx2 currently has priority over write port idx1, From 0565c642a0c5a1b1f7b98ab681bc24226b739f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 17:10:40 +0200 Subject: [PATCH 0423/2410] kernel/mem: Use delayed removal for inits as well. --- kernel/mem.cc | 21 ++++++++++++++++++--- kernel/mem.h | 3 ++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 8d77c36431e..96f71428de6 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -76,6 +76,17 @@ void Mem::emit() { wr_left.push_back(i); } } + std::vector init_left; + for (int i = 0; i < GetSize(inits); i++) { + auto &init = inits[i]; + if (init.removed) { + if (init.cell) { + module->remove(init.cell); + } + } else { + init_left.push_back(i); + } + } for (int i = 0; i < GetSize(rd_left); i++) if (i != rd_left[i]) std::swap(rd_ports[i], rd_ports[rd_left[i]]); @@ -84,6 +95,10 @@ void Mem::emit() { if (i != wr_left[i]) std::swap(wr_ports[i], wr_ports[wr_left[i]]); wr_ports.resize(GetSize(wr_left)); + for (int i = 0; i < GetSize(init_left); i++) + if (i != init_left[i]) + std::swap(inits[i], inits[init_left[i]]); + inits.resize(GetSize(init_left)); // for future: handle transparency mask here @@ -264,14 +279,14 @@ void Mem::emit() { void Mem::clear_inits() { for (auto &init : inits) - if (init.cell) - module->remove(init.cell); - inits.clear(); + init.removed = true; } Const Mem::get_init_data() const { Const init_data(State::Sx, width * size); for (auto &init : inits) { + if (init.removed) + continue; int offset = (init.addr.as_int() - start_offset) * width; for (int i = 0; i < GetSize(init.data); i++) if (0 <= i+offset && i+offset < GetSize(init_data)) diff --git a/kernel/mem.h b/kernel/mem.h index c4575167c4f..6ea18f26f1a 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -65,10 +65,11 @@ struct MemWr : RTLIL::AttrObject { }; struct MemInit : RTLIL::AttrObject { + bool removed; Cell *cell; Const addr; Const data; - MemInit() : cell(nullptr) {} + MemInit() : removed(false), cell(nullptr) {} }; struct Mem : RTLIL::AttrObject { From 4379375d899b917d3f6ed00db64ab52c35f4f004 Mon Sep 17 00:00:00 2001 From: GCHQDeveloper560 <48131108+GCHQDeveloper560@users.noreply.github.com> Date: Wed, 16 Jun 2021 13:19:43 +0100 Subject: [PATCH 0424/2410] Add support for the Bitwuzla solver --- backends/smt2/smtio.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 97eb1c5374e..d73a875ba4c 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -203,14 +203,14 @@ def setup(self): print('timeout option is not supported for mathsat.') sys.exit(1) - if self.solver == "boolector": + if self.solver in ["boolector", "bitwuzla"]: if self.noincr: - self.popen_vargs = ['boolector', '--smt2'] + self.solver_opts + self.popen_vargs = [self.solver, '--smt2'] + self.solver_opts else: - self.popen_vargs = ['boolector', '--smt2', '-i'] + self.solver_opts + self.popen_vargs = [self.solver, '--smt2', '-i'] + self.solver_opts self.unroll = True if self.timeout != 0: - print('timeout option is not supported for boolector.') + print('timeout option is not supported for %s.' % self.solver) sys.exit(1) if self.solver == "abc": @@ -1010,7 +1010,7 @@ def handle(self, o, a): def helpmsg(self): return """ -s - set SMT solver: z3, yices, boolector, cvc4, mathsat, dummy + set SMT solver: z3, yices, boolector, bitwuzla, cvc4, mathsat, dummy default: yices -S From 8bf9cb407d929255ae985b33a537ac6d489553c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 20:04:59 +0200 Subject: [PATCH 0425/2410] kernel/mem: Add a coalesce_inits helper. While this helper is already useful to squash sequential initializations into one in cxxrtl, its main purpose is to squash overlapping masked memory initializations (when they land) and avoid having to deal with them in cxxrtl runtime. --- backends/cxxrtl/cxxrtl_backend.cc | 6 ++- kernel/mem.cc | 72 +++++++++++++++++++++++++++++++ kernel/mem.h | 7 +++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index ddb954073e6..70a3add5d38 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1835,6 +1835,8 @@ struct CxxrtlWorker { f << ",\n"; inc_indent(); for (auto &init : mem->inits) { + if (init.removed) + continue; dump_attrs(&init); int words = GetSize(init.data) / mem->width; f << indent << "memory<" << mem->width << ">::init<" << words << "> { " @@ -2488,8 +2490,10 @@ struct CxxrtlWorker { std::vector &memories = mod_memories[module]; memories = Mem::get_all_memories(module); - for (auto &mem : memories) + for (auto &mem : memories) { mem.narrow(); + mem.coalesce_inits(); + } if (module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto port : module->ports) { diff --git a/kernel/mem.cc b/kernel/mem.cc index 96f71428de6..e95118d4c66 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -282,6 +282,78 @@ void Mem::clear_inits() { init.removed = true; } +void Mem::coalesce_inits() { + // start address -> end address + std::map chunks; + // Figure out chunk boundaries. + for (auto &init : inits) { + if (init.removed) + continue; + int addr = init.addr.as_int(); + int addr_e = addr + GetSize(init.data) / width; + auto it_e = chunks.upper_bound(addr_e); + auto it = it_e; + while (it != chunks.begin()) { + --it; + if (it->second < addr) { + ++it; + break; + } + } + if (it == it_e) { + // No overlapping inits — add this one to index. + chunks[addr] = addr_e; + } else { + // We have an overlap — all chunks in the [it, it_e) + // range will be merged with this init. + if (it->first < addr) + addr = it->first; + auto it_last = it_e; + it_last--; + if (it_last->second > addr_e) + addr_e = it_last->second; + chunks.erase(it, it_e); + chunks[addr] = addr_e; + } + } + // Group inits by the chunk they belong to. + dict> inits_by_chunk; + for (int i = 0; i < GetSize(inits); i++) { + auto &init = inits[i]; + if (init.removed) + continue; + auto it = chunks.upper_bound(init.addr.as_int()); + --it; + inits_by_chunk[it->first].push_back(i); + int addr = init.addr.as_int(); + int addr_e = addr + GetSize(init.data) / width; + log_assert(addr >= it->first && addr_e <= it->second); + } + // Process each chunk. + for (auto &it : inits_by_chunk) { + int caddr = it.first; + int caddr_e = chunks[caddr]; + auto &chunk_inits = it.second; + if (GetSize(chunk_inits) == 1) { + continue; + } + Const cdata(State::Sx, (caddr_e - caddr) * width); + for (int idx : chunk_inits) { + auto &init = inits[idx]; + int offset = (init.addr.as_int() - caddr) * width; + log_assert(offset >= 0); + log_assert(offset + GetSize(init.data) <= GetSize(cdata)); + for (int i = 0; i < GetSize(init.data); i++) + cdata.bits[i+offset] = init.data.bits[i]; + init.removed = true; + } + MemInit new_init; + new_init.addr = caddr; + new_init.data = cdata; + inits.push_back(new_init); + } +} + Const Mem::get_init_data() const { Const init_data(State::Sx, width * size); for (auto &init : inits) { diff --git a/kernel/mem.h b/kernel/mem.h index 6ea18f26f1a..62403e00c52 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -97,6 +97,13 @@ struct Mem : RTLIL::AttrObject { // Marks all inits as removed. void clear_inits(); + // Coalesces inits: whenever two inits have overlapping or touching + // address ranges, they are combined into one, with the higher-priority + // one's data overwriting the other. Running this results in + // an inits list equivalent to the original, in which all entries + // cover disjoint (and non-touching) address ranges. + void coalesce_inits(); + // Checks consistency of this memory and all its ports/inits, using // log_assert. void check(); From 88f20fa4dd6ec534cb30c4663d53e1f4d90ac07b Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Wed, 14 Jul 2021 10:19:07 +0100 Subject: [PATCH 0426/2410] Delete unused found_init variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotted during compilation: passes/proc/proc_init.cc: In function ‘void {anonymous}::proc_init(Yosys::RTLIL::Module*, Yosys::SigMap&, Yosys::RTLIL::Process*)’: passes/proc/proc_init.cc:31:7: warning: variable ‘found_init’ set but not used [-Wunused-but-set-variable] --- passes/proc/proc_init.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 841bce400d5..4da20c39539 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -28,12 +28,9 @@ PRIVATE_NAMESPACE_BEGIN void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc) { - bool found_init = false; - for (auto &sync : proc->syncs) if (sync->type == RTLIL::SyncType::STi) { - found_init = true; log("Found init rule in `%s.%s'.\n", mod->name.c_str(), proc->name.c_str()); for (auto &action : sync->actions) From 7d50b8332204d79fac531134f29a0ab3d5bde04c Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Wed, 27 May 2020 10:42:37 +0100 Subject: [PATCH 0427/2410] Extract missing module support in hierarchy.cc to a helper function I think the code is now a bit easier to follow (and has lost some levels of indentation!). The only non-trivial change is that I removed the check for cell->type[0] != '$' when deciding whether to complain if we couldn't find a module. This will always be true because of the early exit earlier in the function. --- passes/hierarchy/hierarchy.cc | 112 +++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 44 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index dadae04a46d..2f7fc6d8a2f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -318,6 +318,64 @@ struct IFExpander } }; +// Get a module needed by a cell, either by deriving an abstract module or by +// loading one from a directory in libdirs. +// +// If the module can't be found and check is true then exit with an error +// message. Otherwise, return a pointer to the module if we derived or loaded +// something. or null otherwise (the module should be blackbox or we couldn't +// find it and check is not set). +RTLIL::Module *get_module(RTLIL::Design &design, + RTLIL::Cell &cell, + RTLIL::Module &parent, + bool check, + const std::vector &libdirs) +{ + std::string cell_type = cell.type.str(); + RTLIL::Module *abs_mod = design.module("$abstract" + cell_type); + if (abs_mod) { + cell.type = abs_mod->derive(&design, cell.parameters); + cell.parameters.clear(); + RTLIL::Module *mod = design.module(cell.type); + log_assert(mod); + return mod; + } + + // If the cell type starts with '$' and isn't '$abstract', we should + // treat it as a black box and skip. + if (cell_type[0] == '$') + return nullptr; + + for (auto &dir : libdirs) { + static const vector> extensions_list = + { + {".v", "verilog"}, + {".sv", "verilog -sv"}, + {".il", "rtlil"} + }; + + for (auto &ext : extensions_list) { + std::string filename = dir + "/" + RTLIL::unescape_id(cell.type) + ext.first; + if (!check_file_exists(filename)) + continue; + + Frontend::frontend_call(&design, NULL, filename, ext.second); + RTLIL::Module *mod = design.module(cell.type); + if (!mod) + log_error("File `%s' from libdir does not declare module `%s'.\n", + filename.c_str(), cell_type.c_str()); + return mod; + } + } + + // We couldn't find the module anywhere. Complain if check is set. + if (check) + log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n", + cell_type.c_str(), parent.name.c_str(), cell.name.c_str()); + + return nullptr; +} + bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector &libdirs) { bool did_something = false; @@ -354,49 +412,21 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } RTLIL::Module *mod = design->module(cell->type); - if (mod == nullptr) + if (!mod) { - if (design->module("$abstract" + cell->type.str()) != nullptr) - { - cell->type = design->module("$abstract" + cell->type.str())->derive(design, cell->parameters); - cell->parameters.clear(); - did_something = true; - continue; - } + mod = get_module(*design, *cell, *module, flag_check || flag_simcheck, libdirs); - if (cell->type[0] == '$') - continue; - - for (auto &dir : libdirs) - { - static const vector> extensions_list = - { - {".v", "verilog"}, - {".sv", "verilog -sv"}, - {".il", "rtlil"} - }; - - for (auto &ext : extensions_list) - { - filename = dir + "/" + RTLIL::unescape_id(cell->type) + ext.first; - if (check_file_exists(filename)) { - Frontend::frontend_call(design, NULL, filename, ext.second); - goto loaded_module; - } - } - } + // If we still don't have a module, treat the cell as a black box and skip + // it. Otherwise, we either loaded or derived something so should set the + // did_something flag before returning (to ensure we come back and expand + // the thing we just loaded). + if (mod) + did_something = true; - if ((flag_check || flag_simcheck) && cell->type[0] != '$') - log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n", - cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; + } - loaded_module: - mod = design->module(cell->type); - if (mod == nullptr) - log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); - did_something = true; - } else { + log_assert(mod); // Go over all connections and check if any of them are SV // interfaces. @@ -426,12 +456,6 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } - } - - // If we make it out of the if/else block above without leaving - // this iteration, mod will equal design->module(cell->type) and - // will be non-null. - log_assert(mod); if (mod->get_blackbox_attribute()) { if (flag_simcheck) From 1aab608cffa19332dc5cf722def7413b16f5ee54 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Wed, 14 Jul 2021 17:27:13 +0100 Subject: [PATCH 0428/2410] Add a test for interfaces on modules loaded on-demand --- tests/svinterfaces/load_and_derive.sv | 20 ++++++++++++++++++++ tests/svinterfaces/load_and_derive.ys | 6 ++++++ tests/svinterfaces/ondemand.sv | 5 +++++ tests/svinterfaces/run-test.sh | 4 ++-- tests/svinterfaces/run_simple.sh | 15 +++++++++++++++ 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/svinterfaces/load_and_derive.sv create mode 100644 tests/svinterfaces/load_and_derive.ys create mode 100644 tests/svinterfaces/ondemand.sv create mode 100755 tests/svinterfaces/run_simple.sh diff --git a/tests/svinterfaces/load_and_derive.sv b/tests/svinterfaces/load_and_derive.sv new file mode 100644 index 00000000000..0de0de3b346 --- /dev/null +++ b/tests/svinterfaces/load_and_derive.sv @@ -0,0 +1,20 @@ +// This test checks that we correctly elaborate interfaces in modules, even if they are loaded on +// demand. The "ondemand" module is defined in ondemand.sv in this directory and will be read as +// part of the hierarchy pass. + +interface iface; + logic [7:0] x; + logic [7:0] y; +endinterface + +module dut (input logic [7:0] x, output logic [7:0] y); + iface intf(); + assign intf.x = x; + assign y = intf.y; + + ondemand u(.intf); +endmodule + +module ref (input logic [7:0] x, output logic [7:0] y); + assign y = ~x; +endmodule diff --git a/tests/svinterfaces/load_and_derive.ys b/tests/svinterfaces/load_and_derive.ys new file mode 100644 index 00000000000..067235ec2ab --- /dev/null +++ b/tests/svinterfaces/load_and_derive.ys @@ -0,0 +1,6 @@ +read_verilog -sv load_and_derive.sv +hierarchy -libdir . -check +flatten +equiv_make ref dut equiv +equiv_simple +equiv_status -assert diff --git a/tests/svinterfaces/ondemand.sv b/tests/svinterfaces/ondemand.sv new file mode 100644 index 00000000000..70d6048f8c3 --- /dev/null +++ b/tests/svinterfaces/ondemand.sv @@ -0,0 +1,5 @@ +// This is used by the load_and_derive test. + +module ondemand (iface intf); + assign intf.y = ~intf.x; +endmodule diff --git a/tests/svinterfaces/run-test.sh b/tests/svinterfaces/run-test.sh index 86567d1c1aa..9ef53926c3c 100755 --- a/tests/svinterfaces/run-test.sh +++ b/tests/svinterfaces/run-test.sh @@ -1,6 +1,6 @@ #/bin/bash -e - - ./runone.sh svinterface1 ./runone.sh svinterface_at_top + +./run_simple.sh load_and_derive diff --git a/tests/svinterfaces/run_simple.sh b/tests/svinterfaces/run_simple.sh new file mode 100755 index 00000000000..bce9944439c --- /dev/null +++ b/tests/svinterfaces/run_simple.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Run a simple test with a .ys file + +if [ $# != 1 ]; then + echo >&2 "Expected 1 argument" + exit 1 +fi + +echo -n "Test: $1 ->" +../../yosys $1.ys >$1.log_stdout 2>$1.log_stderr || { + echo "ERROR!" + exit 1 +} +echo "ok" From a9c8ca21d583c58a38931389f90bbaae0caec0d6 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 22 Jun 2021 10:39:57 -0400 Subject: [PATCH 0429/2410] sv: fix two struct access bugs - preserve signedness of struct members - fix initial width detection of struct members (e.g., in case expressions) --- frontends/ast/ast.h | 3 ++ frontends/ast/genrtlil.cc | 4 ++ frontends/ast/simplify.cc | 4 +- tests/verilog/struct_access.sv | 88 ++++++++++++++++++++++++++++++++++ tests/verilog/struct_access.ys | 4 ++ 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/struct_access.sv create mode 100644 tests/verilog/struct_access.ys diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 2bda8fa9289..60c7de32d8f 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -370,6 +370,9 @@ namespace AST // Helper for setting the src attribute. void set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast); + + // struct helper exposed from simplify for genrtlil + AstNode *make_struct_member_range(AstNode *node, AstNode *member_node); } namespace AST_INTERNAL diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e6f7b30c1f2..29d0bddefd0 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -812,6 +812,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1; if (children.size() > 1) range = children[1]; + } else if (id_ast->type == AST_STRUCT_ITEM) { + AstNode *tmp_range = make_struct_member_range(this, id_ast); + this_width = tmp_range->range_left - tmp_range->range_right + 1; + delete tmp_range; } else log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str()); if (range) { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 695fc429dd2..5845c050126 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -456,7 +456,7 @@ static AstNode *slice_range(AstNode *rnode, AstNode *snode) } -static AstNode *make_struct_member_range(AstNode *node, AstNode *member_node) +AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node) { // Work out the range in the packed array that corresponds to a struct member // taking into account any range operations applicable to the current node @@ -1693,6 +1693,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, newNode = new AstNode(AST_IDENTIFIER, range); newNode->str = sname; newNode->basic_prep = true; + if (item_node->is_signed) + newNode = new AstNode(AST_TO_SIGNED, newNode); goto apply_newNode; } } diff --git a/tests/verilog/struct_access.sv b/tests/verilog/struct_access.sv new file mode 100644 index 00000000000..f13b8dd5111 --- /dev/null +++ b/tests/verilog/struct_access.sv @@ -0,0 +1,88 @@ +module top; + + typedef struct packed { + logic a; + logic signed b; + byte c; + byte unsigned d; + reg [3:0] e; + reg signed [3:0] f; + struct packed { + logic a; + logic signed b; + } x; + struct packed signed { + logic a; + logic signed b; + } y; + } S; + S s; + + initial begin + // test codegen for LHS + s.a = '1; + s.b = '1; + s.c = '1; + s.d = '1; + s.e = '1; + s.f = '1; + s.x.a = '1; + s.x.b = '1; + s.y.a = '1; + s.y.b = '1; + end + +`define CHECK(expr, width, signedness) \ + case (expr) \ + 1'sb1: \ + case (expr) \ + 2'sb11: if (!(signedness)) fail = 1; \ + default: if (signedness) fail = 1; \ + endcase \ + default: if (signedness) fail = 1; \ + endcase \ + case (expr) \ + 1'b1: if ((width) != 1) fail = 1; \ + 2'b11: if ((width) != 2) fail = 1; \ + 3'b111: if ((width) != 3) fail = 1; \ + 4'b1111: if ((width) != 4) fail = 1; \ + 5'b1111_1: if ((width) != 5) fail = 1; \ + 6'b1111_11: if ((width) != 6) fail = 1; \ + 7'b1111_11: if ((width) != 7) fail = 1; \ + 8'b1111_1111: if ((width) != 8) fail = 1; \ + 9'b1111_1111_1: if ((width) != 9) fail = 1; \ + default: fail = 1; \ + endcase \ + begin \ + reg [9:0] indirect; \ + indirect = (expr); \ + if ((indirect != (expr)) != (signedness)) fail = 1; \ + indirect = $unsigned(expr); \ + if ($countones(indirect) != (width)) fail = 1; \ + end + + initial begin + reg fail; + fail = 0; + + `CHECK(s.a, 1, 0) + `CHECK(s.b, 1, 1) + `CHECK(s.c, 8, 1) + `CHECK(s.d, 8, 0) + `CHECK(s.e, 4, 0) + `CHECK(s.f, 4, 1) + + `CHECK(s.x.a, 1, 0) + `CHECK(s.x.b, 1, 1) + `CHECK(s.y.a, 1, 0) + `CHECK(s.y.b, 1, 1) + + // TODO(zachjs): support access to whole sub-structs and unions + // `CHECK(s.x, 2, 0) + // `CHECK(s.y, 2, 1) + + assert (fail === 0); + end + + +endmodule diff --git a/tests/verilog/struct_access.ys b/tests/verilog/struct_access.ys new file mode 100644 index 00000000000..29d569c010a --- /dev/null +++ b/tests/verilog/struct_access.ys @@ -0,0 +1,4 @@ +read_verilog -formal -sv struct_access.sv +proc +opt -full +sat -verify -seq 1 -prove-asserts -show-all From 54b6cb645fe7ecd492521dd05072baf9086ebdb1 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 15 Jul 2021 22:27:27 +0000 Subject: [PATCH 0430/2410] cxxrtl: mark dead local wires as unused even with inlining disabled. Fixes #2739. --- backends/cxxrtl/cxxrtl_backend.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 70a3add5d38..26c534bec18 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2733,12 +2733,14 @@ struct CxxrtlWorker { for (auto wire : module->wires()) { auto &wire_type = wire_types[wire]; if (!wire_type.is_local()) continue; - if (!wire->name.isPublic() && !inline_internal) continue; - if (wire->name.isPublic() && !inline_public) continue; - if (live_wires[wire].empty()) { wire_type = {WireType::UNUSED}; // wire never used - } else if (flow.is_inlinable(wire, live_wires[wire])) { + continue; + } + + if (!wire->name.isPublic() && !inline_internal) continue; + if (wire->name.isPublic() && !inline_public) continue; + if (flow.is_inlinable(wire, live_wires[wire])) { if (flow.wire_comb_defs[wire].size() > 1) log_cmd_error("Wire %s.%s has multiple drivers!\n", log_id(module), log_id(wire)); log_assert(flow.wire_comb_defs[wire].size() == 1); From 44a3d924ce30adfd3a09ffea40031a8d28445e25 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 16 Jul 2021 07:36:18 +0000 Subject: [PATCH 0431/2410] cxxrtl: don't mark buffered internal wires as UNUSED for debug. Public wires may alias buffered internal wires, so keep BUFFERED wires in debug information even if they are private. Debug items are only created for public wires, so this does not otherwise affect how debug information is emitted. Fixes #2540. Fixes #2841. --- backends/cxxrtl/cxxrtl_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 26c534bec18..eea8103a78b 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2795,7 +2795,7 @@ struct CxxrtlWorker { const auto &wire_type = wire_types[wire]; auto &debug_wire_type = debug_wire_types[wire]; if (wire_type.type == WireType::UNUSED) continue; - if (!wire->name.isPublic()) continue; + if (!wire->name.isPublic() && !wire_type.is_buffered()) continue; if (!debug_info) continue; if (wire->port_input || wire_type.is_buffered()) From b28ca7f5accccae869aab1852c5b680147b3614b Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 16 Jul 2021 09:51:15 +0000 Subject: [PATCH 0432/2410] cxxrtl: don't expect user cell inputs to be wires. Ports can be connected to constants, too. (Usually resets.) Fixes #2521. --- backends/cxxrtl/cxxrtl_backend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index eea8103a78b..bf93c932a7f 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1295,7 +1295,7 @@ struct CxxrtlWorker { for (auto conn : cell->connections()) if (cell->input(conn.first)) { RTLIL::Module *cell_module = cell->module->design->module(cell->type); - log_assert(cell_module != nullptr && cell_module->wire(conn.first) && conn.second.is_wire()); + log_assert(cell_module != nullptr && cell_module->wire(conn.first)); RTLIL::Wire *cell_module_wire = cell_module->wire(conn.first); f << indent << mangle(cell) << access << mangle_wire_name(conn.first); if (!is_cxxrtl_blackbox_cell(cell) && wire_types[cell_module_wire].is_buffered()) { @@ -1305,7 +1305,7 @@ struct CxxrtlWorker { f << " = "; dump_sigspec_rhs(conn.second); f << ";\n"; - if (getenv("CXXRTL_VOID_MY_WARRANTY")) { + if (getenv("CXXRTL_VOID_MY_WARRANTY") && conn.second.is_wire()) { // Until we have proper clock tree detection, this really awful hack that opportunistically // propagates prev_* values for clocks can be used to estimate how much faster a design could // be if only one clock edge was simulated by replacing: From 09218896d606726c7e3cd9caa635445694338fba Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 16 Jul 2021 10:05:24 +0000 Subject: [PATCH 0433/2410] cxxrtl: emit debug items for unused public wires. This greatly improves debug information coverage. Fixes #2500. --- backends/cxxrtl/cxxrtl_backend.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index eea8103a78b..bc9f516ee86 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2794,12 +2794,12 @@ struct CxxrtlWorker { for (auto wire : module->wires()) { const auto &wire_type = wire_types[wire]; auto &debug_wire_type = debug_wire_types[wire]; - if (wire_type.type == WireType::UNUSED) continue; - if (!wire->name.isPublic() && !wire_type.is_buffered()) continue; if (!debug_info) continue; if (wire->port_input || wire_type.is_buffered()) debug_wire_type = wire_type; // wire contains state + else if (!wire->name.isPublic()) + continue; // internal and stateless if (!debug_member) continue; if (wire_type.is_member()) @@ -2863,7 +2863,7 @@ struct CxxrtlWorker { auto &debug_wire_type = debug_wire_types[wire]; if (wire->name.isPublic()) continue; - if (live_wires[wire].empty() || debug_live_wires[wire].empty()) { + if (debug_live_wires[wire].empty()) { continue; // wire never used } else if (flow.is_inlinable(wire, debug_live_wires[wire])) { log_assert(flow.wire_comb_defs[wire].size() == 1); From 5b003d6e5cf1790297f5d0f9fdfc95e0b64aa808 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 16 Jul 2021 10:27:47 +0000 Subject: [PATCH 0434/2410] cxxrtl: run hierarchy pass regardless of (*top*) attribute presence. The hierarchy pass does a lot more than just finding the top module, mainly resolving implicit (positional, wildcard) module connections. Fixes #2589. --- backends/cxxrtl/cxxrtl_backend.cc | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index eea8103a78b..d035dc56bb7 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2939,9 +2939,9 @@ struct CxxrtlWorker { } } - void check_design(RTLIL::Design *design, bool &has_top, bool &has_sync_init) + void check_design(RTLIL::Design *design, bool &has_sync_init) { - has_sync_init = has_top = false; + has_sync_init = false; for (auto module : design->modules()) { if (module->get_blackbox_attribute() && !module->has_attribute(ID(cxxrtl_blackbox))) @@ -2953,9 +2953,6 @@ struct CxxrtlWorker { if (!design->selected_module(module)) continue; - if (module->get_bool_attribute(ID::top)) - has_top = true; - for (auto proc : module->processes) for (auto sync : proc.second->syncs) if (sync->type == RTLIL::STi) @@ -2966,10 +2963,10 @@ struct CxxrtlWorker { void prepare_design(RTLIL::Design *design) { bool did_anything = false; - bool has_top, has_sync_init; + bool has_sync_init; log_push(); - check_design(design, has_top, has_sync_init); - if (run_hierarchy && !has_top) { + check_design(design, has_sync_init); + if (run_hierarchy) { Pass::call(design, "hierarchy -auto-top"); did_anything = true; } @@ -2990,7 +2987,7 @@ struct CxxrtlWorker { } // Recheck the design if it was modified. if (did_anything) - check_design(design, has_top, has_sync_init); + check_design(design, has_sync_init); log_assert(!has_sync_init); log_pop(); if (did_anything) From 414154dd275b8cf9f0ffa071d12fc20fd6fee503 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Thu, 21 May 2020 17:36:29 +0100 Subject: [PATCH 0435/2410] Add support for parsing the SystemVerilog 'bind' construct This doesn't do anything useful yet: the patch just adds support for the syntax to the lexer and parser and adds some tests to check the syntax parses properly. This generates AST nodes, but doesn't yet generate RTLIL. Since our existing hierarchical_identifier parser doesn't allow bit selects (so you can't do something like foo[1].bar[2].baz), I've also not added support for a trailing bit select (the "constant_bit_select" non-terminal in "bind_target_instance" in the spec). If we turn out to need this in future, we'll want to augment hierarchical_identifier and its other users too. Note that you can't easily use the BNF from the spec: bind_directive ::= "bind" bind_target_scope [ : bind_target_instance_list] bind_instantiation ; | "bind" bind_target_instance bind_instantiation ; even if you fix the lookahead problem, because code like this matches both branches in the BNF: bind a b b_i (.*); The problem is that 'a' could either be a module name or a degenerate hierarchical reference. This seems to be a genuine syntactic ambiguity, which the spec resolves (p739) by saying that we have to wait until resolution time (the hierarchy pass) and take whatever is defined, treating 'a' as an instance name if it names both an instance and a module. To keep the parser simple, it currently accepts this invalid syntax: bind a.b : c d e (.*); This is invalid because we're in the first branch of the BNF above, so the "a.b" term should match bind_target_scope: a module or interface identifier, not an arbitrary hierarchical identifier. This will fail in the hierarchy pass (when it's implemented in a future patch). --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 3 +- frontends/ast/genrtlil.cc | 5 ++ frontends/verilog/verilog_lexer.l | 1 + frontends/verilog/verilog_parser.y | 77 ++++++++++++++++++++++++++++-- tests/bind/.gitignore | 2 + tests/bind/basic.sv | 20 ++++++++ tests/bind/basic.ys | 1 + tests/bind/cell_list.sv | 26 ++++++++++ tests/bind/cell_list.ys | 1 + tests/bind/hier.sv | 20 ++++++++ tests/bind/hier.ys | 1 + tests/bind/inst_list.sv | 24 ++++++++++ tests/bind/inst_list.ys | 1 + tests/bind/param.sv | 26 ++++++++++ tests/bind/param.ys | 1 + tests/bind/run-test.sh | 20 ++++++++ tests/bind/toplevel.sv | 20 ++++++++ tests/bind/toplevel.ys | 1 + 19 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 tests/bind/.gitignore create mode 100644 tests/bind/basic.sv create mode 100644 tests/bind/basic.ys create mode 100644 tests/bind/cell_list.sv create mode 100644 tests/bind/cell_list.ys create mode 100644 tests/bind/hier.sv create mode 100644 tests/bind/hier.ys create mode 100644 tests/bind/inst_list.sv create mode 100644 tests/bind/inst_list.ys create mode 100644 tests/bind/param.sv create mode 100644 tests/bind/param.ys create mode 100755 tests/bind/run-test.sh create mode 100644 tests/bind/toplevel.sv create mode 100644 tests/bind/toplevel.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f33b7678560..e42cf0348a6 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -177,6 +177,7 @@ std::string AST::type2str(AstNodeType type) X(AST_STRUCT) X(AST_UNION) X(AST_STRUCT_ITEM) + X(AST_BIND) #undef X default: log_abort(); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 60c7de32d8f..57ce5605f4c 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -160,7 +160,8 @@ namespace AST AST_TYPEDEF, AST_STRUCT, AST_UNION, - AST_STRUCT_ITEM + AST_STRUCT_ITEM, + AST_BIND }; struct AstSrcLocType { diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 29d0bddefd0..7fa751e2482 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1963,6 +1963,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } } break; + case AST_BIND: { + // The bind construct. Currently unimplemented: just ignore it. + break; + } + case AST_FCALL: { if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") { diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 55e8b48b9a9..54fb652403a 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -260,6 +260,7 @@ static bool isUserType(std::string &s) "const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); } "checker" { if (formal_mode) return TOK_CHECKER; SV_KEYWORD(TOK_CHECKER); } "endchecker" { if (formal_mode) return TOK_ENDCHECKER; SV_KEYWORD(TOK_ENDCHECKER); } +"bind" { if (formal_mode) return TOK_BIND; SV_KEYWORD(TOK_BIND); } "final" { SV_KEYWORD(TOK_FINAL); } "logic" { SV_KEYWORD(TOK_LOGIC); } "var" { SV_KEYWORD(TOK_VAR); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 9558b0e873c..de463b47deb 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -299,6 +299,7 @@ static void checkLabelsMatch(const char *element, const std::string *before, con %token TOK_BIT_OR_ASSIGN TOK_BIT_AND_ASSIGN TOK_BIT_XOR_ASSIGN TOK_ADD_ASSIGN %token TOK_SUB_ASSIGN TOK_DIV_ASSIGN TOK_MOD_ASSIGN TOK_MUL_ASSIGN %token TOK_SHL_ASSIGN TOK_SHR_ASSIGN TOK_SSHL_ASSIGN TOK_SSHR_ASSIGN +%token TOK_BIND %type range range_or_multirange non_opt_range non_opt_multirange %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type @@ -364,6 +365,7 @@ design: typedef_decl design | package design | interface design | + bind_directive design | %empty; attr: @@ -636,7 +638,67 @@ interface_body: interface_body_stmt: param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | - modport_stmt; + modport_stmt | bind_directive; + +bind_directive: + TOK_BIND { + AstNode *bnode = new AstNode(AST_BIND); + ast_stack.back()->children.push_back(bnode); + ast_stack.push_back(bnode); + } + bind_target { + // bind_target should have added at least one child + log_assert(ast_stack.back()->children.size() >= 1); + } + TOK_ID { + // The single_cell parser in cell_list_no_array uses astbuf1 as + // a sort of template for constructing cells. + astbuf1 = new AstNode(AST_CELL); + astbuf1->children.push_back(new AstNode(AST_CELLTYPE)); + astbuf1->children[0]->str = *$5; + delete $5; + } + cell_parameter_list_opt cell_list_no_array ';' { + // cell_list should have added at least one more child + log_assert(ast_stack.back()->children.size() >= 2); + delete astbuf1; + ast_stack.pop_back(); + }; + +// bind_target matches the target of the bind (everything before +// bind_instantiation in the IEEE 1800 spec). +// +// We can't use the BNF from the spec directly because it's ambiguous: +// something like "bind foo bar_i (.*)" can either be interpreted with "foo" as +// a module or interface identifier (matching bind_target_scope in the spec) or +// by considering foo as a degenerate hierarchical identifier with no '.' +// characters, followed by no bit select (which matches bind_target_instance in +// the spec). +// +// Instead, we resolve everything as an instance name and then deal with the +// ambiguity when converting to RTLIL / in the hierarchy pass. +bind_target: + bind_target_instance opt_bind_target_instance_list; + +// An optional list of target instances for a bind statement, introduced by a +// colon. +opt_bind_target_instance_list: + ':' bind_target_instance_list | + %empty; + +bind_target_instance_list: + bind_target_instance | + bind_target_instance_list ',' bind_target_instance; + +// A single target instance for a bind statement. The top of ast_stack will be +// the bind node where we should add it. +bind_target_instance: + hierarchical_id { + auto *node = new AstNode(AST_IDENTIFIER); + node->str = *$1; + delete $1; + ast_stack.back()->children.push_back(node); + }; mintypmax_expr: expr { delete $1; } | @@ -813,7 +875,7 @@ module_body: module_body_stmt: task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt | - enum_decl | struct_decl | + enum_decl | struct_decl | bind_directive | always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block; checker_decl: @@ -1975,6 +2037,9 @@ cell_list: cell_list ',' single_cell; single_cell: + single_cell_no_array | single_cell_arraylist; + +single_cell_no_array: TOK_ID { astbuf2 = astbuf1->clone(); if (astbuf2->type != AST_PRIMITIVE) @@ -1983,7 +2048,9 @@ single_cell: ast_stack.back()->children.push_back(astbuf2); } '(' cell_port_list ')' { SET_AST_NODE_LOC(astbuf2, @1, @$); - } | + } + +single_cell_arraylist: TOK_ID non_opt_range { astbuf2 = astbuf1->clone(); if (astbuf2->type != AST_PRIMITIVE) @@ -1994,6 +2061,10 @@ single_cell: SET_AST_NODE_LOC(astbuf2, @1, @$); }; +cell_list_no_array: + single_cell_no_array | + cell_list_no_array ',' single_cell_no_array; + prim_list: single_prim | prim_list ',' single_prim; diff --git a/tests/bind/.gitignore b/tests/bind/.gitignore new file mode 100644 index 00000000000..8355de9dc88 --- /dev/null +++ b/tests/bind/.gitignore @@ -0,0 +1,2 @@ +*.log +run-test.mk diff --git a/tests/bind/basic.sv b/tests/bind/basic.sv new file mode 100644 index 00000000000..ce0d04c488b --- /dev/null +++ b/tests/bind/basic.sv @@ -0,0 +1,20 @@ +// A basic example of the bind construct + +module foo (input logic a, input logic b, output logic c); + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + assign c = a ^ b; +endmodule + +module top (); + logic u, v, w; + foo foo_i (.a (u), .b (v), .c (w)); + + bind foo bar bound_i (.*); + + always_comb begin + assert(w == u ^ v); + end +endmodule diff --git a/tests/bind/basic.ys b/tests/bind/basic.ys new file mode 100644 index 00000000000..266fa4e4800 --- /dev/null +++ b/tests/bind/basic.ys @@ -0,0 +1 @@ +read_verilog -sv basic.sv diff --git a/tests/bind/cell_list.sv b/tests/bind/cell_list.sv new file mode 100644 index 00000000000..c0da13d29a0 --- /dev/null +++ b/tests/bind/cell_list.sv @@ -0,0 +1,26 @@ +// An example of specifying multiple bind instances in a single directive. This +// also uses explicit bound names. + +module foo (input logic a0, input logic b0, output logic c0, + input logic a1, input logic b1, output logic c1); + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + assign c = a ^ b; +endmodule + +module top (); + logic u0, v0, w0; + logic u1, v1, w1; + + foo foo0 (.a0 (u0), .b0 (v0), .c0 (w0), + .a1 (u1), .b1 (v1), .c1 (w1)); + + bind foo bar bar0 (.a(a0), .b(b0), .c(c0)), bar1 (.a(a1), .b(b1), .c(c1)); + + always_comb begin + assert(w0 == u0 ^ v0); + assert(w1 == u1 ^ v1); + end +endmodule diff --git a/tests/bind/cell_list.ys b/tests/bind/cell_list.ys new file mode 100644 index 00000000000..9afd9a941ec --- /dev/null +++ b/tests/bind/cell_list.ys @@ -0,0 +1 @@ +read_verilog -sv cell_list.sv diff --git a/tests/bind/hier.sv b/tests/bind/hier.sv new file mode 100644 index 00000000000..fd3bc62b865 --- /dev/null +++ b/tests/bind/hier.sv @@ -0,0 +1,20 @@ +// An example of the bind construct using a hierarchical reference starting with $root + +module foo (input logic a, input logic b, output logic c); + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + assign c = a ^ b; +endmodule + +module top (); + logic u, v, w; + foo foo_i (.a (u), .b (v), .c (w)); + + always_comb begin + assert(w == u ^ v); + end +endmodule + +bind $root.top.foo_i bar bound_i (.*); diff --git a/tests/bind/hier.ys b/tests/bind/hier.ys new file mode 100644 index 00000000000..c19fba1000a --- /dev/null +++ b/tests/bind/hier.ys @@ -0,0 +1 @@ +read_verilog -sv hier.sv diff --git a/tests/bind/inst_list.sv b/tests/bind/inst_list.sv new file mode 100644 index 00000000000..e0077caec2d --- /dev/null +++ b/tests/bind/inst_list.sv @@ -0,0 +1,24 @@ +// An example of specifying multiple bind targets with an instance list + +module foo (input logic a, input logic b, output logic c); + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + assign c = a ^ b; +endmodule + +module top (); + logic u0, v0, w0; + logic u1, v1, w1; + + foo foo0 (.a (u0), .b (v0), .c (w0)); + foo foo1 (.a (u1), .b (v1), .c (w1)); + + bind foo : foo0, foo1 bar bound_i (.*); + + always_comb begin + assert(w0 == u0 ^ v0); + assert(w1 == u1 ^ v1); + end +endmodule diff --git a/tests/bind/inst_list.ys b/tests/bind/inst_list.ys new file mode 100644 index 00000000000..ac1385b835d --- /dev/null +++ b/tests/bind/inst_list.ys @@ -0,0 +1 @@ +read_verilog -sv inst_list.sv diff --git a/tests/bind/param.sv b/tests/bind/param.sv new file mode 100644 index 00000000000..c7793527aba --- /dev/null +++ b/tests/bind/param.sv @@ -0,0 +1,26 @@ +// An example showing how parameters get inferred when binding + +module foo (input logic a, input logic b, output logic c); + parameter doit = 1; + + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + parameter doit = 1; + + assign c = doit ? a ^ b : 0; +endmodule + +module top (input u0, input v0, output w0, + input u1, input v1, output w1); + foo #(.doit (0)) foo0 (.a (u0), .b (v0), .c (w0)); + foo #(.doit (1)) foo1 (.a (u1), .b (v1), .c (w1)); + + bind foo bar #(.doit (doit)) bound_i (.*); + + always_comb begin + assert (w0 == '0); + assert (w1 == u1 ^ v1); + end +endmodule diff --git a/tests/bind/param.ys b/tests/bind/param.ys new file mode 100644 index 00000000000..a43d057597f --- /dev/null +++ b/tests/bind/param.ys @@ -0,0 +1 @@ +read_verilog -sv param.sv diff --git a/tests/bind/run-test.sh b/tests/bind/run-test.sh new file mode 100755 index 00000000000..ea56b70f029 --- /dev/null +++ b/tests/bind/run-test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e +{ +echo "all::" +for x in *.ys; do + echo "all:: run-$x" + echo "run-$x:" + echo " @echo 'Running $x..'" + echo " @../../yosys -ql ${x%.ys}.log $x" +done +for s in *.sh; do + if [ "$s" != "run-test.sh" ]; then + echo "all:: run-$s" + echo "run-$s:" + echo " @echo 'Running $s..'" + echo " @bash $s" + fi +done +} > run-test.mk +exec ${MAKE:-make} -f run-test.mk diff --git a/tests/bind/toplevel.sv b/tests/bind/toplevel.sv new file mode 100644 index 00000000000..328edcf67ab --- /dev/null +++ b/tests/bind/toplevel.sv @@ -0,0 +1,20 @@ +// The bind construct occurring at top-level in the script + +module foo (input logic a, input logic b, output logic c); + // Magic happens here... +endmodule + +module bar (input a, input b, output c); + assign c = a ^ b; +endmodule + +module top (); + logic u, v, w; + foo foo_i (.a (u), .b (v), .c (w)); + + always_comb begin + assert(w == u ^ v); + end +endmodule + +bind top.foo_i bar bound_i (.*); diff --git a/tests/bind/toplevel.ys b/tests/bind/toplevel.ys new file mode 100644 index 00000000000..11c0ada1959 --- /dev/null +++ b/tests/bind/toplevel.ys @@ -0,0 +1 @@ +read_verilog -sv toplevel.sv From 4aa65f406f3f793978278454fe8d8000a442e2f2 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 17 Jul 2021 14:23:57 +0000 Subject: [PATCH 0436/2410] cxxrtl: treat internal wires used only for debug as constants. Fixes #2739 (again). --- backends/cxxrtl/cxxrtl_backend.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 7ff344e66ed..56305258a4a 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2881,6 +2881,12 @@ struct CxxrtlWorker { debug_live_nodes.erase(node); } else if (wire_type.is_local()) { debug_wire_type = {WireType::LOCAL}; // wire not inlinable + } else if (wire_type.type == WireType::UNUSED) { + if (wire_init.count(wire)) { + debug_wire_type = {WireType::CONST, wire_init.at(wire)}; + } else { + debug_wire_type = {WireType::CONST, RTLIL::SigSpec(RTLIL::S0, wire->width)}; + } // wire never modified } else { log_assert(wire_type.is_member()); debug_wire_type = wire_type; // wire is a member From 948fc10d7b7629803352e758fae9bc12a01074fb Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 18 Jul 2021 06:07:27 +0000 Subject: [PATCH 0437/2410] cxxrtl: add debug_item::{get,set}. Fixes #2877. --- backends/cxxrtl/cxxrtl.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 0e55c46c223..4552a01254d 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -999,6 +999,22 @@ struct debug_item : ::cxxrtl_object { next = nullptr; outline = &group; } + + template + IntegerT get() const { + assert(width == Bits && depth == 1); + value item; + std::copy(curr, curr + value::chunks, item.data); + return item.template get(); + } + + template + void set(IntegerT other) const { + assert(width == Bits && depth == 1); + value item; + item.template set(other); + std::copy(item.data, item.data + value::chunks, next); + } }; static_assert(std::is_standard_layout::value, "debug_item is not compatible with C layout"); From fc84f230011b5a2eab1eefc319e8646b3ca2f657 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 19 Jul 2021 16:20:49 +0000 Subject: [PATCH 0438/2410] cxxrtl: escape colon in variable names in VCD writer. The following VCD file crashes GTKWave's VCD loader: $var wire 1 ! x:1 $end $enddefinitions $end In practice, a colon can be a part of a variable name that is translated from a Verilog function, something like: update$func$.../hdl/hazard3_csr.v:350$2534.$result --- backends/cxxrtl/cxxrtl_vcd.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index 3f40a8d122d..b76922bbd8a 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -69,12 +69,25 @@ class vcd_writer { } while (ident != 0); } + void emit_name(const std::string &name) { + for (char c : name) { + if (c == ':') { + // Due to a bug, GTKWave cannot parse a colon in the variable name, causing the VCD file + // to be unreadable. It cannot be escaped either, so replace it with the sideways colon. + buffer += ".."; + } else { + buffer += c; + } + } + } + void emit_var(const variable &var, const std::string &type, const std::string &name, size_t lsb_at, bool multipart) { assert(!streaming); buffer += "$var " + type + " " + std::to_string(var.width) + " "; emit_ident(var.ident); - buffer += " " + name; + buffer += " "; + emit_name(name); if (multipart || name.back() == ']' || lsb_at != 0) { if (var.width == 1) buffer += " [" + std::to_string(lsb_at) + "]"; From 225af830c131084194378ad1926d2601ff0963da Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 20 Jul 2021 10:10:42 +0000 Subject: [PATCH 0439/2410] cxxrtl: treat assignable internal wires used only for debug as locals. This issue was introduced in commit 4aa65f40 while fixing #2739. Fixes #2882. --- backends/cxxrtl/cxxrtl_backend.cc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 56305258a4a..24422712bd6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2879,17 +2879,19 @@ struct CxxrtlWorker { default: continue; } debug_live_nodes.erase(node); - } else if (wire_type.is_local()) { - debug_wire_type = {WireType::LOCAL}; // wire not inlinable - } else if (wire_type.type == WireType::UNUSED) { - if (wire_init.count(wire)) { - debug_wire_type = {WireType::CONST, wire_init.at(wire)}; - } else { - debug_wire_type = {WireType::CONST, RTLIL::SigSpec(RTLIL::S0, wire->width)}; - } // wire never modified + } else if (wire_type.is_member() || wire_type.is_local()) { + debug_wire_type = wire_type; // wire not inlinable } else { - log_assert(wire_type.is_member()); - debug_wire_type = wire_type; // wire is a member + log_assert(wire_type.type == WireType::UNUSED); + if (flow.wire_comb_defs[wire].size() == 0) { + if (wire_init.count(wire)) { // wire never modified + debug_wire_type = {WireType::CONST, wire_init.at(wire)}; + } else { + debug_wire_type = {WireType::CONST, RTLIL::SigSpec(RTLIL::S0, wire->width)}; + } + } else { + debug_wire_type = {WireType::LOCAL}; // wire used only for debug + } } } From 1a6ddf78921290851ca7bbe7605d9e146055dc39 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 20 Jul 2021 10:30:39 +0000 Subject: [PATCH 0440/2410] cxxrtl: treat wires with multiple defs as not inlinable. Fixes #2883. --- backends/cxxrtl/cxxrtl_backend.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 56305258a4a..46759e8fae6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -326,8 +326,14 @@ struct FlowGraph { for (auto bit : sig.bits()) bit_has_state[bit] |= is_ff; // Only comb defs of an entire wire in the right order can be inlined. - if (!is_ff && sig.is_wire()) - wire_def_inlinable[sig.as_wire()] = inlinable; + if (!is_ff && sig.is_wire()) { + // Only a single def of a wire can be inlined. (Multiple defs of a wire are unsound, but we + // handle them anyway to avoid assertion failures later.) + if (!wire_def_inlinable.count(sig.as_wire())) + wire_def_inlinable[sig.as_wire()] = inlinable; + else + wire_def_inlinable[sig.as_wire()] = false; + } } void add_uses(Node *node, const RTLIL::SigSpec &sig) From 8fd6b45a3c828d87e7e7fd2030026981d679d32b Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Wed, 27 May 2020 15:54:42 +0100 Subject: [PATCH 0441/2410] Extract connection checking logic from expand_module in hierarchy.cc No functional change, but pulls more logic out of the expand_module function. --- passes/hierarchy/hierarchy.cc | 87 ++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 2f7fc6d8a2f..5839a6c759d 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -376,6 +376,69 @@ RTLIL::Module *get_module(RTLIL::Design &design, return nullptr; } +// Try to read an IdString as a numbered connection name ("$123" or similar), +// writing the result to dst. If the string isn't of the right format, ignore +// dst and return false. +bool read_id_num(RTLIL::IdString str, int *dst) +{ + log_assert(dst); + + const char *c_str = str.c_str(); + if (c_str[0] != '$' || !('0' <= c_str[1] && c_str[1] <= '9')) + return false; + + *dst = atoi(c_str + 1); + return true; +} + +// Check that the connections on the cell match those that are defined +// on the type: each named connection should match the name of a port +// and each positional connection should have an index smaller than +// the number of ports. +// +// Also do the same checks on the specified parameters. +void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLIL::Module &mod) +{ + int id; + for (auto &conn : cell.connections()) { + if (read_id_num(conn.first, &id)) { + if (id <= 0 || id > GetSize(mod.ports)) + log_error("Module `%s' referenced in module `%s' in cell `%s' " + "has only %d ports, requested port %d.\n", + log_id(cell.type), log_id(&module), log_id(&cell), + GetSize(mod.ports), id); + continue; + } + + const RTLIL::Wire* wire = mod.wire(conn.first); + if (!wire || wire->port_id == 0) { + log_error("Module `%s' referenced in module `%s' in cell `%s' " + "does not have a port named '%s'.\n", + log_id(cell.type), log_id(&module), log_id(&cell), + log_id(conn.first)); + } + } + for (auto ¶m : cell.parameters) { + if (read_id_num(param.first, &id)) { + if (id <= 0 || id > GetSize(mod.avail_parameters)) + log_error("Module `%s' referenced in module `%s' in cell `%s' " + "has only %d parameters, requested parameter %d.\n", + log_id(cell.type), log_id(&module), log_id(&cell), + GetSize(mod.avail_parameters), id); + continue; + } + + if (mod.avail_parameters.count(param.first) == 0 && + param.first[0] != '$' && + strchr(param.first.c_str(), '.') == NULL) { + log_error("Module `%s' referenced in module `%s' in cell `%s' " + "does not have a parameter named '%s'.\n", + log_id(cell.type), log_id(&module), log_id(&cell), + log_id(param.first)); + } + } +} + bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector &libdirs) { bool did_something = false; @@ -433,29 +496,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check if_expander.visit_connections(*cell, *mod); if (flag_check || flag_simcheck) - { - for (auto &conn : cell->connections()) { - if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { - int id = atoi(conn.first.c_str()+1); - if (id <= 0 || id > GetSize(mod->ports)) - log_error("Module `%s' referenced in module `%s' in cell `%s' has only %d ports, requested port %d.\n", - log_id(cell->type), log_id(module), log_id(cell), GetSize(mod->ports), id); - } else if (mod->wire(conn.first) == nullptr || mod->wire(conn.first)->port_id == 0) - log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a port named '%s'.\n", - log_id(cell->type), log_id(module), log_id(cell), log_id(conn.first)); - } - for (auto ¶m : cell->parameters) { - if (param.first[0] == '$' && '0' <= param.first[1] && param.first[1] <= '9') { - int id = atoi(param.first.c_str()+1); - if (id <= 0 || id > GetSize(mod->avail_parameters)) - log_error("Module `%s' referenced in module `%s' in cell `%s' has only %d parameters, requested parameter %d.\n", - log_id(cell->type), log_id(module), log_id(cell), GetSize(mod->avail_parameters), id); - } else if (mod->avail_parameters.count(param.first) == 0 && param.first[0] != '$' && strchr(param.first.c_str(), '.') == NULL) - log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a parameter named '%s'.\n", - log_id(cell->type), log_id(module), log_id(cell), log_id(param.first)); - } - - } + check_cell_connections(*module, *cell, *mod); if (mod->get_blackbox_attribute()) { if (flag_simcheck) From 7a25246a7ebf0b7495beae4a19569f619ca19c78 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 19 Jul 2021 09:23:41 +0100 Subject: [PATCH 0442/2410] Use new read_id_num helper function elsewhere in hierarchy.cc --- passes/hierarchy/hierarchy.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 5839a6c759d..65003658066 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1106,8 +1106,8 @@ struct HierarchyPass : public Pass { pool> params_rename; for (const auto &p : cell->parameters) { - if (p.first[0] == '$' && '0' <= p.first[1] && p.first[1] <= '9') { - int id = atoi(p.first.c_str()+1); + int id; + if (read_id_num(p.first, &id)) { if (id <= 0 || id > GetSize(cell_mod->avail_parameters)) { log(" Failed to map positional parameter %d of cell %s.%s (%s).\n", id, RTLIL::id2cstr(mod->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); @@ -1134,9 +1134,9 @@ struct HierarchyPass : public Pass { log("Mapping positional arguments of cell %s.%s (%s).\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); dict new_connections; - for (auto &conn : cell->connections()) - if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { - int id = atoi(conn.first.c_str()+1); + for (auto &conn : cell->connections()) { + int id; + if (read_id_num(conn.first, &id)) { std::pair key(design->module(cell->type), id); if (pos_map.count(key) == 0) { log(" Failed to map positional argument %d of cell %s.%s (%s).\n", @@ -1146,6 +1146,7 @@ struct HierarchyPass : public Pass { new_connections[pos_map.at(key)] = conn.second; } else new_connections[conn.first] = conn.second; + } cell->connections_ = new_connections; } } From 987fca5297d4e3290df64b7a54a3af9b6ddf11d9 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Jul 2021 09:46:53 +0200 Subject: [PATCH 0443/2410] Update to latest verific --- frontends/verific/verific.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 997a8e826e4..357b8804379 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -56,7 +56,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210602 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210603 # error "Please update your version of YosysHQ flavored Verific." #endif @@ -1961,7 +1961,7 @@ void verific_import(Design *design, const std::map &par for (const auto &i : parameters) verific_params.Insert(i.first.c_str(), i.second.c_str()); - InitialAssertions::Rewrite("work"); + InitialAssertions::Rewrite("work", &verific_params); if (top.empty()) { netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, &verific_params); @@ -2847,7 +2847,7 @@ struct VerificPass : public Pass { std::set top_mod_names; - InitialAssertions::Rewrite(work); + InitialAssertions::Rewrite(work, ¶meters); if (mode_all) { From 45968ad740d3d060592adb37d8a378e602c7522b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 26 Jul 2021 11:25:32 +0200 Subject: [PATCH 0444/2410] Add version bump workflow --- .github/workflows/version.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/version.yml diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml new file mode 100644 index 00000000000..0cd66875c78 --- /dev/null +++ b/.github/workflows/version.yml @@ -0,0 +1,31 @@ +name: Bump version + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' + +jobs: + bump-version: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Take last commit + id: log + run: echo "::set-output name=message::$(git log --no-merges -1 --oneline)" + - name: Bump version + if: "!contains(steps.log.outputs.message, 'Bump version')" + run: | + make bumpversion + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add Makefile + git commit -m "Bump version" + - name: Push changes # push the output folder to your repo + if: "!contains(steps.log.outputs.message, 'Bump version')" + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} From 9600f20be887b707f6d5d3f74dec58b336e2464e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Jul 2021 00:52:14 +0000 Subject: [PATCH 0445/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 42569ecd870..ed456037de2 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4081 +YOSYS_VER := 0.9+4221 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 436d42c00c2bf1b2eaf84ada388d8aaab65da086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 27 Jul 2021 15:24:48 +0200 Subject: [PATCH 0446/2410] opt_expr: Propagate constants to port connections. This adds one simple piece of functionality to opt_expr: when a cell port is connected to a fully-constant signal (as determined by sigmap), the port is reconnected directly to the constant value. This is just enough optimization to fix the "non-constant $meminit input" problem without requiring a full opt_clean or a separate pass. --- passes/opt/opt_expr.cc | 25 ++++++++++++++++++++++--- tests/opt/opt_expr_constconn.v | 8 ++++++++ tests/opt/opt_expr_constconn.ys | 7 +++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/opt/opt_expr_constconn.v create mode 100644 tests/opt/opt_expr_constconn.ys diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 709cb6020d2..b7bbb2adfa3 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -395,9 +395,6 @@ int get_highest_hot_index(RTLIL::SigSpec signal) void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv) { - if (!design->selected(module)) - return; - CellTypes ct_combinational; ct_combinational.setup_internals(); ct_combinational.setup_stdcells(); @@ -2007,6 +2004,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } +void replace_const_connections(RTLIL::Module *module) { + SigMap assign_map(module); + for (auto cell : module->selected_cells()) + { + std::vector> changes; + for (auto &conn : cell->connections()) { + SigSpec mapped = assign_map(conn.second); + if (conn.second != mapped && mapped.is_fully_const()) + changes.push_back({conn.first, mapped}); + } + if (!changes.empty()) + did_something = true; + for (auto &it : changes) + cell->setPort(it.first, it.second); + } +} + struct OptExprPass : public Pass { OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { } void help() override @@ -2117,6 +2131,11 @@ struct OptExprPass : public Pass { design->scratchpad_set_bool("opt.did_something", true); } while (did_something); + did_something = false; + replace_const_connections(module); + if (did_something) + design->scratchpad_set_bool("opt.did_something", true); + log_suppressed(); } diff --git a/tests/opt/opt_expr_constconn.v b/tests/opt/opt_expr_constconn.v new file mode 100644 index 00000000000..d18b120e311 --- /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 00000000000..9dd848a4b40 --- /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 From a0e912ba9996536f5eab9989e7119d91b20545f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 27 Jul 2021 15:43:36 +0200 Subject: [PATCH 0447/2410] proc: Run opt_expr at the end --- passes/proc/proc.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/passes/proc/proc.cc b/passes/proc/proc.cc index 2dfc30e8722..d7aac57b66f 100644 --- a/passes/proc/proc.cc +++ b/passes/proc/proc.cc @@ -45,6 +45,7 @@ struct ProcPass : public Pass { log(" proc_dff\n"); log(" proc_memwr\n"); log(" proc_clean\n"); + log(" opt_expr -keepdc\n"); log("\n"); log("This replaces the processes in the design with multiplexers,\n"); log("flip-flops and latches.\n"); @@ -61,12 +62,16 @@ struct ProcPass : public Pass { log(" This option is passed through to proc_mux. proc_rmdead is not\n"); log(" executed in -ifx mode.\n"); log("\n"); + log(" -noopt\n"); + log(" Will omit the opt_expr pass.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { std::string global_arst; bool ifxmode = false; bool nomux = false; + bool noopt = false; log_header(design, "Executing PROC pass (convert processes to netlists).\n"); log_push(); @@ -86,6 +91,10 @@ struct ProcPass : public Pass { ifxmode = true; continue; } + if (args[argidx] == "-noopt") { + noopt = true; + continue; + } break; } extra_args(args, argidx, design); @@ -105,6 +114,8 @@ struct ProcPass : public Pass { Pass::call(design, "proc_dff"); Pass::call(design, "proc_memwr"); Pass::call(design, "proc_clean"); + if (!noopt) + Pass::call(design, "opt_expr -keepdc"); log_pop(); } From 37d76deef1229048e145d77b5c75bcc2e0e1cf44 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Jul 2021 00:52:46 +0000 Subject: [PATCH 0448/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ed456037de2..c6ecd0de7c2 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4221 +YOSYS_VER := 0.9+4224 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 19720b970dff017c47805e37745b9fcf29843c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 21 May 2021 02:26:52 +0200 Subject: [PATCH 0449/2410] memory: Introduce $meminit_v2 cell, with EN input. --- CHANGELOG | 1 + kernel/celltypes.h | 1 + kernel/mem.cc | 41 ++++++++++++++++++++++++++++++++++---- kernel/mem.h | 4 +++- kernel/rtlil.cc | 12 ++++++++++- manual/CHAPTER_CellLib.tex | 11 +++++----- passes/opt/opt_clean.cc | 2 +- passes/opt/wreduce.cc | 2 +- passes/sat/sim.cc | 1 + techlibs/common/simlib.v | 24 ++++++++++++++++++++++ 10 files changed, 86 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6dcd05de665..6948ff441aa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -70,6 +70,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "dfflegalize" pass - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass + - Added $meminit_v2 cells (with support for write mask) Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 2918b90395d..2ce7978a463 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -157,6 +157,7 @@ struct CellTypes setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA}); setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool()); setup_type(ID($meminit), {ID::ADDR, ID::DATA}, pool()); + setup_type(ID($meminit_v2), {ID::ADDR, ID::DATA, ID::EN}, pool()); setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA}); setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT}); diff --git a/kernel/mem.cc b/kernel/mem.cc index e95118d4c66..a3b244eab8b 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -263,8 +263,11 @@ void Mem::emit() { } idx = 0; for (auto &init : inits) { + bool v2 = !init.en.is_fully_ones(); if (!init.cell) - init.cell = module->addCell(NEW_ID, ID($meminit)); + init.cell = module->addCell(NEW_ID, v2 ? ID($meminit_v2) : ID($meminit)); + else + init.cell->type = v2 ? ID($meminit_v2) : ID($meminit); init.cell->attributes = init.attributes; init.cell->parameters[ID::MEMID] = memid.str(); init.cell->parameters[ID::ABITS] = GetSize(init.addr); @@ -273,6 +276,10 @@ void Mem::emit() { init.cell->parameters[ID::PRIORITY] = idx++; init.cell->setPort(ID::ADDR, init.addr); init.cell->setPort(ID::DATA, init.data); + if (v2) + init.cell->setPort(ID::EN, init.en); + else + init.cell->unsetPort(ID::EN); } } } @@ -289,6 +296,14 @@ void Mem::coalesce_inits() { for (auto &init : inits) { if (init.removed) continue; + bool valid = false; + for (auto bit : init.en) + if (bit == State::S1) + valid = true; + if (!valid) { + init.removed = true; + continue; + } int addr = init.addr.as_int(); int addr_e = addr + GetSize(init.data) / width; auto it_e = chunks.upper_bound(addr_e); @@ -335,6 +350,13 @@ void Mem::coalesce_inits() { int caddr_e = chunks[caddr]; auto &chunk_inits = it.second; if (GetSize(chunk_inits) == 1) { + auto &init = inits[chunk_inits[0]]; + if (!init.en.is_fully_ones()) { + for (int i = 0; i < GetSize(init.data); i++) + if (init.en[i % width] != State::S1) + init.data[i] = State::Sx; + init.en = Const(State::S1, width); + } continue; } Const cdata(State::Sx, (caddr_e - caddr) * width); @@ -344,12 +366,14 @@ void Mem::coalesce_inits() { log_assert(offset >= 0); log_assert(offset + GetSize(init.data) <= GetSize(cdata)); for (int i = 0; i < GetSize(init.data); i++) - cdata.bits[i+offset] = init.data.bits[i]; + if (init.en[i % width] == State::S1) + cdata.bits[i+offset] = init.data.bits[i]; init.removed = true; } MemInit new_init; new_init.addr = caddr; new_init.data = cdata; + new_init.en = Const(State::S1, width); inits.push_back(new_init); } } @@ -361,7 +385,7 @@ Const Mem::get_init_data() const { continue; int offset = (init.addr.as_int() - start_offset) * width; for (int i = 0; i < GetSize(init.data); i++) - if (0 <= i+offset && i+offset < GetSize(init_data)) + if (0 <= i+offset && i+offset < GetSize(init_data) && init.en[i % width] == State::S1) init_data.bits[i+offset] = init.data.bits[i]; } return init_data; @@ -432,7 +456,7 @@ namespace { wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); else if (cell->type == ID($memrd)) rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); - else if (cell->type == ID($meminit)) + else if (cell->type.in(ID($meminit), ID($meminit_v2))) inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); } } @@ -507,6 +531,14 @@ namespace { log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), log_id(cell)); init.addr = addr.as_const(); init.data = data.as_const(); + if (cell->type == ID($meminit_v2)) { + auto en = cell->getPort(ID::EN); + if (!en.is_fully_const()) + log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), log_id(cell)); + init.en = en.as_const(); + } else { + init.en = RTLIL::Const(State::S1, mem->width); + } inits.push_back(std::make_pair(cell->parameters.at(ID::PRIORITY).as_int(), init)); } std::sort(inits.begin(), inits.end(), [](const std::pair &a, const std::pair &b) { return a.first < b.first; }); @@ -558,6 +590,7 @@ namespace { MemInit minit; minit.addr = res.start_offset + pos; minit.data = init.extract(pos * res.width, (epos - pos) * res.width, State::Sx); + minit.en = RTLIL::Const(State::S1, res.width); res.inits.push_back(minit); pos = epos; } diff --git a/kernel/mem.h b/kernel/mem.h index 62403e00c52..24c2d64c8dc 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -69,6 +69,7 @@ struct MemInit : RTLIL::AttrObject { Cell *cell; Const addr; Const data; + Const en; MemInit() : removed(false), cell(nullptr) {} }; @@ -101,7 +102,8 @@ struct Mem : RTLIL::AttrObject { // address ranges, they are combined into one, with the higher-priority // one's data overwriting the other. Running this results in // an inits list equivalent to the original, in which all entries - // cover disjoint (and non-touching) address ranges. + // cover disjoint (and non-touching) address ranges, and all enable + // masks are all-1. void coalesce_inits(); // Checks consistency of this memory and all its ports/inits, using diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 21ee15ac548..bd6b3ad0558 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1414,6 +1414,16 @@ namespace { return; } + if (cell->type == ID($meminit_v2)) { + param(ID::MEMID); + param(ID::PRIORITY); + port(ID::ADDR, param(ID::ABITS)); + port(ID::DATA, param(ID::WIDTH) * param(ID::WORDS)); + port(ID::EN, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($mem)) { param(ID::MEMID); param(ID::SIZE); @@ -3177,7 +3187,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) bool RTLIL::Cell::has_memid() const { - return type.in(ID($memwr), ID($memrd), ID($meminit)); + return type.in(ID($memwr), ID($memrd), ID($meminit), ID($meminit_v2)); } bool RTLIL::Cell::is_mem_cell() const diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index d4572a88a29..08901debb1a 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -338,14 +338,14 @@ \subsection{Registers} \subsection{Memories} \label{sec:memcells} -Memories are either represented using RTLIL::Memory objects, {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit} +Memories are either represented using RTLIL::Memory objects, {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit\_v2} cells, or by {\tt \$mem} cells alone. In the first alternative the RTLIL::Memory objects hold the general metadata for the memory (bit width, size in number of words, etc.) and for each port a {\tt \$memrd} (read port) or {\tt \$memwr} (write port) cell is created. Having individual cells for read and write ports has the advantage that they can be consolidated using resource sharing passes. In some cases this drastically reduces the number of required -ports on the memory cell. In this alternative, memory initialization data is represented by {\tt \$meminit} cells, +ports on the memory cell. In this alternative, memory initialization data is represented by {\tt \$meminit\_v2} cells, which allow delaying constant folding for initialization addresses and data until after the frontend finishes. The {\tt \$memrd} cells have a clock input \B{CLK}, an enable input \B{EN}, an @@ -401,8 +401,9 @@ \subsection{Memories} The cell with the higher integer value in this parameter wins a write conflict. \end{itemize} -The {\tt \$meminit} cells have an address input \B{ADDR} and a data input \B{DATA}, with the width -of the \B{DATA} port equal to \B{WIDTH} parameter times \B{WORDS} parameter. Both of the inputs +The {\tt \$meminit\_v2} cells have an address input \B{ADDR}, a data input \B{DATA}, with the width +of the \B{DATA} port equal to \B{WIDTH} parameter times \B{WORDS} parameter, and a bit enable mask input +\B{EN} with width equal to \B{WIDTH} parameter. All three of the inputs must resolve to a constant for synthesis to succeed. \begin{itemize} @@ -497,7 +498,7 @@ \subsection{Memories} This input is \B{WR\_PORTS}*\B{WIDTH} bits wide, containing all data signals for the write ports. \end{itemize} -The {\tt memory\_collect} pass can be used to convert discrete {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit} cells +The {\tt memory\_collect} pass can be used to convert discrete {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit\_v2} cells belonging to the same memory to a single {\tt \$mem} cell, whereas the {\tt memory\_unpack} pass performs the inverse operation. The {\tt memory\_dff} pass can combine asynchronous memory ports that are fed by or feeding registers into synchronous memory ports. The {\tt memory\_bram} pass can be used to recognize {\tt \$mem} cells that can be implemented with a block RAM resource on an FPGA. diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 699fd4f80ca..c3a0928ef3b 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -117,7 +117,7 @@ void rmunused_module_cells(Module *module, bool verbose) } for (Cell *cell : module->cells()) { - if (cell->type.in(ID($memwr), ID($meminit))) { + if (cell->type.in(ID($memwr), ID($meminit), ID($meminit_v2))) { IdString mem_id = cell->getParam(ID::MEMID).decode_string(); mem2cells[mem_id].insert(cell); } diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 0cdabcc1a88..f6bf8b51a79 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -558,7 +558,7 @@ struct WreducePass : public Pass { } } - if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) { + if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit), ID($meminit_v2))) { IdString memid = c->getParam(ID::MEMID).decode_string(); RTLIL::Memory *mem = module->memories.at(memid); if (mem->start_offset >= 0) { diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 630e1aaa1ac..4e158da6292 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -559,6 +559,7 @@ struct SimInstance MemInit minit; minit.addr = mem.mem->start_offset; minit.data = mem.data; + minit.en = Const(State::S1, mem.mem->width); mem.mem->inits.push_back(minit); mem.mem->emit(); } diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 42a355c2dd8..ad654c8a43b 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2233,6 +2233,30 @@ endmodule // -------------------------------------------------------- +module \$meminit_v2 (ADDR, DATA, EN); + +parameter MEMID = ""; +parameter ABITS = 8; +parameter WIDTH = 8; +parameter WORDS = 1; + +parameter PRIORITY = 0; + +input [ABITS-1:0] ADDR; +input [WORDS*WIDTH-1:0] DATA; +input [WIDTH-1:0] EN; + +initial begin + if (MEMID != "") begin + $display("ERROR: Found non-simulatable instance of $meminit_v2!"); + $finish; + end +end + +endmodule + +// -------------------------------------------------------- + module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); parameter MEMID = ""; From e9effd58d24afc8470813aec3028e932ea677aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 12 Jul 2021 20:43:09 +0200 Subject: [PATCH 0450/2410] backends/verilog: Support meminit with mask. --- backends/verilog/verilog_backend.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 800865414dd..b363bc2fe43 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -504,9 +504,24 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) int start = init.addr.as_int(); for (int i=0; i Date: Fri, 21 May 2021 02:27:06 +0200 Subject: [PATCH 0451/2410] verilog: Emit $meminit_v2 cell. Fixes #2447. --- frontends/ast/ast.cc | 4 +- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 9 ++- frontends/ast/simplify.cc | 119 +++++++++++++++++++++++-------------- tests/opt/opt_clean_mem.ys | 8 +-- 5 files changed, 87 insertions(+), 55 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index e42cf0348a6..fe503c547a9 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -199,7 +199,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id) // create new node (AstNode constructor) // (the optional child arguments make it easier to create AST trees) -AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *child3) +AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *child3, AstNode *child4) { static unsigned int hashidx_count = 123456789; hashidx_count = mkhash_xorshift(hashidx_count); @@ -236,6 +236,8 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch children.push_back(child2); if (child3) children.push_back(child3); + if (child4) + children.push_back(child4); } // create a (deep recursive) copy of a node diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 57ce5605f4c..ba5a11b9683 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -221,7 +221,7 @@ namespace AST AstSrcLocType location; // creating and deleting nodes - AstNode(AstNodeType type = AST_NONE, AstNode *child1 = NULL, AstNode *child2 = NULL, AstNode *child3 = NULL); + AstNode(AstNodeType type = AST_NONE, AstNode *child1 = nullptr, AstNode *child2 = nullptr, AstNode *child3 = nullptr, AstNode *child4 = nullptr); AstNode *clone() const; void cloneInto(AstNode *other) const; void delete_children(); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 7fa751e2482..90d5f1bba11 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1720,21 +1720,24 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$meminit$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++); - RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($meminit)); + SigSpec en_sig = children[2]->genRTLIL(); + + RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($meminit_v2)); set_src_attr(cell, this); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); - if (children[2]->type != AST_CONSTANT) + if (children[3]->type != AST_CONSTANT) log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n"); - int num_words = int(children[2]->asInt(false)); + int num_words = int(children[3]->asInt(false)); cell->parameters[ID::WORDS] = RTLIL::Const(num_words); SigSpec addr_sig = children[0]->genRTLIL(); cell->setPort(ID::ADDR, addr_sig); cell->setPort(ID::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words, true)); + cell->setPort(ID::EN, en_sig); cell->parameters[ID::MEMID] = RTLIL::Const(str); cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig)); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5845c050126..f713cf8e119 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2648,25 +2648,20 @@ skip_dynamic_range_lvalue_expansion:; node_data->str = id_data; } - AstNode *node_en = nullptr; - if (current_always->type == AST_INITIAL) { - node_en = AstNode::mkconst_int(1, false); - } else { - AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); - wire_en->str = id_en; - wire_en->was_checked = true; - current_ast_mod->children.push_back(wire_en); - current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - - AstNode *assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); - assign_en->children[0]->str = id_en; - assign_en->children[0]->was_checked = true; - defNode->children.push_back(assign_en); + AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); + wire_en->str = id_en; + wire_en->was_checked = true; + current_ast_mod->children.push_back(wire_en); + current_scope[wire_en->str] = wire_en; + while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - node_en = new AstNode(AST_IDENTIFIER); - node_en->str = id_en; - } + AstNode *assign_en_first = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); + assign_en_first->children[0]->str = id_en; + assign_en_first->children[0]->was_checked = true; + defNode->children.push_back(assign_en_first); + + AstNode *node_en = new AstNode(AST_IDENTIFIER); + node_en->str = id_en; if (!defNode->children.empty()) current_top_block->children.insert(current_top_block->children.begin(), defNode); @@ -2690,13 +2685,11 @@ skip_dynamic_range_lvalue_expansion:; assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; - if (current_always->type != AST_INITIAL) { - for (int i = 0; i < mem_width; i++) - set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); - assign_en->children[0]->str = id_en; - assign_en->children[0]->was_checked = true; - } + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + assign_en->children[0]->was_checked = true; } else { @@ -2719,14 +2712,12 @@ skip_dynamic_range_lvalue_expansion:; assign_data->children[0]->str = id_data; assign_data->children[0]->was_checked = true; - if (current_always->type != AST_INITIAL) { - for (int i = 0; i < mem_width; i++) - set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; - assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), - new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); - assign_en->children[0]->str = id_en; - assign_en->children[0]->was_checked = true; - } + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), + new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); + assign_en->children[0]->str = id_en; + assign_en->children[0]->was_checked = true; delete left_at_zero_ast; delete right_at_zero_ast; @@ -2741,18 +2732,20 @@ skip_dynamic_range_lvalue_expansion:; assign_data->children[0]->was_checked = true; } - if (current_always->type != AST_INITIAL) { - assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); - assign_en->children[0]->str = id_en; - assign_en->children[0]->was_checked = true; - } + assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + assign_en->children[0]->was_checked = true; } if (assign_data) newNode->children.push_back(assign_data); if (assign_en) newNode->children.push_back(assign_en); - AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR, node_addr, node_data, node_en); + AstNode *wrnode; + if (current_always->type == AST_INITIAL) + wrnode = new AstNode(AST_MEMINIT, node_addr, node_data, node_en, mkconst_int(1, false)); + else + wrnode = new AstNode(AST_MEMWR, node_addr, node_data, node_en); wrnode->str = children[0]->str; wrnode->id2ast = children[0]->id2ast; wrnode->location = location; @@ -3921,8 +3914,12 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m AstNode *meminit = nullptr; int next_meminit_cursor=0; vector meminit_bits; + vector en_bits; int meminit_size=0; + for (int i = 0; i < mem_width; i++) + en_bits.push_back(State::S1); + std::ifstream f; f.open(mem_filename.c_str()); if (f.fail()) { @@ -3996,12 +3993,13 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m { if (meminit != nullptr) { meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false); - meminit->children[2] = AstNode::mkconst_int(meminit_size, false); + meminit->children[3] = AstNode::mkconst_int(meminit_size, false); } meminit = new AstNode(AST_MEMINIT); meminit->children.push_back(AstNode::mkconst_int(cursor, false)); meminit->children.push_back(nullptr); + meminit->children.push_back(AstNode::mkconst_bits(en_bits, false)); meminit->children.push_back(nullptr); meminit->str = memory->str; meminit->id2ast = memory; @@ -4036,7 +4034,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m if (meminit != nullptr) { meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false); - meminit->children[2] = AstNode::mkconst_int(meminit_size, false); + meminit->children[3] = AstNode::mkconst_int(meminit_size, false); } return block; @@ -4381,10 +4379,12 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, log_assert(children[0]->type == AST_CONSTANT); log_assert(children[1]->type == AST_CONSTANT); log_assert(children[2]->type == AST_CONSTANT); + log_assert(children[3]->type == AST_CONSTANT); int cursor = children[0]->asInt(false); Const data = children[1]->bitsAsConst(); - int length = children[2]->asInt(false); + Const en = children[2]->bitsAsConst(); + int length = children[3]->asInt(false); if (length != 0) { @@ -4395,10 +4395,37 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, int wordsz = GetSize(data) / length; for (int i = 0; i < length; i++) { - block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false))), mkconst_bits(data.extract(i*wordsz, wordsz).bits, false))); - block->children.back()->children[0]->str = str; - block->children.back()->children[0]->id2ast = id2ast; - block->children.back()->children[0]->was_checked = true; + int pos = 0; + while (pos < wordsz) { + if (en[pos] != State::S1) { + pos++; + } else { + int epos = pos + 1; + while (epos < wordsz && en[epos] == State::S1) + epos++; + int clen = epos - pos; + AstNode *range = new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false)); + if (pos != 0 || epos != wordsz) { + int left; + int right; + AstNode *mrange = id2ast->children[0]; + if (mrange->range_left < mrange->range_right) { + right = mrange->range_right - pos; + left = mrange->range_right - epos + 1; + } else { + right = mrange->range_right + pos; + left = mrange->range_right + epos - 1; + } + range = new AstNode(AST_MULTIRANGE, range, new AstNode(AST_RANGE, AstNode::mkconst_int(left, true), AstNode::mkconst_int(right, true))); + } + AstNode *target = new AstNode(AST_IDENTIFIER, range); + target->str = str; + target->id2ast = id2ast; + target->was_checked = true; + block->children.push_back(new AstNode(AST_ASSIGN_EQ, target, mkconst_bits(data.extract(i*wordsz + pos, clen).bits, false))); + pos = epos; + } + } } } diff --git a/tests/opt/opt_clean_mem.ys b/tests/opt/opt_clean_mem.ys index d08943da460..5e85df6c806 100644 --- a/tests/opt/opt_clean_mem.ys +++ b/tests/opt/opt_clean_mem.ys @@ -25,24 +25,24 @@ proc select -assert-count 2 t:$memrd select -assert-count 1 t:$memwr -select -assert-count 1 t:$meminit +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:$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:$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:$meminit_v2 From a055145b95b08bc97f3e3ee27842576d8ea09a94 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Jul 2021 00:49:14 +0000 Subject: [PATCH 0452/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c6ecd0de7c2..b52e1403ebe 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4224 +YOSYS_VER := 0.9+4228 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 3156226233133f5da9dba15c63ca560b4794b831 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 15 Jul 2021 10:36:50 -0400 Subject: [PATCH 0453/2410] verilog: save and restore overwritten macro arguments --- frontends/verilog/preproc.cc | 34 ++++++++++++++++++++++++++++---- frontends/verilog/preproc.h | 1 + tests/verilog/macro_arg_tromp.sv | 21 ++++++++++++++++++++ tests/verilog/macro_arg_tromp.ys | 2 ++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 tests/verilog/macro_arg_tromp.sv create mode 100644 tests/verilog/macro_arg_tromp.ys diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 4b9ebe0aa3d..17f56758752 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -36,6 +36,7 @@ #include "verilog_frontend.h" #include "kernel/log.h" #include +#include #include #include #include @@ -334,6 +335,11 @@ define_map_t::add(const std::string &name, const std::string &txt, const arg_map defines[name] = std::unique_ptr(new define_body_t(txt, args)); } +void define_map_t::add(const std::string &name, const define_body_t &body) +{ + defines[name] = std::unique_ptr(new define_body_t(body)); +} + void define_map_t::merge(const define_map_t &map) { for (const auto &pr : map.defines) { @@ -440,7 +446,17 @@ static bool read_argument(std::string &dest) } } -static bool try_expand_macro(define_map_t &defines, std::string &tok) +using macro_arg_stack_t = std::stack>; + +static void restore_macro_arg(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack) +{ + log_assert(!macro_arg_stack.empty()); + auto &overwritten_arg = macro_arg_stack.top(); + defines.add(overwritten_arg.first, overwritten_arg.second); + macro_arg_stack.pop(); +} + +static bool try_expand_macro(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack, std::string &tok) { if (tok == "`\"") { std::string literal("\""); @@ -450,7 +466,7 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok) if (ntok == "`\"") { insert_input(literal+"\""); return true; - } else if (!try_expand_macro(defines, ntok)) { + } else if (!try_expand_macro(defines, macro_arg_stack, ntok)) { literal += ntok; } } @@ -495,6 +511,10 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok) args.push_back(arg); } for (const auto &pr : body->args.get_vals(name, args)) { + if (const define_body_t *existing = defines.find(pr.first)) { + macro_arg_stack.push({pr.first, *existing}); + insert_input("`__restore_macro_arg "); + } defines.add(pr.first, pr.second); } } else { @@ -725,6 +745,7 @@ frontend_verilog_preproc(std::istream &f, defines.merge(pre_defines); defines.merge(global_defines_cache); + macro_arg_stack_t macro_arg_stack; std::vector filename_stack; // We are inside pass_level levels of satisfied ifdefs, and then within // fail_level levels of unsatisfied ifdefs. The unsatisfied ones are @@ -828,7 +849,7 @@ frontend_verilog_preproc(std::istream &f, if (tok == "`include") { skip_spaces(); std::string fn = next_token(true); - while (try_expand_macro(defines, fn)) { + while (try_expand_macro(defines, macro_arg_stack, fn)) { fn = next_token(); } while (1) { @@ -935,7 +956,12 @@ frontend_verilog_preproc(std::istream &f, continue; } - if (try_expand_macro(defines, tok)) + if (tok == "`__restore_macro_arg") { + restore_macro_arg(defines, macro_arg_stack); + continue; + } + + if (try_expand_macro(defines, macro_arg_stack, tok)) continue; output_code.push_back(tok); diff --git a/frontends/verilog/preproc.h b/frontends/verilog/preproc.h index e1048156c3c..330855a92af 100644 --- a/frontends/verilog/preproc.h +++ b/frontends/verilog/preproc.h @@ -42,6 +42,7 @@ struct define_map_t // Add a definition, overwriting any existing definition for name. void add(const std::string &name, const std::string &txt, const arg_map_t *args = nullptr); + void add(const std::string &name, const define_body_t &body); // Merge in another map of definitions (which take precedence // over anything currently defined). diff --git a/tests/verilog/macro_arg_tromp.sv b/tests/verilog/macro_arg_tromp.sv new file mode 100644 index 00000000000..a9c68a41724 --- /dev/null +++ b/tests/verilog/macro_arg_tromp.sv @@ -0,0 +1,21 @@ +// Taken from: https://github.com/YosysHQ/yosys/issues/2867 + +`define MIN(x, y) ((x) < (y) ? (x) : (y)) +`define CEIL_DIV(x, y) (((x) / (y)) + `MIN((x) % (y), 1)) + +module pad_msg1 (input logic [`MIN(512*`CEIL_DIV(64, 512), 64)-1:0] x, + output logic [`MIN(512*`CEIL_DIV(64, 512), 64)-1:0] y); + assign y[63:0] = x; +endmodule + +module pad_msg2 (input logic [((512*`CEIL_DIV(64, 512)) < (64) ? (512*`CEIL_DIV(64,512)) : (64))-1:0] x, + output logic [((512*`CEIL_DIV(64, 512)) < (64) ? (512*`CEIL_DIV(64,512)) : (64))-1:0] y); + assign y[63:0] = x; +endmodule + +module top(...); +`define add(x) x + +input [3:0] A; +output [3:0] B; +assign B = `add(`add(3)A)A; +endmodule diff --git a/tests/verilog/macro_arg_tromp.ys b/tests/verilog/macro_arg_tromp.ys new file mode 100644 index 00000000000..e8bd58e9b9a --- /dev/null +++ b/tests/verilog/macro_arg_tromp.ys @@ -0,0 +1,2 @@ +logger -expect-no-warnings +read_verilog -sv macro_arg_tromp.sv From 54e75129e57f29df1099f5cd45cec633d80e3841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 29 Jul 2021 16:55:15 +0200 Subject: [PATCH 0454/2410] opt_lut: Allow more than one -dlogic per cell type. Fixes #2061. --- passes/opt/opt_lut.cc | 53 ++++++++++++++++++++--------------- techlibs/ice40/synth_ice40.cc | 2 +- tests/arch/ice40/bug2061.ys | 24 ++++++++++++++++ 3 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 tests/arch/ice40/bug2061.ys diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 62310101645..3b079d964f4 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -24,16 +24,22 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +struct dlogic_t { + IdString cell_type; + // LUT input idx -> hard cell's port name + dict lut_input_port; +}; + struct OptLutWorker { - dict> &dlogic; + const std::vector &dlogic; RTLIL::Module *module; ModIndex index; SigMap sigmap; pool luts; dict luts_arity; - dict> luts_dlogics; + dict>> luts_dlogics; dict> luts_dlogic_inputs; int eliminated_count = 0, combined_count = 0; @@ -64,7 +70,7 @@ struct OptLutWorker void show_stats_by_arity() { dict arity_counts; - dict dlogic_counts; + std::vector dlogic_counts(dlogic.size()); int max_arity = 0; for (auto lut_arity : luts_arity) @@ -77,7 +83,7 @@ struct OptLutWorker { for (auto &lut_dlogic : lut_dlogics.second) { - dlogic_counts[lut_dlogic->type]++; + dlogic_counts[lut_dlogic.first]++; } } @@ -87,13 +93,13 @@ struct OptLutWorker if (arity_counts[arity]) log(" %d-LUT %16d\n", arity, arity_counts[arity]); } - for (auto &dlogic_count : dlogic_counts) + for (int i = 0; i < GetSize(dlogic); i++) { - log(" with %-12s %4d\n", dlogic_count.first.c_str(), dlogic_count.second); + log(" with %-12s (#%d) %4d\n", dlogic[i].cell_type.c_str(), i, dlogic_counts[i]); } } - OptLutWorker(dict> &dlogic, RTLIL::Module *module, int limit) : + OptLutWorker(const std::vector &dlogic, RTLIL::Module *module, int limit) : dlogic(dlogic), module(module), index(module), sigmap(module) { log("Discovering LUTs.\n"); @@ -116,20 +122,19 @@ struct OptLutWorker // First, find all dedicated logic we're connected to. This results in an overapproximation // of such connections. - pool lut_all_dlogics; + pool> lut_all_dlogics; for (int i = 0; i < lut_width; i++) { SigBit bit = lut_input[i]; for (auto &port : index.query_ports(bit)) { - if (dlogic.count(port.cell->type)) + for (int j = 0; j < GetSize(dlogic); j++) { - auto &dlogic_map = dlogic[port.cell->type]; - if (dlogic_map.count(i)) + if (dlogic[j].cell_type == port.cell->type) { - if (port.port == dlogic_map[i]) + if (port.port == dlogic[j].lut_input_port.at(i, IdString())) { - lut_all_dlogics.insert(port.cell); + lut_all_dlogics.insert({j, port.cell}); } } } @@ -143,25 +148,25 @@ struct OptLutWorker // * The connection is illegal. // In either of these cases, we don't need to concern ourselves with preserving the connection // between this LUT and this dedicated logic cell. - pool lut_legal_dlogics; + pool> lut_legal_dlogics; pool lut_dlogic_inputs; for (auto lut_dlogic : lut_all_dlogics) { - auto &dlogic_map = dlogic[lut_dlogic->type]; + auto &dlogic_map = dlogic[lut_dlogic.first].lut_input_port; bool legal = true; for (auto &dlogic_conn : dlogic_map) { if (lut_width <= dlogic_conn.first) { - log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second)); log_debug(" LUT input A[%d] not present.\n", dlogic_conn.first); legal = false; break; } - if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic->getPort(dlogic_conn.second))) + if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic.second->getPort(dlogic_conn.second))) { - log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); - log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic->getPort(dlogic_conn.second))); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second)); + log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic.second->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic.second->getPort(dlogic_conn.second))); legal = false; break; } @@ -169,7 +174,7 @@ struct OptLutWorker if (legal) { - log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); + log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second)); lut_legal_dlogics.insert(lut_dlogic); for (auto &dlogic_conn : dlogic_map) lut_dlogic_inputs.insert(dlogic_conn.first); @@ -544,7 +549,7 @@ struct OptLutPass : public Pass { { log_header(design, "Executing OPT_LUT pass (optimize LUTs).\n"); - dict> dlogic; + std::vector dlogic; int limit = -1; size_t argidx; @@ -556,7 +561,8 @@ struct OptLutPass : public Pass { split(tokens, args[++argidx], ':'); if (tokens.size() < 2) log_cmd_error("The -dlogic option requires at least one connection.\n"); - IdString type = "\\" + tokens[0]; + dlogic_t entry; + entry.cell_type = "\\" + tokens[0]; for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) { std::vector conn_tokens; split(conn_tokens, *it, '='); @@ -564,8 +570,9 @@ struct OptLutPass : public Pass { log_cmd_error("Invalid format of -dlogic signal mapping.\n"); IdString logic_port = "\\" + conn_tokens[0]; int lut_input = atoi(conn_tokens[1].c_str()); - dlogic[type][lut_input] = logic_port; + entry.lut_input_port[lut_input] = logic_port; } + dlogic.push_back(entry); continue; } if (args[argidx] == "-limit" && argidx + 1 < args.size()) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 3c84ea42620..421ec3b4e2e 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -399,7 +399,7 @@ struct SynthIce40Pass : public ScriptPass run("ice40_wrapcarry -unwrap"); run("techmap -map +/ice40/ff_map.v"); run("clean"); - run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3"); + run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 -dlogic SB_CARRY:CO=3"); } if (check_label("map_cells")) diff --git a/tests/arch/ice40/bug2061.ys b/tests/arch/ice40/bug2061.ys new file mode 100644 index 00000000000..7dd7ee6a3a7 --- /dev/null +++ b/tests/arch/ice40/bug2061.ys @@ -0,0 +1,24 @@ +read_verilog < Date: Fri, 30 Jul 2021 00:52:33 +0000 Subject: [PATCH 0455/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b52e1403ebe..1681ba903f5 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4228 +YOSYS_VER := 0.9+4231 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4fec3a85cd7d0fcd35f958bfc89090df25f7de3c Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 29 Jul 2021 12:35:22 -0400 Subject: [PATCH 0456/2410] genrtlil: add width detection for AST_PREFIX nodes --- frontends/ast/genrtlil.cc | 8 ++++++++ tests/simple/loop_prefix_case.v | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/simple/loop_prefix_case.v diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 90d5f1bba11..45aab9d8ebe 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -993,6 +993,14 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; } + case AST_PREFIX: + // Prefix nodes always resolve to identifiers in generate loops, so we + // can simply perform the resolution to determine the sign and width. + simplify(true, false, false, 1, -1, false, false); + log_assert(type == AST_IDENTIFIER); + detectSignWidthWorker(width_hint, sign_hint, found_real); + break; + case AST_FCALL: if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") { if (GetSize(children) == 1) { diff --git a/tests/simple/loop_prefix_case.v b/tests/simple/loop_prefix_case.v new file mode 100644 index 00000000000..7ee28ed7013 --- /dev/null +++ b/tests/simple/loop_prefix_case.v @@ -0,0 +1,18 @@ +module top( + input wire x, + output reg y +); + localparam I = 1; + genvar i; + generate + for (i = 0; i < 1; i = i + 1) begin : blk + wire [i:i] z = x; + end + endgenerate + always @* begin + case (blk[I - 1].z) + 1: y = 0; + 0: y = 1; + endcase + end +endmodule From c016f6a4236fb970196f35c2afb0f2c7c237a77f Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 28 Jul 2021 17:34:24 -0400 Subject: [PATCH 0457/2410] proc_rmdead: use explicit pattern set when there are no wildcards If width of a case expression was large, explicit patterns could cause the existing logic to take an extremely long time, or exhaust the maximum size of the underlying set. For cases where all of the patterns are fully defined and there are no constants in the case expression, this change uses a simple set to track which patterns have been seen. --- passes/proc/proc_rmdead.cc | 65 ++++++++- tests/proc/rmdead.v | 46 +++++++ tests/proc/rmdead.ys | 4 + tests/simple/case_large.v | 273 +++++++++++++++++++++++++++++++++++++ 4 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 tests/proc/rmdead.v create mode 100644 tests/proc/rmdead.ys create mode 100644 tests/simple/case_large.v diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index d49fd7ed31d..2ec11415a75 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -28,9 +28,62 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) +static bool can_use_fully_defined_pool(RTLIL::SwitchRule *sw) +{ + if (!GetSize(sw->signal)) + return false; + + for (const RTLIL::SigBit &bit : sw->signal) + if (bit.wire == NULL) + return false; + + for (const RTLIL::CaseRule *cas : sw->cases) + for (const RTLIL::SigSpec &sig : cas->compare) + if (!sig.is_fully_def()) + return false; + + return true; +} + +// This replicates the necessary parts of BitPatternPool's interface, but rather +// than storing remaining patterns, this explicitly stores which fully-defined +// constants have already been matched. +struct FullyDefinedPool +{ + FullyDefinedPool(const RTLIL::SigSpec &signal) + : max_patterns{signal.size() >= 32 ? 0ul : 1ul << signal.size()} + {} + + bool take(RTLIL::SigSpec sig) + { + if (default_reached || patterns.count(sig)) + return false; + patterns.insert(sig); + return true; + } + + void take_all() + { + default_reached = true; + } + + bool empty() + { + return default_reached || + (max_patterns && max_patterns == patterns.size()); + } + + pool patterns; + bool default_reached = false; + size_t max_patterns; +}; + +void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter); + +template +static void proc_rmdead_impl(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) { - BitPatternPool pool(sw->signal); + Pool pool(sw->signal); for (size_t i = 0; i < sw->cases.size(); i++) { @@ -68,6 +121,14 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) } } +void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) +{ + if (can_use_fully_defined_pool(sw)) + proc_rmdead_impl(sw, counter, full_case_counter); + else + proc_rmdead_impl(sw, counter, full_case_counter); +} + struct ProcRmdeadPass : public Pass { ProcRmdeadPass() : Pass("proc_rmdead", "eliminate dead trees in decision trees") { } void help() override diff --git a/tests/proc/rmdead.v b/tests/proc/rmdead.v new file mode 100644 index 00000000000..2be89e5333f --- /dev/null +++ b/tests/proc/rmdead.v @@ -0,0 +1,46 @@ +module top ( + input wire signed x, + output reg [31:0] y +); + wire signed fail = ~x; + + always @* + case (x) + 1'b0: y = 0; + 1'b1: y = 1; + default: y = fail; + endcase + + always @* + case (x) + 2'sb00: y = 0; + 2'sb00: y = fail; + endcase + + always @* + case (x) + 2'sb00: y = 0; + default: y = fail; + 2'sb01: y = 1; + 2'sb10: y = 2; + 2'sb11: y = 3; + 2'sb00: y = fail; + 2'sb01: y = fail; + 2'sb10: y = fail; + 2'sb11: y = fail; + endcase + + + always @* + case ({x, x}) + 2'b00: y = 0; + 2'b01: y = 1; + 2'b10: y = 2; + 2'b11: y = 3; + default: y = fail; + 2'b00: y = fail; + 2'b01: y = fail; + 2'b10: y = fail; + 2'b11: y = fail; + endcase +endmodule diff --git a/tests/proc/rmdead.ys b/tests/proc/rmdead.ys new file mode 100644 index 00000000000..697d899e3ed --- /dev/null +++ b/tests/proc/rmdead.ys @@ -0,0 +1,4 @@ +read_verilog rmdead.v +proc +opt_clean +select -assert-count 0 w:fail diff --git a/tests/simple/case_large.v b/tests/simple/case_large.v new file mode 100644 index 00000000000..a96ce86fe4e --- /dev/null +++ b/tests/simple/case_large.v @@ -0,0 +1,273 @@ +module top ( + input wire [127:0] x, + output reg [31:0] y +); + localparam A = 32'hDEAD_BEEF; + localparam B = 32'h0BAD_0B01; + localparam C = 32'hC001_D00D; + localparam D = 32'h1234_5678; + + always @* + case (x) + + {C,A,D,B}: y = 142; + {C,A,D,A}: y = 141; + {D,D,A,A}: y = 241; + {A,C,C,D}: y = 44; + {A,A,A,C}: y = 3; + {A,B,A,C}: y = 19; + {A,D,C,C}: y = 59; + {A,A,C,C}: y = 11; + {D,C,B,B}: y = 230; + {A,A,D,D}: y = 16; + {A,C,A,A}: y = 33; + {A,D,D,D}: y = 64; + {D,B,C,B}: y = 218; + {A,C,B,D}: y = 40; + {C,A,B,B}: y = 134; + {A,C,C,C}: y = 43; + {D,A,D,D}: y = 208; + {A,B,C,A}: y = 25; + {B,A,B,B}: y = 70; + {A,C,B,B}: y = 38; + {C,C,C,B}: y = 170; + {C,D,A,C}: y = 179; + {B,C,D,B}: y = 110; + {A,D,A,C}: y = 51; + {C,C,B,B}: y = 166; + {D,D,D,B}: y = 254; + {C,A,D,C}: y = 143; + {C,D,D,B}: y = 190; + {C,B,A,A}: y = 145; + {C,B,A,C}: y = 147; + {B,C,C,B}: y = 106; + {C,D,C,A}: y = 185; + {C,D,B,D}: y = 184; + {D,D,D,D}: y = 256; + {D,C,C,C}: y = 235; + {D,C,D,B}: y = 238; + {A,B,D,C}: y = 31; + {A,C,A,D}: y = 36; + {C,B,C,B}: y = 154; + {A,B,A,A}: y = 17; + {C,B,B,A}: y = 149; + {B,B,D,C}: y = 95; + {B,D,C,B}: y = 122; + {D,B,A,A}: y = 209; + {B,A,B,A}: y = 69; + {B,A,D,A}: y = 77; + {A,B,B,B}: y = 22; + {C,C,C,C}: y = 171; + {C,A,C,B}: y = 138; + {B,A,D,D}: y = 80; + {C,D,D,C}: y = 191; + {B,A,A,C}: y = 67; + {D,C,D,C}: y = 239; + {C,D,D,D}: y = 192; + {C,D,B,B}: y = 182; + {B,B,A,C}: y = 83; + {D,A,A,D}: y = 196; + {A,C,C,B}: y = 42; + {B,C,A,A}: y = 97; + {A,D,B,A}: y = 53; + {D,D,B,C}: y = 247; + {A,A,C,A}: y = 9; + {D,A,C,B}: y = 202; + {A,C,B,C}: y = 39; + {B,C,B,A}: y = 101; + {B,B,B,C}: y = 87; + {C,B,A,B}: y = 146; + {B,D,A,D}: y = 116; + {A,B,D,D}: y = 32; + {B,A,B,C}: y = 71; + {C,A,A,A}: y = 129; + {B,A,D,C}: y = 79; + {B,A,C,B}: y = 74; + {B,B,D,B}: y = 94; + {B,B,C,C}: y = 91; + {D,C,C,A}: y = 233; + {C,A,B,A}: y = 133; + {D,A,B,A}: y = 197; + {D,B,B,D}: y = 216; + {C,C,A,C}: y = 163; + {D,D,B,A}: y = 245; + {B,A,D,B}: y = 78; + {A,B,C,D}: y = 28; + {C,C,C,D}: y = 172; + {D,C,A,D}: y = 228; + {A,C,D,A}: y = 45; + {B,D,C,C}: y = 123; + {C,B,A,D}: y = 148; + {B,D,B,B}: y = 118; + {A,D,A,B}: y = 50; + {C,B,B,C}: y = 151; + {A,A,A,A}: y = 1; + {A,A,B,B}: y = 6; + {B,B,B,B}: y = 86; + {A,D,A,A}: y = 49; + {A,A,A,B}: y = 2; + {B,D,D,A}: y = 125; + {C,C,D,B}: y = 174; + {D,A,D,B}: y = 206; + {D,D,B,D}: y = 248; + {A,A,A,D}: y = 4; + {B,A,A,B}: y = 66; + {B,C,C,A}: y = 105; + {B,C,C,C}: y = 107; + {D,D,D,C}: y = 255; + {B,C,D,D}: y = 112; + {A,D,B,C}: y = 55; + {C,C,C,A}: y = 169; + {C,D,B,C}: y = 183; + {A,A,B,D}: y = 8; + {D,C,B,A}: y = 229; + {C,B,D,A}: y = 157; + {A,D,D,C}: y = 63; + {D,A,D,A}: y = 205; + {A,A,B,C}: y = 7; + {A,C,A,B}: y = 34; + {C,B,D,C}: y = 159; + {C,C,D,D}: y = 176; + {D,D,D,A}: y = 253; + {A,B,B,D}: y = 24; + {B,B,C,A}: y = 89; + {B,D,C,A}: y = 121; + {A,B,C,C}: y = 27; + {A,A,D,C}: y = 15; + {A,B,B,A}: y = 21; + {A,D,A,D}: y = 52; + {D,D,C,C}: y = 251; + {C,D,A,B}: y = 178; + {A,A,D,B}: y = 14; + {D,B,D,B}: y = 222; + {A,C,C,A}: y = 41; + {D,D,A,C}: y = 243; + {A,C,D,B}: y = 46; + {B,B,B,D}: y = 88; + {D,B,B,B}: y = 214; + {C,C,B,D}: y = 168; + {A,D,D,A}: y = 61; + {D,A,C,C}: y = 203; + {D,C,A,C}: y = 227; + {C,D,C,D}: y = 188; + {D,B,D,D}: y = 224; + {A,C,D,C}: y = 47; + {B,A,B,D}: y = 72; + {A,B,B,C}: y = 23; + {C,C,D,A}: y = 173; + {D,B,C,C}: y = 219; + {D,B,C,A}: y = 217; + {A,D,C,D}: y = 60; + {B,B,D,A}: y = 93; + {A,D,C,A}: y = 57; + {C,C,A,A}: y = 161; + {C,B,B,D}: y = 152; + {B,B,B,A}: y = 85; + {B,D,A,A}: y = 113; + {D,C,D,A}: y = 237; + {B,C,B,C}: y = 103; + {A,B,C,B}: y = 26; + {C,D,A,D}: y = 180; + {A,D,B,D}: y = 56; + {D,C,A,B}: y = 226; + {D,B,B,C}: y = 215; + {D,A,B,C}: y = 199; + {B,D,A,C}: y = 115; + {C,B,C,D}: y = 156; + {B,D,D,B}: y = 126; + {D,D,C,B}: y = 250; + {D,C,C,D}: y = 236; + {B,C,B,D}: y = 104; + {C,B,C,A}: y = 153; + {C,B,B,B}: y = 150; + {C,D,C,B}: y = 186; + {C,D,C,C}: y = 187; + {A,D,B,B}: y = 54; + {D,C,C,B}: y = 234; + {C,B,D,D}: y = 160; + {A,B,A,D}: y = 20; + {C,C,B,A}: y = 165; + {C,D,D,A}: y = 189; + {C,C,D,C}: y = 175; + {D,B,D,C}: y = 223; + {B,C,A,B}: y = 98; + {C,C,A,B}: y = 162; + {B,C,D,A}: y = 109; + {D,A,B,D}: y = 200; + {B,D,C,D}: y = 124; + {D,D,C,A}: y = 249; + {B,A,C,C}: y = 75; + {A,A,C,B}: y = 10; + {C,A,B,D}: y = 136; + {B,B,C,D}: y = 92; + {D,D,C,D}: y = 252; + {B,C,A,D}: y = 100; + {C,A,C,C}: y = 139; + {C,A,C,D}: y = 140; + {D,C,A,A}: y = 225; + {A,D,C,B}: y = 58; + {D,B,C,D}: y = 220; + {D,C,B,D}: y = 232; + {B,A,C,D}: y = 76; + {B,B,D,D}: y = 96; + {D,D,B,B}: y = 246; + {C,D,A,A}: y = 177; + {D,D,A,B}: y = 242; + {A,A,D,A}: y = 13; + {B,B,A,D}: y = 84; + {B,C,D,C}: y = 111; + {D,A,A,B}: y = 194; + {C,A,B,C}: y = 135; + {D,A,A,C}: y = 195; + {B,B,A,B}: y = 82; + {D,C,D,D}: y = 240; + {B,C,C,D}: y = 108; + {D,B,A,C}: y = 211; + {A,C,D,D}: y = 48; + {D,A,A,A}: y = 193; + {C,A,A,B}: y = 130; + {D,B,A,D}: y = 212; + {D,A,B,B}: y = 198; + {A,C,B,A}: y = 37; + {B,D,B,D}: y = 120; + {C,C,B,C}: y = 167; + {D,B,A,B}: y = 210; + {A,B,A,B}: y = 18; + {B,C,B,B}: y = 102; + {B,B,A,A}: y = 81; + {D,D,A,D}: y = 244; + {A,B,D,B}: y = 30; + {A,C,A,C}: y = 35; + {A,A,C,D}: y = 12; + {B,D,B,C}: y = 119; + {B,C,A,C}: y = 99; + {D,A,C,A}: y = 201; + {B,A,A,D}: y = 68; + {C,A,A,D}: y = 132; + {B,A,C,A}: y = 73; + {C,C,A,D}: y = 164; + {B,D,B,A}: y = 117; + {A,D,D,B}: y = 62; + {B,D,D,C}: y = 127; + {A,B,D,A}: y = 29; + {C,D,B,A}: y = 181; + {B,B,C,B}: y = 90; + {B,D,A,B}: y = 114; + {B,D,D,D}: y = 128; + {C,A,C,A}: y = 137; + {A,A,B,A}: y = 5; + {C,A,D,D}: y = 144; + {D,C,B,C}: y = 231; + {D,A,C,D}: y = 204; + {C,A,A,C}: y = 131; + {C,B,D,B}: y = 158; + {B,A,A,A}: y = 65; + {D,A,D,C}: y = 207; + {D,B,B,A}: y = 213; + {D,B,D,A}: y = 221; + {C,B,C,C}: y = 155; + + default: y = 0; + + endcase +endmodule From cfddef5d7d265d2260aad2d6ea8595f8b660eb6a Mon Sep 17 00:00:00 2001 From: Maciej Dudek Date: Thu, 29 Jul 2021 21:10:02 +0200 Subject: [PATCH 0458/2410] Fixes xc7 BRAM36s UG473 from Xilinx states that 15 bit should always be set if RAMB isn't in cascade mode. Signed-off-by: Maciej Dudek --- techlibs/xilinx/xc7_brams_map.v | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/techlibs/xilinx/xc7_brams_map.v b/techlibs/xilinx/xc7_brams_map.v index 2b6ad0da60a..982a5a07e9c 100644 --- a/techlibs/xilinx/xc7_brams_map.v +++ b/techlibs/xilinx/xc7_brams_map.v @@ -16,8 +16,9 @@ module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, input [71:0] B1DATA; input [7:0] B1EN; - wire [15:0] A1ADDR_16 = {A1ADDR, 6'b0}; - wire [15:0] B1ADDR_16 = {B1ADDR, 6'b0}; + // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019 + wire [15:0] A1ADDR_16 = {1'b1, A1ADDR, 6'b0}; + wire [15:0] B1ADDR_16 = {1'b1, B1ADDR, 6'b0}; wire [7:0] DIP, DOP; wire [63:0] DI, DO; @@ -153,8 +154,9 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, input [CFG_DBITS-1:0] B1DATA; input [CFG_ENABLE_B-1:0] B1EN; - wire [15:0] A1ADDR_16 = A1ADDR << (15 - CFG_ABITS); - wire [15:0] B1ADDR_16 = B1ADDR << (15 - CFG_ABITS); + // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019 + wire [15:0] A1ADDR_16 = {1'b1, A1ADDR} << (15 - CFG_ABITS); + wire [15:0] B1ADDR_16 = {1'b1, B1ADDR} << (15 - CFG_ABITS); wire [7:0] B1EN_8 = B1EN; wire [3:0] DIP, DOP; From c4a295cb8d74225f70cc6c71ba0d6b56fb2d92eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Fri, 30 Jul 2021 19:50:02 +0200 Subject: [PATCH 0459/2410] Update version.yml --- .github/workflows/version.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 0cd66875c78..c6f4da30d25 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -16,8 +16,11 @@ jobs: - name: Take last commit id: log run: echo "::set-output name=message::$(git log --no-merges -1 --oneline)" + - name: Take repository + id: repo + run: echo "::set-output name=message::$GITHUB_REPOSITORY" - name: Bump version - if: "!contains(steps.log.outputs.message, 'Bump version')" + if: "!contains(steps.log.outputs.message, 'Bump version') && contains(steps.repo.outputs.message, 'YosysHQ/yosys')" run: | make bumpversion git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" @@ -25,7 +28,7 @@ jobs: git add Makefile git commit -m "Bump version" - name: Push changes # push the output folder to your repo - if: "!contains(steps.log.outputs.message, 'Bump version')" + if: "!contains(steps.log.outputs.message, 'Bump version') && contains(steps.repo.outputs.message, 'YosysHQ/yosys')" uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} From 12db9b4273cf2725f361c5fc56f768ad694f9650 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 31 Jul 2021 00:50:30 +0000 Subject: [PATCH 0460/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1681ba903f5..aa366313593 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4231 +YOSYS_VER := 0.9+4236 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4451f7f5e9b451a7885259554cd3e9562bbf8f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 1 Aug 2021 01:29:49 +0200 Subject: [PATCH 0461/2410] memory_bram: Some refactoring This will make more sense when the new transparency masks land. Fixes #2902. --- passes/memory/memory_bram.cc | 370 ++++++++++++++++------------------- 1 file changed, 174 insertions(+), 196 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 7b3df8eecc2..31fd769b0f6 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -30,9 +30,6 @@ struct rules_t int group, index, dupidx; int wrmode, enable, transp, clocks, clkpol; - SigBit sig_clock; - SigSpec sig_addr, sig_data, sig_en; - bool effective_clkpol; bool make_transp; bool make_outreg; int mapped_port; @@ -93,7 +90,6 @@ struct rules_t pi.mapped_port = -1; pi.make_transp = false; pi.make_outreg = false; - pi.effective_clkpol = false; portinfos.push_back(pi); } return portinfos; @@ -402,10 +398,8 @@ struct rules_t } }; -bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, const rules_t::bram_t &bram, const rules_t::match_t &match, dict &match_properties, int mode) +bool replace_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals, const rules_t::bram_t &bram, const rules_t::match_t &match, dict &match_properties, int mode) { - // We will modify ports — make a copy of the structure. - Mem mem(orig_mem); Module *module = mem.module; auto portinfos = bram.make_portinfos(); @@ -441,35 +435,12 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant); // bram.dump_config(); - bool cell_init = !mem.inits.empty(); - vector initdata; - - if (cell_init) { - Const initparam = mem.get_init_data(); - initdata.reserve(mem.size); - for (int i=0; i < mem.size; i++) - initdata.push_back(initparam.extract(mem.width*i, mem.width, State::Sx)); - } - + std::vector shuffle_map; if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && !mem.wr_ports.empty()) { int bucket_size = bram.dbits / portinfos.at(match.shuffle_enable - 'A').enable; log(" Shuffle bit order to accommodate enable buckets of size %d..\n", bucket_size); - // extract unshuffled data/enable bits - - std::vector old_wr_en; - std::vector old_wr_data; - std::vector old_rd_data; - - for (auto &port : mem.wr_ports) { - old_wr_en.push_back(port.en); - old_wr_data.push_back(port.data); - } - - for (auto &port : mem.rd_ports) - old_rd_data.push_back(port.data); - // analyze enable structure std::vector en_order; @@ -484,52 +455,13 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c bits_wr_en[sig].push_back(i); } - // re-create memory ports - - std::vector new_wr_en(GetSize(old_wr_en)); - std::vector new_wr_data(GetSize(old_wr_data)); - std::vector new_rd_data(GetSize(old_rd_data)); - std::vector> new_initdata; - std::vector shuffle_map; - - if (cell_init) - new_initdata.resize(mem.size); - for (auto &it : en_order) { - auto &bits = bits_wr_en.at(it); - int buckets = (GetSize(bits) + bucket_size - 1) / bucket_size; - int fillbits = buckets*bucket_size - GetSize(bits); - SigBit fillbit; - - for (int i = 0; i < GetSize(bits); i++) { - for (int j = 0; j < GetSize(mem.wr_ports); j++) { - new_wr_en[j].append(old_wr_en[j][bits[i]]); - new_wr_data[j].append(old_wr_data[j][bits[i]]); - fillbit = old_wr_en[j][bits[i]]; - } - for (int j = 0; j < GetSize(mem.rd_ports); j++) - new_rd_data[j].append(old_rd_data[j][bits[i]]); - if (cell_init) { - for (int j = 0; j < mem.size; j++) - new_initdata[j].push_back(initdata[j][bits[i]]); - } - shuffle_map.push_back(bits[i]); - } + for (auto bit : bits_wr_en.at(it)) + shuffle_map.push_back(bit); - for (int i = 0; i < fillbits; i++) { - for (int j = 0; j < GetSize(mem.wr_ports); j++) { - new_wr_en[j].append(fillbit); - new_wr_data[j].append(State::S0); - } - for (int j = 0; j < GetSize(mem.rd_ports); j++) - new_rd_data[j].append(State::Sx); - if (cell_init) { - for (int j = 0; j < mem.size; j++) - new_initdata[j].push_back(State::Sx); - } + while (GetSize(shuffle_map) % bucket_size) shuffle_map.push_back(-1); - } } log(" Results of bit order shuffling:"); @@ -538,26 +470,15 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c log("\n"); // update mem_*, wr_*, and rd_* variables - - mem.width = GetSize(new_wr_en.front()); - - for (int i = 0; i < GetSize(mem.wr_ports); i++) { - auto &port = mem.wr_ports[i]; - port.en = new_wr_en[i]; - port.data = new_wr_data[i]; - } - - for (int i = 0; i < GetSize(mem.rd_ports); i++) { - auto &port = mem.rd_ports[i]; - port.data = new_rd_data[i]; - } - - if (cell_init) { - for (int i = 0; i < mem.size; i++) - initdata[i] = Const(new_initdata[i]); - } + } else { + for (int i = 0; i < mem.width; i++) + shuffle_map.push_back(i); } + // Align width up to dbits. + while (GetSize(shuffle_map) % bram.dbits) + shuffle_map.push_back(-1); + // assign write ports pair wr_clkdom; for (int cell_port_i = 0, bram_port_i = 0; cell_port_i < GetSize(mem.wr_ports); cell_port_i++) @@ -575,7 +496,7 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c for (; bram_port_i < GetSize(portinfos); bram_port_i++) { auto &pi = portinfos[bram_port_i]; - make_transp_enbits = pi.enable; + make_transp_enbits = pi.enable ? pi.enable : 1; make_transp_clk = clkdom; if (pi.wrmode != 1) @@ -602,16 +523,25 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c } } - SigSpec sig_en; - SigBit last_en_bit = State::S1; - for (int i = 0; i < mem.width; i++) { - if (pi.enable && i % (bram.dbits / pi.enable) == 0) { - last_en_bit = port.en[i]; - sig_en.append(last_en_bit); - } - if (last_en_bit != port.en[i]) { - log(" Bram port %c%d has incompatible enable structure.\n", pi.group + 'A', pi.index + 1); - goto skip_bram_wport; + // We need to check enable compatibility of this port, as well as all + // ports that have priority over this one (because they will be involved + // in emulate_priority logic). + + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &oport = mem.wr_ports[i]; + if (i != cell_port_i && !oport.priority_mask[cell_port_i]) + continue; + SigBit last_en_bit = State::S1; + for (int j = 0; j < GetSize(shuffle_map); j++) { + if (shuffle_map[j] == -1) + continue; + SigBit en_bit = oport.en[shuffle_map[j]]; + if (pi.enable && j % (bram.dbits / pi.enable) == 0) + last_en_bit = en_bit; + if (last_en_bit != en_bit) { + log(" Bram port %c%d has incompatible enable structure.\n", pi.group + 'A', pi.index + 1); + goto skip_bram_wport; + } } } @@ -621,14 +551,8 @@ bool replace_memory(Mem &orig_mem, const rules_t &rules, FfInitVals *initvals, c if (port.clk_enable) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; - pi.sig_clock = clkdom.first; - pi.effective_clkpol = clkdom.second; } - pi.sig_en = sig_en; - pi.sig_addr = port.addr; - pi.sig_data = port.data; - bram_port_i++; goto mapped_wr_port; } @@ -651,10 +575,6 @@ grow_read_ports:; for (auto &pi : portinfos) { if (pi.wrmode == 0) { pi.mapped_port = -1; - pi.sig_clock = SigBit(); - pi.sig_addr = SigSpec(); - pi.sig_data = SigSpec(); - pi.sig_en = SigSpec(); pi.make_outreg = false; pi.make_transp = false; } @@ -766,19 +686,13 @@ grow_read_ports:; log(" Mapped to bram port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); pi.mapped_port = cell_port_i; - if (port.clk_enable && !pi.make_outreg) { + if (pi.clocks) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; if (!pi.make_transp) read_transp[pi.transp] = transp; - pi.sig_clock = clkdom.first; - pi.sig_en = port.en; - pi.effective_clkpol = clkdom.second; } - pi.sig_addr = port.addr; - pi.sig_data = port.data; - if (grow_read_ports_cursor < cell_port_i) { grow_read_ports_cursor = cell_port_i; try_growing_more_read_ports = true; @@ -798,17 +712,19 @@ grow_read_ports:; // update properties and re-check conditions + int dcells = GetSize(shuffle_map) / bram.dbits; + int acells = (mem.size + (1 << bram.abits) - 1) / (1 << bram.abits); if (mode <= 1) { match_properties["dups"] = dup_count; match_properties["waste"] = match_properties["dups"] * match_properties["bwaste"]; - int cells = ((mem.width + bram.dbits - 1) / bram.dbits) * ((mem.size + (1 << bram.abits) - 1) / (1 << bram.abits)); + int cells = dcells * acells; match_properties["efficiency"] = (100 * match_properties["bits"]) / (dup_count * cells * bram.dbits * (1 << bram.abits)); - match_properties["dcells"] = ((mem.width + bram.dbits - 1) / bram.dbits); - match_properties["acells"] = ((mem.size + (1 << bram.abits) - 1) / (1 << bram.abits)); - match_properties["cells"] = match_properties["dcells"] * match_properties["acells"] * match_properties["dups"]; + match_properties["dcells"] = dcells; + match_properties["acells"] = acells; + match_properties["cells"] = cells * dup_count; log(" Updated properties: dups=%d waste=%d efficiency=%d\n", match_properties["dups"], match_properties["waste"], match_properties["efficiency"]); @@ -875,6 +791,70 @@ grow_read_ports:; return true; } + // At this point we are commited to replacing the RAM, and can mutate mem. + + // We don't really support priorities, emulate them. + for (int i = 0; i < GetSize(mem.wr_ports); i++) + for (int j = 0; j < i; j++) + mem.emulate_priority(j, i); + + // Now the big swizzle. + mem.width = GetSize(shuffle_map); + + // Swizzle write ports. + for (auto &port : mem.wr_ports) { + SigSpec new_en, new_data; + SigBit en_bit = State::S1; + for (auto idx : shuffle_map) { + if (idx == -1) { + new_data.append(State::Sx); + } else { + new_data.append(port.data[idx]); + en_bit = port.en[idx]; + } + new_en.append(en_bit); + } + port.en = new_en; + port.data = new_data; + } + + // Swizzle read ports. + for (auto &port : mem.rd_ports) { + SigSpec new_data = module->addWire(NEW_ID, mem.width); + Const new_init_value = Const(State::Sx, mem.width); + Const new_arst_value = Const(State::Sx, mem.width); + Const new_srst_value = Const(State::Sx, mem.width); + for (int i = 0; i < mem.width; i++) + if (shuffle_map[i] != -1) { + module->connect(port.data[shuffle_map[i]], new_data[i]); + new_init_value[i] = port.init_value[shuffle_map[i]]; + new_arst_value[i] = port.arst_value[shuffle_map[i]]; + new_srst_value[i] = port.srst_value[shuffle_map[i]]; + } + port.data = new_data; + port.init_value = new_init_value; + port.arst_value = new_arst_value; + port.srst_value = new_srst_value; + } + + // Swizzle the init data. + bool cell_init = !mem.inits.empty(); + vector initdata; + if (cell_init) { + Const initparam = mem.get_init_data(); + initdata.reserve(mem.size); + for (int i = 0; i < mem.size; i++) { + std::vector val; + for (auto idx : shuffle_map) { + if (idx == -1) + val.push_back(State::Sx); + else + val.push_back(initparam[mem.width * i + idx]); + } + initdata.push_back(Const(val)); + } + } + // prepare variant parameters dict variant_params; @@ -882,20 +862,15 @@ grow_read_ports:; bram.find_variant_params(variant_params, other_bram); // Apply make_outreg where necessary. - for (auto &pi : portinfos) { - if (pi.make_outreg) { + for (auto &pi : portinfos) + if (pi.make_outreg) mem.extract_rdff(pi.mapped_port, initvals); - auto &port = mem.rd_ports[pi.mapped_port]; - pi.sig_addr = port.addr; - pi.sig_data = port.data; - } - } // actually replace that memory cell dict> dout_cache; - for (int grid_d = 0; grid_d*bram.dbits < mem.width; grid_d++) + for (int grid_d = 0; grid_d < dcells; grid_d++) { SigSpec mktr_wraddr, mktr_wrdata, mktr_wrdata_q; vector mktr_wren; @@ -905,11 +880,11 @@ grow_read_ports:; mktr_wrdata = module->addWire(NEW_ID, bram.dbits); mktr_wrdata_q = module->addWire(NEW_ID, bram.dbits); module->addDff(NEW_ID, make_transp_clk.first, mktr_wrdata, mktr_wrdata_q, make_transp_clk.second); - for (int grid_a = 0; grid_a*(1 << bram.abits) < mem.size; grid_a++) + for (int grid_a = 0; grid_a < acells; grid_a++) mktr_wren.push_back(module->addWire(NEW_ID, make_transp_enbits)); } - for (int grid_a = 0; grid_a*(1 << bram.abits) < mem.size; grid_a++) + for (int grid_a = 0; grid_a < acells; grid_a++) for (int dupidx = 0; dupidx < dup_count; dupidx++) { Cell *c = module->addCell(module->uniquify(stringf("%s.%d.%d.%d", mem.memid.c_str(), grid_d, grid_a, dupidx)), bram.name); @@ -919,18 +894,16 @@ grow_read_ports:; c->setParam(vp.first, vp.second); if (cell_init) { - int init_offset = grid_a*(1 << bram.abits); + int init_offset = grid_a*(1 << bram.abits) - mem.start_offset; int init_shift = grid_d*bram.dbits; int init_size = (1 << bram.abits); Const initparam(State::Sx, init_size*bram.dbits); - for (int i = 0; i < init_size; i++) { - State padding = State::Sx; + for (int i = 0; i < init_size; i++) for (int j = 0; j < bram.dbits; j++) - if (init_offset+i < GetSize(initdata) && init_shift+j < GetSize(initdata[init_offset+i])) + if (init_offset+i < GetSize(initdata) && init_offset+i >= 0) initparam[i*bram.dbits+j] = initdata[init_offset+i][init_shift+j]; else - initparam[i*bram.dbits+j] = padding; - } + initparam[i*bram.dbits+j] = State::Sx; c->setParam(ID::INIT, initparam); } @@ -942,55 +915,75 @@ grow_read_ports:; string prefix = stringf("%c%d", pi.group + 'A', pi.index + 1); const char *pf = prefix.c_str(); - if (pi.clocks && (!c->hasPort(stringf("\\CLK%d", (pi.clocks-1) % clocks_max + 1)) || pi.sig_clock.wire)) { - c->setPort(stringf("\\CLK%d", (pi.clocks-1) % clocks_max + 1), pi.sig_clock); - if (pi.clkpol > 1 && pi.sig_clock.wire) - c->setParam(stringf("\\CLKPOL%d", (pi.clkpol-1) % clkpol_max + 1), clock_polarities.at(pi.clkpol)); - if (pi.transp > 1 && pi.sig_clock.wire) - c->setParam(stringf("\\TRANSP%d", (pi.transp-1) % transp_max + 1), read_transp.at(pi.transp)); - } + if (pi.clocks && clock_domains.count(pi.clocks)) + c->setPort(stringf("\\CLK%d", (pi.clocks-1) % clocks_max + 1), clock_domains.at(pi.clocks).first); + if (pi.clkpol > 1 && clock_polarities.count(pi.clkpol)) + c->setParam(stringf("\\CLKPOL%d", (pi.clkpol-1) % clkpol_max + 1), clock_polarities.at(pi.clkpol)); + if (pi.transp > 1 && read_transp.count(pi.transp)) + c->setParam(stringf("\\TRANSP%d", (pi.transp-1) % transp_max + 1), read_transp.at(pi.transp)); SigSpec addr_ok; - if (GetSize(pi.sig_addr) > bram.abits) { - SigSpec extra_addr = pi.sig_addr.extract(bram.abits, GetSize(pi.sig_addr) - bram.abits); + SigSpec sig_addr; + if (pi.mapped_port >= 0) { + if (pi.wrmode == 1) + sig_addr = mem.wr_ports[pi.mapped_port].addr; + else + sig_addr = mem.rd_ports[pi.mapped_port].addr; + } + + if (GetSize(sig_addr) > bram.abits) { + SigSpec extra_addr = sig_addr.extract(bram.abits, GetSize(sig_addr) - bram.abits); SigSpec extra_addr_sel = SigSpec(grid_a, GetSize(extra_addr)); addr_ok = module->Eq(NEW_ID, extra_addr, extra_addr_sel); } - if (pi.enable) - { - SigSpec sig_en = pi.sig_en; + sig_addr.extend_u0(bram.abits); + c->setPort(stringf("\\%sADDR", pf), sig_addr); - if (pi.wrmode == 1) { - sig_en.extend_u0((grid_d+1) * pi.enable); - sig_en = sig_en.extract(grid_d * pi.enable, pi.enable); + if (pi.wrmode == 1) { + if (pi.mapped_port == -1) + { + if (pi.enable) + c->setPort(stringf("\\%sEN", pf), Const(State::S0, pi.enable)); + continue; } - if (!addr_ok.empty()) - sig_en = module->Mux(NEW_ID, SigSpec(0, GetSize(sig_en)), sig_en, addr_ok); - - c->setPort(stringf("\\%sEN", pf), sig_en); + auto &port = mem.wr_ports[pi.mapped_port]; + SigSpec sig_data = port.data.extract(grid_d * bram.dbits, bram.dbits); + c->setPort(stringf("\\%sDATA", pf), sig_data); - if (pi.wrmode == 1 && enable_make_transp) - module->connect(mktr_wren[grid_a], sig_en); - } + if (pi.enable) + { + SigSpec sig_en; + int stride = bram.dbits / pi.enable; + for (int i = 0; i < pi.enable; i++) + sig_en.append(port.en[stride * i + grid_d * bram.dbits]); - SigSpec sig_addr = pi.sig_addr; - sig_addr.extend_u0(bram.abits); - c->setPort(stringf("\\%sADDR", pf), sig_addr); + if (!addr_ok.empty()) + sig_en = module->Mux(NEW_ID, SigSpec(0, GetSize(sig_en)), sig_en, addr_ok); - if (pi.wrmode == 1 && enable_make_transp && grid_a == 0) - module->connect(mktr_wraddr, sig_addr); + c->setPort(stringf("\\%sEN", pf), sig_en); - SigSpec sig_data = pi.sig_data; - sig_data.extend_u0((grid_d+1) * bram.dbits); - sig_data = sig_data.extract(grid_d * bram.dbits, bram.dbits); + if (enable_make_transp) + module->connect(mktr_wren[grid_a], sig_en); + } + else if (enable_make_transp) + module->connect(mktr_wren[grid_a], addr_ok); - if (pi.wrmode == 1) { - c->setPort(stringf("\\%sDATA", pf), sig_data); - if (enable_make_transp && grid_a == 0) + if (enable_make_transp && grid_a == 0) { + module->connect(mktr_wraddr, sig_addr); module->connect(mktr_wrdata, sig_data); + } } else { + if (pi.mapped_port == -1) + { + if (pi.enable) + c->setPort(stringf("\\%sEN", pf), State::S0); + continue; + } + auto &port = mem.rd_ports[pi.mapped_port]; + SigSpec sig_data = port.data.extract(grid_d * bram.dbits, bram.dbits); + SigSpec bram_dout = module->addWire(NEW_ID, bram.dbits); c->setPort(stringf("\\%sDATA", pf), bram_dout); if (pi.make_transp) { @@ -1010,22 +1003,21 @@ grow_read_ports:; } } - for (int i = bram.dbits-1; i >= 0; i--) - if (sig_data[i].wire == nullptr) { - sig_data.remove(i); - bram_dout.remove(i); - } - SigSpec addr_ok_q = addr_ok; - if (pi.clocks && !addr_ok.empty()) { + if (port.clk_enable && !addr_ok.empty()) { addr_ok_q = module->addWire(NEW_ID); - if (!pi.sig_en.empty()) - addr_ok = module->Mux(NEW_ID, addr_ok_q, addr_ok, pi.sig_en); - module->addDff(NEW_ID, pi.sig_clock, addr_ok, addr_ok_q, pi.effective_clkpol); + module->addDffe(NEW_ID, port.clk, port.en, addr_ok, addr_ok_q, port.clk_polarity); } dout_cache[sig_data].first.append(addr_ok_q); dout_cache[sig_data].second.append(bram_dout); + + if (pi.enable) { + SigSpec sig_en = port.en; + if (!addr_ok.empty()) + sig_en = module->And(NEW_ID, sig_en, addr_ok); + c->setPort(stringf("\\%sEN", pf), sig_en); + } } } } @@ -1070,20 +1062,6 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) log(" %s=%d", it.first.c_str(), it.second); log("\n"); - // This pass cannot deal with write port priority — we need to emulate it, - // if present. Since priority emulation will change the enable signals, - // which in turn may change enable grouping and mapping eligibility in - // pathological cases, we need to do this before checking mapping - // eligibility. This will create priority emulation logic for all - // memories in the design regardless of whether we end up mapping them - // or not, but since we never call Mem::emit(), the new priority masks - // and enables won't be commited to the design, and this logic will be - // unused (and removed by subsequent opt_clean) for unmapped memories. - - for (int i = 0; i < GetSize(mem.wr_ports); i++) - for (int j = 0; j < i; j++) - mem.emulate_priority(j, i); - pool> failed_brams; dict, tuple> best_rule_cache; From ec2a468bd389a8275a9a2584fb475901cc495d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 23:42:58 +0200 Subject: [PATCH 0462/2410] backend/verilog: Add alternate mode for transparent read port output. This mode will be used whenever read port cannot be handled in the "extract address register" way, ie. whenever it has enable, reset, init functionality or (in the future) mixed transparency mask. --- backends/verilog/verilog_backend.cc | 72 ++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index b363bc2fe43..8f96c3a5898 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -553,7 +553,17 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) clk_to_arst_cond[clk_domain_str] = os2.str(); } } - if (!port.transparent) + + // Decide how to represent the transparency; same idea as Mem::extract_rdff. + bool trans_use_addr = port.transparent; + + if (GetSize(mem.wr_ports) == 0) + trans_use_addr = false; + + if (port.en != State::S1 || port.srst != State::S0 || port.arst != State::S0 || !port.init_value.is_fully_undef()) + trans_use_addr = false; + + if (!trans_use_addr) { // for clocked read ports make something like: // reg [..] temp_id; @@ -618,6 +628,66 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) clk_to_lof_body[clk_domain_str].push_back(os.str()); } + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &wport = mem.wr_ports[i]; + if (!port.transparent) + continue; + if (!wport.clk_enable) + continue; + if (wport.clk != port.clk) + continue; + if (wport.clk_polarity != port.clk_polarity) + continue; + int min_wide_log2 = std::min(port.wide_log2, wport.wide_log2); + int max_wide_log2 = std::max(port.wide_log2, wport.wide_log2); + bool wide_write = wport.wide_log2 > port.wide_log2; + for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { + SigSpec raddr = port.addr; + SigSpec waddr = wport.addr; + if (wide_write) + waddr = wport.sub_addr(sub); + else + raddr = port.sub_addr(sub); + int pos = 0; + int ewidth = mem.width << min_wide_log2; + int wsub = wide_write ? sub : 0; + int rsub = wide_write ? 0 : sub; + while (pos < ewidth) { + int epos = pos; + while (epos < ewidth && wport.en[epos + wsub * mem.width] == wport.en[pos + wsub * mem.width]) + epos++; + + std::ostringstream os; + if (has_indent) + os << indent; + os << "if ("; + dump_sigspec(os, wport.en[pos + wsub * mem.width]); + if (raddr != waddr) { + os << " && "; + dump_sigspec(os, raddr); + os << " == "; + dump_sigspec(os, waddr); + } + os << ")\n"; + clk_to_lof_body[clk_domain_str].push_back(os.str()); + + std::ostringstream os2; + if (has_indent) + os2 << indent; + os2 << indent; + os2 << temp_id; + if (epos-pos != GetSize(port.data)) + os2 << stringf("[%d:%d]", rsub * mem.width + epos-1, rsub * mem.width + pos); + os2 << " <= "; + dump_sigspec(os2, wport.data.extract(wsub * mem.width + pos, epos-pos)); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + + pos = epos; + } + } + } + if (port.srst != State::S0 && port.ce_over_srst) { std::ostringstream os; From 10bcc4e1926cb7cee7aa12646e82ec16a42ce480 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Aug 2021 00:50:24 +0000 Subject: [PATCH 0463/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index aa366313593..62859f97fc6 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4236 +YOSYS_VER := 0.9+4239 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From be04d8834ea5380a8926255cd6a9482806006b91 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 2 Aug 2021 10:29:16 +0200 Subject: [PATCH 0464/2410] Require latest verific --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 357b8804379..5a10568c7aa 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -56,7 +56,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210603 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210701 # error "Please update your version of YosysHQ flavored Verific." #endif From ca8ad62696df129a83b77d0e6c2ca33f0c553bc7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Aug 2021 00:55:22 +0000 Subject: [PATCH 0465/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 62859f97fc6..ef2fb17d142 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4239 +YOSYS_VER := 0.9+4241 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 8733e1923a0dd0de727dd791dc4bcbf194b56b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 3 Aug 2021 14:28:10 +0200 Subject: [PATCH 0466/2410] memory_bram: Move init data swizzling before other swizzling. Fixes #2907. --- passes/memory/memory_bram.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 31fd769b0f6..af8137adac1 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -798,6 +798,24 @@ grow_read_ports:; for (int j = 0; j < i; j++) mem.emulate_priority(j, i); + // Swizzle the init data. Do this before changing mem.width, so that get_init_data works. + bool cell_init = !mem.inits.empty(); + vector initdata; + if (cell_init) { + Const initparam = mem.get_init_data(); + initdata.reserve(mem.size); + for (int i = 0; i < mem.size; i++) { + std::vector val; + for (auto idx : shuffle_map) { + if (idx == -1) + val.push_back(State::Sx); + else + val.push_back(initparam[mem.width * i + idx]); + } + initdata.push_back(Const(val)); + } + } + // Now the big swizzle. mem.width = GetSize(shuffle_map); @@ -837,24 +855,6 @@ grow_read_ports:; port.srst_value = new_srst_value; } - // Swizzle the init data. - bool cell_init = !mem.inits.empty(); - vector initdata; - if (cell_init) { - Const initparam = mem.get_init_data(); - initdata.reserve(mem.size); - for (int i = 0; i < mem.size; i++) { - std::vector val; - for (auto idx : shuffle_map) { - if (idx == -1) - val.push_back(State::Sx); - else - val.push_back(initparam[mem.width * i + idx]); - } - initdata.push_back(Const(val)); - } - } - // prepare variant parameters dict variant_params; From d8b0c3277fb778a1d613dde1fd2d1c47e947d01b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:49:53 +0000 Subject: [PATCH 0467/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ef2fb17d142..9cce132d363 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4241 +YOSYS_VER := 0.9+4243 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 63f9e0544fcb793dcc47b9c5a6d8b0e46d84a225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 4 Aug 2021 03:33:41 +0200 Subject: [PATCH 0468/2410] memory_share: Don't skip ports with EN wired to input for SAT sharing. Fixes #2912. --- passes/memory/memory_share.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 846583c2ca2..4e6a30ef1af 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -288,8 +288,7 @@ struct MemoryShareWorker for (auto bit : bits) if (bit == RTLIL::State::S1) goto port_is_always_active; - if (modwalker.has_drivers(bits)) - eligible_ports.insert(i); + eligible_ports.insert(i); port_is_always_active:; } @@ -310,7 +309,6 @@ struct MemoryShareWorker if (checked_ports.count(i)) continue; - std::vector group; group.push_back(i); From 2e421feb0ea526468493ab008f3c72beb12c2bc6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 5 Aug 2021 00:51:08 +0000 Subject: [PATCH 0469/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9cce132d363..c7e410cf9aa 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4243 +YOSYS_VER := 0.9+4245 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 52cbf1bea52b05c3fa57712ce201369c92400008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 6 Aug 2021 20:49:41 +0200 Subject: [PATCH 0470/2410] verilog: Support tri/triand/trior wire types. These are, by the standard, just aliases for wire/wand/wor. Fixes #2918. --- frontends/verilog/verilog_lexer.l | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 54fb652403a..0306f5494b3 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -277,8 +277,11 @@ static bool isUserType(std::string &s) "output" { return TOK_OUTPUT; } "inout" { return TOK_INOUT; } "wire" { return TOK_WIRE; } +"tri" { return TOK_WIRE; } "wor" { return TOK_WOR; } +"trior" { return TOK_WOR; } "wand" { return TOK_WAND; } +"triand" { return TOK_WAND; } "reg" { return TOK_REG; } "integer" { return TOK_INTEGER; } "signed" { return TOK_SIGNED; } From a24906a7d2a1e1d915235044d11db2815f0fba25 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 7 Aug 2021 00:45:55 +0000 Subject: [PATCH 0471/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c7e410cf9aa..607b8d8b245 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4245 +YOSYS_VER := 0.9+4247 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 98003430d672af05cff7d950e08a42526e766f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 8 Aug 2021 00:33:31 +0200 Subject: [PATCH 0472/2410] opt_merge: Use FfInitVals. Partial #2920 fix. --- passes/opt/opt_merge.cc | 35 +++++++------------------------ tests/opt/bug2920.ys | 42 +++++++++++++++++++++++++++++++++++++ tests/opt/opt_merge_init.ys | 2 +- 3 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 tests/opt/bug2920.ys diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index f27277574e2..d9861f49b08 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -18,6 +18,7 @@ */ #include "kernel/register.h" +#include "kernel/ffinit.h" #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" @@ -35,7 +36,7 @@ struct OptMergeWorker RTLIL::Design *design; RTLIL::Module *module; SigMap assign_map; - SigMap dff_init_map; + FfInitVals initvals; bool mode_share_all; CellTypes ct; @@ -121,8 +122,7 @@ struct OptMergeWorker if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) { // For the 'Q' output of state elements, // use its (* init *) attribute value - for (const auto &b : dff_init_map(it.second)) - sig.append(b.wire ? State::Sx : b); + sig = initvals(it.second); } else continue; @@ -176,12 +176,8 @@ struct OptMergeWorker if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) { // For the 'Q' output of state elements, // use the (* init *) attribute value - auto &sig1 = conn1[it.first]; - for (const auto &b : dff_init_map(it.second)) - sig1.append(b.wire ? State::Sx : b); - auto &sig2 = conn2[it.first]; - for (const auto &b : dff_init_map(cell2->getPort(it.first))) - sig2.append(b.wire ? State::Sx : b); + conn1[it.first] = initvals(it.second); + conn2[it.first] = initvals(cell2->getPort(it.first)); } else { conn1[it.first] = RTLIL::SigSpec(); @@ -247,14 +243,7 @@ struct OptMergeWorker log("Finding identical cells in module `%s'.\n", module->name.c_str()); assign_map.set(module); - dff_init_map.set(module); - for (auto &it : module->wires_) - if (it.second->attributes.count(ID::init) != 0) { - Const initval = it.second->attributes.at(ID::init); - for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - dff_init_map.add(SigBit(it.second, i), initval[i]); - } + initvals.set(&assign_map, module); bool did_something = true; while (did_something) @@ -296,16 +285,8 @@ struct OptMergeWorker module->connect(RTLIL::SigSig(it.second, other_sig)); assign_map.add(it.second, other_sig); - if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) { - for (auto c : it.second.chunks()) { - auto jt = c.wire->attributes.find(ID::init); - if (jt == c.wire->attributes.end()) - continue; - for (int i = c.offset; i < c.offset + c.width; i++) - jt->second[i] = State::Sx; - } - dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second))); - } + if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) + initvals.remove_init(it.second); } } log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); diff --git a/tests/opt/bug2920.ys b/tests/opt/bug2920.ys new file mode 100644 index 00000000000..a8281a73ab8 --- /dev/null +++ b/tests/opt/bug2920.ys @@ -0,0 +1,42 @@ +read_ilang < Date: Sun, 8 Aug 2021 00:50:48 +0000 Subject: [PATCH 0473/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 607b8d8b245..8a7d938df64 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4247 +YOSYS_VER := 0.9+4249 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From d25b9088c83ba68b938ef9f0d97793a08001a9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 4 Aug 2021 00:02:16 +0200 Subject: [PATCH 0474/2410] Refactor common parts of SAT-using optimizations into a helper. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also aligns the functionality: - in all cases, the onehot attribute is used to create appropriate constraints (previously, opt_dff didn't do it at all, and share created one-hot constraints based on $pmux presence alone, which is unsound) - in all cases, shift and mul/div/pow cells are now skipped when importing the SAT problem (previously only memory_share did this) — this avoids creating clauses for hard cells that are unlikely to help with proving the UNSATness needed for optimization --- Makefile | 3 +- kernel/modtools.h | 6 +- kernel/qcsat.cc | 102 ++++++++++++++++++++++++++++++++++ kernel/qcsat.h | 76 +++++++++++++++++++++++++ passes/memory/memory_share.cc | 71 ++++------------------- passes/opt/opt_dff.cc | 44 ++++----------- passes/opt/share.cc | 75 ++++++------------------- 7 files changed, 224 insertions(+), 153 deletions(-) create mode 100644 kernel/qcsat.cc create mode 100644 kernel/qcsat.h diff --git a/Makefile b/Makefile index 8a7d938df64..4e13da31c7e 100644 --- a/Makefile +++ b/Makefile @@ -575,6 +575,7 @@ $(eval $(call add_include_file,kernel/modtools.h)) $(eval $(call add_include_file,kernel/macc.h)) $(eval $(call add_include_file,kernel/utils.h)) $(eval $(call add_include_file,kernel/satgen.h)) +$(eval $(call add_include_file,kernel/qcsat.h)) $(eval $(call add_include_file,kernel/ff.h)) $(eval $(call add_include_file,kernel/ffinit.h)) $(eval $(call add_include_file,kernel/mem.h)) @@ -599,7 +600,7 @@ ifneq ($(ABCEXTERNAL),) kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' endif endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/mem.o kernel/ffmerge.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' diff --git a/kernel/modtools.h b/kernel/modtools.h index bd393b5d580..4cbaf78d0d6 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -380,9 +380,11 @@ struct ModWalker } } - ModWalker(RTLIL::Design *design) : design(design), module(NULL) + ModWalker(RTLIL::Design *design, RTLIL::Module *module = nullptr) : design(design), module(NULL) { - ct.setup(design); + ct.setup(design); + if (module) + setup(module); } void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL) diff --git a/kernel/qcsat.cc b/kernel/qcsat.cc new file mode 100644 index 00000000000..b7da958dba1 --- /dev/null +++ b/kernel/qcsat.cc @@ -0,0 +1,102 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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/qcsat.h" + +USING_YOSYS_NAMESPACE + +std::vector QuickConeSat::importSig(SigSpec sig) +{ + sig = modwalker.sigmap(sig); + for (auto bit : sig) + bits_queue.insert(bit); + return satgen.importSigSpec(sig); +} + +int QuickConeSat::importSigBit(SigBit bit) +{ + bit = modwalker.sigmap(bit); + bits_queue.insert(bit); + return satgen.importSigBit(bit); +} + +void QuickConeSat::prepare() +{ + while (!bits_queue.empty()) + { + pool portbits; + modwalker.get_drivers(portbits, bits_queue); + + for (auto bit : bits_queue) + if (bit.wire && bit.wire->get_bool_attribute(ID::onehot) && !imported_onehot.count(bit.wire)) + { + std::vector bits = satgen.importSigSpec(bit.wire); + for (int i : bits) + for (int j : bits) + if (i != j) + ez->assume(ez->NOT(i), j); + imported_onehot.insert(bit.wire); + } + + bits_queue.clear(); + + for (auto &pbit : portbits) + { + if (imported_cells.count(pbit.cell)) + continue; + if (cell_complexity(pbit.cell) > max_cell_complexity) + continue; + if (max_cell_outs && GetSize(modwalker.cell_outputs[pbit.cell]) > max_cell_outs) + continue; + auto &inputs = modwalker.cell_inputs[pbit.cell]; + bits_queue.insert(inputs.begin(), inputs.end()); + satgen.importCell(pbit.cell); + imported_cells.insert(pbit.cell); + } + + if (max_cell_count && GetSize(imported_cells) > max_cell_count) + break; + } +} + +int QuickConeSat::cell_complexity(RTLIL::Cell *cell) +{ + if (cell->type.in(ID($concat), ID($slice), ID($pos), ID($_BUF_))) + return 0; + if (cell->type.in(ID($not), ID($and), ID($or), ID($xor), ID($xnor), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), + ID($reduce_xnor), ID($reduce_bool), + ID($logic_not), ID($logic_and), ID($logic_or), + ID($eq), ID($ne), ID($eqx), ID($nex), ID($fa), + ID($mux), ID($pmux), ID($lut), ID($sop), + ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), + ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), + ID($_MUX_), ID($_NMUX_), ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), + ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) + return 1; + if (cell->type.in(ID($neg), ID($add), ID($sub), ID($alu), ID($lcu), + ID($lt), ID($le), ID($gt), ID($ge))) + return 2; + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) + return 3; + if (cell->type.in(ID($mul), ID($macc), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) + return 4; + // Unknown cell. + return 5; +} diff --git a/kernel/qcsat.h b/kernel/qcsat.h new file mode 100644 index 00000000000..e4d3c3c5dc6 --- /dev/null +++ b/kernel/qcsat.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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. + * + */ + +#ifndef QCSAT_H +#define QCSAT_H + +#include "kernel/satgen.h" +#include "kernel/modtools.h" + +YOSYS_NAMESPACE_BEGIN + +// This is a helper class meant for easy construction of quick SAT queries +// to a combinatorial input cone of some set of signals, meant for SAT-based +// optimizations. Various knobs are provided to set just how much of the +// cone should be included in the model — since this class is meant for +// optimization, it should not be a correctness problem when some cells are +// skipped and the solver spuriously returns SAT with a solution that +// cannot exist in reality due to skipped constraints (ie. only UNSAT results +// from this class should be considered binding). +struct QuickConeSat { + ModWalker &modwalker; + ezSatPtr ez; + SatGen satgen; + + // The effort level knobs. + + // The maximum "complexity level" of cells that will be imported. + // - 1: bitwise operations, muxes, equality comparisons, lut, sop, fa + // - 2: addition, subtraction, greater/less than comparisons, lcu + // - 3: shifts + // - 4: multiplication, division, power + int max_cell_complexity = 2; + // The maximum number of cells to import, or 0 for no limit. + int max_cell_count = 0; + // If non-0, skip importing cells with more than this number of output bits. + int max_cell_outs = 0; + + // Internal state. + pool imported_cells; + pool imported_onehot; + pool bits_queue; + + QuickConeSat(ModWalker &modwalker) : modwalker(modwalker), ez(), satgen(ez.get(), &modwalker.sigmap) {} + + // Imports a signal into the SAT solver, queues its input cone to be + // imported in the next prepare() call. + std::vector importSig(SigSpec sig); + int importSigBit(SigBit bit); + + // Imports the input cones of all previously importSig'd signals into + // the SAT solver. + void prepare(); + + // Returns the "complexity level" of a given cell. + static int cell_complexity(RTLIL::Cell *cell); +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 4e6a30ef1af..91f36ce05cb 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -18,7 +18,7 @@ */ #include "kernel/yosys.h" -#include "kernel/satgen.h" +#include "kernel/qcsat.h" #include "kernel/sigtools.h" #include "kernel/modtools.h" #include "kernel/mem.h" @@ -32,7 +32,6 @@ struct MemoryShareWorker RTLIL::Module *module; SigMap sigmap, sigmap_xmux; ModWalker modwalker; - CellTypes cone_ct; bool flag_widen; @@ -358,56 +357,20 @@ struct MemoryShareWorker // Okay, time to actually run the SAT solver. - ezSatPtr ez; - SatGen satgen(ez.get(), &modwalker.sigmap); + QuickConeSat qcsat(modwalker); // create SAT representation of common input cone of all considered EN signals - pool one_hot_wires; - std::set sat_cells; - std::set bits_queue; dict port_to_sat_variable; - for (auto idx : group) { - RTLIL::SigSpec sig = modwalker.sigmap(mem.wr_ports[idx].en); - port_to_sat_variable[idx] = ez->expression(ez->OpOr, satgen.importSigSpec(sig)); - - std::vector bits = sig; - bits_queue.insert(bits.begin(), bits.end()); - } - - while (!bits_queue.empty()) - { - for (auto bit : bits_queue) - if (bit.wire && bit.wire->get_bool_attribute(ID::onehot)) - one_hot_wires.insert(bit.wire); - - pool portbits; - modwalker.get_drivers(portbits, bits_queue); - bits_queue.clear(); - - for (auto &pbit : portbits) - if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { - pool &cell_inputs = modwalker.cell_inputs[pbit.cell]; - bits_queue.insert(cell_inputs.begin(), cell_inputs.end()); - sat_cells.insert(pbit.cell); - } - } - - for (auto wire : one_hot_wires) { - log(" Adding one-hot constraint for wire %s.\n", log_id(wire)); - vector ez_wire_bits = satgen.importSigSpec(wire); - for (int i : ez_wire_bits) - for (int j : ez_wire_bits) - if (i != j) ez->assume(ez->NOT(i), j); - } + for (auto idx : group) + port_to_sat_variable[idx] = qcsat.ez->expression(qcsat.ez->OpOr, qcsat.importSig(mem.wr_ports[idx].en)); - log(" Common input cone for all EN signals: %d cells.\n", int(sat_cells.size())); + qcsat.prepare(); - for (auto cell : sat_cells) - satgen.importCell(cell); + log(" Common input cone for all EN signals: %d cells.\n", GetSize(qcsat.imported_cells)); - log(" Size of unconstrained SAT problem: %d variables, %d clauses\n", ez->numCnfVariables(), ez->numCnfClauses()); + log(" Size of unconstrained SAT problem: %d variables, %d clauses\n", qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); // now try merging the ports. @@ -422,14 +385,14 @@ struct MemoryShareWorker if (port2.removed) continue; - if (ez->solve(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2))) { + if (qcsat.ez->solve(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2))) { log(" According to SAT solver sharing of port %d with port %d is not possible.\n", idx1, idx2); continue; } log(" Merging port %d into port %d.\n", idx2, idx1); mem.prepare_wr_merge(idx1, idx2); - port_to_sat_variable.at(idx1) = ez->OR(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2)); + port_to_sat_variable.at(idx1) = qcsat.ez->OR(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2)); RTLIL::SigSpec last_addr = port1.addr; RTLIL::SigSpec last_data = port1.data; @@ -511,21 +474,7 @@ struct MemoryShareWorker while (consolidate_wr_by_addr(mem)); } - cone_ct.setup_internals(); - cone_ct.cell_types.erase(ID($mul)); - cone_ct.cell_types.erase(ID($mod)); - cone_ct.cell_types.erase(ID($div)); - cone_ct.cell_types.erase(ID($modfloor)); - cone_ct.cell_types.erase(ID($divfloor)); - cone_ct.cell_types.erase(ID($pow)); - cone_ct.cell_types.erase(ID($shl)); - cone_ct.cell_types.erase(ID($shr)); - cone_ct.cell_types.erase(ID($sshl)); - cone_ct.cell_types.erase(ID($sshr)); - cone_ct.cell_types.erase(ID($shift)); - cone_ct.cell_types.erase(ID($shiftx)); - - modwalker.setup(module, &cone_ct); + modwalker.setup(module); for (auto &mem : memories) consolidate_wr_using_sat(mem); diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 94d6d544366..ddf08392bb8 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -21,7 +21,8 @@ #include "kernel/log.h" #include "kernel/register.h" #include "kernel/rtlil.h" -#include "kernel/satgen.h" +#include "kernel/qcsat.h" +#include "kernel/modtools.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" #include "kernel/ff.h" @@ -51,26 +52,23 @@ struct OptDffWorker FfInitVals initvals; dict bitusers; dict bit2mux; - dict bit2driver; typedef std::map pattern_t; typedef std::set patterns_t; typedef std::pair ctrl_t; typedef std::set ctrls_t; - ezSatPtr ez; - SatGen satgen; - pool sat_cells; + ModWalker modwalker; + QuickConeSat qcsat; // Used as a queue. std::vector dff_cells; - OptDffWorker(const OptDffOptions &opt, Module *mod) : opt(opt), module(mod), sigmap(mod), initvals(&sigmap, mod), ez(), satgen(ez.get(), &sigmap) { - // Gathering three kinds of information here for every sigmapped SigBit: + OptDffWorker(const OptDffOptions &opt, Module *mod) : opt(opt), module(mod), sigmap(mod), initvals(&sigmap, mod), modwalker(module->design, module), qcsat(modwalker) { + // Gathering two kinds of information here for every sigmapped SigBit: // // - bitusers: how many users it has (muxes will only be merged into FFs if this is 1, making the FF the only user) // - bit2mux: the mux cell and bit index that drives it, if any - // - bit2driver: the cell driving it, if any for (auto wire : module->wires()) { @@ -88,10 +86,6 @@ struct OptDffWorker for (auto conn : cell->connections()) { bool is_output = cell->output(conn.first); - if (is_output) { - for (auto bit : sigmap(conn.second)) - bit2driver[bit] = cell; - } if (!is_output || !cell->known()) { for (auto bit : sigmap(conn.second)) bitusers[bit]++; @@ -104,20 +98,6 @@ struct OptDffWorker } - std::function sat_import_cell = [&](Cell *c) { - if (!sat_cells.insert(c).second) - return; - if (!satgen.importCell(c)) - return; - for (auto &conn : c->connections()) { - if (!c->input(conn.first)) - continue; - for (auto bit : sigmap(conn.second)) - if (bit2driver.count(bit)) - sat_import_cell(bit2driver.at(bit)); - } - }; - State combine_const(State a, State b) { if (a == State::Sx && !opt.keepdc) return b; @@ -594,19 +574,19 @@ struct OptDffWorker if (!opt.sat) continue; // For each register bit, try to prove that it cannot change from the initial value. If so, remove it - if (!bit2driver.count(ff.sig_d[i])) + if (!modwalker.has_drivers(ff.sig_d.extract(i))) continue; if (val != State::S0 && val != State::S1) continue; - sat_import_cell(bit2driver.at(ff.sig_d[i])); + int init_sat_pi = qcsat.importSigBit(val); + int q_sat_pi = qcsat.importSigBit(ff.sig_q[i]); + int d_sat_pi = qcsat.importSigBit(ff.sig_d[i]); - int init_sat_pi = satgen.importSigSpec(val).front(); - int q_sat_pi = satgen.importSigBit(ff.sig_q[i]); - int d_sat_pi = satgen.importSigBit(ff.sig_d[i]); + qcsat.prepare(); // Try to find out whether the register bit can change under some circumstances - bool counter_example_found = ez->solve(ez->IFF(q_sat_pi, init_sat_pi), ez->NOT(ez->IFF(d_sat_pi, init_sat_pi))); + bool counter_example_found = qcsat.ez->solve(qcsat.ez->IFF(q_sat_pi, init_sat_pi), qcsat.ez->NOT(qcsat.ez->IFF(d_sat_pi, init_sat_pi))); // If the register bit cannot change, we can replace it with a constant if (counter_example_found) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 88c4dee8bf9..ee1acfb7f9b 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -18,7 +18,7 @@ */ #include "kernel/yosys.h" -#include "kernel/satgen.h" +#include "kernel/qcsat.h" #include "kernel/sigtools.h" #include "kernel/modtools.h" #include "kernel/utils.h" @@ -58,8 +58,6 @@ struct ShareWorker std::map, cell_ptr_cmp> topo_cell_drivers; std::map> topo_bit_drivers; - std::vector> exclusive_ctrls; - // ------------------------------------------------------------------------------ // Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree @@ -1156,7 +1154,6 @@ struct ShareWorker recursion_state.clear(); topo_cell_drivers.clear(); topo_bit_drivers.clear(); - exclusive_ctrls.clear(); terminal_bits.clear(); shareable_cells.clear(); forbidden_controls_cache.clear(); @@ -1171,13 +1168,6 @@ struct ShareWorker log("Found %d cells in module %s that may be considered for resource sharing.\n", GetSize(shareable_cells), log_id(module)); - for (auto cell : module->cells()) - if (cell->type == ID($pmux)) - for (auto bit : cell->getPort(ID::S)) - for (auto other_bit : cell->getPort(ID::S)) - if (bit < other_bit) - exclusive_ctrls.push_back(std::pair(bit, other_bit)); - while (!shareable_cells.empty() && config.limit != 0) { RTLIL::Cell *cell = *shareable_cells.begin(); @@ -1256,8 +1246,11 @@ struct ShareWorker optimize_activation_patterns(filtered_cell_activation_patterns); optimize_activation_patterns(filtered_other_cell_activation_patterns); - ezSatPtr ez; - SatGen satgen(ez.get(), &modwalker.sigmap); + QuickConeSat qcsat(modwalker); + if (config.opt_fast) { + qcsat.max_cell_outs = 3; + qcsat.max_cell_count = 100; + } pool sat_cells; std::set bits_queue; @@ -1267,77 +1260,45 @@ struct ShareWorker for (auto &p : filtered_cell_activation_patterns) { log(" Activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second)); - cell_active.push_back(ez->vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); + cell_active.push_back(qcsat.ez->vec_eq(qcsat.importSig(p.first), qcsat.importSig(p.second))); all_ctrl_signals.append(p.first); } for (auto &p : filtered_other_cell_activation_patterns) { log(" Activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second)); - other_cell_active.push_back(ez->vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); + other_cell_active.push_back(qcsat.ez->vec_eq(qcsat.importSig(p.first), qcsat.importSig(p.second))); all_ctrl_signals.append(p.first); } - for (auto &bit : cell_activation_signals.to_sigbit_vector()) - bits_queue.insert(bit); - - for (auto &bit : other_cell_activation_signals.to_sigbit_vector()) - bits_queue.insert(bit); - - while (!bits_queue.empty()) - { - pool portbits; - modwalker.get_drivers(portbits, bits_queue); - bits_queue.clear(); - - for (auto &pbit : portbits) - if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { - if (config.opt_fast && modwalker.cell_outputs[pbit.cell].size() >= 4) - continue; - // log(" Adding cell %s (%s) to SAT problem.\n", log_id(pbit.cell), log_id(pbit.cell->type)); - bits_queue.insert(modwalker.cell_inputs[pbit.cell].begin(), modwalker.cell_inputs[pbit.cell].end()); - satgen.importCell(pbit.cell); - sat_cells.insert(pbit.cell); - } - - if (config.opt_fast && sat_cells.size() > 100) - break; - } - - for (auto it : exclusive_ctrls) - if (satgen.importedSigBit(it.first) && satgen.importedSigBit(it.second)) { - log(" Adding exclusive control bits: %s vs. %s\n", log_signal(it.first), log_signal(it.second)); - int sub1 = satgen.importSigBit(it.first); - int sub2 = satgen.importSigBit(it.second); - ez->assume(ez->NOT(ez->AND(sub1, sub2))); - } + qcsat.prepare(); - if (!ez->solve(ez->expression(ez->OpOr, cell_active))) { + int sub1 = qcsat.ez->expression(qcsat.ez->OpOr, cell_active); + if (!qcsat.ez->solve(sub1)) { log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(cell)); cells_to_remove.insert(cell); break; } - if (!ez->solve(ez->expression(ez->OpOr, other_cell_active))) { + int sub2 = qcsat.ez->expression(qcsat.ez->OpOr, other_cell_active); + if (!qcsat.ez->solve(sub2)) { log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(other_cell)); cells_to_remove.insert(other_cell); shareable_cells.erase(other_cell); continue; } - ez->non_incremental(); + qcsat.ez->non_incremental(); all_ctrl_signals.sort_and_unify(); - std::vector sat_model = satgen.importSigSpec(all_ctrl_signals); + std::vector sat_model = qcsat.importSig(all_ctrl_signals); std::vector sat_model_values; - int sub1 = ez->expression(ez->OpOr, cell_active); - int sub2 = ez->expression(ez->OpOr, other_cell_active); - ez->assume(ez->AND(sub1, sub2)); + qcsat.ez->assume(qcsat.ez->AND(sub1, sub2)); log(" Size of SAT problem: %d cells, %d variables, %d clauses\n", - GetSize(sat_cells), ez->numCnfVariables(), ez->numCnfClauses()); + GetSize(sat_cells), qcsat.ez->numCnfVariables(), qcsat.ez->numCnfClauses()); - if (ez->solve(sat_model, sat_model_values)) { + if (qcsat.ez->solve(sat_model, sat_model_values)) { log(" According to the SAT solver this pair of cells can not be shared.\n"); log(" Model from SAT solver: %s = %d'", log_signal(all_ctrl_signals), GetSize(sat_model_values)); for (int i = GetSize(sat_model_values)-1; i >= 0; i--) From f368e2c7e650ecb35d3732ad1f3f926a21f063bf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Aug 2021 00:52:49 +0000 Subject: [PATCH 0475/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4e13da31c7e..af2e1439473 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4249 +YOSYS_VER := 0.9+4251 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 681a1c07e52dc82449501f4939e6312f593449bd Mon Sep 17 00:00:00 2001 From: Michael Singer Date: Thu, 5 Aug 2021 21:02:35 +0200 Subject: [PATCH 0476/2410] Allow optional comma after last entry in enum --- frontends/verilog/verilog_parser.y | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index de463b47deb..a5227cb092c 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1624,17 +1624,18 @@ enum_type: TOK_ENUM { // create the template for the names astbuf1 = new AstNode(AST_ENUM_ITEM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } enum_base_type '{' enum_name_list '}' { // create template for the enum vars - auto tnode = astbuf1->clone(); - delete astbuf1; - astbuf1 = tnode; - tnode->type = AST_WIRE; - tnode->attributes[ID::enum_type] = AstNode::mkconst_str(astbuf2->str); - // drop constant but keep any range - delete tnode->children[0]; - tnode->children.erase(tnode->children.begin()); - $$ = astbuf1; } - ; + } enum_base_type '{' enum_name_list optional_comma '}' { + // create template for the enum vars + auto tnode = astbuf1->clone(); + delete astbuf1; + astbuf1 = tnode; + tnode->type = AST_WIRE; + tnode->attributes[ID::enum_type] = AstNode::mkconst_str(astbuf2->str); + // drop constant but keep any range + delete tnode->children[0]; + tnode->children.erase(tnode->children.begin()); + $$ = astbuf1; + }; enum_base_type: type_atom type_signing | type_vec type_signing range { if ($3) astbuf1->children.push_back($3); } From e6f3d1c225abecf736782f43af4f36526c63f4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 31 Jul 2021 23:21:37 +0200 Subject: [PATCH 0477/2410] kernel/mem: Introduce transparency masks. --- backends/cxxrtl/cxxrtl_backend.cc | 39 ++-- backends/verilog/verilog_backend.cc | 18 +- kernel/mem.cc | 313 ++++++++++++++++++++++++++-- kernel/mem.h | 41 +++- passes/memory/memory_bram.cc | 97 +++------ passes/memory/memory_dff.cc | 3 +- passes/memory/memory_share.cc | 11 +- passes/opt/opt_mem_feedback.cc | 4 +- 8 files changed, 408 insertions(+), 118 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 95ad6a86ea9..40e61e5af6e 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -542,19 +542,21 @@ struct FlowGraph { add_uses(node, port.arst); add_uses(node, port.srst); add_uses(node, port.addr); - if (port.transparent && port.clk_enable) { - // Our implementation of transparent read ports reads en, addr and data from every write port - // in the same domain. - for (auto &wrport : mem->wr_ports) { - if (wrport.clk_enable && wrport.clk == port.clk && wrport.clk_polarity == port.clk_polarity) { - add_uses(node, wrport.en); - add_uses(node, wrport.addr); - add_uses(node, wrport.data); - } + bool transparent = false; + for (int j = 0; j < GetSize(mem->wr_ports); j++) { + auto &wrport = mem->wr_ports[j]; + if (port.transparency_mask[j]) { + // Our implementation of transparent read ports reads en, addr and data from every write port + // the read port is transparent with. + add_uses(node, wrport.en); + add_uses(node, wrport.addr); + add_uses(node, wrport.data); + transparent = true; } - // Also we read the address twice in this case (prevent inlining). - add_uses(node, port.addr); } + // Also we read the read address twice in this case (prevent inlining). + if (transparent) + add_uses(node, port.addr); } if (!mem->wr_ports.empty()) { Node *node = new Node; @@ -1604,17 +1606,18 @@ struct CxxrtlWorker { std::string lhs_temp = fresh_temporary(); f << indent << "value<" << mem->width << "> " << lhs_temp << " = " << mangle(mem) << "[" << valid_index_temp << ".index];\n"; - if (port.transparent && port.clk_enable) { + bool transparent = false; + for (auto bit : port.transparency_mask) + if (bit) + transparent = true; + if (transparent) { std::string addr_temp = fresh_temporary(); f << indent << "const value<" << port.addr.size() << "> &" << addr_temp << " = "; dump_sigspec_rhs(port.addr); f << ";\n"; - for (auto &wrport : mem->wr_ports) { - if (!wrport.clk_enable) - continue; - if (wrport.clk != port.clk) - continue; - if (wrport.clk_polarity != port.clk_polarity) + for (int i = 0; i < GetSize(mem->wr_ports); i++) { + auto &wrport = mem->wr_ports[i]; + if (!port.transparency_mask[i]) continue; f << indent << "if (" << addr_temp << " == "; dump_sigspec_rhs(wrport.addr); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 8f96c3a5898..47b48a46039 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -555,7 +555,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) } // Decide how to represent the transparency; same idea as Mem::extract_rdff. - bool trans_use_addr = port.transparent; + bool trans_use_addr = true; + for (auto bit : port.transparency_mask) + if (!bit) + trans_use_addr = false; if (GetSize(mem.wr_ports) == 0) trans_use_addr = false; @@ -630,13 +633,7 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) for (int i = 0; i < GetSize(mem.wr_ports); i++) { auto &wport = mem.wr_ports[i]; - if (!port.transparent) - continue; - if (!wport.clk_enable) - continue; - if (wport.clk != port.clk) - continue; - if (wport.clk_polarity != port.clk_polarity) + if (!port.transparency_mask[i] && !port.collision_x_mask[i]) continue; int min_wide_log2 = std::min(port.wide_log2, wport.wide_log2); int max_wide_log2 = std::max(port.wide_log2, wport.wide_log2); @@ -679,7 +676,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) if (epos-pos != GetSize(port.data)) os2 << stringf("[%d:%d]", rsub * mem.width + epos-1, rsub * mem.width + pos); os2 << " <= "; - dump_sigspec(os2, wport.data.extract(wsub * mem.width + pos, epos-pos)); + if (port.transparency_mask[i]) + dump_sigspec(os2, wport.data.extract(wsub * mem.width + pos, epos-pos)); + else + dump_sigspec(os2, Const(State::Sx, epos - pos)); os2 << ";\n"; clk_to_lof_body[clk_domain_str].push_back(os2.str()); diff --git a/kernel/mem.cc b/kernel/mem.cc index a3b244eab8b..402ab55200f 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -100,8 +100,14 @@ void Mem::emit() { std::swap(inits[i], inits[init_left[i]]); inits.resize(GetSize(init_left)); - // for future: handle transparency mask here - + for (auto &port : rd_ports) { + for (int i = 0; i < GetSize(wr_left); i++) { + port.transparency_mask[i] = port.transparency_mask[wr_left[i]]; + port.collision_x_mask[i] = port.collision_x_mask[wr_left[i]]; + } + port.transparency_mask.resize(GetSize(wr_left)); + port.collision_x_mask.resize(GetSize(wr_left)); + } for (auto &port : wr_ports) { for (int i = 0; i < GetSize(wr_left); i++) port.priority_mask[i] = port.priority_mask[wr_left[i]]; @@ -139,6 +145,20 @@ void Mem::emit() { log_assert(port.arst == State::S0); log_assert(port.srst == State::S0); log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); + bool transparent = false; + bool non_transparent = false; + if (port.clk_enable) { + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &oport = wr_ports[i]; + if (oport.clk_enable && oport.clk == port.clk && oport.clk_polarity == port.clk_polarity) { + if (port.transparency_mask[i]) + transparent = true; + else if (!port.collision_x_mask[i]) + non_transparent = true; + } + } + log_assert(!transparent || !non_transparent); + } if (port.cell) { module->remove(port.cell); port.cell = nullptr; @@ -148,7 +168,7 @@ void Mem::emit() { rd_wide_continuation.bits.push_back(State(sub != 0)); rd_clk_enable.bits.push_back(State(port.clk_enable)); rd_clk_polarity.bits.push_back(State(port.clk_polarity)); - rd_transparent.bits.push_back(State(port.transparent)); + rd_transparent.bits.push_back(State(transparent)); rd_clk.append(port.clk); rd_en.append(port.en); SigSpec addr = port.sub_addr(sub); @@ -231,6 +251,20 @@ void Mem::emit() { log_assert(port.arst == State::S0); log_assert(port.srst == State::S0); log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); + bool transparent = false; + bool non_transparent = false; + if (port.clk_enable) { + for (int i = 0; i < GetSize(wr_ports); i++) { + auto &oport = wr_ports[i]; + if (oport.clk_enable && oport.clk == port.clk && oport.clk_polarity == port.clk_polarity) { + if (port.transparency_mask[i]) + transparent = true; + else if (!port.collision_x_mask[i]) + non_transparent = true; + } + } + log_assert(!transparent || !non_transparent); + } if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memrd)); port.cell->attributes = port.attributes; @@ -239,7 +273,7 @@ void Mem::emit() { port.cell->parameters[ID::WIDTH] = width << port.wide_log2; port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; - port.cell->parameters[ID::TRANSPARENT] = port.transparent; + port.cell->parameters[ID::TRANSPARENT] = transparent; port.cell->setPort(ID::CLK, port.clk); port.cell->setPort(ID::EN, port.en); port.cell->setPort(ID::ADDR, port.addr); @@ -405,7 +439,6 @@ void Mem::check() { log_assert(GetSize(port.arst_value) == (width << port.wide_log2)); log_assert(GetSize(port.srst_value) == (width << port.wide_log2)); if (!port.clk_enable) { - log_assert(!port.transparent); log_assert(port.en == State::S1); log_assert(port.arst == State::S0); log_assert(port.srst == State::S0); @@ -414,6 +447,18 @@ void Mem::check() { log_assert(port.addr[j] == State::S0); } max_wide_log2 = std::max(max_wide_log2, port.wide_log2); + log_assert(GetSize(port.transparency_mask) == GetSize(wr_ports)); + log_assert(GetSize(port.collision_x_mask) == GetSize(wr_ports)); + for (int j = 0; j < GetSize(wr_ports); j++) { + auto &wport = wr_ports[j]; + if ((port.transparency_mask[j] || port.collision_x_mask[j]) && !wport.removed) { + log_assert(port.clk_enable); + log_assert(wport.clk_enable); + log_assert(port.clk == wport.clk); + log_assert(port.clk_polarity == wport.clk_polarity); + } + log_assert(!port.transparency_mask[j] || !port.collision_x_mask[j]); + } } for (int i = 0; i < GetSize(wr_ports); i++) { auto &port = wr_ports[i]; @@ -467,6 +512,7 @@ namespace { res.packed = false; res.mem = mem; res.attributes = mem->attributes; + std::vector rd_transparent; if (index.rd_ports.count(mem->name)) { for (auto cell : index.rd_ports.at(mem->name)) { MemRd mrd; @@ -474,7 +520,7 @@ namespace { mrd.attributes = cell->attributes; mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); mrd.clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); - mrd.transparent = cell->parameters.at(ID::TRANSPARENT).as_bool(); + bool transparent = cell->parameters.at(ID::TRANSPARENT).as_bool(); mrd.clk = cell->getPort(ID::CLK); mrd.en = cell->getPort(ID::EN); mrd.addr = cell->getPort(ID::ADDR); @@ -491,11 +537,12 @@ namespace { // but don't want to see moving forwards: async transparent // ports (inherently meaningless) and async ports without // const 1 tied to EN bit (which may mean a latch in the future). - mrd.transparent = false; + transparent = false; if (mrd.en == State::Sx) mrd.en = State::S1; } res.rd_ports.push_back(mrd); + rd_transparent.push_back(transparent); } } if (index.wr_ports.count(mem->name)) { @@ -559,6 +606,25 @@ namespace { port.priority_mask[j] = true; } } + for (int i = 0; i < GetSize(res.rd_ports); i++) { + auto &port = res.rd_ports[i]; + port.transparency_mask.resize(GetSize(res.wr_ports)); + port.collision_x_mask.resize(GetSize(res.wr_ports)); + if (!rd_transparent[i]) + continue; + if (!port.clk_enable) + continue; + for (int j = 0; j < GetSize(res.wr_ports); j++) { + auto &wport = res.wr_ports[j]; + if (!wport.clk_enable) + continue; + if (port.clk != wport.clk) + continue; + if (port.clk_polarity != wport.clk_polarity) + continue; + port.transparency_mask[j] = true; + } + } res.check(); return res; } @@ -601,7 +667,6 @@ namespace { mrd.wide_log2 = 0; mrd.clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE).extract(i, 1).as_bool(); mrd.clk_polarity = cell->parameters.at(ID::RD_CLK_POLARITY).extract(i, 1).as_bool(); - mrd.transparent = cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool(); mrd.clk = cell->getPort(ID::RD_CLK).extract(i, 1); mrd.en = cell->getPort(ID::RD_EN).extract(i, 1); mrd.addr = cell->getPort(ID::RD_ADDR).extract(i * abits, abits); @@ -639,6 +704,25 @@ namespace { port.priority_mask[j] = true; } } + for (int i = 0; i < GetSize(res.rd_ports); i++) { + auto &port = res.rd_ports[i]; + port.transparency_mask.resize(GetSize(res.wr_ports)); + port.collision_x_mask.resize(GetSize(res.wr_ports)); + if (!cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool()) + continue; + if (!port.clk_enable) + continue; + for (int j = 0; j < GetSize(res.wr_ports); j++) { + auto &wport = res.wr_ports[j]; + if (!wport.clk_enable) + continue; + if (port.clk != wport.clk) + continue; + if (port.clk_polarity != wport.clk_polarity) + continue; + port.transparency_mask[j] = true; + } + } res.check(); return res; } @@ -690,7 +774,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { // // - otherwise, put the FF on the data output, and make bypass paths for // all write ports wrt which this port is transparent - bool trans_use_addr = port.transparent; + bool trans_use_addr = true; + for (int i = 0; i < GetSize(wr_ports); i++) + if (!port.transparency_mask[i] && !wr_ports[i].removed) + trans_use_addr = false; // If there are no write ports at all, we could possibly use either way; do data // FF in this case. @@ -735,7 +822,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { for (int i = 0; i < GetSize(wr_ports); i++) { auto &wport = wr_ports[i]; - if (port.transparent) { + if (wport.removed) + continue; + if (port.transparency_mask[i] || port.collision_x_mask[i]) { log_assert(wport.clk_enable); log_assert(wport.clk == port.clk); log_assert(wport.clk_enable == port.clk_enable); @@ -761,7 +850,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { while (epos < ewidth && wport.en[epos + wsub * width] == wport.en[pos + wsub * width]) epos++; SigSpec cur = sig_d.extract(pos + rsub * width, epos-pos); - SigSpec other = wport.data.extract(pos + wsub * width, epos-pos); + SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos); SigSpec cond; if (raddr != waddr) cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid.c_str(), idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq); @@ -815,12 +904,16 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { port.srst = State::S0; port.clk_enable = false; port.clk_polarity = true; - port.transparent = false; port.ce_over_srst = false; port.arst_value = Const(State::Sx, GetSize(port.data)); port.srst_value = Const(State::Sx, GetSize(port.data)); port.init_value = Const(State::Sx, GetSize(port.data)); + for (int i = 0; i < GetSize(wr_ports); i++) { + port.transparency_mask[i] = false; + port.collision_x_mask[i] = false; + } + return c; } @@ -857,6 +950,12 @@ void Mem::narrow() { port.addr = port.sub_addr(it.second); port.wide_log2 = 0; } + port.transparency_mask.clear(); + port.collision_x_mask.clear(); + for (auto &it2 : new_wr_map) + port.transparency_mask.push_back(orig.transparency_mask[it2.first]); + for (auto &it2 : new_wr_map) + port.collision_x_mask.push_back(orig.collision_x_mask[it2.first]); new_rd_ports.push_back(port); } for (auto &it : new_wr_map) { @@ -879,12 +978,19 @@ void Mem::narrow() { std::swap(wr_ports, new_wr_ports); } -void Mem::emulate_priority(int idx1, int idx2) +void Mem::emulate_priority(int idx1, int idx2, FfInitVals *initvals) { auto &port1 = wr_ports[idx1]; auto &port2 = wr_ports[idx2]; if (!port2.priority_mask[idx1]) return; + for (int i = 0; i < GetSize(rd_ports); i++) { + auto &rport = rd_ports[i]; + if (rport.removed) + continue; + if (rport.transparency_mask[idx1] && !(rport.transparency_mask[idx2] || rport.collision_x_mask[idx2])) + emulate_transparency(idx1, i, initvals); + } int min_wide_log2 = std::min(port1.wide_log2, port2.wide_log2); int max_wide_log2 = std::max(port1.wide_log2, port2.wide_log2); bool wide1 = port1.wide_log2 > port2.wide_log2; @@ -916,7 +1022,99 @@ void Mem::emulate_priority(int idx1, int idx2) port2.priority_mask[idx1] = false; } -void Mem::prepare_wr_merge(int idx1, int idx2) { +void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) { + auto &wport = wr_ports[widx]; + auto &rport = rd_ports[ridx]; + log_assert(rport.transparency_mask[widx]); + // If other write ports have priority over this one, emulate their transparency too. + for (int i = GetSize(wr_ports) - 1; i > widx; i--) { + if (wr_ports[i].removed) + continue; + if (rport.transparency_mask[i] && wr_ports[i].priority_mask[widx]) + emulate_transparency(i, ridx, initvals); + } + int min_wide_log2 = std::min(rport.wide_log2, wport.wide_log2); + int max_wide_log2 = std::max(rport.wide_log2, wport.wide_log2); + bool wide_write = wport.wide_log2 > rport.wide_log2; + // The write data FF doesn't need full reset/init behavior, as it'll be masked by + // the mux whenever this would be relevant. It does, however, need to have the same + // clock enable signal as the read port. + SigSpec wdata_q = module->addWire(NEW_ID, GetSize(wport.data)); + module->addDffe(NEW_ID, rport.clk, rport.en, wport.data, wdata_q, rport.clk_polarity, true); + for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { + SigSpec raddr = rport.addr; + SigSpec waddr = wport.addr; + for (int j = min_wide_log2; j < max_wide_log2; j++) + if (wide_write) + waddr = wport.sub_addr(sub); + else + raddr = rport.sub_addr(sub); + SigSpec addr_eq; + if (raddr != waddr) + addr_eq = module->Eq(NEW_ID, raddr, waddr); + int pos = 0; + int ewidth = width << min_wide_log2; + int wsub = wide_write ? sub : 0; + int rsub = wide_write ? 0 : sub; + SigSpec rdata_a = module->addWire(NEW_ID, ewidth); + while (pos < ewidth) { + int epos = pos; + while (epos < ewidth && wport.en[epos + wsub * width] == wport.en[pos + wsub * width]) + epos++; + SigSpec cond; + if (raddr != waddr) + cond = module->And(NEW_ID, wport.en[pos + wsub * width], addr_eq); + else + cond = wport.en[pos + wsub * width]; + SigSpec cond_q = module->addWire(NEW_ID); + // The FF for storing the bypass enable signal must be carefully + // constructed to preserve the overall init/reset/enable behavior + // of the whole port. + FfData ff(initvals); + ff.width = 1; + ff.sig_q = cond_q; + ff.has_d = true; + ff.sig_d = cond; + ff.has_clk = true; + ff.sig_clk = rport.clk; + ff.pol_clk = rport.clk_polarity; + if (rport.en != State::S1) { + ff.has_en = true; + ff.sig_en = rport.en; + ff.pol_en = true; + } + if (rport.arst != State::S0) { + ff.has_arst = true; + ff.sig_arst = rport.arst; + ff.pol_arst = true; + ff.val_arst = State::S0; + } + if (rport.srst != State::S0) { + ff.has_srst = true; + ff.sig_srst = rport.srst; + ff.pol_srst = true; + ff.val_srst = State::S0; + ff.ce_over_srst = rport.ce_over_srst; + } + if (!rport.init_value.is_fully_undef()) + ff.val_init = State::S0; + else + ff.val_init = State::Sx; + ff.emit(module, NEW_ID); + // And the final bypass mux. + SigSpec cur = rdata_a.extract(pos, epos-pos); + SigSpec other = wdata_q.extract(pos + wsub * width, epos-pos); + SigSpec dest = rport.data.extract(pos + rsub * width, epos-pos); + module->addMux(NEW_ID, cur, other, cond_q, dest); + pos = epos; + } + rport.data.replace(rsub * width, rdata_a); + } + rport.transparency_mask[widx] = false; + rport.collision_x_mask[widx] = true; +} + +void Mem::prepare_wr_merge(int idx1, int idx2, FfInitVals *initvals) { log_assert(idx1 < idx2); auto &port1 = wr_ports[idx1]; auto &port2 = wr_ports[idx2]; @@ -926,14 +1124,97 @@ void Mem::prepare_wr_merge(int idx1, int idx2) { port1.priority_mask[i] = true; // If port 2 has priority over a port after port 1, emulate it. for (int i = idx1 + 1; i < idx2; i++) - if (port2.priority_mask[i]) - emulate_priority(i, idx2); + if (port2.priority_mask[i] && !wr_ports[i].removed) + emulate_priority(i, idx2, initvals); // If some port had priority over port 2, make it have priority over the merged port too. for (int i = idx2 + 1; i < GetSize(wr_ports); i++) { auto &oport = wr_ports[i]; if (oport.priority_mask[idx2]) oport.priority_mask[idx1] = true; } + // Make sure all read ports have identical collision/transparency behavior wrt both + // ports. + for (int i = 0; i < GetSize(rd_ports); i++) { + auto &rport = rd_ports[i]; + if (rport.removed) + continue; + // If collision already undefined with both ports, it's fine. + if (rport.collision_x_mask[idx1] && rport.collision_x_mask[idx2]) + continue; + // If one port has undefined collision, change it to the behavior + // of the other port. + if (rport.collision_x_mask[idx1]) { + rport.collision_x_mask[idx1] = false; + rport.transparency_mask[idx1] = rport.transparency_mask[idx2]; + continue; + } + if (rport.collision_x_mask[idx2]) { + rport.collision_x_mask[idx2] = false; + rport.transparency_mask[idx2] = rport.transparency_mask[idx1]; + continue; + } + // If transparent with both ports, also fine. + if (rport.transparency_mask[idx1] && rport.transparency_mask[idx2]) + continue; + // If transparent with only one, emulate it, and remove the collision-X + // flag that emulate_transparency will set (to align with the other port). + if (rport.transparency_mask[idx1]) { + emulate_transparency(i, idx1, initvals); + rport.collision_x_mask[idx1] = false; + continue; + } + if (rport.transparency_mask[idx2]) { + emulate_transparency(i, idx2, initvals); + rport.collision_x_mask[idx2] = false; + continue; + } + // If we got here, it's transparent with neither port, which is fine. + } +} + +void Mem::prepare_rd_merge(int idx1, int idx2, FfInitVals *initvals) { + auto &port1 = rd_ports[idx1]; + auto &port2 = rd_ports[idx2]; + // Note that going through write ports in order is important, since + // emulating transparency of a write port can change transparency + // mask for higher-numbered ports (due to transitive transparency + // emulation needed because of write port priority). + for (int i = 0; i < GetSize(wr_ports); i++) { + if (wr_ports[i].removed) + continue; + // Both ports undefined, OK. + if (port1.collision_x_mask[i] && port2.collision_x_mask[i]) + continue; + // Only one port undefined — change its behavior + // to align with the other port. + if (port1.collision_x_mask[i]) { + port1.collision_x_mask[i] = false; + port1.transparency_mask[i] = port2.transparency_mask[i]; + continue; + } + if (port2.collision_x_mask[i]) { + port2.collision_x_mask[i] = false; + port2.transparency_mask[i] = port1.transparency_mask[i]; + continue; + } + // Both ports transparent, OK. + if (port1.transparency_mask[i] && port2.transparency_mask[i]) + continue; + // Only one port transparent — emulate transparency + // on the other. + if (port1.transparency_mask[i]) { + emulate_transparency(i, idx1, initvals); + port1.collision_x_mask[i] = false; + continue; + } + if (port2.transparency_mask[i]) { + emulate_transparency(i, idx2, initvals); + port2.collision_x_mask[i] = false; + continue; + } + // No ports transparent, OK. + } + } void Mem::widen_prep(int wide_log2) { diff --git a/kernel/mem.h b/kernel/mem.h index 24c2d64c8dc..87a148bebdd 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -31,7 +31,19 @@ struct MemRd : RTLIL::AttrObject { int wide_log2; bool clk_enable, clk_polarity, ce_over_srst; Const arst_value, srst_value, init_value; - bool transparent; + // One bit for every write port, true iff simultanous read on this + // port and write on the other port will bypass the written data + // to this port's output (default behavior is to read old value). + // Can only be set for write ports that have the same clock domain. + std::vector transparency_mask; + // One bit for every write port, true iff simultanous read on this + // port and write on the other port will return an all-X (don't care) + // value. Mutually exclusive with transparency_mask. + // Can only be set for write ports that have the same clock domain. + // For optimization purposes, this will also be set if we can + // determine that the two ports can never be active simultanously + // (making the above vacuously true). + std::vector collision_x_mask; SigSpec clk, en, arst, srst, addr, data; MemRd() : removed(false), cell(nullptr) {} @@ -139,15 +151,34 @@ struct Mem : RTLIL::AttrObject { // If write port idx2 currently has priority over write port idx1, // inserts extra logic on idx1's enable signal to disable writes // when idx2 is writing to the same address, then removes the priority - // from the priority mask. - void emulate_priority(int idx1, int idx2); + // from the priority mask. If there is a memory port that is + // transparent with idx1, but not with idx2, that port is converted + // to use soft transparency logic. + void emulate_priority(int idx1, int idx2, FfInitVals *initvals); + + // Creates soft-transparency logic on read port ridx, bypassing the + // data from write port widx. Should only be called when ridx is + // transparent wrt widx in the first place. Once we're done, the + // transparency_mask bit will be cleared, and the collision_x_mask + // bit will be set instead (since whatever value is read will be + // replaced by the soft transparency logic). + void emulate_transparency(int widx, int ridx, FfInitVals *initvals); // Prepares for merging write port idx2 into idx1 (where idx1 < idx2). // Specifically, takes care of priority masks: any priority relations // that idx2 had are replicated onto idx1, unless they conflict with // priorities already present on idx1, in which case emulate_priority - // is called. - void prepare_wr_merge(int idx1, int idx2); + // is called. Likewise, ensures transparency and undefined collision + // masks of all read ports have the same values for both ports, + // calling emulate_transparency if necessary. + void prepare_wr_merge(int idx1, int idx2, FfInitVals *initvals); + + // Prepares for merging read port idx2 into idx1. + // Specifically, makes sure the transparency and undefined collision + // masks of both ports are equal, by changing undefined behavior + // of one port to the other's defined behavior, or by calling + // emulate_transparency if necessary. + void prepare_rd_merge(int idx1, int idx2, FfInitVals *initvals); // Prepares the memory for widening a port to a given width. This // involves ensuring that start_offset and size are aligned to the diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index af8137adac1..fed9d60c0ff 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -405,10 +405,6 @@ bool replace_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals, const auto portinfos = bram.make_portinfos(); int dup_count = 1; - pair make_transp_clk; - bool enable_make_transp = false; - int make_transp_enbits = 0; - dict> clock_domains; dict clock_polarities; dict read_transp; @@ -496,8 +492,6 @@ bool replace_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals, const for (; bram_port_i < GetSize(portinfos); bram_port_i++) { auto &pi = portinfos[bram_port_i]; - make_transp_enbits = pi.enable ? pi.enable : 1; - make_transp_clk = clkdom; if (pi.wrmode != 1) skip_bram_wport: @@ -606,10 +600,16 @@ grow_read_ports:; for (int cell_port_i = 0; cell_port_i < GetSize(mem.rd_ports); cell_port_i++) { auto &port = mem.rd_ports[cell_port_i]; - bool transp = port.transparent; - - if (mem.wr_ports.empty()) - transp = false; + bool transp = false; + bool non_transp = false; + + if (port.clk_enable) { + for (int i = 0; i < GetSize(mem.wr_ports); i++) + if (port.transparency_mask[i]) + transp = true; + else if (!port.collision_x_mask[i]) + non_transp = true; + } pair clkdom(port.clk, port.clk_polarity); if (!port.clk_enable) @@ -660,16 +660,13 @@ grow_read_ports:; log(" Bram port %c%d.%d has no initial value support.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } - if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) { - if (match.make_transp && GetSize(mem.wr_ports) <= 1) { + if (non_transp && read_transp.count(pi.transp) && read_transp.at(pi.transp)) { + log(" Bram port %c%d.%d has incompatible read transparency.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + goto skip_bram_rport; + } + if (transp && (non_transp || (read_transp.count(pi.transp) && !read_transp.at(pi.transp)))) { + if (match.make_transp) { pi.make_transp = true; - if (pi.clocks != 0) { - if (GetSize(mem.wr_ports) == 1 && wr_clkdom != clkdom) { - log(" Bram port %c%d.%d cannot have soft transparency logic added as read and write clock domains differ.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); - goto skip_bram_rport; - } - enable_make_transp = true; - } } else { log(" Bram port %c%d.%d has incompatible read transparency.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; @@ -689,8 +686,10 @@ grow_read_ports:; if (pi.clocks) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; - if (!pi.make_transp) - read_transp[pi.transp] = transp; + if (non_transp) + read_transp[pi.transp] = false; + if (transp && !pi.make_transp) + read_transp[pi.transp] = true; } if (grow_read_ports_cursor < cell_port_i) { @@ -793,10 +792,22 @@ grow_read_ports:; // At this point we are commited to replacing the RAM, and can mutate mem. + // Apply make_outreg and make_transp where necessary. + for (auto &pi : portinfos) { + if (pi.make_outreg) + mem.extract_rdff(pi.mapped_port, initvals); + if (pi.make_transp) { + auto &port = mem.rd_ports[pi.mapped_port]; + for (int i = 0; i < GetSize(mem.wr_ports); i++) + if (port.transparency_mask[i]) + mem.emulate_transparency(i, pi.mapped_port, initvals); + } + } + // We don't really support priorities, emulate them. for (int i = 0; i < GetSize(mem.wr_ports); i++) for (int j = 0; j < i; j++) - mem.emulate_priority(j, i); + mem.emulate_priority(j, i, initvals); // Swizzle the init data. Do this before changing mem.width, so that get_init_data works. bool cell_init = !mem.inits.empty(); @@ -861,29 +872,12 @@ grow_read_ports:; for (auto &other_bram : rules.brams.at(bram.name)) bram.find_variant_params(variant_params, other_bram); - // Apply make_outreg where necessary. - for (auto &pi : portinfos) - if (pi.make_outreg) - mem.extract_rdff(pi.mapped_port, initvals); - // actually replace that memory cell dict> dout_cache; for (int grid_d = 0; grid_d < dcells; grid_d++) { - SigSpec mktr_wraddr, mktr_wrdata, mktr_wrdata_q; - vector mktr_wren; - - if (enable_make_transp) { - mktr_wraddr = module->addWire(NEW_ID, bram.abits); - mktr_wrdata = module->addWire(NEW_ID, bram.dbits); - mktr_wrdata_q = module->addWire(NEW_ID, bram.dbits); - module->addDff(NEW_ID, make_transp_clk.first, mktr_wrdata, mktr_wrdata_q, make_transp_clk.second); - for (int grid_a = 0; grid_a < acells; grid_a++) - mktr_wren.push_back(module->addWire(NEW_ID, make_transp_enbits)); - } - for (int grid_a = 0; grid_a < acells; grid_a++) for (int dupidx = 0; dupidx < dup_count; dupidx++) { @@ -964,15 +958,6 @@ grow_read_ports:; c->setPort(stringf("\\%sEN", pf), sig_en); - if (enable_make_transp) - module->connect(mktr_wren[grid_a], sig_en); - } - else if (enable_make_transp) - module->connect(mktr_wren[grid_a], addr_ok); - - if (enable_make_transp && grid_a == 0) { - module->connect(mktr_wraddr, sig_addr); - module->connect(mktr_wrdata, sig_data); } } else { if (pi.mapped_port == -1) @@ -986,22 +971,6 @@ grow_read_ports:; SigSpec bram_dout = module->addWire(NEW_ID, bram.dbits); c->setPort(stringf("\\%sDATA", pf), bram_dout); - if (pi.make_transp) { - log(" Adding extra logic for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); - - SigSpec transp_en_d = module->Mux(NEW_ID, SigSpec(0, make_transp_enbits), - mktr_wren[grid_a], module->Eq(NEW_ID, mktr_wraddr, sig_addr)); - - SigSpec transp_en_q = module->addWire(NEW_ID, make_transp_enbits); - module->addDff(NEW_ID, make_transp_clk.first, transp_en_d, transp_en_q, make_transp_clk.second); - - for (int i = 0; i < make_transp_enbits; i++) { - int en_width = bram.dbits / make_transp_enbits; - SigSpec orig_bram_dout = bram_dout.extract(i * en_width, en_width); - SigSpec bypass_dout = mktr_wrdata_q.extract(i * en_width, en_width); - bram_dout.replace(i * en_width, module->Mux(NEW_ID, orig_bram_dout, bypass_dout, transp_en_q[i])); - } - } SigSpec addr_ok_q = addr_ok; if (port.clk_enable && !addr_ok.empty()) { diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 5cfb3f48a4e..e6b4b2400dc 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -143,7 +143,8 @@ struct MemoryDffWorker port.addr = ff.sig_d; port.clk_enable = true; port.clk_polarity = ff.pol_clk; - port.transparent = true; + for (int i = 0; i < GetSize(mem.wr_ports); i++) + port.transparency_mask[i] = true; mem.emit(); log("merged address FF to cell.\n"); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 91f36ce05cb..8499b46d8d6 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/modtools.h" #include "kernel/mem.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -32,6 +33,7 @@ struct MemoryShareWorker RTLIL::Module *module; SigMap sigmap, sigmap_xmux; ModWalker modwalker; + FfInitVals initvals; bool flag_widen; @@ -106,8 +108,6 @@ struct MemoryShareWorker continue; if (port1.ce_over_srst != port2.ce_over_srst) continue; - if (port1.transparent != port2.transparent) - continue; // If the width of the ports doesn't match, they can still be // merged by widening the narrow one. Check if the conditions // hold for that. @@ -147,8 +147,10 @@ struct MemoryShareWorker continue; if (!merge_rst_value(mem, srst_value, wide_log2, port1.srst_value, sub1, port2.srst_value, sub2)) continue; + // At this point we are committed to the merge. { log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); + mem.prepare_rd_merge(i, j, &initvals); mem.widen_prep(wide_log2); SigSpec new_data = module->addWire(NEW_ID, mem.width << wide_log2); module->connect(port1.data, new_data.extract(sub1 * mem.width, mem.width << port1.wide_log2)); @@ -231,7 +233,7 @@ struct MemoryShareWorker continue; } log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); - mem.prepare_wr_merge(i, j); + mem.prepare_wr_merge(i, j, &initvals); port1.addr = sigmap_xmux(port1.addr); port2.addr = sigmap_xmux(port2.addr); mem.widen_wr_port(i, wide_log2); @@ -391,7 +393,7 @@ struct MemoryShareWorker } log(" Merging port %d into port %d.\n", idx2, idx1); - mem.prepare_wr_merge(idx1, idx2); + mem.prepare_wr_merge(idx1, idx2, &initvals); port_to_sat_variable.at(idx1) = qcsat.ez->OR(port_to_sat_variable.at(idx1), port_to_sat_variable.at(idx2)); RTLIL::SigSpec last_addr = port1.addr; @@ -453,6 +455,7 @@ struct MemoryShareWorker this->module = module; sigmap.set(module); + initvals.set(&sigmap, module); sigmap_xmux = sigmap; for (auto cell : module->cells()) diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 9e04772b4e3..20a2a79ed84 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -43,6 +43,7 @@ struct OptMemFeedbackWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap, sigmap_xmux; + FfInitVals initvals; dict> sig_to_mux; dict sig_users_count; @@ -245,7 +246,7 @@ struct OptMemFeedbackWorker for (int i = 0; i < wrport_idx; i++) if (port.priority_mask[i]) - mem.emulate_priority(i, wrport_idx); + mem.emulate_priority(i, wrport_idx, &initvals); } for (auto &it : portbit_conds) @@ -278,6 +279,7 @@ struct OptMemFeedbackWorker this->module = module; sigmap.set(module); + initvals.set(&sigmap, module); sig_to_mux.clear(); conditions_logic_cache.clear(); From b96eb888cc7518c20532ff688ec24b8b51f88f8e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Aug 2021 00:52:20 +0000 Subject: [PATCH 0478/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index af2e1439473..dc66291a45b 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4251 +YOSYS_VER := 0.9+4254 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From fd7921776387a05edadcc90d1300670d49a73d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 20:54:29 +0200 Subject: [PATCH 0479/2410] Add v2 memory cells. --- CHANGELOG | 5 + kernel/celltypes.h | 3 + kernel/constids.inc | 17 ++ kernel/mem.cc | 359 +++++++++++++++++++----------- kernel/rtlil.cc | 70 +++++- manual/CHAPTER_CellLib.tex | 126 ++++++++--- passes/cmds/torder.cc | 2 +- passes/opt/opt_clean.cc | 4 +- passes/opt/opt_expr.cc | 2 +- passes/opt/opt_reduce.cc | 4 +- passes/opt/share.cc | 9 +- passes/opt/wreduce.cc | 2 +- passes/techmap/extract.cc | 1 + techlibs/common/simlib.v | 169 ++++++++++++++ tests/arch/ecp5/memories.ys | 34 +-- tests/arch/ice40/memories.ys | 16 +- tests/memories/run-test.sh | 2 +- tests/opt/bug2765.ys | 2 +- tests/opt/opt_mem_feedback.ys | 4 +- tests/svtypes/logic_rom.ys | 2 +- tests/svtypes/typedef_memory.ys | 2 +- tests/svtypes/typedef_memory_2.ys | 2 +- 22 files changed, 631 insertions(+), 206 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6948ff441aa..713ae1b50ae 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -71,6 +71,11 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass - Added $meminit_v2 cells (with support for write mask) + - Added $mem_v2, $memrd_v2, $memwr_v2, with the following features: + - write priority masks, per write/write port pair + - transparency and undefined collision behavior masks, per read/write port pair + - read port reset and initialization + - wide ports (accessing a naturally aligned power-of-two number of memory cells) Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 2ce7978a463..a977501e3e8 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -155,10 +155,13 @@ struct CellTypes setup_internals_ff(); setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA}); + setup_type(ID($memrd_v2), {ID::CLK, ID::EN, ID::ARST, ID::SRST, ID::ADDR}, {ID::DATA}); setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool()); + setup_type(ID($memwr_v2), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool()); setup_type(ID($meminit), {ID::ADDR, ID::DATA}, pool()); setup_type(ID($meminit_v2), {ID::ADDR, ID::DATA, ID::EN}, pool()); setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA}); + setup_type(ID($mem_v2), {ID::RD_CLK, ID::RD_EN, ID::RD_ARST, ID::RD_SRST, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA}); setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT}); } diff --git a/kernel/constids.inc b/kernel/constids.inc index 3c2ff9beb20..68d10def6c9 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -32,6 +32,7 @@ X(bugpoint_keep) X(B_WIDTH) X(C) X(cells_not_processed) +X(CE_OVER_SRST) X(CFG_ABITS) X(CFG_DBITS) X(CFG_INIT) @@ -46,6 +47,7 @@ X(CLK_POLARITY) X(CLR) X(CLR_POLARITY) X(CO) +X(COLLISION_X_MASK) X(CONFIG) X(CONFIG_WIDTH) X(CTRL_IN) @@ -95,6 +97,7 @@ X(hdlname) X(hierconn) X(I) X(INIT) +X(INIT_VALUE) X(init) X(initial_top) X(interface_modport) @@ -133,18 +136,29 @@ X(onehot) X(P) X(parallel_case) X(parameter) +X(PORTID) X(PRIORITY) +X(PRIORITY_MASK) X(Q) X(qwp_position) X(R) X(RD_ADDR) +X(RD_ARST) +X(RD_ARST_VALUE) +X(RD_CE_OVER_SRST) X(RD_CLK) X(RD_CLK_ENABLE) X(RD_CLK_POLARITY) +X(RD_COLLISION_X_MASK) X(RD_DATA) X(RD_EN) +X(RD_INIT_VALUE) X(RD_PORTS) +X(RD_SRST) +X(RD_SRST_VALUE) +X(RD_TRANSPARENCY_MASK) X(RD_TRANSPARENT) +X(RD_WIDE_CONTINUATION) X(reg) X(S) X(SET) @@ -195,6 +209,7 @@ X(T_LIMIT_TYP) X(to_delete) X(top) X(TRANS_NUM) +X(TRANSPARENCY_MASK) X(TRANSPARENT) X(TRANS_TABLE) X(T_RISE_MAX) @@ -220,6 +235,8 @@ X(WR_CLK_POLARITY) X(WR_DATA) X(WR_EN) X(WR_PORTS) +X(WR_PRIORITY_MASK) +X(WR_WIDE_CONTINUATION) X(X) X(Y) X(Y_WIDTH) diff --git a/kernel/mem.cc b/kernel/mem.cc index 402ab55200f..ee6b8b6cf2a 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -123,42 +123,31 @@ void Mem::emit() { if (!cell) { if (memid.empty()) memid = NEW_ID; - cell = module->addCell(memid, ID($mem)); + cell = module->addCell(memid, ID($mem_v2)); } + cell->type = ID($mem_v2); cell->attributes = attributes; cell->parameters[ID::MEMID] = Const(memid.str()); cell->parameters[ID::WIDTH] = Const(width); cell->parameters[ID::OFFSET] = Const(start_offset); cell->parameters[ID::SIZE] = Const(size); - Const rd_wide_continuation, rd_clk_enable, rd_clk_polarity, rd_transparent; - Const wr_wide_continuation, wr_clk_enable, wr_clk_polarity; + Const rd_wide_continuation, rd_clk_enable, rd_clk_polarity, rd_transparency_mask, rd_collision_x_mask; + Const wr_wide_continuation, wr_clk_enable, wr_clk_polarity, wr_priority_mask; + Const rd_ce_over_srst, rd_arst_value, rd_srst_value, rd_init_value; SigSpec rd_clk, rd_en, rd_addr, rd_data; SigSpec wr_clk, wr_en, wr_addr, wr_data; + SigSpec rd_arst, rd_srst; int abits = 0; for (auto &port : rd_ports) abits = std::max(abits, GetSize(port.addr)); for (auto &port : wr_ports) abits = std::max(abits, GetSize(port.addr)); cell->parameters[ID::ABITS] = Const(abits); + std::vector wr_port_xlat; + for (int i = 0; i < GetSize(wr_ports); i++) + for (int j = 0; j < (1 << wr_ports[i].wide_log2); j++) + wr_port_xlat.push_back(i); for (auto &port : rd_ports) { - // TODO: remove - log_assert(port.arst == State::S0); - log_assert(port.srst == State::S0); - log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); - bool transparent = false; - bool non_transparent = false; - if (port.clk_enable) { - for (int i = 0; i < GetSize(wr_ports); i++) { - auto &oport = wr_ports[i]; - if (oport.clk_enable && oport.clk == port.clk && oport.clk_polarity == port.clk_polarity) { - if (port.transparency_mask[i]) - transparent = true; - else if (!port.collision_x_mask[i]) - non_transparent = true; - } - } - log_assert(!transparent || !non_transparent); - } if (port.cell) { module->remove(port.cell); port.cell = nullptr; @@ -168,28 +157,55 @@ void Mem::emit() { rd_wide_continuation.bits.push_back(State(sub != 0)); rd_clk_enable.bits.push_back(State(port.clk_enable)); rd_clk_polarity.bits.push_back(State(port.clk_polarity)); - rd_transparent.bits.push_back(State(transparent)); + rd_ce_over_srst.bits.push_back(State(port.ce_over_srst)); rd_clk.append(port.clk); + rd_arst.append(port.arst); + rd_srst.append(port.srst); rd_en.append(port.en); SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); rd_addr.append(addr); log_assert(GetSize(addr) == abits); + for (auto idx : wr_port_xlat) { + rd_transparency_mask.bits.push_back(State(bool(port.transparency_mask[idx]))); + rd_collision_x_mask.bits.push_back(State(bool(port.collision_x_mask[idx]))); + } } rd_data.append(port.data); + for (auto &bit : port.arst_value) + rd_arst_value.bits.push_back(bit); + for (auto &bit : port.srst_value) + rd_srst_value.bits.push_back(bit); + for (auto &bit : port.init_value) + rd_init_value.bits.push_back(bit); } if (rd_ports.empty()) { rd_wide_continuation = State::S0; rd_clk_enable = State::S0; rd_clk_polarity = State::S0; - rd_transparent = State::S0; + rd_ce_over_srst = State::S0; + rd_arst_value = State::S0; + rd_srst_value = State::S0; + rd_init_value = State::S0; + } + if (rd_ports.empty() || wr_ports.empty()) { + rd_transparency_mask = State::S0; + rd_collision_x_mask = State::S0; } cell->parameters[ID::RD_PORTS] = Const(GetSize(rd_clk)); cell->parameters[ID::RD_CLK_ENABLE] = rd_clk_enable; cell->parameters[ID::RD_CLK_POLARITY] = rd_clk_polarity; - cell->parameters[ID::RD_TRANSPARENT] = rd_transparent; + cell->parameters[ID::RD_TRANSPARENCY_MASK] = rd_transparency_mask; + cell->parameters[ID::RD_COLLISION_X_MASK] = rd_collision_x_mask; + cell->parameters[ID::RD_WIDE_CONTINUATION] = rd_wide_continuation; + cell->parameters[ID::RD_CE_OVER_SRST] = rd_ce_over_srst; + cell->parameters[ID::RD_ARST_VALUE] = rd_arst_value; + cell->parameters[ID::RD_SRST_VALUE] = rd_srst_value; + cell->parameters[ID::RD_INIT_VALUE] = rd_init_value; cell->setPort(ID::RD_CLK, rd_clk); cell->setPort(ID::RD_EN, rd_en); + cell->setPort(ID::RD_ARST, rd_arst); + cell->setPort(ID::RD_SRST, rd_srst); cell->setPort(ID::RD_ADDR, rd_addr); cell->setPort(ID::RD_DATA, rd_data); for (auto &port : wr_ports) { @@ -203,6 +219,8 @@ void Mem::emit() { wr_clk_enable.bits.push_back(State(port.clk_enable)); wr_clk_polarity.bits.push_back(State(port.clk_polarity)); wr_clk.append(port.clk); + for (auto idx : wr_port_xlat) + wr_priority_mask.bits.push_back(State(bool(port.priority_mask[idx]))); SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); wr_addr.append(addr); @@ -215,10 +233,13 @@ void Mem::emit() { wr_wide_continuation = State::S0; wr_clk_enable = State::S0; wr_clk_polarity = State::S0; + wr_priority_mask = State::S0; } cell->parameters[ID::WR_PORTS] = Const(GetSize(wr_clk)); cell->parameters[ID::WR_CLK_ENABLE] = wr_clk_enable; cell->parameters[ID::WR_CLK_POLARITY] = wr_clk_polarity; + cell->parameters[ID::WR_PRIORITY_MASK] = wr_priority_mask; + cell->parameters[ID::WR_WIDE_CONTINUATION] = wr_wide_continuation; cell->setPort(ID::WR_CLK, wr_clk); cell->setPort(ID::WR_EN, wr_en); cell->setPort(ID::WR_ADDR, wr_addr); @@ -247,49 +268,44 @@ void Mem::emit() { mem->size = size; mem->attributes = attributes; for (auto &port : rd_ports) { - // TODO: remove - log_assert(port.arst == State::S0); - log_assert(port.srst == State::S0); - log_assert(port.init_value == Const(State::Sx, width << port.wide_log2)); - bool transparent = false; - bool non_transparent = false; - if (port.clk_enable) { - for (int i = 0; i < GetSize(wr_ports); i++) { - auto &oport = wr_ports[i]; - if (oport.clk_enable && oport.clk == port.clk && oport.clk_polarity == port.clk_polarity) { - if (port.transparency_mask[i]) - transparent = true; - else if (!port.collision_x_mask[i]) - non_transparent = true; - } - } - log_assert(!transparent || !non_transparent); - } if (!port.cell) - port.cell = module->addCell(NEW_ID, ID($memrd)); + port.cell = module->addCell(NEW_ID, ID($memrd_v2)); + port.cell->type = ID($memrd_v2); port.cell->attributes = port.attributes; port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); port.cell->parameters[ID::WIDTH] = width << port.wide_log2; port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; - port.cell->parameters[ID::TRANSPARENT] = transparent; + port.cell->parameters[ID::CE_OVER_SRST] = port.ce_over_srst; + port.cell->parameters[ID::ARST_VALUE] = port.arst_value; + port.cell->parameters[ID::SRST_VALUE] = port.srst_value; + port.cell->parameters[ID::INIT_VALUE] = port.init_value; + port.cell->parameters[ID::TRANSPARENCY_MASK] = port.transparency_mask; + port.cell->parameters[ID::COLLISION_X_MASK] = port.collision_x_mask; + port.cell->parameters.erase(ID::TRANSPARENT); port.cell->setPort(ID::CLK, port.clk); port.cell->setPort(ID::EN, port.en); + port.cell->setPort(ID::ARST, port.arst); + port.cell->setPort(ID::SRST, port.srst); port.cell->setPort(ID::ADDR, port.addr); port.cell->setPort(ID::DATA, port.data); } int idx = 0; for (auto &port : wr_ports) { if (!port.cell) - port.cell = module->addCell(NEW_ID, ID($memwr)); + port.cell = module->addCell(NEW_ID, ID($memwr_v2)); + port.cell->type = ID($memwr_v2); port.cell->attributes = port.attributes; + if (port.cell->parameters.count(ID::PRIORITY)) + port.cell->parameters.erase(ID::PRIORITY); port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); port.cell->parameters[ID::WIDTH] = width << port.wide_log2; port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; - port.cell->parameters[ID::PRIORITY] = idx++; + port.cell->parameters[ID::PORTID] = idx++; + port.cell->parameters[ID::PRIORITY_MASK] = port.priority_mask; port.cell->setPort(ID::CLK, port.clk); port.cell->setPort(ID::EN, port.en); port.cell->setPort(ID::ADDR, port.addr); @@ -497,9 +513,9 @@ namespace { dict> inits; MemIndex (Module *module) { for (auto cell: module->cells()) { - if (cell->type == ID($memwr)) + if (cell->type.in(ID($memwr), ID($memwr_v2))) wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); - else if (cell->type == ID($memrd)) + else if (cell->type.in(ID($memrd), ID($memrd_v2))) rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); else if (cell->type.in(ID($meminit), ID($meminit_v2))) inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); @@ -513,33 +529,45 @@ namespace { res.mem = mem; res.attributes = mem->attributes; std::vector rd_transparent; + std::vector wr_portid; if (index.rd_ports.count(mem->name)) { for (auto cell : index.rd_ports.at(mem->name)) { MemRd mrd; + bool is_compat = cell->type == ID($memrd); mrd.cell = cell; mrd.attributes = cell->attributes; mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); mrd.clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); - bool transparent = cell->parameters.at(ID::TRANSPARENT).as_bool(); mrd.clk = cell->getPort(ID::CLK); mrd.en = cell->getPort(ID::EN); mrd.addr = cell->getPort(ID::ADDR); mrd.data = cell->getPort(ID::DATA); mrd.wide_log2 = ceil_log2(GetSize(mrd.data) / mem->width); - mrd.ce_over_srst = false; - mrd.arst_value = Const(State::Sx, mem->width << mrd.wide_log2); - mrd.srst_value = Const(State::Sx, mem->width << mrd.wide_log2); - mrd.init_value = Const(State::Sx, mem->width << mrd.wide_log2); - mrd.srst = State::S0; - mrd.arst = State::S0; - if (!mrd.clk_enable) { - // Fix some patterns that we'll allow for backwards compatibility, - // but don't want to see moving forwards: async transparent - // ports (inherently meaningless) and async ports without - // const 1 tied to EN bit (which may mean a latch in the future). - transparent = false; - if (mrd.en == State::Sx) - mrd.en = State::S1; + bool transparent = false; + if (is_compat) { + transparent = cell->parameters.at(ID::TRANSPARENT).as_bool(); + mrd.ce_over_srst = false; + mrd.arst_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.srst_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.init_value = Const(State::Sx, mem->width << mrd.wide_log2); + mrd.srst = State::S0; + mrd.arst = State::S0; + if (!mrd.clk_enable) { + // Fix some patterns that we'll allow for backwards compatibility, + // but don't want to see moving forwards: async transparent + // ports (inherently meaningless) and async ports without + // const 1 tied to EN bit (which may mean a latch in the future). + transparent = false; + if (mrd.en == State::Sx) + mrd.en = State::S1; + } + } else { + mrd.ce_over_srst = cell->parameters.at(ID::CE_OVER_SRST).as_bool(); + mrd.arst_value = cell->parameters.at(ID::ARST_VALUE); + mrd.srst_value = cell->parameters.at(ID::SRST_VALUE); + mrd.init_value = cell->parameters.at(ID::INIT_VALUE); + mrd.arst = cell->getPort(ID::ARST); + mrd.srst = cell->getPort(ID::SRST); } res.rd_ports.push_back(mrd); rd_transparent.push_back(transparent); @@ -549,6 +577,7 @@ namespace { std::vector> ports; for (auto cell : index.wr_ports.at(mem->name)) { MemWr mwr; + bool is_compat = cell->type == ID($memwr); mwr.cell = cell; mwr.attributes = cell->attributes; mwr.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); @@ -558,11 +587,36 @@ namespace { mwr.addr = cell->getPort(ID::ADDR); mwr.data = cell->getPort(ID::DATA); mwr.wide_log2 = ceil_log2(GetSize(mwr.data) / mem->width); - ports.push_back(std::make_pair(cell->parameters.at(ID::PRIORITY).as_int(), mwr)); + ports.push_back(std::make_pair(cell->parameters.at(is_compat ? ID::PRIORITY : ID::PORTID).as_int(), mwr)); } std::sort(ports.begin(), ports.end(), [](const std::pair &a, const std::pair &b) { return a.first < b.first; }); - for (auto &it : ports) + for (auto &it : ports) { res.wr_ports.push_back(it.second); + wr_portid.push_back(it.first); + } + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + bool is_compat = port.cell->type == ID($memwr); + if (is_compat) { + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } + } else { + Const orig_prio_mask = port.cell->parameters.at(ID::PRIORITY_MASK); + for (int orig_portid : wr_portid) { + bool has_prio = orig_portid < GetSize(orig_prio_mask) && orig_prio_mask[orig_portid] == State::S1; + port.priority_mask.push_back(has_prio); + } + } + } } if (index.inits.count(mem->name)) { std::vector> inits; @@ -592,37 +646,33 @@ namespace { for (auto &it : inits) res.inits.push_back(it.second); } - for (int i = 0; i < GetSize(res.wr_ports); i++) { - auto &port = res.wr_ports[i]; - port.priority_mask.resize(GetSize(res.wr_ports)); - for (int j = 0; j < i; j++) { - auto &oport = res.wr_ports[j]; - if (port.clk_enable != oport.clk_enable) - continue; - if (port.clk_enable && port.clk != oport.clk) - continue; - if (port.clk_enable && port.clk_polarity != oport.clk_polarity) - continue; - port.priority_mask[j] = true; - } - } for (int i = 0; i < GetSize(res.rd_ports); i++) { auto &port = res.rd_ports[i]; - port.transparency_mask.resize(GetSize(res.wr_ports)); - port.collision_x_mask.resize(GetSize(res.wr_ports)); - if (!rd_transparent[i]) - continue; - if (!port.clk_enable) - continue; - for (int j = 0; j < GetSize(res.wr_ports); j++) { - auto &wport = res.wr_ports[j]; - if (!wport.clk_enable) - continue; - if (port.clk != wport.clk) + bool is_compat = port.cell->type == ID($memrd); + if (is_compat) { + port.transparency_mask.resize(GetSize(res.wr_ports)); + port.collision_x_mask.resize(GetSize(res.wr_ports)); + if (!rd_transparent[i]) continue; - if (port.clk_polarity != wport.clk_polarity) + if (!port.clk_enable) continue; - port.transparency_mask[j] = true; + for (int j = 0; j < GetSize(res.wr_ports); j++) { + auto &wport = res.wr_ports[j]; + if (!wport.clk_enable) + continue; + if (port.clk != wport.clk) + continue; + if (port.clk_polarity != wport.clk_polarity) + continue; + port.transparency_mask[j] = true; + } + } else { + Const orig_trans_mask = port.cell->parameters.at(ID::TRANSPARENCY_MASK); + Const orig_cx_mask = port.cell->parameters.at(ID::COLLISION_X_MASK); + for (int orig_portid : wr_portid) { + port.transparency_mask.push_back(orig_portid < GetSize(orig_trans_mask) && orig_trans_mask[orig_portid] == State::S1); + port.collision_x_mask.push_back(orig_portid < GetSize(orig_cx_mask) && orig_cx_mask[orig_portid] == State::S1); + } } } res.check(); @@ -635,6 +685,7 @@ namespace { cell->parameters.at(ID::OFFSET).as_int(), cell->parameters.at(ID::SIZE).as_int() ); + bool is_compat = cell->type == ID($mem); int abits = cell->parameters.at(ID::ABITS).as_int(); res.packed = true; res.cell = cell; @@ -662,65 +713,103 @@ namespace { } } } - for (int i = 0; i < cell->parameters.at(ID::RD_PORTS).as_int(); i++) { + int n_rd_ports = cell->parameters.at(ID::RD_PORTS).as_int(); + int n_wr_ports = cell->parameters.at(ID::WR_PORTS).as_int(); + Const rd_wide_continuation = is_compat ? Const(State::S0, n_rd_ports) : cell->parameters.at(ID::RD_WIDE_CONTINUATION); + Const wr_wide_continuation = is_compat ? Const(State::S0, n_wr_ports) : cell->parameters.at(ID::WR_WIDE_CONTINUATION); + for (int i = 0, ni; i < n_rd_ports; i = ni) { + ni = i + 1; + while (ni < n_rd_ports && rd_wide_continuation[ni] == State::S1) + ni++; MemRd mrd; - mrd.wide_log2 = 0; + mrd.wide_log2 = ceil_log2(ni - i); + log_assert(ni - i == (1 << mrd.wide_log2)); mrd.clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE).extract(i, 1).as_bool(); mrd.clk_polarity = cell->parameters.at(ID::RD_CLK_POLARITY).extract(i, 1).as_bool(); mrd.clk = cell->getPort(ID::RD_CLK).extract(i, 1); mrd.en = cell->getPort(ID::RD_EN).extract(i, 1); mrd.addr = cell->getPort(ID::RD_ADDR).extract(i * abits, abits); - mrd.data = cell->getPort(ID::RD_DATA).extract(i * res.width, res.width); - mrd.ce_over_srst = false; - mrd.arst_value = Const(State::Sx, res.width << mrd.wide_log2); - mrd.srst_value = Const(State::Sx, res.width << mrd.wide_log2); - mrd.init_value = Const(State::Sx, res.width << mrd.wide_log2); - mrd.srst = State::S0; - mrd.arst = State::S0; + mrd.data = cell->getPort(ID::RD_DATA).extract(i * res.width, (ni - i) * res.width); + if (is_compat) { + mrd.ce_over_srst = false; + mrd.arst_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.srst_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.init_value = Const(State::Sx, res.width << mrd.wide_log2); + mrd.arst = State::S0; + mrd.srst = State::S0; + } else { + mrd.ce_over_srst = cell->parameters.at(ID::RD_CE_OVER_SRST).extract(i, 1).as_bool(); + mrd.arst_value = cell->parameters.at(ID::RD_ARST_VALUE).extract(i * res.width, (ni - i) * res.width); + mrd.srst_value = cell->parameters.at(ID::RD_SRST_VALUE).extract(i * res.width, (ni - i) * res.width); + mrd.init_value = cell->parameters.at(ID::RD_INIT_VALUE).extract(i * res.width, (ni - i) * res.width); + mrd.arst = cell->getPort(ID::RD_ARST).extract(i, 1); + mrd.srst = cell->getPort(ID::RD_SRST).extract(i, 1); + } + if (!is_compat) { + Const transparency_mask = cell->parameters.at(ID::RD_TRANSPARENCY_MASK).extract(i * n_wr_ports, n_wr_ports); + Const collision_x_mask = cell->parameters.at(ID::RD_COLLISION_X_MASK).extract(i * n_wr_ports, n_wr_ports); + for (int j = 0; j < n_wr_ports; j++) + if (wr_wide_continuation[j] != State::S1) { + mrd.transparency_mask.push_back(transparency_mask[j] == State::S1); + mrd.collision_x_mask.push_back(collision_x_mask[j] == State::S1); + } + } res.rd_ports.push_back(mrd); } - for (int i = 0; i < cell->parameters.at(ID::WR_PORTS).as_int(); i++) { + for (int i = 0, ni; i < n_wr_ports; i = ni) { + ni = i + 1; + while (ni < n_wr_ports && wr_wide_continuation[ni] == State::S1) + ni++; MemWr mwr; - mwr.wide_log2 = 0; + mwr.wide_log2 = ceil_log2(ni - i); + log_assert(ni - i == (1 << mwr.wide_log2)); mwr.clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE).extract(i, 1).as_bool(); mwr.clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY).extract(i, 1).as_bool(); mwr.clk = cell->getPort(ID::WR_CLK).extract(i, 1); - mwr.en = cell->getPort(ID::WR_EN).extract(i * res.width, res.width); + mwr.en = cell->getPort(ID::WR_EN).extract(i * res.width, (ni - i) * res.width); mwr.addr = cell->getPort(ID::WR_ADDR).extract(i * abits, abits); - mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, res.width); + mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, (ni - i) * res.width); + if (!is_compat) { + Const priority_mask = cell->parameters.at(ID::WR_PRIORITY_MASK).extract(i * n_wr_ports, n_wr_ports); + for (int j = 0; j < n_wr_ports; j++) + if (wr_wide_continuation[j] != State::S1) + mwr.priority_mask.push_back(priority_mask[j] == State::S1); + } res.wr_ports.push_back(mwr); } - for (int i = 0; i < GetSize(res.wr_ports); i++) { - auto &port = res.wr_ports[i]; - port.priority_mask.resize(GetSize(res.wr_ports)); - for (int j = 0; j < i; j++) { - auto &oport = res.wr_ports[j]; - if (port.clk_enable != oport.clk_enable) - continue; - if (port.clk_enable && port.clk != oport.clk) - continue; - if (port.clk_enable && port.clk_polarity != oport.clk_polarity) - continue; - port.priority_mask[j] = true; + if (is_compat) { + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } } - } - for (int i = 0; i < GetSize(res.rd_ports); i++) { - auto &port = res.rd_ports[i]; - port.transparency_mask.resize(GetSize(res.wr_ports)); - port.collision_x_mask.resize(GetSize(res.wr_ports)); - if (!cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool()) - continue; - if (!port.clk_enable) - continue; - for (int j = 0; j < GetSize(res.wr_ports); j++) { - auto &wport = res.wr_ports[j]; - if (!wport.clk_enable) - continue; - if (port.clk != wport.clk) + for (int i = 0; i < GetSize(res.rd_ports); i++) { + auto &port = res.rd_ports[i]; + port.transparency_mask.resize(GetSize(res.wr_ports)); + port.collision_x_mask.resize(GetSize(res.wr_ports)); + if (!cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool()) continue; - if (port.clk_polarity != wport.clk_polarity) + if (!port.clk_enable) continue; - port.transparency_mask[j] = true; + for (int j = 0; j < GetSize(res.wr_ports); j++) { + auto &wport = res.wr_ports[j]; + if (!wport.clk_enable) + continue; + if (port.clk != wport.clk) + continue; + if (port.clk_polarity != wport.clk_polarity) + continue; + port.transparency_mask[j] = true; + } } } res.check(); @@ -736,7 +825,7 @@ std::vector Mem::get_all_memories(Module *module) { res.push_back(mem_from_memory(module, it.second, index)); } for (auto cell: module->cells()) { - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($mem_v2))) res.push_back(mem_from_cell(cell)); } return res; @@ -750,7 +839,7 @@ std::vector Mem::get_selected_memories(Module *module) { res.push_back(mem_from_memory(module, it.second, index)); } for (auto cell: module->selected_cells()) { - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($mem_v2))) res.push_back(mem_from_cell(cell)); } return res; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index bd6b3ad0558..b414556f36c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1392,6 +1392,26 @@ namespace { return; } + if (cell->type == ID($memrd_v2)) { + param(ID::MEMID); + param_bool(ID::CLK_ENABLE); + param_bool(ID::CLK_POLARITY); + param(ID::TRANSPARENCY_MASK); + param(ID::COLLISION_X_MASK); + param_bool(ID::CE_OVER_SRST); + param_bits(ID::ARST_VALUE, param(ID::WIDTH)); + param_bits(ID::SRST_VALUE, param(ID::WIDTH)); + param_bits(ID::INIT_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::ARST, 1); + port(ID::SRST, 1); + port(ID::ADDR, param(ID::ABITS)); + port(ID::DATA, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($memwr)) { param(ID::MEMID); param_bool(ID::CLK_ENABLE); @@ -1405,6 +1425,20 @@ namespace { return; } + if (cell->type == ID($memwr_v2)) { + param(ID::MEMID); + param_bool(ID::CLK_ENABLE); + param_bool(ID::CLK_POLARITY); + param(ID::PORTID); + param(ID::PRIORITY_MASK); + port(ID::CLK, 1); + port(ID::EN, param(ID::WIDTH)); + port(ID::ADDR, param(ID::ABITS)); + port(ID::DATA, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($meminit)) { param(ID::MEMID); param(ID::PRIORITY); @@ -1446,6 +1480,38 @@ namespace { return; } + if (cell->type == ID($mem_v2)) { + param(ID::MEMID); + param(ID::SIZE); + param(ID::OFFSET); + param(ID::INIT); + param_bits(ID::RD_CLK_ENABLE, max(1, param(ID::RD_PORTS))); + param_bits(ID::RD_CLK_POLARITY, max(1, param(ID::RD_PORTS))); + param_bits(ID::RD_TRANSPARENCY_MASK, max(1, param(ID::RD_PORTS) * param(ID::WR_PORTS))); + param_bits(ID::RD_COLLISION_X_MASK, max(1, param(ID::RD_PORTS) * param(ID::WR_PORTS))); + param_bits(ID::RD_WIDE_CONTINUATION, max(1, param(ID::RD_PORTS))); + param_bits(ID::RD_CE_OVER_SRST, max(1, param(ID::RD_PORTS))); + param_bits(ID::RD_ARST_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); + param_bits(ID::RD_SRST_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); + param_bits(ID::RD_INIT_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); + param_bits(ID::WR_CLK_ENABLE, max(1, param(ID::WR_PORTS))); + param_bits(ID::WR_CLK_POLARITY, max(1, param(ID::WR_PORTS))); + param_bits(ID::WR_WIDE_CONTINUATION, max(1, param(ID::WR_PORTS))); + param_bits(ID::WR_PRIORITY_MASK, max(1, param(ID::WR_PORTS) * param(ID::WR_PORTS))); + port(ID::RD_CLK, param(ID::RD_PORTS)); + port(ID::RD_EN, param(ID::RD_PORTS)); + port(ID::RD_ARST, param(ID::RD_PORTS)); + port(ID::RD_SRST, param(ID::RD_PORTS)); + port(ID::RD_ADDR, param(ID::RD_PORTS) * param(ID::ABITS)); + port(ID::RD_DATA, param(ID::RD_PORTS) * param(ID::WIDTH)); + port(ID::WR_CLK, param(ID::WR_PORTS)); + port(ID::WR_EN, param(ID::WR_PORTS) * param(ID::WIDTH)); + port(ID::WR_ADDR, param(ID::WR_PORTS) * param(ID::ABITS)); + port(ID::WR_DATA, param(ID::WR_PORTS) * param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($tribuf)) { port(ID::A, param(ID::WIDTH)); port(ID::Y, param(ID::WIDTH)); @@ -3187,12 +3253,12 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) bool RTLIL::Cell::has_memid() const { - return type.in(ID($memwr), ID($memrd), ID($meminit), ID($meminit_v2)); + return type.in(ID($memwr), ID($memwr_v2), ID($memrd), ID($memrd_v2), ID($meminit), ID($meminit_v2)); } bool RTLIL::Cell::is_mem_cell() const { - return type == ID($mem) || has_memid(); + return type.in(ID($mem), ID($mem_v2)) || has_memid(); } RTLIL::SigChunk::SigChunk() diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 08901debb1a..74ba224df5c 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -338,19 +338,19 @@ \subsection{Registers} \subsection{Memories} \label{sec:memcells} -Memories are either represented using RTLIL::Memory objects, {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit\_v2} -cells, or by {\tt \$mem} cells alone. +Memories are either represented using RTLIL::Memory objects, {\tt \$memrd\_v2}, {\tt \$memwr\_v2}, and {\tt \$meminit\_v2} +cells, or by {\tt \$mem\_v2} cells alone. In the first alternative the RTLIL::Memory objects hold the general metadata for the memory (bit width, -size in number of words, etc.) and for each port a {\tt \$memrd} (read port) or {\tt \$memwr} (write port) +size in number of words, etc.) and for each port a {\tt \$memrd\_v2} (read port) or {\tt \$memwr\_v2} (write port) cell is created. Having individual cells for read and write ports has the advantage that they can be consolidated using resource sharing passes. In some cases this drastically reduces the number of required ports on the memory cell. In this alternative, memory initialization data is represented by {\tt \$meminit\_v2} cells, which allow delaying constant folding for initialization addresses and data until after the frontend finishes. -The {\tt \$memrd} cells have a clock input \B{CLK}, an enable input \B{EN}, an -address input \B{ADDR}, and a data output \B{DATA}. They also have the -following parameters: +The {\tt \$memrd\_v2} cells have a clock input \B{CLK}, an enable input \B{EN}, an +address input \B{ADDR}, a data output \B{DATA}, an asynchronous reset input \B{ARST}, +and a synchronous reset input \B{SRST}. They also have the following parameters: \begin{itemize} \item \B{MEMID} \\ @@ -360,7 +360,9 @@ \subsection{Memories} The number of address bits (width of the \B{ADDR} input port). \item \B{WIDTH} \\ -The number of data bits (width of the \B{DATA} output port). +The number of data bits (width of the \B{DATA} output port). Note that this may be a power-of-two +multiple of the underlying memory's width -- such ports are called wide ports and access an aligned +group of cells at once. In this case, the corresponding low bits of \B{ADDR} must be tied to 0. \item \B{CLK\_ENABLE} \\ When this parameter is non-zero, the clock is used. Otherwise this read port is asynchronous and @@ -370,12 +372,37 @@ \subsection{Memories} Clock is active on the positive edge if this parameter has the value {\tt 1'b1} and on the negative edge if this parameter is {\tt 1'b0}. -\item \B{TRANSPARENT} \\ -If this parameter is set to {\tt 1'b1}, a read and write to the same address in the same cycle will -return the new value. Otherwise the old value is returned. +\item \B{TRANSPARENCY\_MASK} \\ +This parameter is a bitmask of write ports that this read port is transparent with. The bits +of this parameter are indexed by the write port's \B{PORTID} parameter. Transparency can only be +enabled between synchronous ports sharing a clock domain. When transparency is enabled for a given +port pair, a read and write to the same address in the same cycle will return the new value. +Otherwise the old value is returned. + +\item \B{COLLISION\_X\_MASK} \\ +This parameter is a bitmask of write ports that have undefined collision behavior with this port. +The bits of this parameter are indexed by the write port's \B{PORTID} parameter. This behavior can only be +enabled between synchronous ports sharing a clock domain. When undefined collision is enabled for a given +port pair, a read and write to the same address in the same cycle will return the undefined (all-X) value. +This option is exclusive (for a given port pair) with the transparency option. + +\item \B{ARST\_VALUE} \\ +Whenever the \B{ARST} input is asserted, the data output will be reset to this value. +Only used for synchronous ports. + +\item \B{SRST\_VALUE} \\ +Whenever the \B{SRST} input is synchronously asserted, the data output will be reset to this value. +Only used for synchronous ports. + +\item \B{INIT\_VALUE} \\ +The initial value of the data output, for synchronous ports. + +\item \B{CE\_OVER\_SRST} \\ +If this parameter is non-zero, the \B{SRST} input is only recognized when \B{EN} is true. +Otherwise, \B{SRST} is recognized regardless of \B{EN}. \end{itemize} -The {\tt \$memwr} cells have a clock input \B{CLK}, an enable input \B{EN} (one +The {\tt \$memwr\_v2} cells have a clock input \B{CLK}, an enable input \B{EN} (one enable bit for each data bit), an address input \B{ADDR} and a data input \B{DATA}. They also have the following parameters: @@ -387,7 +414,9 @@ \subsection{Memories} The number of address bits (width of the \B{ADDR} input port). \item \B{WIDTH} \\ -The number of data bits (width of the \B{DATA} output port). +The number of data bits (width of the \B{DATA} output port). Like with {\tt \$memrd\_v2} cells, +the width is allowed to be any power-of-two multiple of memory width, with the corresponding +restriction on address. \item \B{CLK\_ENABLE} \\ When this parameter is non-zero, the clock is used. Otherwise this write port is asynchronous and @@ -397,8 +426,15 @@ \subsection{Memories} Clock is active on positive edge if this parameter has the value {\tt 1'b1} and on the negative edge if this parameter is {\tt 1'b0}. -\item \B{PRIORITY} \\ -The cell with the higher integer value in this parameter wins a write conflict. +\item \B{PORTID} \\ +An identifier for this write port, used to index write port bit mask parameters. + +\item \B{PRIORITY\_MASK} \\ +This parameter is a bitmask of write ports that this write port has priority over in case of writing +to the same address. The bits of this parameter are indexed by the other write port's \B{PORTID} parameter. +Write ports can only have priority over write ports with lower port ID. When two ports write to the same +address and neither has priority over the other, the result is undefined. Priority can only be set between +two synchronous ports sharing the same clock domain. \end{itemize} The {\tt \$meminit\_v2} cells have an address input \B{ADDR}, a data input \B{DATA}, with the width @@ -424,17 +460,17 @@ \subsection{Memories} \end{itemize} The HDL frontend models a memory using RTLIL::Memory objects and asynchronous -{\tt \$memrd} and {\tt \$memwr} cells. The {\tt memory} pass (i.e.~its various sub-passes) migrates -{\tt \$dff} cells into the {\tt \$memrd} and {\tt \$memwr} cells making them synchronous, then -converts them to a single {\tt \$mem} cell and (optionally) maps this cell type +{\tt \$memrd\_v2} and {\tt \$memwr\_v2} cells. The {\tt memory} pass (i.e.~its various sub-passes) migrates +{\tt \$dff} cells into the {\tt \$memrd\_v2} and {\tt \$memwr\_v2} cells making them synchronous, then +converts them to a single {\tt \$mem\_v2} cell and (optionally) maps this cell type to {\tt \$dff} cells for the individual words and multiplexer-based address decoders for the read and -write interfaces. When the last step is disabled or not possible, a {\tt \$mem} cell is left in the design. +write interfaces. When the last step is disabled or not possible, a {\tt \$mem\_v2} cell is left in the design. -The {\tt \$mem} cell provides the following parameters: +The {\tt \$mem\_v2} cell provides the following parameters: \begin{itemize} \item \B{MEMID} \\ -The name of the original RTLIL::Memory object that became this {\tt \$mem} cell. +The name of the original RTLIL::Memory object that became this {\tt \$mem\_v2} cell. \item \B{SIZE} \\ The number of words in the memory. @@ -451,26 +487,56 @@ \subsection{Memories} \item \B{RD\_PORTS} \\ The number of read ports on this memory cell. +\item \B{RD\_WIDE\_CONTINUATION} \\ +This parameter is \B{RD\_PORTS} bits wide, containing a bitmask of ``wide continuation'' read ports. +Such ports are used to represent the extra data bits of wide ports in the combined cell, and must +have all control signals identical with the preceding port, except for address, which must have +the proper sub-cell address encoded in the low bits. + \item \B{RD\_CLK\_ENABLE} \\ This parameter is \B{RD\_PORTS} bits wide, containing a clock enable bit for each read port. \item \B{RD\_CLK\_POLARITY} \\ This parameter is \B{RD\_PORTS} bits wide, containing a clock polarity bit for each read port. -\item \B{RD\_TRANSPARENT} \\ -This parameter is \B{RD\_PORTS} bits wide, containing a transparent bit for each read port. +\item \B{RD\_TRANSPARENCY\_MASK} \\ +This parameter is \B{RD\_PORTS*WR\_PORTS} bits wide, containing a concatenation of all +\B{TRANSPARENCY\_MASK} values of the original {\tt \$memrd\_v2} cells. + +\item \B{RD\_COLLISION\_X\_MASK} \\ +This parameter is \B{RD\_PORTS*WR\_PORTS} bits wide, containing a concatenation of all +\B{COLLISION\_X\_MASK} values of the original {\tt \$memrd\_v2} cells. + +\item \B{RD\_CE\_OVER\_SRST} \\ +This parameter is \B{RD\_PORTS} bits wide, determining relative synchronous reset and enable priority for each read port. + +\item \B{RD\_INIT\_VALUE} \\ +This parameter is \B{RD\_PORTS*WIDTH} bits wide, containing the initial value for each synchronous read port. + +\item \B{RD\_ARST\_VALUE} \\ +This parameter is \B{RD\_PORTS*WIDTH} bits wide, containing the asynchronous reset value for each synchronous read port. + +\item \B{RD\_SRST\_VALUE} \\ +This parameter is \B{RD\_PORTS*WIDTH} bits wide, containing the synchronous reset value for each synchronous read port. \item \B{WR\_PORTS} \\ The number of write ports on this memory cell. +\item \B{WR\_WIDE\_CONTINUATION} \\ +This parameter is \B{WR\_PORTS} bits wide, containing a bitmask of ``wide continuation'' write ports. + \item \B{WR\_CLK\_ENABLE} \\ This parameter is \B{WR\_PORTS} bits wide, containing a clock enable bit for each write port. \item \B{WR\_CLK\_POLARITY} \\ This parameter is \B{WR\_PORTS} bits wide, containing a clock polarity bit for each write port. + +\item \B{WR\_PRIORITY\_MASK} \\ +This parameter is \B{WR\_PORTS*WR\_PORTS} bits wide, containing a concatenation of all +\B{PRIORITY\_MASK} values of the original {\tt \$memwr\_v2} cells. \end{itemize} -The {\tt \$mem} cell has the following ports: +The {\tt \$mem\_v2} cell has the following ports: \begin{itemize} \item \B{RD\_CLK} \\ @@ -485,6 +551,12 @@ \subsection{Memories} \item \B{RD\_DATA} \\ This input is \B{RD\_PORTS}*\B{WIDTH} bits wide, containing all data signals for the read ports. +\item \B{RD\_ARST} \\ +This input is \B{RD\_PORTS} bits wide, containing all asynchronous reset signals for the read ports. + +\item \B{RD\_SRST} \\ +This input is \B{RD\_PORTS} bits wide, containing all synchronous reset signals for the read ports. + \item \B{WR\_CLK} \\ This input is \B{WR\_PORTS} bits wide, containing all clock signals for the write ports. @@ -498,11 +570,11 @@ \subsection{Memories} This input is \B{WR\_PORTS}*\B{WIDTH} bits wide, containing all data signals for the write ports. \end{itemize} -The {\tt memory\_collect} pass can be used to convert discrete {\tt \$memrd}, {\tt \$memwr}, and {\tt \$meminit\_v2} cells -belonging to the same memory to a single {\tt \$mem} cell, whereas the {\tt memory\_unpack} pass performs the inverse operation. +The {\tt memory\_collect} pass can be used to convert discrete {\tt \$memrd\_v2}, {\tt \$memwr\_v2}, and {\tt \$meminit\_v2} cells +belonging to the same memory to a single {\tt \$mem\_v2} cell, whereas the {\tt memory\_unpack} pass performs the inverse operation. The {\tt memory\_dff} pass can combine asynchronous memory ports that are fed by or feeding registers into synchronous memory ports. -The {\tt memory\_bram} pass can be used to recognize {\tt \$mem} cells that can be implemented with a block RAM resource on an FPGA. -The {\tt memory\_map} pass can be used to implement {\tt \$mem} cells as basic logic: word-wide DFFs and address decoders. +The {\tt memory\_bram} pass can be used to recognize {\tt \$mem\_v2} cells that can be implemented with a block RAM resource on an FPGA. +The {\tt memory\_map} pass can be used to implement {\tt \$mem\_v2} cells as basic logic: word-wide DFFs and address decoders. \subsection{Finite State Machines} diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 9fc7f2e9cd3..1620c0bca27 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -83,7 +83,7 @@ struct TorderPass : public Pass { if (!noautostop && yosys_celltypes.cell_known(cell->type)) { if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) continue; - if (cell->type == ID($memrd) && conn.first == ID::DATA) + if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA) continue; } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c3a0928ef3b..08e9d6b791c 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -117,7 +117,7 @@ void rmunused_module_cells(Module *module, bool verbose) } for (Cell *cell : module->cells()) { - if (cell->type.in(ID($memwr), ID($meminit), ID($meminit_v2))) { + if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2))) { IdString mem_id = cell->getParam(ID::MEMID).decode_string(); mem2cells[mem_id].insert(cell); } @@ -167,7 +167,7 @@ void rmunused_module_cells(Module *module, bool verbose) for (auto bit : sigmap(it.second)) bits.insert(bit); - if (cell->type == ID($memrd)) { + if (cell->type.in(ID($memrd), ID($memrd_v2))) { IdString mem_id = cell->getParam(ID::MEMID).decode_string(); if (mem_unused.count(mem_id)) { mem_unused.erase(mem_id); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index b7bbb2adfa3..cdd821c52e6 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -441,7 +441,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (!noclkinv) { - if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memwr))) + if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2))) handle_polarity_inv(cell, ID::CLK, ID::CLK_POLARITY, assign_map, invert_map); if (cell->type.in(ID($sr), ID($dffsr), ID($dffsre), ID($dlatchsr))) { diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 15b2772c755..b558f547e59 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -254,9 +254,9 @@ struct OptReduceWorker SigPool mem_wren_sigs; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($mem_v2))) mem_wren_sigs.add(assign_map(cell->getPort(ID::WR_EN))); - if (cell->type == ID($memwr)) + if (cell->type.in(ID($memwr), ID($memwr_v2))) mem_wren_sigs.add(assign_map(cell->getPort(ID::EN))); } for (auto &cell_it : module->cells_) { diff --git a/passes/opt/share.cc b/passes/opt/share.cc index ee1acfb7f9b..abef719370b 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -366,7 +366,7 @@ struct ShareWorker continue; } - if (cell->type == ID($memrd)) { + if (cell->type.in(ID($memrd), ID($memrd_v2))) { if (cell->parameters.at(ID::CLK_ENABLE).as_bool()) continue; if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID::ADDR)).is_fully_const()) @@ -399,11 +399,14 @@ struct ShareWorker if (c1->type != c2->type) return false; - if (c1->type == ID($memrd)) + if (c1->type.in(ID($memrd), ID($memrd_v2))) { if (c1->parameters.at(ID::MEMID).decode_string() != c2->parameters.at(ID::MEMID).decode_string()) return false; + if (c1->parameters.at(ID::WIDTH) != c2->parameters.at(ID::WIDTH)) + return false; + return true; } @@ -703,7 +706,7 @@ struct ShareWorker return supercell; } - if (c1->type == ID($memrd)) + if (c1->type.in(ID($memrd), ID($memrd_v2))) { RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); RTLIL::SigSpec addr1 = c1->getPort(ID::ADDR); diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index f6bf8b51a79..aaad28ef0ab 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -558,7 +558,7 @@ struct WreducePass : public Pass { } } - if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit), ID($meminit_v2))) { + if (!opt_memx && c->type.in(ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2))) { IdString memid = c->getParam(ID::MEMID).decode_string(); RTLIL::Memory *mem = module->memories.at(memid); if (mem->start_offset >= 0) { diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index eb6b3b858aa..137d2217064 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -74,6 +74,7 @@ class SubCircuitSolver : public SubCircuit::Solver param_int(ID::CTRL_IN_WIDTH) param_int(ID::CTRL_OUT_WIDTH) param_int(ID::OFFSET) + param_int(ID::PORTID) param_int(ID::PRIORITY) param_int(ID::RD_PORTS) param_int(ID::SIZE) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index ad654c8a43b..cf0839ebef7 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2182,6 +2182,34 @@ end endmodule +module \$memrd_v2 (CLK, EN, ARST, SRST, ADDR, DATA); + +parameter MEMID = ""; +parameter ABITS = 8; +parameter WIDTH = 8; + +parameter CLK_ENABLE = 0; +parameter CLK_POLARITY = 0; +parameter TRANSPARENCY_MASK = 0; +parameter COLLISION_X_MASK = 0; +parameter ARST_VALUE = 0; +parameter SRST_VALUE = 0; +parameter INIT_VALUE = 0; +parameter CE_OVER_SRST = 0; + +input CLK, EN, ARST, SRST; +input [ABITS-1:0] ADDR; +output [WIDTH-1:0] DATA; + +initial begin + if (MEMID != "") begin + $display("ERROR: Found non-simulatable instance of $memrd_v2!"); + $finish; + end +end + +endmodule + // -------------------------------------------------------- module \$memwr (CLK, EN, ADDR, DATA); @@ -2208,6 +2236,31 @@ end endmodule +module \$memwr_v2 (CLK, EN, ADDR, DATA); + +parameter MEMID = ""; +parameter ABITS = 8; +parameter WIDTH = 8; + +parameter CLK_ENABLE = 0; +parameter CLK_POLARITY = 0; +parameter PORTID = 0; +parameter PRIORITY_MASK = 0; + +input CLK; +input [WIDTH-1:0] EN; +input [ABITS-1:0] ADDR; +input [WIDTH-1:0] DATA; + +initial begin + if (MEMID != "") begin + $display("ERROR: Found non-simulatable instance of $memwr_v2!"); + $finish; + end +end + +endmodule + // -------------------------------------------------------- module \$meminit (ADDR, DATA); @@ -2344,6 +2397,122 @@ end endmodule +module \$mem_v2 (RD_CLK, RD_EN, RD_ARST, RD_SRST, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); + +parameter MEMID = ""; +parameter signed SIZE = 4; +parameter signed OFFSET = 0; +parameter signed ABITS = 2; +parameter signed WIDTH = 8; +parameter signed INIT = 1'bx; + +parameter signed RD_PORTS = 1; +parameter RD_CLK_ENABLE = 1'b1; +parameter RD_CLK_POLARITY = 1'b1; +parameter RD_TRANSPARENCY_MASK = 1'b0; +parameter RD_COLLISION_X_MASK = 1'b0; +parameter RD_WIDE_CONTINUATION = 1'b0; +parameter RD_CE_OVER_SRST = 1'b0; +parameter RD_ARST_VALUE = 1'b0; +parameter RD_SRST_VALUE = 1'b0; +parameter RD_INIT_VALUE = 1'b0; + +parameter signed WR_PORTS = 1; +parameter WR_CLK_ENABLE = 1'b1; +parameter WR_CLK_POLARITY = 1'b1; +parameter WR_PRIORITY_MASK = 1'b0; +parameter WR_WIDE_CONTINUATION = 1'b0; + +input [RD_PORTS-1:0] RD_CLK; +input [RD_PORTS-1:0] RD_EN; +input [RD_PORTS-1:0] RD_ARST; +input [RD_PORTS-1:0] RD_SRST; +input [RD_PORTS*ABITS-1:0] RD_ADDR; +output reg [RD_PORTS*WIDTH-1:0] RD_DATA; + +input [WR_PORTS-1:0] WR_CLK; +input [WR_PORTS*WIDTH-1:0] WR_EN; +input [WR_PORTS*ABITS-1:0] WR_ADDR; +input [WR_PORTS*WIDTH-1:0] WR_DATA; + +reg [WIDTH-1:0] memory [SIZE-1:0]; + +integer i, j, k; +reg [WR_PORTS-1:0] LAST_WR_CLK; +reg [RD_PORTS-1:0] LAST_RD_CLK; + +function port_active; + input clk_enable; + input clk_polarity; + input last_clk; + input this_clk; + begin + casez ({clk_enable, clk_polarity, last_clk, this_clk}) + 4'b0???: port_active = 1; + 4'b1101: port_active = 1; + 4'b1010: port_active = 1; + default: port_active = 0; + endcase + end +endfunction + +initial begin + for (i = 0; i < SIZE; i = i+1) + memory[i] = INIT >>> (i*WIDTH); + RD_DATA = RD_INIT_VALUE; +end + +always @(RD_CLK, RD_ARST, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin +`ifdef SIMLIB_MEMDELAY + #`SIMLIB_MEMDELAY; +`endif + for (i = 0; i < RD_PORTS; i = i+1) begin + if (RD_CLK_ENABLE[i] && RD_EN[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin + // $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); + RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; + + for (j = 0; j < WR_PORTS; j = j+1) begin + if (RD_TRANSPARENCY_MASK[i*WR_PORTS + j] && port_active(WR_CLK_ENABLE[j], WR_CLK_POLARITY[j], LAST_WR_CLK[j], WR_CLK[j]) && RD_ADDR[i*ABITS +: ABITS] == WR_ADDR[j*ABITS +: ABITS]) + for (k = 0; k < WIDTH; k = k+1) + if (WR_EN[j*WIDTH+k]) + RD_DATA[i*WIDTH+k] <= WR_DATA[j*WIDTH+k]; + if (RD_COLLISION_X_MASK[i*WR_PORTS + j] && port_active(WR_CLK_ENABLE[j], WR_CLK_POLARITY[j], LAST_WR_CLK[j], WR_CLK[j]) && RD_ADDR[i*ABITS +: ABITS] == WR_ADDR[j*ABITS +: ABITS]) + for (k = 0; k < WIDTH; k = k+1) + if (WR_EN[j*WIDTH+k]) + RD_DATA[i*WIDTH+k] <= 1'bx; + end + end + end + + for (i = 0; i < WR_PORTS; i = i+1) begin + if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) + for (j = 0; j < WIDTH; j = j+1) + if (WR_EN[i*WIDTH+j]) begin + // $display("Write to %s: addr=%b data=%b", MEMID, WR_ADDR[i*ABITS +: ABITS], WR_DATA[i*WIDTH+j]); + memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; + end + end + + for (i = 0; i < RD_PORTS; i = i+1) begin + if (!RD_CLK_ENABLE[i]) begin + // $display("Combinatorial read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]); + RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; + end + end + + for (i = 0; i < RD_PORTS; i = i+1) begin + if (RD_SRST[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i]) && (RD_EN[i] || !RD_CE_OVER_SRST[i])) + RD_DATA[i*WIDTH +: WIDTH] <= RD_SRST_VALUE[i*WIDTH +: WIDTH]; + if (RD_ARST[i]) + RD_DATA[i*WIDTH +: WIDTH] <= RD_ARST_VALUE[i*WIDTH +: WIDTH]; + end + + LAST_RD_CLK <= RD_CLK; + LAST_WR_CLK <= WR_CLK; +end + +endmodule + `endif // -------------------------------------------------------- diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys index f55bf01d2ab..03de49cc05d 100644 --- a/tests/arch/ecp5/memories.ys +++ b/tests/arch/ecp5/memories.ys @@ -50,25 +50,25 @@ design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp setattr -set rom_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # RAM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD @@ -141,25 +141,25 @@ design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp setattr -set rom_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # RAM bits <= 64; Data width <= 4; Address width <= 4: -> DPR16X4 @@ -194,7 +194,7 @@ design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp setattr -set syn_ramstyle "distributed" m:memory synth_ecp5 -top sync_ram_sdp -nolutram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested LUTRAM but LUTRAM is disabled +select -assert-count 1 t:$mem_v2 # requested LUTRAM but LUTRAM is disabled # ================================ ROM ================================ # ROM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD @@ -242,25 +242,25 @@ design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom setattr -set ram_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom setattr -set syn_ramstyle "block_rom" m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled # ROM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD @@ -307,22 +307,22 @@ design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom setattr -set ram_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom setattr -set syn_ramstyle "block_rom" m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled diff --git a/tests/arch/ice40/memories.ys b/tests/arch/ice40/memories.ys index c32f12315b7..a0b0f95b2d0 100644 --- a/tests/arch/ice40/memories.ys +++ b/tests/arch/ice40/memories.ys @@ -65,25 +65,25 @@ design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp setattr -set rom_block 1 m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BROM but this is a RAM +select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled design -reset; read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp setattr -set ram_block 1 m:memory synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp -select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # ================================ ROM ================================ # ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K @@ -146,22 +146,22 @@ design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ice40 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom setattr -set ram_block 1 m:memory synth_ice40 -top sync_rom; cd sync_rom -select -assert-count 1 t:$mem # requested BRAM but this is a ROM +select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom setattr -set syn_romstyle "ebr" m:memory synth_ice40 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled design -reset; read_verilog ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom setattr -set rom_block 1 m:memory synth_ice40 -top sync_rom -nobram; cd sync_rom -select -assert-count 1 t:$mem # requested BROM but BRAM is disabled +select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index 376f5bf79b7..cded3eb40a5 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -18,7 +18,7 @@ ${MAKE:-make} -f ../tools/autotest.mk SEED="$seed" EXTRA_FLAGS="$abcopt" *.v for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do echo -n "Testing expectations for $f .." - ../../yosys -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem" $f + ../../yosys -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem_v2" $f if grep -q expect-wr-ports $f; then grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of write ports."; false; } diff --git a/tests/opt/bug2765.ys b/tests/opt/bug2765.ys index de670c2d1a0..fef9abb02cb 100644 --- a/tests/opt/bug2765.ys +++ b/tests/opt/bug2765.ys @@ -31,4 +31,4 @@ proc opt select -assert-count 2 t:$memwr opt_mem -select -assert-count 1 t:$memwr +select -assert-count 1 t:$memwr_v2 diff --git a/tests/opt/opt_mem_feedback.ys b/tests/opt/opt_mem_feedback.ys index 56078ec278d..06d6e7e776e 100644 --- a/tests/opt/opt_mem_feedback.ys +++ b/tests/opt/opt_mem_feedback.ys @@ -37,7 +37,7 @@ design -save preopt design -load start opt_mem_feedback -select -assert-count 1 t:$memrd +select -assert-count 1 t:$memrd_v2 memory_map design -save postopt @@ -182,7 +182,7 @@ design -save preopt design -load start opt_mem_feedback -select -assert-count 1 t:$memrd +select -assert-count 1 t:$memrd_v2 memory_map design -save postopt diff --git a/tests/svtypes/logic_rom.ys b/tests/svtypes/logic_rom.ys index 7b079c13627..776d2e98508 100644 --- a/tests/svtypes/logic_rom.ys +++ b/tests/svtypes/logic_rom.ys @@ -1,3 +1,3 @@ read_verilog -sv logic_rom.sv prep -top top -select -assert-count 1 t:$mem r:SIZE=16 %i r:WIDTH=8 %i +select -assert-count 1 t:$mem_v2 r:SIZE=16 %i r:WIDTH=8 %i diff --git a/tests/svtypes/typedef_memory.ys b/tests/svtypes/typedef_memory.ys index 93cf47bbe6f..d47ee992973 100644 --- a/tests/svtypes/typedef_memory.ys +++ b/tests/svtypes/typedef_memory.ys @@ -1,3 +1,3 @@ read_verilog -sv typedef_memory.sv prep -top top -select -assert-count 1 t:$mem r:SIZE=16 %i r:WIDTH=4 %i +select -assert-count 1 t:$mem_v2 r:SIZE=16 %i r:WIDTH=4 %i diff --git a/tests/svtypes/typedef_memory_2.ys b/tests/svtypes/typedef_memory_2.ys index 854e554f389..bfebd05fc86 100644 --- a/tests/svtypes/typedef_memory_2.ys +++ b/tests/svtypes/typedef_memory_2.ys @@ -1,4 +1,4 @@ read_verilog -sv typedef_memory_2.sv prep -top top dump -select -assert-count 1 t:$mem r:SIZE=16 %i r:WIDTH=4 %i +select -assert-count 1 t:$mem_v2 r:SIZE=16 %i r:WIDTH=4 %i From 24027b5446ffa9d47e00e2ab8bc773fdebc246bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 20:55:09 +0200 Subject: [PATCH 0480/2410] proc_memwr: Use the v2 memwr cell. --- passes/proc/proc_memwr.cc | 28 +++++++++++++++++++--------- tests/opt/bug2765.ys | 2 +- tests/opt/opt_clean_mem.ys | 8 ++++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/passes/proc/proc_memwr.cc b/passes/proc/proc_memwr.cc index f898979d8c8..cf10bd4b2ad 100644 --- a/passes/proc/proc_memwr.cc +++ b/passes/proc/proc_memwr.cc @@ -29,17 +29,26 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict &next_priority) +void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict &next_port_id) { for (auto sr : proc->syncs) { + std::vector prev_port_ids; for (auto memwr : sr->mem_write_actions) { - RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($memwr)); + int port_id = next_port_id[memwr.memid]++; + Const priority_mask(State::S0, port_id); + for (int i = 0; i < GetSize(prev_port_ids); i++) + if (memwr.priority_mask[i] == State::S1) + priority_mask[prev_port_ids[i]] = State::S1; + prev_port_ids.push_back(port_id); + + RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($memwr_v2)); cell->attributes = memwr.attributes; cell->setParam(ID::MEMID, Const(memwr.memid.str())); cell->setParam(ID::ABITS, GetSize(memwr.address)); cell->setParam(ID::WIDTH, GetSize(memwr.data)); - cell->setParam(ID::PRIORITY, next_priority[memwr.memid]++); + cell->setParam(ID::PORTID, port_id); + cell->setParam(ID::PRIORITY_MASK, priority_mask); cell->setPort(ID::ADDR, memwr.address); cell->setPort(ID::DATA, memwr.data); SigSpec enable = memwr.enable; @@ -91,18 +100,19 @@ struct ProcMemWrPass : public Pass { extra_args(args, 1, design); for (auto module : design->selected_modules()) { - dict next_priority; + dict next_port_id; for (auto cell : module->cells()) { - if (cell->type == ID($memwr)) { + if (cell->type.in(ID($memwr), ID($memwr_v2))) { + bool is_compat = cell->type == ID($memwr); IdString memid = cell->parameters.at(ID::MEMID).decode_string(); - int priority = cell->parameters.at(ID::PRIORITY).as_int(); - if (priority >= next_priority[memid]) - next_priority[memid] = priority + 1; + int port_id = cell->parameters.at(is_compat ? ID::PRIORITY : ID::PORTID).as_int(); + if (port_id >= next_port_id[memid]) + next_port_id[memid] = port_id + 1; } } for (auto &proc_it : module->processes) if (design->selected(module, proc_it.second)) - proc_memwr(module, proc_it.second, next_priority); + proc_memwr(module, proc_it.second, next_port_id); } } } ProcMemWrPass; diff --git a/tests/opt/bug2765.ys b/tests/opt/bug2765.ys index fef9abb02cb..7cb790bd708 100644 --- a/tests/opt/bug2765.ys +++ b/tests/opt/bug2765.ys @@ -29,6 +29,6 @@ EOT proc opt -select -assert-count 2 t:$memwr +select -assert-count 2 t:$memwr_v2 opt_mem select -assert-count 1 t:$memwr_v2 diff --git a/tests/opt/opt_clean_mem.ys b/tests/opt/opt_clean_mem.ys index 5e85df6c806..71f9e0d7b06 100644 --- a/tests/opt/opt_clean_mem.ys +++ b/tests/opt/opt_clean_mem.ys @@ -24,25 +24,25 @@ EOT proc select -assert-count 2 t:$memrd -select -assert-count 1 t:$memwr +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:$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:$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:$memwr_v2 select -assert-count 1 t:$meminit_v2 From 72d86c327e203a097f15e502e6a90f1e6d345d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 21:08:11 +0200 Subject: [PATCH 0481/2410] memory_dff: Recognize read ports with reset / initial value. --- passes/memory/memory_dff.cc | 7 ------- tests/memories/read_arst.v | 27 +++++++++++++++++++++++++++ tests/memories/read_two_mux.v | 5 ++++- tests/memories/run-test.sh | 24 ++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 tests/memories/read_arst.v diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index e6b4b2400dc..8ad131c7c16 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -60,11 +60,6 @@ struct MemoryDffWorker log("output FF has both set and reset, not supported.\n"); return; } - if (ff.has_srst || ff.has_arst || !ff.val_init.is_fully_undef()) { - // TODO: not supported yet - log("output FF has reset and/or init value, not supported yet.\n"); - return; - } merger.remove_output_ff(bits); if (ff.has_en && !ff.pol_en) ff.sig_en = module->LogicNot(NEW_ID, ff.sig_en); @@ -79,7 +74,6 @@ struct MemoryDffWorker port.en = ff.sig_en; else port.en = State::S1; -#if 0 if (ff.has_arst) { port.arst = ff.sig_arst; port.arst_value = ff.val_arst; @@ -94,7 +88,6 @@ struct MemoryDffWorker port.srst = State::S0; } port.init_value = ff.val_init; -#endif port.data = ff.sig_q; mem.emit(); log("merged output FF to cell.\n"); diff --git a/tests/memories/read_arst.v b/tests/memories/read_arst.v new file mode 100644 index 00000000000..6100cc4a787 --- /dev/null +++ b/tests/memories/read_arst.v @@ -0,0 +1,27 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk +// expect-rd-en \re +// expect-rd-arst-sig \reset +// expect-rd-arst-val 8'01011010 +// expect-rd-init-val 8'00111100 + +module top(input clk, input we, re, reset, input [7:0] addr, wdata, output reg [7:0] rdata); + +reg [7:0] bram[0:255]; +initial rdata = 8'h3c; + +always @(posedge clk) begin + if (we) + bram[addr] <= wdata; +end + +always @(posedge clk, posedge reset) begin + if (reset) + rdata <= 8'h5a; + else if (re) + rdata <= bram[addr]; +end + +endmodule + diff --git a/tests/memories/read_two_mux.v b/tests/memories/read_two_mux.v index 4f2e7e1cd7b..8b609c5521d 100644 --- a/tests/memories/read_two_mux.v +++ b/tests/memories/read_two_mux.v @@ -1,6 +1,9 @@ // expect-wr-ports 1 // expect-rd-ports 1 -// expect-no-rd-clk +// expect-rd-clk \clk +// expect-rd-en \re +// expect-rd-srst-sig \reset +// expect-rd-srst-val 8'00000000 module top(input clk, input we, re, reset, input [7:0] addr, wdata, output reg [7:0] rdata); diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index cded3eb40a5..49922e3da8f 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -31,6 +31,30 @@ for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do grep -q "connect \\\\RD_CLK \\$(gawk '/expect-rd-clk/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected read clock."; false; } fi + if grep -q expect-rd-en $f; then + grep -q "connect \\\\RD_EN \\$(gawk '/expect-rd-en/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read enable."; false; } + fi + if grep -q expect-rd-srst-sig $f; then + grep -q "connect \\\\RD_SRST \\$(gawk '/expect-rd-srst-sig/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read sync reset."; false; } + fi + if grep -q expect-rd-srst-val $f; then + grep -q "parameter \\\\RD_SRST_VALUE $(gawk '/expect-rd-srst-val/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read sync reset value."; false; } + fi + if grep -q expect-rd-arst-sig $f; then + grep -q "connect \\\\RD_ARST \\$(gawk '/expect-rd-arst-sig/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read async reset."; false; } + fi + if grep -q expect-rd-arst-val $f; then + grep -q "parameter \\\\RD_ARST_VALUE $(gawk '/expect-rd-arst-val/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read async reset value."; false; } + fi + if grep -q expect-rd-init-val $f; then + grep -q "parameter \\\\RD_INIT_VALUE $(gawk '/expect-rd-init-val/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read init value."; false; } + fi if grep -q expect-no-rd-clk $f; then grep -q "connect \\\\RD_CLK 1'x\$" ${f%.v}.dmp || { echo " ERROR: Expected no read clock."; false; } From b98376884e559330a0de191fadb098eadfe3fe0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 11 Aug 2021 14:14:45 +0200 Subject: [PATCH 0482/2410] test/arch/{ecp5,ice40}/memories.ys: Use read_verilog -defer. These parts keep rereading a Verilog module, then using chparam to test it with various parameter combinations. Since the default parameters are on the large side, this spends a lot of time needlessly elaborating the default parametrization that will then be discarded. Fix it with -deref and manual hierarchy call. Shaves 30s off the test time on my machine. --- tests/arch/ecp5/memories.ys | 153 +++++++++++++++++++++++------------ tests/arch/ice40/memories.ys | 81 ++++++++++++------- 2 files changed, 156 insertions(+), 78 deletions(-) diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys index 03de49cc05d..44651ba2534 100644 --- a/tests/arch/ecp5/memories.ys +++ b/tests/arch/ecp5/memories.ys @@ -1,197 +1,228 @@ # ================================ RAM ================================ # RAM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:PDPW16KD ## With parameters -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:PDPW16KD # too inefficient select -assert-count 9 t:TRELLIS_DPR16X4 -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:PDPW16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "Block_RAM" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:PDPW16KD # any case works -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:PDPW16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "registers" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly select -assert-count 180 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set logic_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly select -assert-count 180 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set rom_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # RAM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 9 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 13 -set DATA_WIDTH 2 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD ## With parameters -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:DP16KD # too inefficient select -assert-count 5 t:TRELLIS_DPR16X4 -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "Block_RAM" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD # any case works -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "registers" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:DP16KD # requested FFRAM explicitly select -assert-count 90 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set logic_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:DP16KD # requested FFRAM explicitly select -assert-count 90 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set rom_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # RAM bits <= 64; Data width <= 4; Address width <= 4: -> DPR16X4 -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:TRELLIS_DPR16X4 ## With parameters -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "distributed" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:TRELLIS_DPR16X4 -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "registers" m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly select -assert-count 68 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set logic_block 1 m:memory synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly select -assert-count 68 t:TRELLIS_FF -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "distributed" m:memory synth_ecp5 -top sync_ram_sdp -nolutram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested LUTRAM but LUTRAM is disabled @@ -199,130 +230,150 @@ select -assert-count 1 t:$mem_v2 # requested LUTRAM but LUTRAM is disabled # ================================ ROM ================================ # ROM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:PDPW16KD ## With parameters -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:PDPW16KD # too inefficient select -assert-min 18 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:PDPW16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:PDPW16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "logic" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly select -assert-min 18 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set logic_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly select -assert-min 18 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set ram_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set syn_ramstyle "block_rom" m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled # ROM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:DP16KD ## With parameters -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # too inefficient select -assert-min 9 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "ebr" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:DP16KD -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "logic" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # requested LUTROM explicitly select -assert-min 9 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set logic_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # requested LUTROM explicitly select -assert-min 9 t:LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set ram_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set syn_ramstyle "block_rom" m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ecp5 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled diff --git a/tests/arch/ice40/memories.ys b/tests/arch/ice40/memories.ys index a0b0f95b2d0..4920a45e35d 100644 --- a/tests/arch/ice40/memories.ys +++ b/tests/arch/ice40/memories.ys @@ -1,86 +1,100 @@ # ================================ RAM ================================ # RAM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K ## With parameters -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:SB_RAM40_4K # too inefficient select -assert-min 1 t:SB_DFFE -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "Block_RAM" m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K # any case works -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "registers" m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly select -assert-min 1 t:SB_DFFE -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set logic_block 1 m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly select -assert-min 1 t:SB_DFFE -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_romstyle "ebr" m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set rom_block 1 m:memory synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set syn_ramstyle "block_ram" m:memory synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled -design -reset; read_verilog ../common/blockram.v +design -reset; read_verilog -defer ../common/blockram.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp +hierarchy -top sync_ram_sdp setattr -set ram_block 1 m:memory synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled @@ -88,80 +102,93 @@ select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled # ================================ ROM ================================ # ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_rom +hierarchy -top sync_rom synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_rom +hierarchy -top sync_rom synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_rom +hierarchy -top sync_rom synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K ## With parameters -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom synth_ice40 -top sync_rom; cd sync_rom select -assert-count 0 t:SB_RAM40_4K # too inefficient select -assert-min 1 t:SB_LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "ebr" m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:SB_RAM40_4K -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "logic" m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly select -assert-min 1 t:SB_LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set logic_block 1 m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly select -assert-min 1 t:SB_LUT4 -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set syn_ramstyle "block_ram" m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set ram_block 1 m:memory synth_ice40 -top sync_rom; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set syn_romstyle "ebr" m:memory synth_ice40 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled -design -reset; read_verilog ../common/blockrom.v +design -reset; read_verilog -defer ../common/blockrom.v chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom +hierarchy -top sync_rom setattr -set rom_block 1 m:memory synth_ice40 -top sync_rom -nobram; cd sync_rom select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled From bfcd08a323044e1856ca971ba942bd36ee979f8e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Aug 2021 00:49:51 +0000 Subject: [PATCH 0483/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dc66291a45b..9a714e94e67 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4254 +YOSYS_VER := 0.9+4259 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From c58ac63c97183dde25b7a42c1a8e85ab0dd7fe96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 12 Aug 2021 17:36:03 +0200 Subject: [PATCH 0484/2410] logger: Add -check-expected subcommand. This allows us to have multiple "expect this warning" calls in a single long script, covering only as many passes as necessary. --- kernel/log.cc | 10 +++++----- passes/cmds/logger.cc | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 8d3bdd15be3..e7ce4cc466c 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -71,7 +71,6 @@ int string_buf_index = -1; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; static int log_newline_count = 0; -static bool check_expected_logs = true; static bool display_error_log_msg = true; static void log_id_cache_clear() @@ -349,8 +348,7 @@ static void logv_error_with_prefix(const char *prefix, if (YS_REGEX_NS::regex_search(log_last_error, item.second.pattern)) item.second.current_count++; - if (check_expected_logs) - log_check_expected(); + log_check_expected(); if (log_error_atexit) log_error_atexit(); @@ -667,8 +665,6 @@ void log_wire(RTLIL::Wire *wire, std::string indent) void log_check_expected() { - check_expected_logs = false; - for (auto &item : log_expect_warning) { if (item.second.current_count == 0) { log_warn_regexes.clear(); @@ -709,6 +705,10 @@ void log_check_expected() log_warn_regexes.clear(); log_error("Expected error pattern '%s' not found !\n", item.first.c_str()); } + + log_expect_warning.clear(); + log_expect_log.clear(); + log_expect_error.clear(); } // --------------------------------------------------- diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index d06939c2e59..ec92f1d013c 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -64,6 +64,11 @@ struct LoggerPass : public Pass { log(" -expect-no-warnings\n"); log(" gives error in case there is at least one warning that is not expected.\n"); log("\n"); + log(" -check-expected\n"); + log(" verifies that the patterns previously set up by -expect have actually\n"); + log(" been met, then clears the expected log list. If this is not called\n"); + log(" manually, the check will happen at yosys exist time instead.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design * design) override @@ -176,6 +181,10 @@ struct LoggerPass : public Pass { log_expect_no_warnings = true; continue; } + if (args[argidx] == "-check-expected") { + log_check_expected(); + continue; + } break; } extra_args(args, argidx, design, false); From d0d9aca2c301e0d71a6828bf0cf7b8673973ecb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 12 Aug 2021 23:06:51 +0200 Subject: [PATCH 0485/2410] memory_share: Pass addresses through sigmap_xmux everywhere. This fixes wide port recognition in some cases. --- passes/memory/memory_share.cc | 45 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 8499b46d8d6..1951b540088 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -112,25 +112,27 @@ struct MemoryShareWorker // merged by widening the narrow one. Check if the conditions // hold for that. int wide_log2 = std::max(port1.wide_log2, port2.wide_log2); - if (GetSize(port1.addr) <= wide_log2) + SigSpec addr1 = sigmap_xmux(port1.addr); + SigSpec addr2 = sigmap_xmux(port2.addr); + if (GetSize(addr1) <= wide_log2) continue; - if (GetSize(port2.addr) <= wide_log2) + if (GetSize(addr2) <= wide_log2) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) continue; - if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) { + if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) { // Incompatible addresses after widening. Last chance — widen both // ports by one more bit to merge them. if (!flag_widen) continue; wide_log2++; - if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) + if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) continue; } // Combine init/reset values. @@ -150,12 +152,13 @@ struct MemoryShareWorker // At this point we are committed to the merge. { log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); + port1.addr = addr1; + port2.addr = addr2; mem.prepare_rd_merge(i, j, &initvals); mem.widen_prep(wide_log2); SigSpec new_data = module->addWire(NEW_ID, mem.width << wide_log2); module->connect(port1.data, new_data.extract(sub1 * mem.width, mem.width << port1.wide_log2)); module->connect(port2.data, new_data.extract(sub2 * mem.width, mem.width << port2.wide_log2)); - port1.addr = sigmap_xmux(port1.addr); for (int k = 0; k < wide_log2; k++) port1.addr[k] = State::S0; port1.init_value = init_value; @@ -211,31 +214,33 @@ struct MemoryShareWorker // merged by widening the narrow one. Check if the conditions // hold for that. int wide_log2 = std::max(port1.wide_log2, port2.wide_log2); - if (GetSize(port1.addr) <= wide_log2) + SigSpec addr1 = sigmap_xmux(port1.addr); + SigSpec addr2 = sigmap_xmux(port2.addr); + if (GetSize(addr1) <= wide_log2) continue; - if (GetSize(port2.addr) <= wide_log2) + if (GetSize(addr2) <= wide_log2) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) continue; - if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) { + if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) { // Incompatible addresses after widening. Last chance — widen both // ports by one more bit to merge them. if (!flag_widen) continue; wide_log2++; - if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) + if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) continue; } - log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr)); + log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(addr1)); + port1.addr = addr1; + port2.addr = addr2; mem.prepare_wr_merge(i, j, &initvals); - port1.addr = sigmap_xmux(port1.addr); - port2.addr = sigmap_xmux(port2.addr); mem.widen_wr_port(i, wide_log2); mem.widen_wr_port(j, wide_log2); int pos = 0; From c8023e37d82adffd0c0ba54575c949be9da45198 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Aug 2021 00:50:48 +0000 Subject: [PATCH 0486/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9a714e94e67..6b64b0e35a8 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4259 +YOSYS_VER := 0.9+4261 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 979053855c85b72c6344bf6350fb9a8360f3d092 Mon Sep 17 00:00:00 2001 From: Brett Witherspoon Date: Tue, 22 Jun 2021 09:51:41 -0500 Subject: [PATCH 0487/2410] sv: improve support for wire and var with user-defined types - User-defined types must be data types. Using a net type (e.g. wire) is a syntax error. - User-defined types without a net type are always variables (i.e. logic). - Nets and variables can now be explicitly declared using user-defined types: typedef logic [1:0] W; wire W w; typedef logic [1:0] V; var V v; Fixes #2846 --- frontends/verilog/verilog_parser.y | 55 +++++++++--- tests/svtypes/typedef_initial_and_assign.sv | 94 +++++++++++++++++++++ tests/svtypes/typedef_initial_and_assign.ys | 14 +++ 3 files changed, 152 insertions(+), 11 deletions(-) create mode 100644 tests/svtypes/typedef_initial_and_assign.sv create mode 100644 tests/svtypes/typedef_initial_and_assign.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index a5227cb092c..b0c16c0f44f 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -127,6 +127,15 @@ struct specify_rise_fall { specify_triple fall; }; +static void addWiretypeNode(std::string *name, AstNode *node) +{ + log_assert(node); + node->is_custom_type = true; + node->children.push_back(new AstNode(AST_WIRETYPE)); + node->children.back()->str = *name; + delete name; +} + static void addTypedefNode(std::string *name, AstNode *node) { log_assert(node); @@ -305,10 +314,10 @@ static void checkLabelsMatch(const char *element, const std::string *before, con %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type %type opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type type_name -%type opt_enum_init enum_type struct_type non_wire_data_type func_return_type +%type opt_enum_init enum_type struct_type enum_struct_type func_return_type typedef_base_type %type opt_property always_comb_or_latch always_or_always_ff %type opt_signedness_default_signed opt_signedness_default_unsigned -%type integer_atom_type +%type integer_atom_type integer_vector_type %type attr case_attr %type struct_union %type asgn_binop @@ -763,12 +772,6 @@ opt_wire_type_token: wire_type_token | %empty; wire_type_token: - hierarchical_type_id { - astbuf3->is_custom_type = true; - astbuf3->children.push_back(new AstNode(AST_WIRETYPE)); - astbuf3->children.back()->str = *$1; - delete $1; - } | TOK_WOR { astbuf3->is_wor = true; } | @@ -812,6 +815,9 @@ logic_type: astbuf3->range_left = $1 - 1; astbuf3->range_right = 0; astbuf3->is_signed = true; + } | + hierarchical_type_id { + addWiretypeNode($1, astbuf3); }; integer_atom_type: @@ -821,6 +827,10 @@ integer_atom_type: TOK_LONGINT { $$ = 64; } | TOK_BYTE { $$ = 8; } ; +integer_vector_type: + TOK_LOGIC { $$ = TOK_LOGIC; } | + TOK_REG { $$ = TOK_REG; } ; + non_opt_range: '[' expr ':' expr ']' { $$ = new AstNode(AST_RANGE); @@ -1985,7 +1995,7 @@ type_name: TOK_ID // first time seen ; typedef_decl: - TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' { + TOK_TYPEDEF typedef_base_type range type_name range_or_multirange ';' { astbuf1 = $2; astbuf2 = checkRange(astbuf1, $3); if (astbuf2) @@ -1998,10 +2008,33 @@ typedef_decl: rewriteAsMemoryNode(astbuf1, $5); } addTypedefNode($4, astbuf1); } - | TOK_TYPEDEF non_wire_data_type type_name ';' { addTypedefNode($3, $2); } + | TOK_TYPEDEF enum_struct_type type_name ';' { addTypedefNode($3, $2); } ; -non_wire_data_type: +typedef_base_type: + hierarchical_type_id { + $$ = new AstNode(AST_WIRE); + $$->is_logic = true; + addWiretypeNode($1, $$); + } | + integer_vector_type opt_signedness_default_unsigned { + $$ = new AstNode(AST_WIRE); + if ($1 == TOK_REG) { + $$->is_reg = true; + } else { + $$->is_logic = true; + } + $$->is_signed = $2; + } | + integer_atom_type opt_signedness_default_signed { + $$ = new AstNode(AST_WIRE); + $$->is_logic = true; + $$->is_signed = $2; + $$->range_left = $1 - 1; + $$->range_right = 0; + }; + +enum_struct_type: enum_type | struct_type ; diff --git a/tests/svtypes/typedef_initial_and_assign.sv b/tests/svtypes/typedef_initial_and_assign.sv new file mode 100644 index 00000000000..05579947d1c --- /dev/null +++ b/tests/svtypes/typedef_initial_and_assign.sv @@ -0,0 +1,94 @@ +package pkg; + typedef logic pkg_user_t; +endpackage + +module top; + typedef logic user_t; + + // Continuous assignment to a variable is legal + user_t var_1; + assign var_1 = 0; + assert property (var_1 == 0); + + var user_t var_2; + assign var_2 = 0; + assert property (var_2 == 0); + + var pkg::pkg_user_t var_3; + assign var_3 = 0; + assert property (var_3 == 0); + + // Procedural assignment to a variable is legal + user_t var_4 = 0; + assert property (var_4 == 0); + + user_t var_5; + initial var_5 = 0; + assert property (var_5 == 0); + + var user_t var_6 = 0; + assert property (var_6 == 0); + + var user_t var_7; + initial var_7 = 0; + assert property (var_7 == 0); + + pkg::pkg_user_t var_8 = 0; + assert property (var_8 == 0); + + pkg::pkg_user_t var_9; + initial var_9 = 0; + assert property (var_9 == 0); + + var pkg::pkg_user_t var_10 = 0; + assert property (var_10 == 0); + + var pkg::pkg_user_t var_11; + initial var_11 = 0; + assert property (var_11 == 0); + + // Continuous assignment to a net is legal + wire user_t wire_1 = 0; + assert property (wire_3 == 0); + + wire user_t wire_2; + assign wire_2 = 0; + assert property (wire_2 == 0); + + wire pkg::pkg_user_t wire_3 = 0; + assert property (wire_3 == 0); + + wire pkg::pkg_user_t wire_4; + assign wire_4 = 0; + assert property (wire_4 == 0); + + // Mixing continuous and procedural assignments is illegal + user_t var_12 = 0; + assign var_12 = 1; // warning: reg assigned in a continuous assignment + + user_t var_13; + initial var_13 = 0; + assign var_13 = 1; // warning: reg assigned in a continuous assignment + + var user_t var_14 = 0; + assign var_14 = 1; // warning: reg assigned in a continuous assignment + + var user_t var_15; + initial var_15 = 0; + assign var_15 = 1; // warning: reg assigned in a continuous assignment + + pkg::pkg_user_t var_16 = 0; + assign var_16 = 1; // warning: reg assigned in a continuous assignment + + pkg::pkg_user_t var_17; + initial var_17 = 0; + assign var_17 = 1; // warning: reg assigned in a continuous assignment + + var pkg::pkg_user_t var_18 = 0; + assign var_18 = 1; // warning: reg assigned in a continuous assignment + + var pkg::pkg_user_t var_19; + initial var_19 = 0; + assign var_19 = 1; // warning: reg assigned in a continuous assignment + +endmodule diff --git a/tests/svtypes/typedef_initial_and_assign.ys b/tests/svtypes/typedef_initial_and_assign.ys new file mode 100644 index 00000000000..de456bb82bd --- /dev/null +++ b/tests/svtypes/typedef_initial_and_assign.ys @@ -0,0 +1,14 @@ +logger -expect-no-warnings +logger -expect warning "reg '\\var_12' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_13' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_14' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_15' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_16' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_17' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_18' is assigned in a continuous assignment" 1 +logger -expect warning "reg '\\var_19' is assigned in a continuous assignment" 1 + +read_verilog -sv typedef_initial_and_assign.sv +hierarchy; proc; opt +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all \ No newline at end of file From 616ace2d9299eee2006650ed3f13e9241664ad20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 12 Aug 2021 03:31:56 +0200 Subject: [PATCH 0488/2410] Add new opt_mem_priority pass. --- passes/memory/memory.cc | 6 +- passes/opt/Makefile.inc | 1 + passes/opt/opt_mem_priority.cc | 109 ++++++++++++++++++ tests/opt/opt_mem_priority.ys | 205 +++++++++++++++++++++++++++++++++ 4 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 passes/opt/opt_mem_priority.cc create mode 100644 tests/opt/opt_mem_priority.ys diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index 29e140ba998..a4751cb61ac 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -36,9 +36,10 @@ struct MemoryPass : public Pass { log("This pass calls all the other memory_* passes in a useful order:\n"); log("\n"); log(" opt_mem\n"); + log(" opt_mem_priority\n"); + log(" opt_mem_feedback\n"); log(" memory_dff (skipped if called with -nordff or -memx)\n"); log(" opt_clean\n"); - log(" opt_mem_feedback\n"); log(" memory_share\n"); log(" memory_memx (when called with -memx)\n"); log(" opt_clean\n"); @@ -84,10 +85,11 @@ struct MemoryPass : public Pass { extra_args(args, argidx, design); Pass::call(design, "opt_mem"); + Pass::call(design, "opt_mem_priority"); + Pass::call(design, "opt_mem_feedback"); if (!flag_nordff) Pass::call(design, "memory_dff"); Pass::call(design, "opt_clean"); - Pass::call(design, "opt_mem_feedback"); Pass::call(design, "memory_share"); if (flag_memx) Pass::call(design, "memory_memx"); diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index b0192235b12..d8eb2f0b9f3 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -3,6 +3,7 @@ OBJS += passes/opt/opt.o OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_mem.o OBJS += passes/opt/opt_mem_feedback.o +OBJS += passes/opt/opt_mem_priority.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_dff.o diff --git a/passes/opt/opt_mem_priority.cc b/passes/opt/opt_mem_priority.cc new file mode 100644 index 00000000000..49ece570b7e --- /dev/null +++ b/passes/opt/opt_mem_priority.cc @@ -0,0 +1,109 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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/modtools.h" +#include "kernel/qcsat.h" +#include "kernel/mem.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct OptMemPriorityPass : public Pass { + OptMemPriorityPass() : Pass("opt_mem_priority", "remove priority relations between write ports that can never collide") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_mem_priority [selection]\n"); + log("\n"); + log("This pass detects cases where one memory write port has priority over another\n"); + log("even though they can never collide with each other — ie. there can never be\n"); + log("a situation where a given memory bit is written by both ports at the same\n"); + log("time, for example because of always-different addresses, or mutually exclusive\n"); + log("enable signals. In such cases, the priority relation is removed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override { + log_header(design, "Executing OPT_MEM_PRIORITY pass (removing unnecessary memory write priority relations).\n"); + extra_args(args, 1, design); + + ModWalker modwalker(design); + + int total_count = 0; + for (auto module : design->selected_modules()) { + modwalker.setup(module); + for (auto &mem : Mem::get_selected_memories(module)) { + bool mem_changed = false; + QuickConeSat qcsat(modwalker); + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &wport1 = mem.wr_ports[i]; + for (int j = 0; j < GetSize(mem.wr_ports); j++) { + auto &wport2 = mem.wr_ports[j]; + if (!wport1.priority_mask[j]) + continue; + // No mixed width support — we could do it, but + // that would complicate code and wouldn't help + // anything since we run this pass before + // wide ports are created in normal flow. + if (wport1.wide_log2 != wport2.wide_log2) + continue; + // Two ports with priority, let's go. + pool> checked; + SigSpec addr1 = wport1.addr; + SigSpec addr2 = wport2.addr; + int abits = std::max(GetSize(addr1), GetSize(addr2)); + addr1.extend_u0(abits); + addr2.extend_u0(abits); + int addr_eq = qcsat.ez->vec_eq(qcsat.importSig(addr1), qcsat.importSig(addr2)); + bool ok = true; + for (int k = 0; k < GetSize(wport1.data); k++) { + SigBit wen1 = wport1.en[k]; + SigBit wen2 = wport2.en[k]; + if (checked.count({wen1, wen2})) + continue; + int wen1_sat = qcsat.importSigBit(wen1); + int wen2_sat = qcsat.importSigBit(wen2); + qcsat.prepare(); + if (qcsat.ez->solve(wen1_sat, wen2_sat, addr_eq)) { + ok = false; + break; + } + checked.insert({wen1, wen2}); + } + if (ok) { + total_count++; + mem_changed = true; + wport1.priority_mask[j] = false; + } + } + } + if (mem_changed) + mem.emit(); + } + } + + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); + log("Performed a total of %d transformations.\n", total_count); + } +} OptMemPriorityPass; + +PRIVATE_NAMESPACE_END + diff --git a/tests/opt/opt_mem_priority.ys b/tests/opt/opt_mem_priority.ys new file mode 100644 index 00000000000..c1261ddf777 --- /dev/null +++ b/tests/opt/opt_mem_priority.ys @@ -0,0 +1,205 @@ +# 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 +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=64'h0804020100000000 %i From 9fdedf4d1c5b1715f98ad107d322966eaee91f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 10 Aug 2021 19:42:10 +0200 Subject: [PATCH 0489/2410] memory_dff: Recognize soft transparency logic. --- passes/memory/memory_dff.cc | 458 +++++++++++++++++- tests/memories/trans_sdp.v | 21 + tests/memories/trans_sp.v | 21 + tests/opt/memory_dff_trans.ys | 862 ++++++++++++++++++++++++++++++++++ 4 files changed, 1355 insertions(+), 7 deletions(-) create mode 100644 tests/memories/trans_sdp.v create mode 100644 tests/memories/trans_sp.v create mode 100644 tests/opt/memory_dff_trans.ys diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 8ad131c7c16..21962c238c9 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -19,7 +19,9 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/modtools.h" #include "kernel/ffinit.h" +#include "kernel/qcsat.h" #include "kernel/mem.h" #include "kernel/ff.h" #include "kernel/ffmerge.h" @@ -27,27 +29,317 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +struct MuxData { + int base_idx; + int size; + bool is_b; + SigSpec sig_s; + std::vector sig_other; +}; + +struct PortData { + bool relevant; + std::vector uncollidable_mask; + std::vector transparency_mask; + std::vector collision_x_mask; + bool final_transparency; + bool final_collision_x; +}; + +// A helper with some caching for transparency-related SAT queries. +// Bound to a single memory read port in the process of being converted +// from async to sync.. +struct MemQueryCache +{ + QuickConeSat &qcsat; + // The memory. + Mem &mem; + // The port, still async at this point. + MemRd &port; + // The virtual FF that will end up merged into this port. + FfData &ff; + // An ezSAT variable that is true when we actually care about the data + // read from memory (ie. the FF has enable on and is not in reset). + int port_ren; + // Some caches. + dict, bool> cache_can_collide_rdwr; + dict, bool> cache_can_collide_together; + dict, bool> cache_is_w2rbyp; + dict, bool> cache_impossible_with_ren; + + MemQueryCache(QuickConeSat &qcsat, Mem &mem, MemRd &port, FfData &ff) : qcsat(qcsat), mem(mem), port(port), ff(ff) { + // port_ren is an upper bound on when we care about the value fetched + // from memory this cycle. + int ren = ezSAT::CONST_TRUE; + if (ff.has_en) { + ren = qcsat.importSigBit(ff.sig_en); + if (!ff.pol_en) + ren = qcsat.ez->NOT(ren); + } + if (ff.has_srst) { + int nrst = qcsat.importSigBit(ff.sig_srst); + if (ff.pol_srst) + nrst = qcsat.ez->NOT(nrst); + ren = qcsat.ez->AND(ren, nrst); + } + port_ren = ren; + } + + // Returns ezSAT variable that is true iff the two addresses are the same. + int addr_eq(SigSpec raddr, SigSpec waddr) { + int abits = std::max(GetSize(raddr), GetSize(waddr)); + raddr.extend_u0(abits); + waddr.extend_u0(abits); + return qcsat.ez->vec_eq(qcsat.importSig(raddr), qcsat.importSig(waddr)); + } + + // Returns true if a given write port bit can be active at the same time + // as this read port and at the same address. + bool can_collide_rdwr(int widx, SigBit wen) { + std::pair key(widx, wen); + auto it = cache_can_collide_rdwr.find(key); + if (it != cache_can_collide_rdwr.end()) + return it->second; + auto &wport = mem.wr_ports[widx]; + int aeq = addr_eq(port.addr, wport.addr); + int wen_sat = qcsat.importSigBit(wen); + qcsat.prepare(); + bool res = qcsat.ez->solve(aeq, wen_sat, port_ren); + cache_can_collide_rdwr[key] = res; + return res; + } + + // Returns true if both given write port bits can be active at the same + // time as this read port and at the same address (three-way collision). + bool can_collide_together(int widx1, int widx2, int bitidx) { + auto &wport1 = mem.wr_ports[widx1]; + auto &wport2 = mem.wr_ports[widx2]; + SigBit wen1 = wport1.en[bitidx]; + SigBit wen2 = wport2.en[bitidx]; + std::tuple key(widx1, widx2, wen1, wen2); + auto it = cache_can_collide_together.find(key); + if (it != cache_can_collide_together.end()) + return it->second; + int aeq1 = addr_eq(port.addr, wport1.addr); + int aeq2 = addr_eq(port.addr, wport2.addr); + int wen1_sat = qcsat.importSigBit(wen1); + int wen2_sat = qcsat.importSigBit(wen2); + qcsat.prepare(); + bool res = qcsat.ez->solve(wen1_sat, wen2_sat, aeq1, aeq2, port_ren); + cache_can_collide_together[key] = res; + return res; + } + + // Returns true if the given mux selection signal is a valid data-bypass + // signal in soft transparency logic for a given write port bit. + bool is_w2rbyp(int widx, SigBit wen, SigBit sel, bool neg_sel) { + std::tuple key(widx, wen, sel, neg_sel); + auto it = cache_is_w2rbyp.find(key); + if (it != cache_is_w2rbyp.end()) + return it->second; + auto &wport = mem.wr_ports[widx]; + int aeq = addr_eq(port.addr, wport.addr); + int wen_sat = qcsat.importSigBit(wen); + int sel_expected = qcsat.ez->AND(aeq, wen_sat); + int sel_sat = qcsat.importSigBit(sel); + if (neg_sel) + sel_sat = qcsat.ez->NOT(sel_sat); + qcsat.prepare(); + bool res = !qcsat.ez->solve(port_ren, qcsat.ez->XOR(sel_expected, sel_sat)); + cache_is_w2rbyp[key] = res; + return res; + } + + // Returns true if the given mux selection signal can never be true + // when this port is active. + bool impossible_with_ren(SigBit sel, bool neg_sel) { + std::tuple key(sel, neg_sel); + auto it = cache_impossible_with_ren.find(key); + if (it != cache_impossible_with_ren.end()) + return it->second; + int sel_sat = qcsat.importSigBit(sel); + if (neg_sel) + sel_sat = qcsat.ez->NOT(sel_sat); + qcsat.prepare(); + bool res = !qcsat.ez->solve(port_ren, sel_sat); + cache_impossible_with_ren[key] = res; + return res; + } + + // Helper for data_eq: walks up a multiplexer when the value of its + // sel signal is constant under the assumption that this read port + // is active and a given other mux sel signal is true. + bool walk_up_mux_cond(SigBit sel, bool neg_sel, SigBit &bit) { + auto &drivers = qcsat.modwalker.signal_drivers[qcsat.modwalker.sigmap(bit)]; + if (GetSize(drivers) != 1) + return false; + auto driver = *drivers.begin(); + if (!driver.cell->type.in(ID($mux), ID($pmux))) + return false; + log_assert(driver.port == ID::Y); + SigSpec sig_s = driver.cell->getPort(ID::S); + int sel_sat = qcsat.importSigBit(sel); + if (neg_sel) + sel_sat = qcsat.ez->NOT(sel_sat); + bool all_0 = true; + int width = driver.cell->parameters.at(ID::WIDTH).as_int(); + for (int i = 0; i < GetSize(sig_s); i++) { + int sbit = qcsat.importSigBit(sig_s[i]); + qcsat.prepare(); + if (!qcsat.ez->solve(port_ren, sel_sat, qcsat.ez->NOT(sbit))) { + bit = driver.cell->getPort(ID::B)[i * width + driver.offset]; + return true; + } + if (qcsat.ez->solve(port_ren, sel_sat, sbit)) + all_0 = false; + } + if (all_0) { + bit = driver.cell->getPort(ID::A)[driver.offset]; + return true; + } + return false; + } + + // Returns true if a given data signal is equivalent to another, under + // the assumption that this read port is active and a given mux sel signal + // is true. Used to match transparency logic data with write port data. + // The walk_up_mux_cond part is necessary because write ports in yosys + // tend to be connected to things like (wen ? wdata : 'x). + bool data_eq(SigBit sel, bool neg_sel, SigBit dbit, SigBit odbit) { + if (qcsat.modwalker.sigmap(dbit) == qcsat.modwalker.sigmap(odbit)) + return true; + while (walk_up_mux_cond(sel, neg_sel, dbit)); + while (walk_up_mux_cond(sel, neg_sel, odbit)); + return qcsat.modwalker.sigmap(dbit) == qcsat.modwalker.sigmap(odbit); + } +}; + struct MemoryDffWorker { Module *module; - SigMap sigmap; + ModWalker modwalker; FfInitVals initvals; FfMergeHelper merger; - MemoryDffWorker(Module *module) : module(module), sigmap(module) + MemoryDffWorker(Module *module) : module(module), modwalker(module->design) { - initvals.set(&sigmap, module); + modwalker.setup(module); + initvals.set(&modwalker.sigmap, module); merger.set(&initvals, module); } - void handle_rd_port(Mem &mem, int idx) + // Starting from the output of an async read port, as long as the data + // signal's only user is a mux data signal, passes through the mux + // and remembers information about it. Conceptually works on every + // bit separately, but coalesces the result when possible. + SigSpec walk_muxes(SigSpec data, std::vector &res) { + bool did_something; + do { + did_something = false; + int prev_idx = -1; + Cell *prev_cell = nullptr; + bool prev_is_b = false; + for (int i = 0; i < GetSize(data); i++) { + SigBit bit = modwalker.sigmap(data[i]); + auto &consumers = modwalker.signal_consumers[bit]; + if (GetSize(consumers) != 1 || modwalker.signal_outputs.count(bit)) + continue; + auto consumer = *consumers.begin(); + bool is_b; + if (consumer.cell->type == ID($mux)) { + if (consumer.port == ID::A) { + is_b = false; + } else if (consumer.port == ID::B) { + is_b = true; + } else { + continue; + } + } else if (consumer.cell->type == ID($pmux)) { + if (consumer.port == ID::A) { + is_b = false; + } else { + continue; + } + } else { + continue; + } + SigSpec y = consumer.cell->getPort(ID::Y); + int mux_width = GetSize(y); + SigBit ybit = y.extract(consumer.offset); + if (prev_cell != consumer.cell || prev_idx+1 != i || prev_is_b != is_b) { + MuxData md; + md.base_idx = i; + md.size = 0; + md.is_b = is_b; + md.sig_s = consumer.cell->getPort(ID::S); + md.sig_other.resize(GetSize(md.sig_s)); + prev_cell = consumer.cell; + prev_is_b = is_b; + res.push_back(md); + } + auto &md = res.back(); + md.size++; + for (int j = 0; j < GetSize(md.sig_s); j++) { + SigBit obit = consumer.cell->getPort(is_b ? ID::A : ID::B).extract(j * mux_width + consumer.offset); + md.sig_other[j].append(obit); + } + prev_idx = i; + data[i] = ybit; + did_something = true; + } + } while (did_something); + return data; + } + + // Merges FF and possibly soft transparency logic into an asynchronous + // read port, making it into a synchronous one. + // + // There are three moving parts involved here: + // + // - the async port, which we start from, whose data port is input to... + // - an arbitrary chain of $mux and $pmux cells implementing soft transparency + // logic (ie. bypassing write port's data iff the write port is active and + // writing to the same address as this read port), which in turn feeds... + // - a final FF + // + // The async port and the mux chain are not allowed to have any users that + // are not part of the above. + // + // The algorithm is: + // + // 1. Walk through the muxes. + // 2. Recognize the final FF. + // 3. Knowing the FF's clock and read enable, make a list of write ports + // that we'll run transparency analysis on. + // 4. For every mux bit, recognize it as one of: + // - a transparency bypass mux for some port + // - a bypass mux that feeds 'x instead (this will result in collision + // don't care behavior being recognized) + // - a mux that never selects the other value when read port is active, + // and can thus be skipped (this is necessary because this could + // be a transparency bypass mux for never-colliding port that other + // passes failed to optimize) + // - a mux whose other input is 'x, and can thus be skipped + // 5. When recognizing transparency bypasses, take care to preserve priority + // behavior — when two bypasses are sequential muxes on the chain, they + // effectively have priority over one another, and the transform can + // only be performed when either a) their corresponding write ports + // also have priority, or b) there can never be a three-way collision + // between the two write ports and the read port. + // 6. Check consistency of per-bit transparency masks, merge them into + // per-port transparency masks + // 7. If everything went fine in the previous steps, actually perform + // the merge. + void handle_rd_port(Mem &mem, QuickConeSat &qcsat, int idx) { auto &port = mem.rd_ports[idx]; log("Checking read port `%s'[%d] in module `%s': ", mem.memid.c_str(), idx, module->name.c_str()); + std::vector muxdata; + SigSpec data = walk_muxes(port.data, muxdata); FfData ff; pool> bits; - if (!merger.find_output_ff(port.data, ff, bits)) { + if (!merger.find_output_ff(data, ff, bits)) { log("no output FF found.\n"); return; } @@ -60,6 +352,144 @@ struct MemoryDffWorker log("output FF has both set and reset, not supported.\n"); return; } + + // Construct cache. + MemQueryCache cache(qcsat, mem, port, ff); + + // Prepare information structure about all ports, recognize port bits + // that can never collide at all and don't need to be checked. + std::vector portdata; + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + PortData pd; + auto &wport = mem.wr_ports[i]; + pd.relevant = true; + if (!wport.clk_enable) + pd.relevant = false; + if (wport.clk != ff.sig_clk) + pd.relevant = false; + if (wport.clk_polarity != ff.pol_clk) + pd.relevant = false; + // In theory, we *could* support mismatched width + // ports here. However, it's not worth it — wide + // ports are recognized *after* memory_dff in + // a normal flow. + if (wport.wide_log2 != port.wide_log2) + pd.relevant = false; + pd.uncollidable_mask.resize(GetSize(port.data)); + pd.transparency_mask.resize(GetSize(port.data)); + pd.collision_x_mask.resize(GetSize(port.data)); + if (pd.relevant) { + // If we got this far, this port is potentially + // transparent and/or has undefined collision + // behavior. Now, for every bit, check if it can + // ever collide. + for (int j = 0; j < ff.width; j++) { + if (!cache.can_collide_rdwr(i, wport.en[j])) { + pd.uncollidable_mask[j] = true; + pd.collision_x_mask[j] = true; + } + } + } + portdata.push_back(pd); + } + + // Now inspect the mux chain. + for (auto &md : muxdata) { + // We only mark transparent bits after processing a complete + // mux, so that the transparency priority validation check + // below sees transparency information as of previous mux. + std::vector> trans_queue; + for (int sel_idx = 0; sel_idx < GetSize(md.sig_s); sel_idx++) { + SigBit sbit = md.sig_s[sel_idx]; + SigSpec &odata = md.sig_other[sel_idx]; + for (int bitidx = md.base_idx; bitidx < md.base_idx+md.size; bitidx++) { + SigBit odbit = odata[bitidx-md.base_idx]; + bool recognized = false; + for (int pi = 0; pi < GetSize(mem.wr_ports); pi++) { + auto &pd = portdata[pi]; + auto &wport = mem.wr_ports[pi]; + if (!pd.relevant) + continue; + if (pd.uncollidable_mask[bitidx]) + continue; + bool match = cache.is_w2rbyp(pi, wport.en[bitidx], sbit, md.is_b); + if (!match) + continue; + // If we got here, we recognized this mux sel + // as valid bypass sel for a given port bit. + if (odbit == State::Sx) { + // 'x, mark collision don't care. + pd.collision_x_mask[bitidx] = true; + pd.transparency_mask[bitidx] = false; + } else if (cache.data_eq(sbit, md.is_b, wport.data[bitidx], odbit)) { + // Correct data value, mark transparency, + // but only after verifying that priority + // is fine. + for (int k = 0; k < GetSize(mem.wr_ports); k++) { + if (portdata[k].transparency_mask[bitidx]) { + if (wport.priority_mask[k]) + continue; + if (!cache.can_collide_together(pi, k, bitidx)) + continue; + log("FF found, but transparency logic priority doesn't match write priority.\n"); + return; + } + } + recognized = true; + trans_queue.push_back({pd, bitidx}); + break; + } else { + log("FF found, but with a mux data input that doesn't seem to correspond to transparency logic.\n"); + return; + } + } + if (!recognized) { + // If we haven't positively identified this as + // a bypass: it's still skippable if the + // data is 'x, or if the sel cannot actually be + // active. + if (odbit == State::Sx) + continue; + if (cache.impossible_with_ren(sbit, md.is_b)) + continue; + log("FF found, but with a mux select that doesn't seem to correspond to transparency logic.\n"); + return; + } + } + } + // Done with this mux, now actually apply the transparencies. + for (auto it : trans_queue) { + it.first.transparency_mask[it.second] = true; + it.first.collision_x_mask[it.second] = false; + } + } + + // Final merging and validation of per-bit masks. + for (int pi = 0; pi < GetSize(mem.wr_ports); pi++) { + auto &pd = portdata[pi]; + if (!pd.relevant) + continue; + bool trans = false; + bool non_trans = false; + for (int i = 0; i < ff.width; i++) { + if (pd.collision_x_mask[i]) + continue; + if (pd.transparency_mask[i]) + trans = true; + else + non_trans = true; + } + if (trans && non_trans) { + log("FF found, but soft transparency logic is inconsistent for port %d.\n", pi); + return; + } + pd.final_transparency = trans; + pd.final_collision_x = !trans && !non_trans; + } + + // OK, it worked. + log("merging output FF to cell.\n"); + merger.remove_output_ff(bits); if (ff.has_en && !ff.pol_en) ff.sig_en = module->LogicNot(NEW_ID, ff.sig_en); @@ -89,8 +519,21 @@ struct MemoryDffWorker } port.init_value = ff.val_init; port.data = ff.sig_q; + for (int pi = 0; pi < GetSize(mem.wr_ports); pi++) { + auto &pd = portdata[pi]; + if (!pd.relevant) + continue; + if (pd.final_collision_x) { + log(" Write port %d: don't care on collision.\n", pi); + port.collision_x_mask[pi] = true; + } else if (pd.final_transparency) { + log(" Write port %d: transparent.\n", pi); + port.transparency_mask[pi] = true; + } else { + log(" Write port %d: non-transparent.\n", pi); + } + } mem.emit(); - log("merged output FF to cell.\n"); } void handle_rd_port_addr(Mem &mem, int idx) @@ -146,9 +589,10 @@ struct MemoryDffWorker { std::vector memories = Mem::get_selected_memories(module); for (auto &mem : memories) { + QuickConeSat qcsat(modwalker); for (int i = 0; i < GetSize(mem.rd_ports); i++) { if (!mem.rd_ports[i].clk_enable) - handle_rd_port(mem, i); + handle_rd_port(mem, qcsat, i); } } for (auto &mem : memories) { diff --git a/tests/memories/trans_sdp.v b/tests/memories/trans_sdp.v new file mode 100644 index 00000000000..b89f2ccf02f --- /dev/null +++ b/tests/memories/trans_sdp.v @@ -0,0 +1,21 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk +// expect-rd-en \re + +module top(input clk, we, re, input [7:0] ra, wa, wd, output reg [7:0] rd); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (we) + mem[wa] <= wd; + + if (re) begin + rd <= mem[ra]; + if (we && ra == wa) + rd <= wd; + end +end + +endmodule diff --git a/tests/memories/trans_sp.v b/tests/memories/trans_sp.v new file mode 100644 index 00000000000..ddd41a13e8b --- /dev/null +++ b/tests/memories/trans_sp.v @@ -0,0 +1,21 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk +// expect-rd-en \re + +module top(input clk, we, re, input [7:0] addr, wd, output reg [7:0] rd); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (we) + mem[addr] <= wd; + + if (re) begin + rd <= mem[addr]; + if (we) + rd <= wd; + end +end + +endmodule diff --git a/tests/opt/memory_dff_trans.ys b/tests/opt/memory_dff_trans.ys new file mode 100644 index 00000000000..7599949f3b4 --- /dev/null +++ b/tests/opt/memory_dff_trans.ys @@ -0,0 +1,862 @@ +# 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 + +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 + +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 + +design -reset From 1f74ec3535dba67d3e71ab1b9bf509c86bdca560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 29 May 2021 17:45:05 +0200 Subject: [PATCH 0490/2410] memory_share: Add -nosat and -nowiden options. This unlocks wide port recognition by default. --- passes/memory/memory.cc | 15 ++++++++-- passes/memory/memory_share.cc | 36 +++++++++++++++++----- tests/memories/run-test.sh | 8 +++++ tests/memories/wide_read_async.v | 27 +++++++++++++++++ tests/memories/wide_read_mixed.v | 46 +++++++++++++++++++++++++++++ tests/memories/wide_read_sync.v | 32 ++++++++++++++++++++ tests/memories/wide_read_trans.v | 40 +++++++++++++++++++++++++ tests/memories/wide_thru_priority.v | 29 ++++++++++++++++++ tests/memories/wide_write.v | 29 ++++++++++++++++++ tests/opt/memory_dff_trans.ys | 12 ++++++++ tests/opt/opt_mem_priority.ys | 6 +++- 11 files changed, 269 insertions(+), 11 deletions(-) create mode 100644 tests/memories/wide_read_async.v create mode 100644 tests/memories/wide_read_mixed.v create mode 100644 tests/memories/wide_read_sync.v create mode 100644 tests/memories/wide_read_trans.v create mode 100644 tests/memories/wide_thru_priority.v create mode 100644 tests/memories/wide_write.v diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index a4751cb61ac..bc1b19d00c3 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -31,7 +31,7 @@ struct MemoryPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" memory [-nomap] [-nordff] [-memx] [-bram ] [selection]\n"); + log(" memory [-nomap] [-nordff] [-nowiden] [-nosat] [-memx] [-bram ] [selection]\n"); log("\n"); log("This pass calls all the other memory_* passes in a useful order:\n"); log("\n"); @@ -40,7 +40,7 @@ struct MemoryPass : public Pass { log(" opt_mem_feedback\n"); log(" memory_dff (skipped if called with -nordff or -memx)\n"); log(" opt_clean\n"); - log(" memory_share\n"); + log(" memory_share [-nowiden] [-nosat]\n"); log(" memory_memx (when called with -memx)\n"); log(" opt_clean\n"); log(" memory_collect\n"); @@ -57,6 +57,7 @@ struct MemoryPass : public Pass { bool flag_nordff = false; bool flag_memx = false; string memory_bram_opts; + string memory_share_opts; log_header(design, "Executing MEMORY pass.\n"); log_push(); @@ -76,6 +77,14 @@ struct MemoryPass : public Pass { flag_memx = true; continue; } + if (args[argidx] == "-nowiden") { + memory_share_opts += " -nowiden"; + continue; + } + if (args[argidx] == "-nosat") { + memory_share_opts += " -nosat"; + continue; + } if (argidx+1 < args.size() && args[argidx] == "-bram") { memory_bram_opts += " -rules " + args[++argidx]; continue; @@ -90,7 +99,7 @@ struct MemoryPass : public Pass { if (!flag_nordff) Pass::call(design, "memory_dff"); Pass::call(design, "opt_clean"); - Pass::call(design, "memory_share"); + Pass::call(design, "memory_share" + memory_share_opts); if (flag_memx) Pass::call(design, "memory_memx"); Pass::call(design, "opt_clean"); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 1951b540088..9d82739aa4b 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -35,7 +35,7 @@ struct MemoryShareWorker ModWalker modwalker; FfInitVals initvals; bool flag_widen; - + bool flag_sat; // -------------------------------------------------- // Consolidate read ports that read the same address @@ -452,7 +452,7 @@ struct MemoryShareWorker // Setup and run // ------------- - MemoryShareWorker(RTLIL::Design *design, bool flag_widen) : design(design), modwalker(design), flag_widen(flag_widen) {} + MemoryShareWorker(RTLIL::Design *design, bool flag_widen, bool flag_sat) : design(design), modwalker(design), flag_widen(flag_widen), flag_sat(flag_sat) {} void operator()(RTLIL::Module* module) { @@ -482,6 +482,9 @@ struct MemoryShareWorker while (consolidate_wr_by_addr(mem)); } + if (!flag_sat) + return; + modwalker.setup(module); for (auto &mem : memories) @@ -495,7 +498,7 @@ struct MemorySharePass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" memory_share [selection]\n"); + log(" memory_share [-nosat] [-nowiden] [selection]\n"); log("\n"); log("This pass merges share-able memory ports into single memory ports.\n"); log("\n"); @@ -504,9 +507,13 @@ struct MemorySharePass : public Pass { log(" - When multiple write ports access the same address then this is converted\n"); log(" to a single write port with a more complex data and/or enable logic path.\n"); log("\n"); + log(" - When multiple read or write ports access adjacent aligned addresses, they are\n"); + log(" merged to a single wide read or write port. This transformation can be\n"); + log(" disabled with the \"-nowiden\" option.\n"); + log("\n"); log(" - When multiple write ports are never accessed at the same time (a SAT\n"); log(" solver is used to determine this), then the ports are merged into a single\n"); - log(" write port.\n"); + log(" write port. This transformation can be disabled with the \"-nosat\" option.\n"); log("\n"); log("Note that in addition to the algorithms implemented in this pass, the $memrd\n"); log("and $memwr cells are also subject to generic resource sharing passes (and other\n"); @@ -514,11 +521,26 @@ struct MemorySharePass : public Pass { log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { + bool flag_widen = true; + bool flag_sat = true; log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n"); - // TODO: expose when wide ports are actually supported. - bool flag_widen = false; + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-nosat") + { + flag_sat = false; + continue; + } + if (args[argidx] == "-nowiden") + { + flag_widen = false; + continue; + } + break; + } extra_args(args, 1, design); - MemoryShareWorker msw(design, flag_widen); + MemoryShareWorker msw(design, flag_widen, flag_sat); for (auto module : design->selected_modules()) msw(module); diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index 49922e3da8f..b8657056adf 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -23,6 +23,10 @@ for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of write ports."; false; } fi + if grep -q expect-wr-wide-continuation $f; then + grep -q "parameter \\\\WR_WIDE_CONTINUATION $(gawk '/expect-wr-wide-continuation/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected write wide continuation."; false; } + fi if grep -q expect-rd-ports $f; then grep -q "parameter \\\\RD_PORTS $(gawk '/expect-rd-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of read ports."; false; } @@ -55,6 +59,10 @@ for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do grep -q "parameter \\\\RD_INIT_VALUE $(gawk '/expect-rd-init-val/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected read init value."; false; } fi + if grep -q expect-rd-wide-continuation $f; then + grep -q "parameter \\\\RD_WIDE_CONTINUATION $(gawk '/expect-rd-wide-continuation/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read wide continuation."; false; } + fi if grep -q expect-no-rd-clk $f; then grep -q "connect \\\\RD_CLK 1'x\$" ${f%.v}.dmp || { echo " ERROR: Expected no read clock."; false; } diff --git a/tests/memories/wide_read_async.v b/tests/memories/wide_read_async.v new file mode 100644 index 00000000000..aecdb19386b --- /dev/null +++ b/tests/memories/wide_read_async.v @@ -0,0 +1,27 @@ +// expect-wr-ports 1 +// expect-rd-ports 4 +// expect-rd-wide-continuation 4'1110 + +module test( + input clk, + input we, + input [5:0] ra, + input [7:0] wa, + input [7:0] wd, + output [31:0] rd +); + +reg [7:0] mem[0:255]; + +assign rd[7:0] = mem[{ra, 2'b00}]; +assign rd[15:8] = mem[{ra, 2'b01}]; +assign rd[23:16] = mem[{ra, 2'b10}]; +assign rd[31:24] = mem[{ra, 2'b11}]; + +always @(posedge clk) begin + if (we) + mem[wa] <= wd; +end + +endmodule + diff --git a/tests/memories/wide_read_mixed.v b/tests/memories/wide_read_mixed.v new file mode 100644 index 00000000000..c36db3d3131 --- /dev/null +++ b/tests/memories/wide_read_mixed.v @@ -0,0 +1,46 @@ +// expect-wr-ports 1 +// expect-rd-ports 4 +// expect-rd-wide-continuation 4'1110 +// expect-rd-srst-val 32'10000111011001010100001100100001 +// expect-rd-init-val 32'10101011110011011110111110101011 + +// In this testcase, the byte-wide read ports are merged into a single +// word-wide port despite mismatched transparency, with soft transparency +// logic inserted on half the port to preserve the semantics. + +module test( + input clk, + input re, rr, + input we, + input [5:0] ra, + input [7:0] wa, + input [7:0] wd, + output reg [31:0] rd +); + +reg [7:0] mem[0:255]; + +initial rd = 32'habcdefab; + +always @(posedge clk) begin + if (rr) begin + rd <= 32'h87654321; + end else if (re) begin + rd[7:0] <= mem[{ra, 2'b00}]; + rd[15:8] <= mem[{ra, 2'b01}]; + rd[23:16] <= mem[{ra, 2'b10}]; + rd[31:24] <= mem[{ra, 2'b11}]; + if (we && wa == {ra, 2'b00}) + rd [7:0] <= wd; + if (we && wa == {ra, 2'b01}) + rd [15:8] <= wd; + end +end + +always @(posedge clk) begin + if (we) + mem[wa] <= wd; +end + +endmodule + diff --git a/tests/memories/wide_read_sync.v b/tests/memories/wide_read_sync.v new file mode 100644 index 00000000000..54ba3f25627 --- /dev/null +++ b/tests/memories/wide_read_sync.v @@ -0,0 +1,32 @@ +// expect-wr-ports 1 +// expect-rd-ports 4 +// expect-rd-wide-continuation 4'1110 + +module test( + input clk, + input re, + input we, + input [5:0] ra, + input [7:0] wa, + input [7:0] wd, + output reg [31:0] rd +); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (re) begin + rd[7:0] <= mem[{ra, 2'b00}]; + rd[15:8] <= mem[{ra, 2'b01}]; + rd[23:16] <= mem[{ra, 2'b10}]; + rd[31:24] <= mem[{ra, 2'b11}]; + end +end + +always @(posedge clk) begin + if (we) + mem[wa] <= wd; +end + +endmodule + diff --git a/tests/memories/wide_read_trans.v b/tests/memories/wide_read_trans.v new file mode 100644 index 00000000000..fe329350050 --- /dev/null +++ b/tests/memories/wide_read_trans.v @@ -0,0 +1,40 @@ +// expect-wr-ports 1 +// expect-rd-ports 4 +// expect-rd-wide-continuation 4'1110 + +module test( + input clk, + input re, + input we, + input [5:0] ra, + input [7:0] wa, + input [7:0] wd, + output reg [31:0] rd +); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (re) begin + rd[7:0] <= mem[{ra, 2'b00}]; + rd[15:8] <= mem[{ra, 2'b01}]; + rd[23:16] <= mem[{ra, 2'b10}]; + rd[31:24] <= mem[{ra, 2'b11}]; + if (we && wa == {ra, 2'b00}) + rd [7:0] <= wd; + if (we && wa == {ra, 2'b01}) + rd [15:8] <= wd; + if (we && wa == {ra, 2'b10}) + rd [23:16] <= wd; + if (we && wa == {ra, 2'b11}) + rd [31:24] <= wd; + end +end + +always @(posedge clk) begin + if (we) + mem[wa] <= wd; +end + +endmodule + diff --git a/tests/memories/wide_thru_priority.v b/tests/memories/wide_thru_priority.v new file mode 100644 index 00000000000..10c0d837b26 --- /dev/null +++ b/tests/memories/wide_thru_priority.v @@ -0,0 +1,29 @@ +// expect-wr-ports 3 +// expect-rd-ports 1 +// expect-wr-wide-continuation 3'010 + +module test( + input clk, + input we1, we2, + input [5:0] ra, + input [4:0] wa1, + input [5:0] wa2, + input [15:0] wd1, + input [7:0] wd2, + output [7:0] rd +); + +reg [7:0] mem[0:63]; + +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[{wa1, 1'b0}] <= wd1[7:0]; + if (we2) + mem[wa2] <= wd2; + if (we1) + mem[{wa1, 1'b1}] <= wd1[15:8]; +end + +endmodule diff --git a/tests/memories/wide_write.v b/tests/memories/wide_write.v new file mode 100644 index 00000000000..5c4cc41f93d --- /dev/null +++ b/tests/memories/wide_write.v @@ -0,0 +1,29 @@ +// expect-wr-ports 4 +// expect-rd-ports 1 +// expect-wr-wide-continuation 4'1110 + +module test( + input clk, + input [3:0] we, + input [7:0] ra, + input [5:0] wa, + input [31:0] wd, + output [7:0] rd +); + +reg [7:0] mem[0:255]; + +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we[0]) + mem[{wa, 2'b00}] <= wd[7:0]; + if (we[1]) + mem[{wa, 2'b01}] <= wd[15:8]; + if (we[2]) + mem[{wa, 2'b10}] <= wd[23:16]; + if (we[3]) + mem[{wa, 2'b11}] <= wd[31:24]; +end + +endmodule diff --git a/tests/opt/memory_dff_trans.ys b/tests/opt/memory_dff_trans.ys index 7599949f3b4..102b36f2670 100644 --- a/tests/opt/memory_dff_trans.ys +++ b/tests/opt/memory_dff_trans.ys @@ -759,6 +759,10 @@ 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 @@ -808,6 +812,10 @@ 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 @@ -858,5 +866,9 @@ select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0001 r:COLLISION_X_MAS 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/opt_mem_priority.ys b/tests/opt/opt_mem_priority.ys index c1261ddf777..a4119e12ad3 100644 --- a/tests/opt/opt_mem_priority.ys +++ b/tests/opt/opt_mem_priority.ys @@ -200,6 +200,10 @@ EOT hierarchy -auto-top proc opt -memory -nomap +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 From f7913285067ed30bf5087f265db7e0bd523af2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 13 Aug 2021 00:43:15 +0200 Subject: [PATCH 0491/2410] Add opt_mem_widen pass. If all of us are wide, then none of us are! --- passes/memory/memory.cc | 2 + passes/opt/Makefile.inc | 1 + passes/opt/opt_mem_widen.cc | 107 ++++++++++++++++++++++++++++++++++++ tests/memories/wide_all.v | 36 ++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 passes/opt/opt_mem_widen.cc create mode 100644 tests/memories/wide_all.v diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index bc1b19d00c3..bac547c1a4f 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -41,6 +41,7 @@ struct MemoryPass : public Pass { log(" memory_dff (skipped if called with -nordff or -memx)\n"); log(" opt_clean\n"); log(" memory_share [-nowiden] [-nosat]\n"); + log(" opt_mem_widen\n"); log(" memory_memx (when called with -memx)\n"); log(" opt_clean\n"); log(" memory_collect\n"); @@ -100,6 +101,7 @@ struct MemoryPass : public Pass { Pass::call(design, "memory_dff"); Pass::call(design, "opt_clean"); Pass::call(design, "memory_share" + memory_share_opts); + Pass::call(design, "opt_mem_widen"); if (flag_memx) Pass::call(design, "memory_memx"); Pass::call(design, "opt_clean"); diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index d8eb2f0b9f3..4e52ad8da04 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -4,6 +4,7 @@ OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_mem.o OBJS += passes/opt/opt_mem_feedback.o OBJS += passes/opt/opt_mem_priority.o +OBJS += passes/opt/opt_mem_widen.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_dff.o diff --git a/passes/opt/opt_mem_widen.cc b/passes/opt/opt_mem_widen.cc new file mode 100644 index 00000000000..95e01088cf0 --- /dev/null +++ b/passes/opt/opt_mem_widen.cc @@ -0,0 +1,107 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * 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/mem.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct OptMemWidenPass : public Pass { + OptMemWidenPass() : Pass("opt_mem_widen", "optimize memories where all ports are wide") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_mem_widen [options] [selection]\n"); + log("\n"); + log("This pass looks for memories where all ports are wide and adjusts the base\n"); + log("memory width up until that stops being the case.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing OPT_MEM_WIDEN pass (optimize memories where all ports are wide).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + // if (args[argidx] == "-nomux") { + // mode_nomux = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + int total_count = 0; + for (auto module : design->selected_modules()) { + for (auto &mem : Mem::get_selected_memories(module)) { + // If the memory has no read ports, opt_clean will remove it + // instead. + if (mem.rd_ports.empty()) + continue; + int factor_log2 = mem.rd_ports[0].wide_log2; + for (auto &port : mem.rd_ports) + if (port.wide_log2 < factor_log2) + factor_log2 = port.wide_log2; + for (auto &port : mem.wr_ports) + if (port.wide_log2 < factor_log2) + factor_log2 = port.wide_log2; + if (factor_log2 == 0) + continue; + log("Widening base width of memory %s in module %s by factor %d.\n", log_id(mem.memid), log_id(module->name), 1 << factor_log2); + total_count++; + // The inits are too messy to expand one-by-one, for they may + // collide with one another after expansion. Just hit it with + // a hammer. + bool has_init = !mem.inits.empty(); + Const init_data; + if (has_init) { + init_data = mem.get_init_data(); + mem.clear_inits(); + } + mem.width <<= factor_log2; + mem.size >>= factor_log2; + mem.start_offset >>= factor_log2; + if (has_init) { + MemInit new_init; + new_init.addr = mem.start_offset; + new_init.data = init_data; + new_init.en = Const(State::S1, mem.width); + mem.inits.push_back(new_init); + } + for (auto &port : mem.rd_ports) { + port.wide_log2 -= factor_log2; + port.addr = port.addr.extract_end(factor_log2); + } + for (auto &port : mem.wr_ports) { + port.wide_log2 -= factor_log2; + port.addr = port.addr.extract_end(factor_log2); + } + mem.emit(); + } + } + + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); + log("Performed a total of %d transformations.\n", total_count); + } +} OptMemWidenPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/memories/wide_all.v b/tests/memories/wide_all.v new file mode 100644 index 00000000000..f7bc3e5ce21 --- /dev/null +++ b/tests/memories/wide_all.v @@ -0,0 +1,36 @@ +// expect-wr-ports 2 +// expect-rd-ports 1 +// expect-wr-wide-continuation 2'10 + +module test( + input clk, + input [3:0] we, + input [6:0] ra, + input [5:0] wa, + input [31:0] wd, + output [15:0] rd +); + +reg [7:0] mem[3:254]; + +assign rd[7:0] = mem[{ra, 1'b0}]; +assign rd[15:0] = mem[{ra, 1'b1}]; + +initial begin + mem[5] = 8'h12; + mem[6] = 8'h34; + mem[7] = 8'h56; +end + +always @(posedge clk) begin + if (we[0]) + mem[{wa, 2'b00}] <= wd[7:0]; + if (we[1]) + mem[{wa, 2'b01}] <= wd[15:8]; + if (we[2]) + mem[{wa, 2'b10}] <= wd[23:16]; + if (we[3]) + mem[{wa, 2'b11}] <= wd[31:24]; +end + +endmodule From ee2b5b7ed186414897a8a570a9e503c438803ad8 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 20 Apr 2020 16:06:53 +0100 Subject: [PATCH 0492/2410] Generate an RTLIL representation of bind constructs This code now takes the AST nodes of type AST_BIND and generates a representation in the RTLIL for them. This is a little tricky, because a binding of the form: bind baz foo_t foo_i (.arg (1 + bar)); means "make an instance of foo_t called foo_i, instantiate it inside baz and connect the port arg to the result of the expression 1+bar". Of course, 1+bar needs a cell for the addition. Where should that cell live? With this patch, the Binding structure that represents the construct is itself an AST::AstModule module. This lets us put the adder cell inside it. We'll pull the contents out and plonk them into 'baz' when we actually do the binding operation as part of the hierarchy pass. Of course, we don't want RTLIL::Binding to contain an AST::AstModule (since kernel code shouldn't depend on a frontend), so we define RTLIL::Binding as an abstract base class and put the AST-specific code into an AST::Binding subclass. This is analogous to the AST::AstModule class. --- Makefile | 3 ++ frontends/ast/Makefile.inc | 1 + frontends/ast/ast.cc | 5 +++ frontends/ast/ast.h | 3 ++ frontends/ast/ast_binding.cc | 49 ++++++++++++++++++++++ frontends/ast/ast_binding.h | 58 ++++++++++++++++++++++++++ frontends/ast/genrtlil.cc | 79 +++++++++++++++++++++++++++++++++++- kernel/binding.cc | 29 +++++++++++++ kernel/binding.h | 60 +++++++++++++++++++++++++++ kernel/rtlil.cc | 17 ++++++++ kernel/rtlil.h | 11 ++++- 11 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 frontends/ast/ast_binding.cc create mode 100644 frontends/ast/ast_binding.h create mode 100644 kernel/binding.cc create mode 100644 kernel/binding.h diff --git a/Makefile b/Makefile index 6b64b0e35a8..a4d8007e465 100644 --- a/Makefile +++ b/Makefile @@ -565,6 +565,7 @@ $(eval $(call add_include_file,kernel/yosys.h)) $(eval $(call add_include_file,kernel/hashlib.h)) $(eval $(call add_include_file,kernel/log.h)) $(eval $(call add_include_file,kernel/rtlil.h)) +$(eval $(call add_include_file,kernel/binding.h)) $(eval $(call add_include_file,kernel/register.h)) $(eval $(call add_include_file,kernel/celltypes.h)) $(eval $(call add_include_file,kernel/celledges.h)) @@ -585,6 +586,7 @@ $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) $(eval $(call add_include_file,frontends/ast/ast.h)) +$(eval $(call add_include_file,frontends/ast/ast_binding.h)) $(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h)) @@ -595,6 +597,7 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.cc)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o +OBJS += kernel/binding.o ifeq ($(ENABLE_ABC),1) ifneq ($(ABCEXTERNAL),) kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' diff --git a/frontends/ast/Makefile.inc b/frontends/ast/Makefile.inc index 91d917c9169..9e6eee1e8fb 100644 --- a/frontends/ast/Makefile.inc +++ b/frontends/ast/Makefile.inc @@ -3,4 +3,5 @@ OBJS += frontends/ast/ast.o OBJS += frontends/ast/simplify.o OBJS += frontends/ast/genrtlil.o OBJS += frontends/ast/dpicall.o +OBJS += frontends/ast/ast_binding.o diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index fe503c547a9..4fbc238b02d 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1310,6 +1310,11 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump design->verilog_packages.push_back(child->clone()); current_scope.clear(); } + else if (child->type == AST_BIND) { + // top-level bind construct + for (RTLIL::Binding *binding : child->genBindings()) + design->add(binding); + } else { // must be global definition if (child->type == AST_PARAMETER) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ba5a11b9683..63104bca4b9 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -284,6 +284,9 @@ namespace AST void dumpAst(FILE *f, std::string indent) const; void dumpVlog(FILE *f, std::string indent) const; + // Generate RTLIL for a bind construct + std::vector genBindings() const; + // used by genRTLIL() for detecting expression width and sign void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL); void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL); diff --git a/frontends/ast/ast_binding.cc b/frontends/ast/ast_binding.cc new file mode 100644 index 00000000000..c20d1df4d6e --- /dev/null +++ b/frontends/ast/ast_binding.cc @@ -0,0 +1,49 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * 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 "ast_binding.h" +#include "ast.h" + +YOSYS_NAMESPACE_BEGIN + +using namespace AST_INTERNAL; + +AST::Binding::Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name, + const AstNode &cell) + : RTLIL::Binding(target_type, target_name), + ast_node(cell.clone()) +{ + log_assert(cell.type == AST_CELL); +} + +std::string +AST::Binding::describe() const +{ + std::ostringstream oss; + oss << "directive to bind " << ast_node->str + << " to " << target_name.str(); + if (!target_type.empty()) + oss << " (target type: " + << target_type.str() + << ")"; + return oss.str(); +} + +PRIVATE_NAMESPACE_END diff --git a/frontends/ast/ast_binding.h b/frontends/ast/ast_binding.h new file mode 100644 index 00000000000..641497d52d4 --- /dev/null +++ b/frontends/ast/ast_binding.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * 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. + * + * --- + * + * This header declares the AST::Binding class + * + * This is used to support the bind directive and is to RTLIL::Binding as + * AST::AstModule is to RTLIL::Module, holding a syntax-level representation of + * cells until we get to a stage where they make sense. In the case of a bind + * directive, this is when we elaborate the design in the hierarchy pass. + * + */ + +#ifndef AST_BINDING_H +#define AST_BINDING_H + +#include "kernel/rtlil.h" +#include "kernel/binding.h" + +#include + +YOSYS_NAMESPACE_BEGIN + +namespace AST +{ + class Binding : public RTLIL::Binding + { + public: + Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name, + const AstNode &cell); + + std::string describe() const override; + + private: + // The syntax-level representation of the cell to be bound. + std::unique_ptr ast_node; + }; +} + +YOSYS_NAMESPACE_END + +#endif diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 45aab9d8ebe..c82664b98a4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -28,8 +28,10 @@ #include "kernel/log.h" #include "kernel/utils.h" +#include "kernel/binding.h" #include "libs/sha1/sha1.h" #include "ast.h" +#include "ast_binding.h" #include #include @@ -733,6 +735,69 @@ struct AST_INTERNAL::ProcessGenerator } }; +// Generate RTLIL for a bind construct +// +// The AST node will have one or more AST_IDENTIFIER children, which were added +// by bind_target_instance in the parser. After these, it will have one or more +// cells, as parsed by single_cell. These have type AST_CELL. +// +// If there is more than one AST_IDENTIFIER, the first one should be considered +// a module identifier. If there is only one AST_IDENTIFIER, we can't tell at +// this point whether it's a module/interface name or the name of an instance +// because the correct interpretation depends on what's visible at elaboration +// time. For now, we just treat it as a target instance with unknown type, and +// we'll deal with the corner case in the hierarchy pass. +// +// To simplify downstream code, RTLIL::Binding only has a single target and +// single bound instance. If we see the syntax that allows more than one of +// either, we split it into multiple Binding objects. +std::vector AstNode::genBindings() const +{ + // Partition children into identifiers and cells + int num_ids = 0; + for (int i = 0; i < GetSize(children); ++i) { + if (children[i]->type != AST_IDENTIFIER) { + log_assert(i > 0); + num_ids = i; + break; + } + } + + // We should have found at least one child that's not an identifier + log_assert(num_ids > 0); + + // Make sense of the identifiers, extracting a possible type name and a + // list of hierarchical IDs. We represent an unknown type with an empty + // string. + RTLIL::IdString tgt_type; + int first_tgt_inst = 0; + if (num_ids > 1) { + tgt_type = children[0]->str; + first_tgt_inst = 1; + } + + std::vector ret; + + // At this point, we know that children with index >= first_tgt_inst and + // index < num_ids are (hierarchical?) names of target instances. Make a + // binding object for each of them, and fill in the generated instance + // cells each time. + for (int i = first_tgt_inst; i < num_ids; ++i) { + const AstNode &tgt_child = *children[i]; + + for (int j = num_ids; j < GetSize(children); ++j) { + const AstNode &cell_child = *children[j]; + + log_assert(cell_child.type == AST_CELL); + + ret.push_back(new AST::Binding(tgt_type, tgt_child.str, + cell_child)); + } + } + + return ret; +} + // detect sign and width of an expression void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real) { @@ -1311,7 +1376,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = current_module->addWire(str); set_src_attr(wire, this); wire->name = str; - if (flag_autowire) + + // If we are currently processing a bind directive which wires up + // signals or parameters explicitly, rather than with .*, then + // current_module will start out empty and we don't want to warn the + // user about it: we'll spot broken wiring later, when we run the + // hierarchy pass. + if (dynamic_cast(current_module)) { + /* nothing to do here */ + } else if (flag_autowire) log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str()); else log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); @@ -1975,7 +2048,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } break; case AST_BIND: { - // The bind construct. Currently unimplemented: just ignore it. + // Read a bind construct. This should have one or more cells as children. + for (RTLIL::Binding *binding : genBindings()) + current_module->add(binding); break; } diff --git a/kernel/binding.cc b/kernel/binding.cc new file mode 100644 index 00000000000..621f7007bfa --- /dev/null +++ b/kernel/binding.cc @@ -0,0 +1,29 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * 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 "binding.h" + +YOSYS_NAMESPACE_BEGIN + +RTLIL::Binding::Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name) + : target_type(target_type), target_name(target_name) +{} + +YOSYS_NAMESPACE_END diff --git a/kernel/binding.h b/kernel/binding.h new file mode 100644 index 00000000000..3b64e76dac3 --- /dev/null +++ b/kernel/binding.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * 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. + * + */ + +#ifndef BINDING_H +#define BINDING_H + +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +struct RTLIL::Binding +{ + // Represents a bind construct. + // + // The target of the binding is represented by target_type and + // target_name (see comments above the fields). + + Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name); + + virtual ~Binding() {} + + // Return a string describing the binding + virtual std::string describe() const = 0; + +protected: + // May be empty. If not, it's the name of the module or interface to + // bind to. + RTLIL::IdString target_type; + + // If target_type is nonempty (the usual case), this is a hierarchical + // reference to the bind target. If target_type is empty, we have to + // wait until the hierarchy pass to figure out whether this was the name + // of a module/interface type or an instance. + RTLIL::IdString target_name; + + // An attribute name which contains an ID that's unique across binding + // instances (used to ensure we don't apply a binding twice to a module) + RTLIL::IdString attr_name; +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b414556f36c..40b9b761aa2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/macc.h" #include "kernel/celltypes.h" +#include "kernel/binding.h" #include "frontends/verilog/verilog_frontend.h" #include "frontends/verilog/preproc.h" #include "backends/rtlil/rtlil_backend.h" @@ -573,6 +574,8 @@ RTLIL::Design::~Design() { for (auto &pr : modules_) delete pr.second; + for (auto n : bindings_) + delete n; for (auto n : verilog_packages) delete n; for (auto n : verilog_globals) @@ -636,6 +639,12 @@ void RTLIL::Design::add(RTLIL::Module *module) } } +void RTLIL::Design::add(RTLIL::Binding *binding) +{ + log_assert(binding != nullptr); + bindings_.push_back(binding); +} + RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) { if (modules_.count(name) != 0) @@ -872,6 +881,8 @@ RTLIL::Module::~Module() delete pr.second; for (auto &pr : processes) delete pr.second; + for (auto binding : bindings_) + delete binding; #ifdef WITH_PYTHON RTLIL::Module::get_all_modules()->erase(hashidx_); #endif @@ -1923,6 +1934,12 @@ void RTLIL::Module::add(RTLIL::Process *process) process->module = this; } +void RTLIL::Module::add(RTLIL::Binding *binding) +{ + log_assert(binding != nullptr); + bindings_.push_back(binding); +} + void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index dc0d5234b98..50707c0aee4 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -72,6 +72,7 @@ namespace RTLIL struct MemWriteAction; struct SyncRule; struct Process; + struct Binding; typedef std::pair SigSig; @@ -1033,6 +1034,8 @@ struct RTLIL::Design int refcount_modules_; dict modules_; + std::vector bindings_; + std::vector verilog_packages, verilog_globals; std::unique_ptr verilog_defines; @@ -1053,6 +1056,8 @@ struct RTLIL::Design } void add(RTLIL::Module *module); + void add(RTLIL::Binding *binding); + RTLIL::Module *addModule(RTLIL::IdString name); void remove(RTLIL::Module *module); void rename(RTLIL::Module *module, RTLIL::IdString new_name); @@ -1140,7 +1145,9 @@ struct RTLIL::Module : public RTLIL::AttrObject dict wires_; dict cells_; - std::vector connections_; + + std::vector connections_; + std::vector bindings_; RTLIL::IdString name; idict avail_parameters; @@ -1207,6 +1214,8 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + void add(RTLIL::Binding *binding); + // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const pool &wires); void remove(RTLIL::Cell *cell); From 539d4ee90767a839b1c3689dedb6c161b652410f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 14 Aug 2021 00:46:42 +0000 Subject: [PATCH 0493/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a4d8007e465..93b24ef971d 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4261 +YOSYS_VER := 0.9+4270 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From faacc7ad897437a8169af9dbbab6818f88c7b1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 14 Aug 2021 14:23:12 +0200 Subject: [PATCH 0494/2410] proc_prune: Make assign removal and promotion per-bit, remember promoted bits. Fixes #2962. --- passes/proc/proc_prune.cc | 65 +++++++++++++++------------------------ tests/proc/bug2962.ys | 22 +++++++++++++ 2 files changed, 47 insertions(+), 40 deletions(-) create mode 100644 tests/proc/bug2962.ys diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index bd122b91fff..9f1080ef635 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -67,51 +67,36 @@ struct PruneWorker } for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) { RTLIL::SigSpec lhs = sigmap(it->first); - bool redundant = true; - for (auto &bit : lhs) { + RTLIL::SigSpec rhs = sigmap(it->second); + SigSpec new_lhs, new_rhs; + SigSpec conn_lhs, conn_rhs; + for (int i = 0; i < GetSize(lhs); i++) { + SigBit bit = lhs[i]; if (bit.wire && !assigned[bit]) { - redundant = false; - break; - } - } - bool remove = false; - if (redundant) { - removed_count++; - remove = true; - } else { - if (root) { - bool promotable = true; - for (auto &bit : lhs) { - if (bit.wire && affected[bit] && !assigned[bit]) { - promotable = false; - break; - } - } - if (promotable) { - RTLIL::SigSpec rhs = sigmap(it->second); - RTLIL::SigSig conn; - for (int i = 0; i < GetSize(lhs); i++) { - RTLIL::SigBit lhs_bit = lhs[i]; - if (lhs_bit.wire && !assigned[lhs_bit]) { - conn.first.append(lhs_bit); - conn.second.append(rhs.extract(i)); - } - } - promoted_count++; - module->connect(conn); - remove = true; + if (!affected[bit] && root) { + conn_lhs.append(bit); + conn_rhs.append(rhs[i]); + } else { + new_lhs.append(bit); + new_rhs.append(rhs[i]); } + assigned.insert(bit); + affected.insert(bit); } - for (auto &bit : lhs) - if (bit.wire) - assigned.insert(bit); - for (auto &bit : lhs) - if (bit.wire) - affected.insert(bit); } - if (remove) + if (GetSize(conn_lhs)) { + promoted_count++; + module->connect(conn_lhs, conn_rhs); + } + if (GetSize(new_lhs) == 0) { + if (GetSize(conn_lhs) == 0) + removed_count++; cs->actions.erase((it++).base() - 1); - else it++; + } else { + it->first = new_lhs; + it->second = new_rhs; + it++; + } } return assigned; } diff --git a/tests/proc/bug2962.ys b/tests/proc/bug2962.ys new file mode 100644 index 00000000000..99da8db5d5d --- /dev/null +++ b/tests/proc/bug2962.ys @@ -0,0 +1,22 @@ +read_ilang << EOT +module \top + wire width 4 input 1 \a + wire width 2 input 2 \b + wire input 3 \clk + wire width 4 output 4 \q + wire input 5 \en + wire width 4 \nq + process \p + assign \nq \a + assign \nq [1:0] \b + switch \en + case 1'1 + assign \nq [3] 1'0 + end + sync posedge \clk + update \q \nq + end +end +EOT +proc +check -assert From 83c0f82dc842fc859dfb4b19e766b23f965cfbb3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 15 Aug 2021 00:50:04 +0000 Subject: [PATCH 0495/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 93b24ef971d..45253aac054 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4270 +YOSYS_VER := 0.9+4272 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 10f8b75dca82ad9aa665e1e4b599bda9258b831d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 16 Aug 2021 12:31:01 +0200 Subject: [PATCH 0496/2410] kernel/mem: Remove old parameter when upgrading $mem to $mem_v2. Fixes #2967. --- kernel/mem.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/mem.cc b/kernel/mem.cc index ee6b8b6cf2a..b176e40575c 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -202,6 +202,7 @@ void Mem::emit() { cell->parameters[ID::RD_ARST_VALUE] = rd_arst_value; cell->parameters[ID::RD_SRST_VALUE] = rd_srst_value; cell->parameters[ID::RD_INIT_VALUE] = rd_init_value; + cell->parameters.erase(ID::RD_TRANSPARENT); cell->setPort(ID::RD_CLK, rd_clk); cell->setPort(ID::RD_EN, rd_en); cell->setPort(ID::RD_ARST, rd_arst); From e6dd4db0afa230fd382e9789d9aaf9c3b536b50c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Aug 2021 00:49:33 +0000 Subject: [PATCH 0497/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 45253aac054..84ec551c611 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4272 +YOSYS_VER := 0.9+4274 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 3806b073031f1782f41762ebb6080a07e4182e95 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Tue, 17 Aug 2021 10:21:04 +0200 Subject: [PATCH 0498/2410] ice40: Fix typo in SB_CARRY specify for LP/UltraPlus Signed-off-by: Sylvain Munaut --- techlibs/ice40/cells_sim.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 0f28e227015..f33e92488e6 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -244,7 +244,7 @@ module SB_CARRY (output CO, input I0, I1, CI); // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82 (I0 => CO) = (382, 362); // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85 - (I0 => CO) = (341, 196); + (I1 => CO) = (341, 196); endspecify `endif `ifdef ICE40_U @@ -254,7 +254,7 @@ module SB_CARRY (output CO, input I0, I1, CI); // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94 (I0 => CO) = (675, 662); // https://github.com/YosysHQ/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97 - (I0 => CO) = (609, 358); + (I1 => CO) = (609, 358); endspecify `endif endmodule From 75a4cdfc8afc10fed80e43fb1ba31c7edaf6e361 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Aug 2021 00:51:20 +0000 Subject: [PATCH 0499/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 84ec551c611..b267f62944c 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4274 +YOSYS_VER := 0.9+4276 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From b59c42734837f6cb987e97d60e56e096c8d4d40a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 20 Aug 2021 10:19:04 +0200 Subject: [PATCH 0500/2410] Make Verific extensions optional --- Makefile | 7 ++++++- frontends/verific/verific.cc | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b267f62944c..d88a7e95a46 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ ENABLE_READLINE := 1 ENABLE_EDITLINE := 0 ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 +DISABLE_VERIFIC_EXTENSIONS := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 ENABLE_PROTOBUF := 0 @@ -498,7 +499,11 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree extensions +VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree +ifneq ($(DISABLE_VERIFIC_EXTENSIONS),1) +VERIFIC_COMPONENTS += extensions +CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS +endif CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC ifeq ($(OS), Darwin) LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)) -lz diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5a10568c7aa..1b8bc1b5124 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -50,7 +50,9 @@ USING_YOSYS_NAMESPACE #include "VhdlUnits.h" #include "VeriLibrary.h" +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS #include "InitialAssertions.h" +#endif #ifndef YOSYSHQ_VERIFIC_API_VERSION # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." @@ -1961,7 +1963,9 @@ void verific_import(Design *design, const std::map &par for (const auto &i : parameters) verific_params.Insert(i.first.c_str(), i.second.c_str()); +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS InitialAssertions::Rewrite("work", &verific_params); +#endif if (top.empty()) { netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, &verific_params); @@ -2847,8 +2851,9 @@ struct VerificPass : public Pass { std::set top_mod_names; +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS InitialAssertions::Rewrite(work, ¶meters); - +#endif if (mode_all) { log("Running hier_tree::ElaborateAll().\n"); From c2d358484fa5188be350ef1a8496f88b60d69ef7 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Fri, 20 Aug 2021 21:21:06 +0200 Subject: [PATCH 0501/2410] Gowin: deal with active-low tristate (#2971) * deal with active-low tristate * remove empty port * update sim models * add expected lut1 to tests --- techlibs/gowin/cells_map.v | 7 +++++++ techlibs/gowin/cells_sim.v | 4 ++-- techlibs/gowin/synth_gowin.cc | 6 +++--- techlibs/nexus/cells_map.v | 2 +- tests/arch/gowin/tribuf.ys | 3 ++- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v index 851ef20b262..90eb9b5a435 100644 --- a/techlibs/gowin/cells_map.v +++ b/techlibs/gowin/cells_map.v @@ -122,6 +122,13 @@ module \$_DFFE_NP0P_ (input D, C, R, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$__GW_IOBUF (input I, OE, output O, inout IO); + IOBUF _TECHMAP_REPLACE_ (.I(I), .O(O), .OEN(~OE), .IO(IO)); +endmodule + +module \$__GW_TBUF (input I, OE, output O); + TBUF _TECHMAP_REPLACE_ (.I(I), .OEN(~OE), .O(O)); +endmodule module \$lut (A, Y); parameter WIDTH = 0; diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 509bf3ef293..41398409d31 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -573,14 +573,14 @@ endmodule module TBUF (O, I, OEN); input I, OEN; output O; - assign O = OEN ? I : 1'bz; + assign O = OEN ? 1'bz : I; endmodule module IOBUF (O, IO, I, OEN); input I,OEN; output O; inout IO; - assign IO = OEN ? I : 1'bz; + assign IO = OEN ? 1'bz : I; assign I = IO; endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index c97bd595ca7..087f6b8cf45 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -241,6 +241,9 @@ struct SynthGowinPass : public ScriptPass if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); run("splitnets"); + if (!noiopads || help_mode) + run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " + "-toutpad $__GW_TBUF OE:I:O -tinoutpad $__GW_IOBUF OE:O:I:IO", "(unless -noiopads)"); } if (check_label("map_ffs")) @@ -277,9 +280,6 @@ struct SynthGowinPass : public ScriptPass run("opt_lut_ins -tech gowin"); run("setundef -undriven -params -zero"); run("hilomap -singleton -hicell VCC V -locell GND G"); - if (!noiopads || help_mode) - run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " - "-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)"); run("clean"); run("autoname"); } diff --git a/techlibs/nexus/cells_map.v b/techlibs/nexus/cells_map.v index 86911d7a0f0..1e53e402652 100644 --- a/techlibs/nexus/cells_map.v +++ b/techlibs/nexus/cells_map.v @@ -58,7 +58,7 @@ module \$__NX_TINOUTPAD (input I, OE, output O, inout B); endmodule module \$__NX_TOUTPAD (input I, OE, output O); - OBZ _TECHMAP_REPLACE_ (.I(I), .O(), .T(~OE), .O(O)); + OBZ _TECHMAP_REPLACE_ (.I(I), .T(~OE), .O(O)); endmodule `ifndef NO_LUT diff --git a/tests/arch/gowin/tribuf.ys b/tests/arch/gowin/tribuf.ys index 5855b9d975f..eef7e379ffd 100644 --- a/tests/arch/gowin/tribuf.ys +++ b/tests/arch/gowin/tribuf.ys @@ -9,5 +9,6 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. select -assert-count 1 t:TBUF +select -assert-count 1 t:LUT1 select -assert-count 2 t:IBUF -select -assert-none t:TBUF t:IBUF %% t:* %D +select -assert-none t:TBUF t:IBUF t:LUT1 %% t:* %D \ No newline at end of file From 21e710eb556d14d1cdfe4a3387a1dbe3e05ca04c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 21 Aug 2021 00:48:23 +0000 Subject: [PATCH 0502/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d88a7e95a46..0a3c75e5836 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4276 +YOSYS_VER := 0.9+4280 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 62d41d46397a93d1efa2b8282203d192b256d824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 21 Aug 2021 23:36:00 +0200 Subject: [PATCH 0503/2410] opt_clean: Make the init attribute follow the FF's Q. Previously, opt_clean would reconnect all ports (including FF Q ports) to a "canonical" SigBit chosen by complex rules, but would leave the init attribute on the old wire. This change applies the same canonicalization rules to the init attributes, ensuring that init moves to wherever the Q port moved. Part of another jab at #2920. --- passes/opt/opt_clean.cc | 24 ++++++++++++++++++++++++ tests/techmap/iopadmap.ys | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 08e9d6b791c..cb2c261c44e 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -339,6 +339,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos used_signals_nodrivers.add(it2.second); } } + dict init_bits; for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { @@ -354,6 +355,29 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos assign_map.apply(sig); used_signals.add(sig); } + auto it2 = wire->attributes.find(ID::init); + if (it2 != wire->attributes.end()) { + RTLIL::Const &val = it2->second; + SigSpec sig = assign_map(wire); + for (int i = 0; i < GetSize(val) && i < GetSize(sig); i++) + if (val.bits[i] != State::Sx) + init_bits[sig[i]] = val.bits[i]; + wire->attributes.erase(it2); + } + } + + for (auto wire : module->wires()) { + bool found = false; + Const val(State::Sx, wire->width); + for (int i = 0; i < wire->width; i++) { + auto it = init_bits.find(RTLIL::SigBit(wire, i)); + if (it != init_bits.end()) { + val.bits[i] = it->second; + found = true; + } + } + if (found) + wire->attributes[ID::init] = val; } pool del_wires_queue; diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index df029b3a039..f8e6bc37400 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -169,7 +169,7 @@ sub s2(.i(i[1]), .o(w[1])); assign o = oe ? w : 2'bz; endmodule -module c(input i, oe, (* init=2'b00 *) inout io, output o1, o2); +module c(input i, oe, (* init=1'b0 *) inout io, output o1, o2); assign io = oe ? i : 1'bz; assign {o1,o2} = {io,io}; endmodule @@ -182,5 +182,5 @@ select -assert-count 1 a/c:s %co a/a:init=1'b1 %i select -assert-count 1 a/a:init select -assert-count 1 b/c:s* %co %a b/a:init=2'b1x %i select -assert-count 1 b/a:init -select -assert-count 1 c/t:iobuf %co c/a:init=2'b00 %i +select -assert-count 1 c/t:iobuf %co c/a:init=1'b0 %i select -assert-count 1 c/a:init From 9cbff3a4a972f359d3842b689e135d4f906d763b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 22 Aug 2021 17:01:58 +0200 Subject: [PATCH 0504/2410] opt_merge: Remove and reinsert init when connecting nets. Mutating the SigMap by adding a new connection will throw off FfInitVals index. Work around this by removing the relevant init values from index whenever we connect nets, then re-add the new init value. Should fix #2920. --- passes/opt/opt_merge.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index d9861f49b08..115eb97a923 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -282,11 +282,12 @@ struct OptMergeWorker RTLIL::SigSpec other_sig = r.first->second->getPort(it.first); log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); + Const init = initvals(other_sig); + initvals.remove_init(it.second); + initvals.remove_init(other_sig); module->connect(RTLIL::SigSig(it.second, other_sig)); assign_map.add(it.second, other_sig); - - if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) - initvals.remove_init(it.second); + initvals.set_init(other_sig, init); } } log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); From dfc453b246c3b211a8c5df5e04c7afe2451b0986 Mon Sep 17 00:00:00 2001 From: ECP5-PCIe Date: Sun, 22 Aug 2021 18:08:04 +0200 Subject: [PATCH 0505/2410] Add DLLDELD --- techlibs/ecp5/cells_bb.v | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v index c9a6e52321e..e616d24d61c 100644 --- a/techlibs/ecp5/cells_bb.v +++ b/techlibs/ecp5/cells_bb.v @@ -339,6 +339,15 @@ module DDRDLLA( parameter GSR = "ENABLED"; endmodule +(* blackbox *) +module DLLDELD( + input A, DDRDEL, LOADN, MOVE, DIRECTION, + output Z, CFLAG +); + parameter DEL_ADJ = "PLUS"; + parameter DEL_VAL = 0; +endmodule + (* blackbox *) module CLKDIVF( input CLKI, RST, ALIGNWD, From 591fe72203d0d85f8790984f218903a059d1cc69 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 00:46:01 +0000 Subject: [PATCH 0506/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0a3c75e5836..90d8f085101 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4280 +YOSYS_VER := 0.9+4284 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 6de500ec08fefe8626033c996fa5c4c1deb7e210 Mon Sep 17 00:00:00 2001 From: kittennbfive <58293822+kittennbfive@users.noreply.github.com> Date: Sun, 29 Aug 2021 09:45:23 +0000 Subject: [PATCH 0507/2410] [ECP5] fix wrong link for syn_* attributes description (#2984) --- techlibs/ecp5/brams.txt | 2 +- techlibs/ecp5/lutrams.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/ecp5/brams.txt b/techlibs/ecp5/brams.txt index d34d9ec0746..615d8b2e518 100644 --- a/techlibs/ecp5/brams.txt +++ b/techlibs/ecp5/brams.txt @@ -38,7 +38,7 @@ bram $__ECP5_DP16KD endbram # The syn_* attributes are described in: -# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx +# https://www.latticesemi.com/view_document?document_id=51556 attr_icase 1 match $__ECP5_PDPW16KD diff --git a/techlibs/ecp5/lutrams.txt b/techlibs/ecp5/lutrams.txt index 9e6a23eba7e..5370a1ddbd0 100644 --- a/techlibs/ecp5/lutrams.txt +++ b/techlibs/ecp5/lutrams.txt @@ -12,7 +12,7 @@ bram $__TRELLIS_DPR16X4 endbram # The syn_* attributes are described in: -# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx +# https://www.latticesemi.com/view_document?document_id=51556 attr_icase 1 match $__TRELLIS_DPR16X4 From 1dbf91a8ef3109d6573ae64fc3fd08aedc0a690d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 00:49:03 +0000 Subject: [PATCH 0508/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 90d8f085101..d186bfc8bc1 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4284 +YOSYS_VER := 0.9+4286 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From f0a52e3dd275ee57a1b3ffd0a734b591bf21f668 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 30 Aug 2021 11:35:36 -0600 Subject: [PATCH 0509/2410] sv: support declaration in procedural for initialization In line with other tools, this adds an extra wrapping block around such for loops to appropriately scope the variable. --- frontends/verilog/verilog_parser.y | 49 +++++++++++++++++++++++++++++- tests/verilog/for_decl_no_init.ys | 9 ++++++ tests/verilog/for_decl_no_sv.ys | 9 ++++++ tests/verilog/for_decl_shadow.sv | 32 +++++++++++++++++++ tests/verilog/for_decl_shadow.ys | 6 ++++ 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/for_decl_no_init.ys create mode 100644 tests/verilog/for_decl_no_sv.ys create mode 100644 tests/verilog/for_decl_shadow.sv create mode 100644 tests/verilog/for_decl_shadow.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index b0c16c0f44f..23404f844b2 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2607,6 +2607,53 @@ asgn_binop: TOK_SSHL_ASSIGN { $$ = AST_SHIFT_SLEFT; } | TOK_SSHR_ASSIGN { $$ = AST_SHIFT_SRIGHT; } ; +for_initialization: + TOK_ID '=' expr { + AstNode *ident = new AstNode(AST_IDENTIFIER); + ident->str = *$1; + AstNode *node = new AstNode(AST_ASSIGN_EQ, ident, $3); + ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @3); + } | + non_io_wire_type range TOK_ID { + frontend_verilog_yyerror("For loop variable declaration is missing initialization!"); + } | + non_io_wire_type range TOK_ID '=' expr { + if (!sv_mode) + frontend_verilog_yyerror("For loop inline variable declaration is only supported in SystemVerilog mode!"); + + // loop variable declaration + AstNode *wire = $1; + AstNode *range = checkRange(wire, $2); + if (range != nullptr) + wire->children.push_back(range); + SET_AST_NODE_LOC(wire, @1, @3); + SET_AST_NODE_LOC(range, @2, @2); + + AstNode *ident = new AstNode(AST_IDENTIFIER); + ident->str = *$3; + wire->str = *$3; + delete $3; + + AstNode *loop = ast_stack.back(); + AstNode *parent = ast_stack.at(ast_stack.size() - 2); + log_assert(parent->children.back() == loop); + + // loop variable initialization + AstNode *asgn = new AstNode(AST_ASSIGN_EQ, ident, $5); + loop->children.push_back(asgn); + SET_AST_NODE_LOC(asgn, @3, @5); + SET_AST_NODE_LOC(ident, @3, @3); + + // inject a wrapping block to declare the loop variable and + // contain the current loop + AstNode *wrapper = new AstNode(AST_BLOCK); + wrapper->str = "$fordecl_block$" + std::to_string(autoidx++); + wrapper->children.push_back(wire); + wrapper->children.push_back(loop); + parent->children.back() = wrapper; // replaces `loop` + }; + // this production creates the obligatory if-else shift/reduce conflict behavioral_stmt: defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl | @@ -2667,7 +2714,7 @@ behavioral_stmt: ast_stack.back()->children.push_back(node); ast_stack.push_back(node); append_attr(node, $1); - } simple_behavioral_stmt ';' expr { + } for_initialization ';' expr { ast_stack.back()->children.push_back($7); } ';' simple_behavioral_stmt ')' { AstNode *block = new AstNode(AST_BLOCK); diff --git a/tests/verilog/for_decl_no_init.ys b/tests/verilog/for_decl_no_init.ys new file mode 100644 index 00000000000..68c1584e088 --- /dev/null +++ b/tests/verilog/for_decl_no_init.ys @@ -0,0 +1,9 @@ +logger -expect error "For loop variable declaration is missing initialization!" 1 +read_verilog -sv < Date: Tue, 31 Aug 2021 00:51:55 +0000 Subject: [PATCH 0510/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d186bfc8bc1..4ecc98a3cc3 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4286 +YOSYS_VER := 0.9+4288 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From b2e9717419e9a852f4e64f12891b8e9742900917 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 31 Aug 2021 11:45:02 -0600 Subject: [PATCH 0511/2410] sv: support declaration in generate for initialization This is accomplished by generating a unique name for the genvar, renaming references to the genvar only in the loop's initialization, guard, and incrementation, and finally adding a localparam inside the loop body with the original name so that the genvar can be shadowed as expected. --- frontends/verilog/verilog_parser.y | 96 +++++++++++++++++++++++++++- tests/verilog/genfor_decl_no_init.ys | 7 ++ tests/verilog/genfor_decl_no_sv.ys | 7 ++ tests/verilog/genvar_loop_decl_1.sv | 18 ++++++ tests/verilog/genvar_loop_decl_1.ys | 14 ++++ tests/verilog/genvar_loop_decl_2.sv | 30 +++++++++ tests/verilog/genvar_loop_decl_2.ys | 5 ++ tests/verilog/genvar_loop_decl_3.sv | 28 ++++++++ tests/verilog/genvar_loop_decl_3.ys | 5 ++ 9 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/genfor_decl_no_init.ys create mode 100644 tests/verilog/genfor_decl_no_sv.ys create mode 100644 tests/verilog/genvar_loop_decl_1.sv create mode 100644 tests/verilog/genvar_loop_decl_1.ys create mode 100644 tests/verilog/genvar_loop_decl_2.sv create mode 100644 tests/verilog/genvar_loop_decl_2.ys create mode 100644 tests/verilog/genvar_loop_decl_3.sv create mode 100644 tests/verilog/genvar_loop_decl_3.ys diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 23404f844b2..8d0ba4cf67a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -254,6 +254,65 @@ static void checkLabelsMatch(const char *element, const std::string *before, con element, before->c_str() + 1, after->c_str() + 1); } +// This transforms a loop like +// for (genvar i = 0; i < 10; i++) begin : blk +// to +// genvar _i; +// for (_i = 0; _i < 10; _i++) begin : blk +// localparam i = _i; +// where `_i` is actually some auto-generated name. +static void rewriteGenForDeclInit(AstNode *loop) +{ + // check if this generate for loop contains an inline declaration + log_assert(loop->type == AST_GENFOR); + AstNode *decl = loop->children[0]; + if (decl->type == AST_ASSIGN_EQ) + return; + log_assert(decl->type == AST_GENVAR); + log_assert(loop->children.size() == 5); + + // identify each component of the loop + AstNode *init = loop->children[1]; + AstNode *cond = loop->children[2]; + AstNode *incr = loop->children[3]; + AstNode *body = loop->children[4]; + log_assert(init->type == AST_ASSIGN_EQ); + log_assert(incr->type == AST_ASSIGN_EQ); + log_assert(body->type == AST_GENBLOCK); + + // create a unique name for the genvar + std::string old_str = decl->str; + std::string new_str = stringf("$genfordecl$%d$%s", autoidx++, old_str.c_str()); + + // rename and move the genvar declaration to the containing description + decl->str = new_str; + loop->children.erase(loop->children.begin()); + log_assert(current_ast_mod != nullptr); + current_ast_mod->children.push_back(decl); + + // create a new localparam with old name so that the items in the loop + // can simply use the old name and shadow it as necessary + AstNode *indirect = new AstNode(AST_LOCALPARAM); + indirect->str = old_str; + AstNode *ident = new AstNode(AST_IDENTIFIER); + ident->str = new_str; + indirect->children.push_back(ident); + + body->children.insert(body->children.begin(), indirect); + + // only perform the renaming for the initialization, guard, and + // incrementation to enable proper shadowing of the synthetic localparam + std::function substitute = [&](AstNode *node) { + if (node->type == AST_IDENTIFIER && node->str == old_str) + node->str = new_str; + for (AstNode *child : node->children) + substitute(child); + }; + substitute(init); + substitute(cond); + substitute(incr); +} + %} %define api.prefix {frontend_verilog_yy} @@ -321,6 +380,7 @@ static void checkLabelsMatch(const char *element, const std::string *before, con %type attr case_attr %type struct_union %type asgn_binop +%type genvar_identifier %type specify_target %type specify_triple specify_opt_triple @@ -2978,16 +3038,50 @@ gen_stmt_or_module_body_stmt: free_attr($1); }; +genvar_identifier: + TOK_ID { + $$ = new AstNode(AST_IDENTIFIER); + $$->str = *$1; + delete $1; + }; + +genvar_initialization: + TOK_GENVAR genvar_identifier { + frontend_verilog_yyerror("Generate for loop variable declaration is missing initialization!"); + } | + TOK_GENVAR genvar_identifier '=' expr { + if (!sv_mode) + frontend_verilog_yyerror("Generate for loop inline variable declaration is only supported in SystemVerilog mode!"); + AstNode *node = new AstNode(AST_GENVAR); + node->is_reg = true; + node->is_signed = true; + node->range_left = 31; + node->range_right = 0; + node->str = $2->str; + node->children.push_back(checkRange(node, nullptr)); + ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @4); + node = new AstNode(AST_ASSIGN_EQ, $2, $4); + ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @4); + } | + genvar_identifier '=' expr { + AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $3); + ast_stack.back()->children.push_back(node); + SET_AST_NODE_LOC(node, @1, @3); + }; + // this production creates the obligatory if-else shift/reduce conflict gen_stmt: TOK_FOR '(' { AstNode *node = new AstNode(AST_GENFOR); ast_stack.back()->children.push_back(node); ast_stack.push_back(node); - } simple_behavioral_stmt ';' expr { + } genvar_initialization ';' expr { ast_stack.back()->children.push_back($6); } ';' simple_behavioral_stmt ')' gen_stmt_block { SET_AST_NODE_LOC(ast_stack.back(), @1, @11); + rewriteGenForDeclInit(ast_stack.back()); ast_stack.pop_back(); } | TOK_IF '(' expr ')' { diff --git a/tests/verilog/genfor_decl_no_init.ys b/tests/verilog/genfor_decl_no_init.ys new file mode 100644 index 00000000000..348899195ef --- /dev/null +++ b/tests/verilog/genfor_decl_no_init.ys @@ -0,0 +1,7 @@ +logger -expect error "Generate for loop variable declaration is missing initialization!" 1 +read_verilog -sv < Date: Wed, 1 Sep 2021 00:55:51 +0000 Subject: [PATCH 0512/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4ecc98a3cc3..1c082ce28a6 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4288 +YOSYS_VER := 0.9+4290 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From c3d4bb4cc95c417225fec8b16147dec3453ab94d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Sep 2021 14:59:16 +0200 Subject: [PATCH 0513/2410] update required verific version --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1b8bc1b5124..99094f09955 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -58,7 +58,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210701 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210801 # error "Please update your version of YosysHQ flavored Verific." #endif From 50be8fd0c23856be7afa28527fe4f30dcc975c87 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 00:50:30 +0000 Subject: [PATCH 0514/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1c082ce28a6..e8fc4e32475 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4290 +YOSYS_VER := 0.9+4292 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From f03e2c30aa3ad92bffb7ecd7179fe859d1b993b0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Sep 2021 10:05:55 -0700 Subject: [PATCH 0515/2410] abc9: replace cell type/parameters if derived type already processed (#2991) * Add close bracket * Add testcase * Replace cell type/param if in unmap_design * Improve abc9_box error message too * Update comment as per review --- passes/techmap/abc9_ops.cc | 28 ++++++++++++++++++++++------ techlibs/ecp5/synth_ecp5.cc | 2 +- tests/arch/ecp5/bug2731.ys | 7 +++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/arch/ecp5/bug2731.ys diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 4b5def5eb92..c3eaa70d1c9 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -180,8 +180,16 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) continue; } else { - if (!derived_module->get_bool_attribute(ID::abc9_box) && !derived_module->get_bool_attribute(ID::abc9_bypass)) + if (!derived_module->get_bool_attribute(ID::abc9_box) && !derived_module->get_bool_attribute(ID::abc9_bypass)) { + if (unmap_design->module(derived_type)) { + // If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if + // it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties + // as a compatible type, yet will be safely unmapped later + cell->type = derived_type; + cell->parameters.clear(); + } continue; + } } if (!unmap_design->module(derived_type)) { @@ -442,7 +450,14 @@ void prep_dff(RTLIL::Design *design) if (!inst_module->get_bool_attribute(ID::abc9_flop)) continue; log_assert(!inst_module->get_blackbox_attribute(true /* ignore_wb */)); - log_assert(cell->parameters.empty()); + if (!cell->parameters.empty()) + { + // At this stage of the ABC9 flow, cells instantiating (* abc9_flop *) modules must not contain any parameters -- instead it should + // be instantiating the derived module which will have had any parameters constant-propagated. + // This task is expected to be performed by `abc9_ops -prep_hier`, but it looks like it failed to do so for this design. + // Please file a bug report! + log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_flop *)\n", log_id(cell->name), log_id(cell->type)); + } modules_sel.select(inst_module); } } @@ -783,10 +798,11 @@ void prep_xaiger(RTLIL::Module *module, bool dff) continue; if (!cell->parameters.empty()) { - // At this stage of the ABC9 flow, all modules must be nonparametric, because ABC itself requires concrete netlists, and the presence of - // parameters implies a non-concrete netlist. This means an (* abc9_box *) parametric module but due to a bug somewhere this hasn't been - // uniquified into a concrete parameter-free module. This is a bug, and a bug report would be welcomed. - log_error("Not expecting parameters on module '%s' marked (* abc9_box *)\n", log_id(cell_name)); + // At this stage of the ABC9 flow, cells instantiating (* abc9_box *) modules must not contain any parameters -- instead it should + // be instantiating the derived module which will have had any parameters constant-propagated. + // This task is expected to be performed by `abc9_ops -prep_hier`, but it looks like it failed to do so for this design. + // Please file a bug report! + log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", log_id(cell_name), log_id(cell->type)); } log_assert(box_module->get_blackbox_attribute()); diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 2df9a1f8765..dc67fc71b52 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -326,7 +326,7 @@ struct SynthEcp5Pass : public ScriptPass } run("dfflegalize" + dfflegalize_args, "($_DFFSR_*_ only if -asyncprld, $_*DFFE_* only if not -nodffe)"); if ((abc9 && dff) || help_mode) - run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff"); + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); diff --git a/tests/arch/ecp5/bug2731.ys b/tests/arch/ecp5/bug2731.ys new file mode 100644 index 00000000000..c609cea3b1f --- /dev/null +++ b/tests/arch/ecp5/bug2731.ys @@ -0,0 +1,7 @@ +read_verilog -icells < Date: Thu, 9 Sep 2021 10:06:20 -0700 Subject: [PATCH 0516/2410] abc9: holes module to instantiate cells with NEW_ID (#2992) * Add testcase * holes module to instantiate cells with NEW_ID --- passes/techmap/abc9_ops.cc | 2 +- tests/techmap/bug2759.ys | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/techmap/bug2759.ys diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index c3eaa70d1c9..a2f1dd95562 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -812,7 +812,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) auto &holes_cell = r.first->second; if (r.second) { if (box_module->get_bool_attribute(ID::whitebox)) { - holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell = holes_module->addCell(NEW_ID, cell->type); if (box_module->has_processes()) Pass::call_on_module(design, box_module, "proc"); diff --git a/tests/techmap/bug2759.ys b/tests/techmap/bug2759.ys new file mode 100644 index 00000000000..05699bef813 --- /dev/null +++ b/tests/techmap/bug2759.ys @@ -0,0 +1,14 @@ +read_verilog -specify < o) = 1; +endspecify +assign o = ^i; +endmodule + +module top(input [1:0] i, output o); +box i1(i, o); +endmodule +EOT +abc9 -lut 4 From 96b6410dcb7a82e7be8d4a2025835936f2ca84a7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 9 Sep 2021 10:06:31 -0700 Subject: [PATCH 0517/2410] abc9: make re-entrant (#2993) * Add testcase * Cleanup some state at end of abc9 * Re-assign abc9_box_id from scratch * Suppress delete unless prep_bypass did something --- passes/techmap/abc9.cc | 7 ++++++- passes/techmap/abc9_ops.cc | 11 +++-------- tests/techmap/bug2972.ys | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 tests/techmap/bug2972.ys diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 207a280fc1b..1f00fc3e7f1 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -289,8 +289,10 @@ struct Abc9Pass : public ScriptPass run("scc -specify -set_attr abc9_scc_id {}"); if (help_mode) run("abc9_ops -prep_bypass [-prep_dff]", "(option if -dff)"); - else + else { + active_design->scratchpad_unset("abc9_ops.prep_bypass.did_something"); run(stringf("abc9_ops -prep_bypass %s", dff_mode ? "-prep_dff" : "")); + } if (dff_mode) { run("design -copy-to $abc9_map @$abc9_flops", "(only if -dff)"); run("select -unset $abc9_flops", " (only if -dff)"); @@ -450,6 +452,9 @@ struct Abc9Pass : public ScriptPass run("design -delete $abc9_unmap"); if (saved_designs.count("$abc9_holes") || help_mode) run("design -delete $abc9_holes"); + if (help_mode || active_design->scratchpad_get_bool("abc9_ops.prep_bypass.did_something")) + run("delete =*_$abc9_byp"); + run("setattr -mod -unset abc9_box_id"); } } } Abc9Pass; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index a2f1dd95562..7a695997198 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -432,6 +432,8 @@ void prep_bypass(RTLIL::Design *design) } } unmap_module->fixup_ports(); + + design->scratchpad_set_bool("abc9_ops.prep_bypass.did_something", true); } } @@ -942,15 +944,8 @@ void prep_box(RTLIL::Design *design) { TimingInfo timing; - std::stringstream ss; int abc9_box_id = 1; - for (auto module : design->modules()) { - auto it = module->attributes.find(ID::abc9_box_id); - if (it == module->attributes.end()) - continue; - abc9_box_id = std::max(abc9_box_id, it->second.as_int()); - } - + std::stringstream ss; dict> box_ports; for (auto module : design->modules()) { auto it = module->attributes.find(ID::abc9_box); diff --git a/tests/techmap/bug2972.ys b/tests/techmap/bug2972.ys new file mode 100644 index 00000000000..8ae895f56b5 --- /dev/null +++ b/tests/techmap/bug2972.ys @@ -0,0 +1,20 @@ +read_verilog -specify < (q : d)) = 1; + (d => do) = 1; +endspecify +endmodule + +module top(input clk, d, output q); +box i1(clk, d, q); +endmodule +EOT +hierarchy +abc9 -lut 4 +abc9 -lut 4 From 1d61a911b7a47a557796b48ca920e40c903071f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 00:55:14 +0000 Subject: [PATCH 0518/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e8fc4e32475..5b08dc745d3 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4292 +YOSYS_VER := 0.9+4296 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 33749f1e3aea0d0ee4d1b5b29eb00f3e4f4bae41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 10 Sep 2021 04:55:48 +0200 Subject: [PATCH 0519/2410] yosys-smtbmc: Fix reused loop variable. Fixes #2999. --- backends/smt2/smtbmc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index be27a3d097c..e5cfcdc08a4 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -771,12 +771,12 @@ def write_vcd_trace(steps_start, steps_stop, index): if gotread: buf = data[:] - for i in reversed(range(len(tdata))): + for ii in reversed(range(len(tdata))): for k in range(width): - if tdata[i][k] == "x": - tdata[i][k] = buf[k] + if tdata[ii][k] == "x": + tdata[ii][k] = buf[k] else: - buf[k] = tdata[i][k] + buf[k] = tdata[ii][k] if not asyncwr: tdata.append(data[:]) From 4708907be8249d93a2aefbb36e4420a8b2054df3 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Fri, 10 Sep 2021 16:51:34 +0200 Subject: [PATCH 0520/2410] Add additional check to SigSpec Signed-off-by: Claire Xenia Wolf --- kernel/rtlil.cc | 16 ++++++++++++---- kernel/rtlil.h | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 40b9b761aa2..a05023c5293 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1753,7 +1753,7 @@ void RTLIL::Module::check() log_assert(!it.second->type.empty()); for (auto &it2 : it.second->connections()) { log_assert(!it2.first.empty()); - it2.second.check(); + it2.second.check(this); } for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); @@ -1799,8 +1799,8 @@ void RTLIL::Module::check() for (auto &it : connections_) { log_assert(it.first.size() == it.second.size()); log_assert(!it.first.has_const()); - it.first.check(); - it.second.check(); + it.first.check(this); + it.second.check(this); } for (auto &it : attributes) @@ -4130,7 +4130,7 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const } #ifndef NDEBUG -void RTLIL::SigSpec::check() const +void RTLIL::SigSpec::check(Module *mod) const { if (width_ > 64) { @@ -4156,6 +4156,8 @@ void RTLIL::SigSpec::check() const log_assert(chunk.width >= 0); log_assert(chunk.offset + chunk.width <= chunk.wire->width); log_assert(chunk.data.size() == 0); + if (mod != nullptr) + log_assert(chunk.wire->module == mod); } w += chunk.width; } @@ -4166,6 +4168,12 @@ void RTLIL::SigSpec::check() const { cover("kernel.rtlil.sigspec.check.unpacked"); + if (mod != nullptr) { + for (size_t i = 0; i < bits_.size(); i++) + if (bits_[i].wire != nullptr) + log_assert(bits_[i].wire->module == mod); + } + log_assert(width_ == GetSize(bits_)); log_assert(chunks_.empty()); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 50707c0aee4..06198b26a6d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -965,9 +965,9 @@ struct RTLIL::SigSpec unsigned int hash() const { if (!hash_) updhash(); return hash_; }; #ifndef NDEBUG - void check() const; + void check(Module *mod = nullptr) const; #else - void check() const { } + void check(Module *mod = nullptr) const { } #endif }; From f44110c62561b21fa673f44d8e115c3ee70d2900 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Sep 2021 00:50:11 +0000 Subject: [PATCH 0521/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5b08dc745d3..7298a2bfbe7 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4296 +YOSYS_VER := 0.9+4300 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1d52c07e9b2365de47d5fcbb7cac909a0d40e98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Mon, 13 Sep 2021 16:25:42 +0200 Subject: [PATCH 0522/2410] Updates for CHANGELOG (#2997) Added missing changes from git log and group items --- CHANGELOG | 174 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 48 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 713ae1b50ae..dade2f0e93d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,75 +7,153 @@ Yosys 0.9 .. Yosys 0.9-dev -------------------------- * Various + - Added automatic gzip decompression for frontends + - Added $_NMUX_ cell type + - 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]* + - Improvements in pmgen: subpattern and recursive matches + - Support explicit FIRRTL properties + - Improvements in pmgen: slices, choices, define, generate + - Added "_TECHMAP_WIREINIT_*_" parameter and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass + - Added +/mul2dsp.v for decomposing wide multipliers to custom-sized ones + - Added new frontend: rpc + - Added --version and -version as aliases for -V + - Improve yosys-smtbmc "solver not found" handling + - Improved support of $readmem[hb] Memory Content File inclusion + - Added CXXRTL backend + - Use YosysHQ/abc instead of upstream berkeley-abc/abc + - Added WASI platform support. + - Added extmodule support to firrtl backend + - Added $divfloor and $modfloor cells + - Added $adffe, $dffsre, $sdff, $sdffe, $sdffce, $adlatch cells + - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass + - Added firrtl backend support for generic parameters in blackbox components + - Added $meminit_v2 cells (with support for write mask) + - Added $mem_v2, $memrd_v2, $memwr_v2, with the following features: + - write priority masks, per write/write port pair + - transparency and undefined collision behavior masks, per read/write port pair + - read port reset and initialization + - wide ports (accessing a naturally aligned power-of-two number of memory cells) + + * New commands and options - Added "write_xaiger" backend + - Added "read_xaiger" - Added "abc9" pass for timing-aware techmapping (experimental, FPGA only) - - Added "synth_xilinx -abc9" (experimental) - - Added "synth_ice40 -abc9" (experimental) - Added "synth -abc9" (experimental) - Added "script -scriptwire" + - Added "clkbufmap" pass + - Added "extractinv" pass and "invertible_pin" attribute + - Added "proc_clean -quiet" + - Added "proc_prune" pass + - Added "stat -tech cmos" + - Added "opt_share" pass, run as part of "opt -full" + - Added "-match-init" option to "dff2dffs" pass + - Added "equiv_opt -multiclock" + - Added "techmap_autopurge" support to techmap + - Added "add -mod " + - Added "paramap" pass + - Added "portlist" command + - Added "check -mapped" + - Added "check -allow-tbuf" + - Added "autoname" pass + - Added "write_verilog -extmem" + - Added "opt_mem" pass + - Added "scratchpad" pass + - Added "fminit" pass + - Added "opt_lut_ins" pass + - Added "logger" pass + - Added "show -nobg" + - Added "exec" command + - Added "design -delete" + - Added "design -push-copy" + - Added "qbfsat" command + - Added "select -unset" + - Added "dfflegalize" pass + - Removed "opt_expr -clkinv" option, made it the default + - Added "proc -nomux + - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass + + * SystemVerilog + - Added checking of always block types (always_comb, always_latch and always_ff) + - Added support for wildcard port connections (.*) + - Added support for enum typedefs + - Added support for structs and packed unions. + - Allow constant function calls in for loops and generate if and case + - Added support for static cast + - Added support for logic typed parameters + - Fixed generate scoping issues + - Added support for real-valued parameters + - Allow localparams in constant functions + - Module name scope support + - Support recursive functions using ternary expressions + - Extended support for integer types + - Support for parameters without default values + - Allow globals in one file to depend on globals in another + - Added support for: *=, /=, %=, <<=, >>=, <<<=, >>>= + - Added support for parsing the 'bind' construct + - support declaration in procedural for initialization + - support declaration in generate for initialization + + * Verific support + - Added "verific -L" + - Add Verific SVA support for "always" properties + - Add Verific support for SVA nexttime properties + - Improve handling of verific primitives in "verific -import -V" mode + - Import attributes for wires + - Support VHDL enums + - Added support for command files + + * New back-ends + - Added initial EFINIX support + - Added Intel ALM: alternative synthesis for Intel FPGAs + - Added initial Nexus support + - Added initial MachXO2 support + - Added initial QuickLogic PolarPro 3 support + + * ECP5 support + - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Added "synth_ecp5 -abc9" (experimental) + - Added "synth_ecp5 -nowidelut" + - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) + + * iCE40 support + - Added "synth_ice40 -abc9" (experimental) + - Added "synth_ice40 -device" + - Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping + - Removed "ice40_unlut" + - Added "ice40_dsp" for Lattice iCE40 DSP packing + - "synth_ice40 -dsp" to infer DSP blocks + + * Xilinx support + - Added "synth_xilinx -abc9" (experimental) - Added "synth_xilinx -nocarry" - Added "synth_xilinx -nowidelut" - - Added "synth_ecp5 -nowidelut" - "synth_xilinx" to now infer wide multiplexers (-widemux to enable) - - Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels in synth_intel (e.g. bram -> map_bram) - Renamed labels/options in synth_xilinx (e.g. dram -> map_lutram; -nodram -> -nolutram) - - Added automatic gzip decompression for frontends - - Added $_NMUX_ cell type - - 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 "clkbufmap" pass - - Added "extractinv" pass and "invertible_pin" attribute - Added "synth_xilinx -family xc6s" for Spartan 6 support (experimental) - Added "synth_xilinx -ise" (experimental) - Added "synth_xilinx -iopad" - "synth_xilinx" now automatically inserts clock buffers (add -noclkbuf to disable) - - Improvements in pmgen: subpattern and recursive matches - - Added "opt_share" pass, run as part of "opt -full" - - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping - - Removed "ice40_unlut" - - Improvements in pmgen: slices, choices, define, generate - Added "xilinx_srl" for Xilinx shift register extraction - Removed "shregmap -tech xilinx" (superseded by "xilinx_srl") - - Added "_TECHMAP_WIREINIT_*_" parameter and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass - - Added "-match-init" option to "dff2dffs" pass - - Added "techmap_autopurge" support to techmap - - Added "add -mod " - - Added +/mul2dsp.v for decomposing wide multipliers to custom-sized ones - - Added "ice40_dsp" for Lattice iCE40 DSP packing - Added "xilinx_dsp" for Xilinx DSP packing - "synth_xilinx" to now infer DSP blocks (-nodsp to disable) - - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) - - "synth_ice40 -dsp" to infer DSP blocks - Added latch support to synth_xilinx - Added support for flip-flops with synchronous reset to synth_xilinx - Added support for flip-flops with reset and enable to synth_xilinx - - Added "check -mapped" - - Added checking of SystemVerilog always block types (always_comb, - always_latch and always_ff) - - Added support for SystemVerilog wildcard port connections (.*) - Added "xilinx_dffopt" pass - - Added "scratchpad" pass - Added "synth_xilinx -dff" - - Improved support of $readmem[hb] Memory Content File inclusion - - Added "opt_lut_ins" pass - - Added "logger" pass - - Added "design -delete" - - Added "select -unset" - - Use YosysHQ/abc instead of upstream berkeley-abc/abc - - Added $divfloor and $modfloor cells - - Added $adffe, $dffsre, $sdff, $sdffe, $sdffce, $adlatch cells - - Added "dfflegalize" pass - - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass - - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass - - Added $meminit_v2 cells (with support for write mask) - - Added $mem_v2, $memrd_v2, $memwr_v2, with the following features: - - write priority masks, per write/write port pair - - transparency and undefined collision behavior masks, per read/write port pair - - read port reset and initialization - - wide ports (accessing a naturally aligned power-of-two number of memory cells) + + * Intel support + - Renamed labels in synth_intel (e.g. bram -> map_bram) + - synth_intel: cyclone10 -> cyclone10lp, a10gx -> arria10gx + - Added "intel_alm -abc9" (experimental) + + * CoolRunner2 support + - Separate and improve buffer cell insertion pass + - Use extract_counter to optimize counters Yosys 0.8 .. Yosys 0.9 ---------------------- From 551ef85cd74c0d984322990b462a7835c7023dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 13 Sep 2021 15:38:54 +0200 Subject: [PATCH 0523/2410] verilog: Squash flex-triggered warning. --- frontends/verilog/verilog_lexer.l | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 0306f5494b3..89c1aa89529 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -37,6 +37,8 @@ #ifdef __clang__ // bison generates code using the 'register' storage class specifier #pragma clang diagnostic ignored "-Wdeprecated-register" +// flex generates weirdly-indented code +#pragma clang diagnostic ignored "-Wmisleading-indentation" #endif #include "kernel/log.h" From c88eaea6e02337409c13237d81834972d0851d01 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 00:56:06 +0000 Subject: [PATCH 0524/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7298a2bfbe7..9afe458fc89 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4300 +YOSYS_VER := 0.9+4303 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From c25122e33993b6634280bd1babef4b329c112921 Mon Sep 17 00:00:00 2001 From: the6p4c Date: Fri, 17 Sep 2021 13:36:37 +1000 Subject: [PATCH 0525/2410] Fix protobuf backend build dependencies backends/protobuf/protobuf.cc depends on the source and header files generated by protoc, but this dependency wasn't explicitly declared. Add a rule to the Makefile to fix intermittent build failures when the protobuf header/source file isn't built before protobuf.cc. --- backends/protobuf/Makefile.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/protobuf/Makefile.inc b/backends/protobuf/Makefile.inc index 834cad42cde..9cac9dcaa2e 100644 --- a/backends/protobuf/Makefile.inc +++ b/backends/protobuf/Makefile.inc @@ -3,6 +3,8 @@ ifeq ($(ENABLE_PROTOBUF),1) backends/protobuf/yosys.pb.cc backends/protobuf/yosys.pb.h: misc/yosys.proto $(Q) cd misc && protoc --cpp_out "../backends/protobuf" yosys.proto +backends/protobuf/protobuf.cc: backends/protobuf/yosys.pb.h + OBJS += backends/protobuf/protobuf.o backends/protobuf/yosys.pb.o endif From 1362ad0bf86226d1a8a44a3dc26e8ae3c17037dc Mon Sep 17 00:00:00 2001 From: Daniel Huisman Date: Sat, 18 Sep 2021 16:24:40 +0200 Subject: [PATCH 0526/2410] Update WaveDrom script URLs --- misc/yosysjs/demo03.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/yosysjs/demo03.html b/misc/yosysjs/demo03.html index 3dc465cbff4..c2ca40ef5d1 100644 --- a/misc/yosysjs/demo03.html +++ b/misc/yosysjs/demo03.html @@ -1,8 +1,8 @@ YosysJS Example Application #02 - - + + From 3931b3a03f65965daca20b1228d8882192e74650 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 19 Sep 2021 00:52:56 +0000 Subject: [PATCH 0527/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9afe458fc89..7ef98d39392 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4303 +YOSYS_VER := 0.9+4306 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 6b7267b849abf7688938e5e53ae7017e8588ff18 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 2 Aug 2021 18:42:34 -0600 Subject: [PATCH 0528/2410] verilog: fix multiple AST_PREFIX scope resolution issues - Root AST_PREFIX nodes are now subject to genblk expansion to allow them to refer to a locally-visible generate block - Part selects on AST_PREFIX member leafs can now refer to generate block items (previously would not resolve and raise an error) - Add source location information to AST_PREFIX nodes --- frontends/ast/simplify.cc | 13 ++-- frontends/verilog/verilog_parser.y | 1 + tests/verilog/prefix.sv | 95 ++++++++++++++++++++++++++++++ tests/verilog/prefix.ys | 5 ++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 tests/verilog/prefix.sv create mode 100644 tests/verilog/prefix.ys diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index f713cf8e119..607ca9a8b73 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -4045,7 +4045,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m // prefix is carried forward, but resolution of their children is deferred void AstNode::expand_genblock(const std::string &prefix) { - if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) { + if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE || type == AST_PREFIX) { log_assert(!str.empty()); // search starting in the innermost scope and then stepping outward @@ -4131,10 +4131,15 @@ void AstNode::expand_genblock(const std::string &prefix) for (size_t i = 0; i < children.size(); i++) { AstNode *child = children[i]; - // AST_PREFIX member names should not be prefixed; a nested AST_PREFIX - // still needs to recursed-into - if (type == AST_PREFIX && i == 1 && child->type == AST_IDENTIFIER) + // AST_PREFIX member names should not be prefixed; we recurse into them + // as normal to ensure indices and ranges are properly resolved, and + // then restore the previous string + if (type == AST_PREFIX && i == 1) { + std::string backup_scope_name = child->str; + child->expand_genblock(prefix); + child->str = backup_scope_name; continue; + } // functions/tasks may reference wires, constants, etc. in this scope if (child->type == AST_FUNCTION || child->type == AST_TASK) continue; diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 8d0ba4cf67a..91b1140e9e2 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2973,6 +2973,7 @@ rvalue: hierarchical_id '[' expr ']' '.' rvalue { $$ = new AstNode(AST_PREFIX, $3, $6); $$->str = *$1; + SET_AST_NODE_LOC($$, @1, @6); delete $1; } | hierarchical_id range { diff --git a/tests/verilog/prefix.sv b/tests/verilog/prefix.sv new file mode 100644 index 00000000000..2d7fbb13447 --- /dev/null +++ b/tests/verilog/prefix.sv @@ -0,0 +1,95 @@ +module top; + genvar i, j; + if (1) begin : blk1 + integer a = 1; + for (i = 0; i < 2; i = i + 1) begin : blk2 + integer b = i; + for (j = 0; j < 2; j = j + 1) begin : blk3 + integer c = j; + localparam x = i; + localparam y = j; + always @* begin + assert (1 == a); + assert (1 == blk1.a); + assert (1 == top.blk1.a); + assert (i == b); + assert (i == blk2[i].b); + assert (i == blk1.blk2[i].b); + assert (i == top.blk1.blk2[i].b); + assert (i == blk2[x].b); + assert (i == blk1.blk2[x].b); + assert (i == top.blk1.blk2[x].b); + assert (j == c); + assert (j == blk3[j].c); + assert (j == blk2[x].blk3[j].c); + assert (j == blk1.blk2[x].blk3[j].c); + assert (j == top.blk1.blk2[x].blk3[j].c); + assert (j == c); + assert (j == blk3[y].c); + assert (j == blk2[x].blk3[y].c); + assert (j == blk1.blk2[x].blk3[y].c); + assert (j == top.blk1.blk2[x].blk3[y].c); + assert (j == top.blk1.blk2[x].blk3[y].c[0]); + assert (0 == top.blk1.blk2[x].blk3[y].c[1]); + assert (0 == top.blk1.blk2[x].blk3[y].c[j]); + end + end + always @* begin + assert (1 == a); + assert (1 == blk1.a); + assert (1 == top.blk1.a); + assert (i == b); + assert (i == blk2[i].b); + assert (i == blk1.blk2[i].b); + assert (i == top.blk1.blk2[i].b); + assert (0 == blk3[0].c); + assert (0 == blk2[i].blk3[0].c); + assert (0 == blk1.blk2[i].blk3[0].c); + assert (0 == top.blk1.blk2[i].blk3[0].c); + assert (1 == blk3[1].c); + assert (1 == blk2[i].blk3[1].c); + assert (1 == blk1.blk2[i].blk3[1].c); + assert (1 == top.blk1.blk2[i].blk3[1].c); + end + end + always @* begin + assert (1 == a); + assert (1 == blk1.a); + assert (1 == top.blk1.a); + assert (0 == blk2[0].b); + assert (0 == blk1.blk2[0].b); + assert (0 == top.blk1.blk2[0].b); + assert (1 == blk2[1].b); + assert (1 == blk1.blk2[1].b); + assert (1 == top.blk1.blk2[1].b); + assert (0 == blk2[0].blk3[0].c); + assert (0 == blk1.blk2[0].blk3[0].c); + assert (0 == top.blk1.blk2[0].blk3[0].c); + assert (1 == blk2[0].blk3[1].c); + assert (1 == blk1.blk2[0].blk3[1].c); + assert (1 == top.blk1.blk2[0].blk3[1].c); + assert (0 == blk2[1].blk3[0].c); + assert (0 == blk1.blk2[1].blk3[0].c); + assert (0 == top.blk1.blk2[1].blk3[0].c); + assert (1 == blk2[1].blk3[1].c); + assert (1 == blk1.blk2[1].blk3[1].c); + assert (1 == top.blk1.blk2[1].blk3[1].c); + end + end + always @* begin + assert (1 == blk1.a); + assert (1 == top.blk1.a); + assert (0 == blk1.blk2[0].b); + assert (0 == top.blk1.blk2[0].b); + assert (1 == blk1.blk2[1].b); + assert (1 == top.blk1.blk2[1].b); + assert (0 == blk1.blk2[0].blk3[0].c); + assert (0 == top.blk1.blk2[0].blk3[0].c); + assert (1 == blk1.blk2[0].blk3[1].c); + assert (1 == top.blk1.blk2[0].blk3[1].c); + assert (0 == blk1.blk2[1].blk3[0].c); + assert (0 == top.blk1.blk2[1].blk3[0].c); + assert (1 == blk1.blk2[1].blk3[1].c); + assert (1 == top.blk1.blk2[1].blk3[1].c); + end +endmodule diff --git a/tests/verilog/prefix.ys b/tests/verilog/prefix.ys new file mode 100644 index 00000000000..ed3b3a111a6 --- /dev/null +++ b/tests/verilog/prefix.ys @@ -0,0 +1,5 @@ +read_verilog -sv prefix.sv +hierarchy +proc +select -module top +sat -verify -seq 1 -prove-asserts -show-all From d6fe6d4fb62be3bb5ec876f1f56356d757b65a41 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 13 Aug 2021 20:51:28 -0700 Subject: [PATCH 0529/2410] sv: support wand and wor of data types This enables the usage of declarations of wand or wor with a base type of logic, integer, or a typename. Note that declarations of nets with 2-state base types is still permitted, in violation of the spec. --- CHANGELOG | 3 ++- frontends/verilog/verilog_parser.y | 21 ++++++++++-------- tests/verilog/net_types.sv | 34 ++++++++++++++++++++++++++++++ tests/verilog/net_types.ys | 5 +++++ 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 tests/verilog/net_types.sv create mode 100644 tests/verilog/net_types.ys diff --git a/CHANGELOG b/CHANGELOG index dade2f0e93d..ab41d689d6b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,7 +56,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "portlist" command - Added "check -mapped" - Added "check -allow-tbuf" - - Added "autoname" pass + - Added "autoname" pass - Added "write_verilog -extmem" - Added "opt_mem" pass - Added "scratchpad" pass @@ -94,6 +94,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added support for parsing the 'bind' construct - support declaration in procedural for initialization - support declaration in generate for initialization + - Support wand and wor of data types * Verific support - Added "verific -L" diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 91b1140e9e2..80b40f9826f 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -832,16 +832,10 @@ opt_wire_type_token: wire_type_token | %empty; wire_type_token: - TOK_WOR { - astbuf3->is_wor = true; + // nets + net_type { } | - TOK_WAND { - astbuf3->is_wand = true; - } | - // wires - TOK_WIRE { - } | - TOK_WIRE logic_type { + net_type logic_type { } | // regs TOK_REG { @@ -868,6 +862,15 @@ wire_type_token: astbuf3->range_right = 0; }; +net_type: + TOK_WOR { + astbuf3->is_wor = true; + } | + TOK_WAND { + astbuf3->is_wand = true; + } | + TOK_WIRE; + logic_type: TOK_LOGIC { } | diff --git a/tests/verilog/net_types.sv b/tests/verilog/net_types.sv new file mode 100644 index 00000000000..7226a7ee5eb --- /dev/null +++ b/tests/verilog/net_types.sv @@ -0,0 +1,34 @@ +module top; + wire logic wire_logic_0; assign wire_logic_0 = 0; + wire logic wire_logic_1; assign wire_logic_1 = 1; + wand logic wand_logic_0; assign wand_logic_0 = 0; assign wand_logic_0 = 1; + wand logic wand_logic_1; assign wand_logic_1 = 1; assign wand_logic_1 = 1; + wor logic wor_logic_0; assign wor_logic_0 = 0; assign wor_logic_0 = 0; + wor logic wor_logic_1; assign wor_logic_1 = 1; assign wor_logic_1 = 0; + + wire integer wire_integer; assign wire_integer = 4'b1001; + wand integer wand_integer; assign wand_integer = 4'b1001; assign wand_integer = 4'b1010; + wor integer wor_integer; assign wor_integer = 4'b1001; assign wor_integer = 4'b1010; + + typedef logic [3:0] typename; + wire typename wire_typename; assign wire_typename = 4'b1001; + wand typename wand_typename; assign wand_typename = 4'b1001; assign wand_typename = 4'b1010; + wor typename wor_typename; assign wor_typename = 4'b1001; assign wor_typename = 4'b1010; + + always @* begin + assert (wire_logic_0 == 0); + assert (wire_logic_1 == 1); + assert (wand_logic_0 == 0); + assert (wand_logic_1 == 1); + assert (wor_logic_0 == 0); + assert (wor_logic_1 == 1); + + assert (wire_integer == 4'b1001); + assert (wand_integer == 4'b1000); + assert (wor_integer == 4'b1011); + + assert (wire_typename == 4'b1001); + assert (wand_typename == 4'b1000); + assert (wor_typename == 4'b1011); + end +endmodule diff --git a/tests/verilog/net_types.ys b/tests/verilog/net_types.ys new file mode 100644 index 00000000000..9f75812ea4a --- /dev/null +++ b/tests/verilog/net_types.ys @@ -0,0 +1,5 @@ +read_verilog -sv net_types.sv +hierarchy +proc +opt -full +sat -verify -prove-asserts -show-all From 9432400ec8e24646a2a7a789574a20d038fef79a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Sep 2021 00:54:54 +0000 Subject: [PATCH 0530/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7ef98d39392..60ab2ccc273 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4306 +YOSYS_VER := 0.9+4309 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 15fb0107dcdfcf98c56f229727c7cd701ff9b4b3 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Wed, 22 Sep 2021 17:34:20 +0200 Subject: [PATCH 0531/2410] Fix "make vgtest" so it runs to the end (but now it fails ;) Signed-off-by: Claire Xenia Wolf --- tests/simple/attrib01_module.v | 6 ++--- tests/simple/attrib02_port_decl.v | 6 ++--- tests/simple/attrib03_parameter.v | 6 ++--- tests/simple/attrib04_net_var.v | 6 ++--- tests/simple/attrib05_port_conn.v.DISABLED | 6 ++--- tests/simple/attrib06_operator_suffix.v | 6 ++--- tests/simple/attrib07_func_call.v.DISABLED | 6 ++--- tests/simple/attrib08_mod_inst.v | 6 ++--- tests/simple/attrib09_case.v | 6 ++--- tests/simple/case_expr_const.v | 2 +- tests/simple/case_expr_non_const.v | 2 +- tests/simple/case_large.v | 2 +- tests/simple/const_branch_finish.v | 2 +- tests/simple/const_fold_func.v | 2 +- tests/simple/const_func_shadow.v | 2 +- tests/simple/defvalue.sv | 2 +- tests/simple/func_block.v | 2 +- tests/simple/func_recurse.v | 2 +- tests/simple/func_width_scope.v | 2 +- tests/simple/genblk_collide.v | 4 ++-- tests/simple/genblk_dive.v | 2 +- tests/simple/genblk_order.v | 2 +- tests/simple/genblk_port_shadow.v | 2 +- tests/simple/hierarchy.v | 2 +- tests/simple/ifdef_1.v | 2 +- tests/simple/ifdef_2.v | 2 +- tests/simple/local_loop_var.sv | 2 +- tests/simple/loop_prefix_case.v | 2 +- tests/simple/loop_var_shadow.v | 2 +- tests/simple/macro_arg_spaces.sv | 2 +- tests/simple/macro_arg_surrounding_spaces.v | 2 +- tests/simple/matching_end_labels.sv | 2 +- tests/simple/mem2reg_bounds_tern.v | 2 +- tests/simple/module_scope.v | 26 ++++++++++----------- tests/simple/module_scope_case.v | 8 +++---- tests/simple/named_genblk.v | 2 +- tests/simple/nested_genblk_resolve.v | 2 +- tests/simple/string_format.v | 2 +- tests/simple/unnamed_block_decl.sv | 2 +- tests/simple/wandwor.v | 12 +++++----- 40 files changed, 79 insertions(+), 79 deletions(-) diff --git a/tests/simple/attrib01_module.v b/tests/simple/attrib01_module.v index adef34f5b76..d6e36fb8024 100644 --- a/tests/simple/attrib01_module.v +++ b/tests/simple/attrib01_module.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib01_bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; @@ -10,12 +10,12 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib01_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; - bar bar_instance (clk, rst, inp, out); + attrib01_bar bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/attrib02_port_decl.v b/tests/simple/attrib02_port_decl.v index 3505e726535..989213b773a 100644 --- a/tests/simple/attrib02_port_decl.v +++ b/tests/simple/attrib02_port_decl.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib02_bar(clk, rst, inp, out); (* this_is_clock = 1 *) input wire clk; (* this_is_reset = 1 *) @@ -13,13 +13,13 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib02_foo(clk, rst, inp, out); (* this_is_the_master_clock *) input wire clk; input wire rst; input wire inp; output wire out; - bar bar_instance (clk, rst, inp, out); + attrib02_bar bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/attrib03_parameter.v b/tests/simple/attrib03_parameter.v index 562d225cd5b..d2ae989787b 100644 --- a/tests/simple/attrib03_parameter.v +++ b/tests/simple/attrib03_parameter.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib03_bar(clk, rst, inp, out); (* bus_width *) parameter WIDTH = 2; @@ -17,12 +17,12 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib03_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire [7:0] inp; output wire [7:0] out; - bar # (.WIDTH(8)) bar_instance (clk, rst, inp, out); + attrib03_bar # (.WIDTH(8)) bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/attrib04_net_var.v b/tests/simple/attrib04_net_var.v index 8b552340651..98826e971cb 100644 --- a/tests/simple/attrib04_net_var.v +++ b/tests/simple/attrib04_net_var.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib04_bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; @@ -21,12 +21,12 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib04_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; - bar bar_instance (clk, rst, inp, out); + attrib04_bar bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/attrib05_port_conn.v.DISABLED b/tests/simple/attrib05_port_conn.v.DISABLED index e20e6631950..8cc471f4e7c 100644 --- a/tests/simple/attrib05_port_conn.v.DISABLED +++ b/tests/simple/attrib05_port_conn.v.DISABLED @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib05_bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; @@ -10,12 +10,12 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib05_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; - bar bar_instance ( (* clock_connected *) clk, rst, (* this_is_the_input *) inp, out); + attrib05_bar bar_instance ( (* clock_connected *) clk, rst, (* this_is_the_input *) inp, out); endmodule diff --git a/tests/simple/attrib06_operator_suffix.v b/tests/simple/attrib06_operator_suffix.v index e21173c58f4..2bc136f9a29 100644 --- a/tests/simple/attrib06_operator_suffix.v +++ b/tests/simple/attrib06_operator_suffix.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp_a, inp_b, out); +module attrib06_bar(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; @@ -11,13 +11,13 @@ module bar(clk, rst, inp_a, inp_b, out); endmodule -module foo(clk, rst, inp_a, inp_b, out); +module attrib06_foo(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; input wire [7:0] inp_b; output wire [7:0] out; - bar bar_instance (clk, rst, inp_a, inp_b, out); + attrib06_bar bar_instance (clk, rst, inp_a, inp_b, out); endmodule diff --git a/tests/simple/attrib07_func_call.v.DISABLED b/tests/simple/attrib07_func_call.v.DISABLED index f55ef231609..282fc5da783 100644 --- a/tests/simple/attrib07_func_call.v.DISABLED +++ b/tests/simple/attrib07_func_call.v.DISABLED @@ -1,4 +1,4 @@ -function [7:0] do_add; +function [7:0] attrib07_do_add; input [7:0] inp_a; input [7:0] inp_b; @@ -6,7 +6,7 @@ function [7:0] do_add; endfunction -module foo(clk, rst, inp_a, inp_b, out); +module attri07_foo(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; @@ -15,7 +15,7 @@ module foo(clk, rst, inp_a, inp_b, out); always @(posedge clk) if (rst) out <= 0; - else out <= do_add (* combinational_adder *) (inp_a, inp_b); + else out <= attrib07_do_add (* combinational_adder *) (inp_a, inp_b); endmodule diff --git a/tests/simple/attrib08_mod_inst.v b/tests/simple/attrib08_mod_inst.v index c5a32234eed..759e67c7bb0 100644 --- a/tests/simple/attrib08_mod_inst.v +++ b/tests/simple/attrib08_mod_inst.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib08_bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; @@ -10,13 +10,13 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib08_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; (* my_module_instance = 99 *) - bar bar_instance (clk, rst, inp, out); + attrib08_bar bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/attrib09_case.v b/tests/simple/attrib09_case.v index 8551bf9d0a4..a72b81ddab4 100644 --- a/tests/simple/attrib09_case.v +++ b/tests/simple/attrib09_case.v @@ -1,4 +1,4 @@ -module bar(clk, rst, inp, out); +module attrib09_bar(clk, rst, inp, out); input wire clk; input wire rst; input wire [1:0] inp; @@ -15,12 +15,12 @@ module bar(clk, rst, inp, out); endmodule -module foo(clk, rst, inp, out); +module attrib09_foo(clk, rst, inp, out); input wire clk; input wire rst; input wire [1:0] inp; output wire [1:0] out; - bar bar_instance (clk, rst, inp, out); + attrib09_bar bar_instance (clk, rst, inp, out); endmodule diff --git a/tests/simple/case_expr_const.v b/tests/simple/case_expr_const.v index 58267b965e8..d9169c084c4 100644 --- a/tests/simple/case_expr_const.v +++ b/tests/simple/case_expr_const.v @@ -1,6 +1,6 @@ // Note: case_expr_{,non_}const.v should be modified in tandem to ensure both // the constant and non-constant case evaluation logic is covered -module top( +module case_expr_const_top( // expected to output all 1s output reg a, b, c, d, e, f, g, h ); diff --git a/tests/simple/case_expr_non_const.v b/tests/simple/case_expr_non_const.v index 7856e781c27..6dfc2e54eff 100644 --- a/tests/simple/case_expr_non_const.v +++ b/tests/simple/case_expr_non_const.v @@ -1,6 +1,6 @@ // Note: case_expr_{,non_}const.v should be modified in tandem to ensure both // the constant and non-constant case evaluation logic is covered -module top( +module case_expr_non_const_top( // expected to output all 1s output reg a, b, c, d, e, f, g, h ); diff --git a/tests/simple/case_large.v b/tests/simple/case_large.v index a96ce86fe4e..ec8ed603868 100644 --- a/tests/simple/case_large.v +++ b/tests/simple/case_large.v @@ -1,4 +1,4 @@ -module top ( +module case_lage_top ( input wire [127:0] x, output reg [31:0] y ); diff --git a/tests/simple/const_branch_finish.v b/tests/simple/const_branch_finish.v index f585be87a97..7e365eeb411 100644 --- a/tests/simple/const_branch_finish.v +++ b/tests/simple/const_branch_finish.v @@ -4,7 +4,7 @@ $finish; \ end -module top; +module case_branch_finish_top; parameter WIDTH = 32; integer j; initial begin diff --git a/tests/simple/const_fold_func.v b/tests/simple/const_fold_func.v index ee2f12e0689..b3f476ce3fc 100644 --- a/tests/simple/const_fold_func.v +++ b/tests/simple/const_fold_func.v @@ -1,4 +1,4 @@ -module top( +module const_fold_func_top( input wire [3:0] inp, output wire [3:0] out1, out2, out3, out4, out5, output reg [3:0] out6 diff --git a/tests/simple/const_func_shadow.v b/tests/simple/const_func_shadow.v index ca63606d95d..fb4f148f6e2 100644 --- a/tests/simple/const_func_shadow.v +++ b/tests/simple/const_func_shadow.v @@ -1,4 +1,4 @@ -module top(w, x, y, z); +module const_func_shadow_top(w, x, y, z); function [11:0] func; input reg [2:0] x; input reg [2:0] y; diff --git a/tests/simple/defvalue.sv b/tests/simple/defvalue.sv index b0a087ecbf0..77d7ba26be5 100644 --- a/tests/simple/defvalue.sv +++ b/tests/simple/defvalue.sv @@ -1,4 +1,4 @@ -module top(input clock, input [3:0] delta, output [3:0] cnt1, cnt2); +module defvalue_top(input clock, input [3:0] delta, output [3:0] cnt1, cnt2); cnt #(1) foo (.clock, .cnt(cnt1), .delta); cnt #(2) bar (.clock, .cnt(cnt2)); endmodule diff --git a/tests/simple/func_block.v b/tests/simple/func_block.v index be759d1a95e..0ac7ca3bf52 100644 --- a/tests/simple/func_block.v +++ b/tests/simple/func_block.v @@ -1,6 +1,6 @@ `default_nettype none -module top(inp, out1, out2, out3); +module func_block_top(inp, out1, out2, out3); input wire [31:0] inp; function automatic [31:0] func1; diff --git a/tests/simple/func_recurse.v b/tests/simple/func_recurse.v index d61c8cc06fc..02cfbcddf55 100644 --- a/tests/simple/func_recurse.v +++ b/tests/simple/func_recurse.v @@ -1,4 +1,4 @@ -module top( +module func_recurse_top( input wire [3:0] inp, output wire [3:0] out1, out2 ); diff --git a/tests/simple/func_width_scope.v b/tests/simple/func_width_scope.v index ce81e894e96..2f82988ae1d 100644 --- a/tests/simple/func_width_scope.v +++ b/tests/simple/func_width_scope.v @@ -1,4 +1,4 @@ -module top(inp, out1, out2); +module func_width_scope_top(inp, out1, out2); input wire signed inp; localparam WIDTH_A = 5; diff --git a/tests/simple/genblk_collide.v b/tests/simple/genblk_collide.v index f42dd2cfc7b..118c0b008fb 100644 --- a/tests/simple/genblk_collide.v +++ b/tests/simple/genblk_collide.v @@ -1,6 +1,6 @@ `default_nettype none -module top1; +module genblock_collide_top1; generate if (1) begin : foo if (1) begin : bar @@ -12,7 +12,7 @@ module top1; endgenerate endmodule -module top2; +module genblock_collide_top2; genvar i; generate if (1) begin : foo diff --git a/tests/simple/genblk_dive.v b/tests/simple/genblk_dive.v index 98d0e1f4bf6..ca0c0d4a1d3 100644 --- a/tests/simple/genblk_dive.v +++ b/tests/simple/genblk_dive.v @@ -1,5 +1,5 @@ `default_nettype none -module top(output wire x); +module genblk_dive_top(output wire x); generate if (1) begin : Z if (1) begin : A diff --git a/tests/simple/genblk_order.v b/tests/simple/genblk_order.v index 7c3a7a756fe..c80c1ac1ac0 100644 --- a/tests/simple/genblk_order.v +++ b/tests/simple/genblk_order.v @@ -1,5 +1,5 @@ `default_nettype none -module top( +module genblk_order_top( output wire out1, output wire out2 ); diff --git a/tests/simple/genblk_port_shadow.v b/tests/simple/genblk_port_shadow.v index a04631a209f..c1348632c2a 100644 --- a/tests/simple/genblk_port_shadow.v +++ b/tests/simple/genblk_port_shadow.v @@ -1,4 +1,4 @@ -module top(x); +module genblock_port_shadow_top(x); generate if (1) begin : blk wire x; diff --git a/tests/simple/hierarchy.v b/tests/simple/hierarchy.v index 123afaeab9c..b03044fde0f 100644 --- a/tests/simple/hierarchy.v +++ b/tests/simple/hierarchy.v @@ -1,6 +1,6 @@ (* top *) -module top(a, b, y1, y2, y3, y4); +module hierarchy_top(a, b, y1, y2, y3, y4); input [3:0] a; input signed [3:0] b; output [7:0] y1, y2, y3, y4; diff --git a/tests/simple/ifdef_1.v b/tests/simple/ifdef_1.v index fa962355cb9..f1358185c49 100644 --- a/tests/simple/ifdef_1.v +++ b/tests/simple/ifdef_1.v @@ -1,4 +1,4 @@ -module top(o1, o2, o3, o4); +module ifdef_1_top(o1, o2, o3, o4); `define FAIL input wire not_a_port; diff --git a/tests/simple/ifdef_2.v b/tests/simple/ifdef_2.v index 6dd89efed76..9fae7570d34 100644 --- a/tests/simple/ifdef_2.v +++ b/tests/simple/ifdef_2.v @@ -1,4 +1,4 @@ -module top(o1, o2, o3); +module ifdef_2_top(o1, o2, o3); output wire o1; diff --git a/tests/simple/local_loop_var.sv b/tests/simple/local_loop_var.sv index 46b4e5c229f..42860e21856 100644 --- a/tests/simple/local_loop_var.sv +++ b/tests/simple/local_loop_var.sv @@ -1,4 +1,4 @@ -module top(out); +module local_loop_top(out); output integer out; initial begin integer i; diff --git a/tests/simple/loop_prefix_case.v b/tests/simple/loop_prefix_case.v index 7ee28ed7013..0cfa005477c 100644 --- a/tests/simple/loop_prefix_case.v +++ b/tests/simple/loop_prefix_case.v @@ -1,4 +1,4 @@ -module top( +module loop_prefix_case_top( input wire x, output reg y ); diff --git a/tests/simple/loop_var_shadow.v b/tests/simple/loop_var_shadow.v index 0222a4493d4..b75a15ab06c 100644 --- a/tests/simple/loop_var_shadow.v +++ b/tests/simple/loop_var_shadow.v @@ -1,4 +1,4 @@ -module top(out); +module loop_var_shadow_top(out); genvar i; generate for (i = 0; i < 2; i = i + 1) begin : loop diff --git a/tests/simple/macro_arg_spaces.sv b/tests/simple/macro_arg_spaces.sv index 75c4cd1369f..5fc9e288189 100644 --- a/tests/simple/macro_arg_spaces.sv +++ b/tests/simple/macro_arg_spaces.sv @@ -1,4 +1,4 @@ -module top( +module macro_arg_spaces_top( input wire [31:0] i, output wire [31:0] x, y, z ); diff --git a/tests/simple/macro_arg_surrounding_spaces.v b/tests/simple/macro_arg_surrounding_spaces.v index 3dbb5ea015d..e0239c08bd4 100644 --- a/tests/simple/macro_arg_surrounding_spaces.v +++ b/tests/simple/macro_arg_surrounding_spaces.v @@ -1,4 +1,4 @@ -module top( +module macr_arg_surrounding_spaces_top( IDENT_V_, IDENT_W_, IDENT_X_, diff --git a/tests/simple/matching_end_labels.sv b/tests/simple/matching_end_labels.sv index 09182ebcf4f..2d42e7e10d6 100644 --- a/tests/simple/matching_end_labels.sv +++ b/tests/simple/matching_end_labels.sv @@ -1,4 +1,4 @@ -module top( +module matching_end_labels_top( output reg [7:0] out1, out2, out3, out4 ); diff --git a/tests/simple/mem2reg_bounds_tern.v b/tests/simple/mem2reg_bounds_tern.v index 89d6dd3e88a..0e6852fe764 100644 --- a/tests/simple/mem2reg_bounds_tern.v +++ b/tests/simple/mem2reg_bounds_tern.v @@ -1,4 +1,4 @@ -module top( +module mem2reg_bounds_term_top( input clk, input wire [1:0] sel, input wire [7:0] base, diff --git a/tests/simple/module_scope.v b/tests/simple/module_scope.v index 3e46b72ef1f..d0778391292 100644 --- a/tests/simple/module_scope.v +++ b/tests/simple/module_scope.v @@ -1,29 +1,29 @@ `default_nettype none -module Example(o1, o2); +module module_scope_Example(o1, o2); parameter [31:0] v1 = 10; parameter [31:0] v2 = 20; output [31:0] o1, o2; - assign Example.o1 = Example.v1; - assign Example.o2 = Example.v2; + assign module_scope_Example.o1 = module_scope_Example.v1; + assign module_scope_Example.o2 = module_scope_Example.v2; endmodule -module ExampleLong(o1, o2); +module module_scope_ExampleLong(o1, o2); parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1 = 10; parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2 = 20; output [31:0] o1, o2; - assign ExampleLong.o1 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1; - assign ExampleLong.o2 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2; + assign module_scope_ExampleLong.o1 = module_scope_ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1; + assign module_scope_ExampleLong.o2 = module_scope_ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2; endmodule -module top( +module module_scope_top( output [31:0] a1, a2, b1, b2, c1, c2, output [31:0] d1, d2, e1, e2, f1, f2 ); - Example a(a1, a2); - Example #(1) b(b1, b2); - Example #(1, 2) c(c1, c2); - ExampleLong d(d1, d2); - ExampleLong #(1) e(e1, e2); - ExampleLong #(1, 2) f(f1, f2); + module_scope_Example a(a1, a2); + module_scope_Example #(1) b(b1, b2); + module_scope_Example #(1, 2) c(c1, c2); + module_scope_ExampleLong d(d1, d2); + module_scope_ExampleLong #(1) e(e1, e2); + module_scope_ExampleLong #(1, 2) f(f1, f2); endmodule diff --git a/tests/simple/module_scope_case.v b/tests/simple/module_scope_case.v index 1472b6912a2..bceba4424e1 100644 --- a/tests/simple/module_scope_case.v +++ b/tests/simple/module_scope_case.v @@ -1,11 +1,11 @@ -module top( +module module_scope_case_top( input wire x, output reg y ); always @* begin - case (top.x) - 1: top.y = 0; - 0: top.y = 1; + case (module_scope_case_top.x) + 1: module_scope_case_top.y = 0; + 0: module_scope_case_top.y = 1; endcase end endmodule diff --git a/tests/simple/named_genblk.v b/tests/simple/named_genblk.v index b8300fc4dc5..b98b7c8ceed 100644 --- a/tests/simple/named_genblk.v +++ b/tests/simple/named_genblk.v @@ -1,5 +1,5 @@ `default_nettype none -module top; +module named_genblk_top; generate if (1) begin wire t; diff --git a/tests/simple/nested_genblk_resolve.v b/tests/simple/nested_genblk_resolve.v index da5593f8a79..70bbc611ba8 100644 --- a/tests/simple/nested_genblk_resolve.v +++ b/tests/simple/nested_genblk_resolve.v @@ -1,5 +1,5 @@ `default_nettype none -module top; +module nested_genblk_resolve_top; generate if (1) begin wire x; diff --git a/tests/simple/string_format.v b/tests/simple/string_format.v index ce45ca1e95c..cb7b419ac27 100644 --- a/tests/simple/string_format.v +++ b/tests/simple/string_format.v @@ -1,4 +1,4 @@ -module top; +module string_format_top; parameter STR = "something interesting"; initial begin $display("A: %s", STR); diff --git a/tests/simple/unnamed_block_decl.sv b/tests/simple/unnamed_block_decl.sv index e81b457a88a..e78c577daae 100644 --- a/tests/simple/unnamed_block_decl.sv +++ b/tests/simple/unnamed_block_decl.sv @@ -1,4 +1,4 @@ -module top(z); +module unnamed_block_decl(z); output integer z; initial begin integer x; diff --git a/tests/simple/wandwor.v b/tests/simple/wandwor.v index 34404aa26b2..40502acfc01 100644 --- a/tests/simple/wandwor.v +++ b/tests/simple/wandwor.v @@ -5,9 +5,9 @@ module wandwor_test0 (A, B, C, D, X, Y, Z); output Z; assign X = A, X = B, Y = C, Y = D; - foo foo_0 (C, D, X); - foo foo_1 (A, B, Y); - foo foo_2 (X, Y, Z); + wandwor_foo foo_0 (C, D, X); + wandwor_foo foo_1 (A, B, Y); + wandwor_foo foo_2 (X, Y, Z); endmodule module wandwor_test1 (A, B, C, D, X, Y, Z); @@ -16,7 +16,7 @@ module wandwor_test1 (A, B, C, D, X, Y, Z); output wand [3:0] Y; output Z; - bar bar_inst ( + wandwor_bar bar_inst ( .I0({A, B}), .I1({B, A}), .O({X, Y}) @@ -27,10 +27,10 @@ module wandwor_test1 (A, B, C, D, X, Y, Z); assign Z = ^{X,Y}; endmodule -module foo(input I0, I1, output O); +module wandwor_foo(input I0, I1, output O); assign O = I0 ^ I1; endmodule -module bar(input [7:0] I0, I1, output [7:0] O); +module wandwor_bar(input [7:0] I0, I1, output [7:0] O); assign O = I0 + I1; endmodule From 9658d2e337a54fc06873de716d0ae5586ffd869b Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 23 Sep 2021 13:33:55 -0400 Subject: [PATCH 0532/2410] Fix TOK_ID memory leak in for_initialization --- frontends/verilog/verilog_parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 8d0ba4cf67a..acb8b996c08 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2674,6 +2674,7 @@ for_initialization: AstNode *node = new AstNode(AST_ASSIGN_EQ, ident, $3); ast_stack.back()->children.push_back(node); SET_AST_NODE_LOC(node, @1, @3); + delete $1; } | non_io_wire_type range TOK_ID { frontend_verilog_yyerror("For loop variable declaration is missing initialization!"); From 1cac671c70bc3da9808ceb3add15686da4a5d82e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 25 Sep 2021 00:51:53 +0000 Subject: [PATCH 0533/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 60ab2ccc273..5b7dd169cb5 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4309 +YOSYS_VER := 0.9+4313 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 89df26e4bcc958708f9c0715440ff08975d4e0f7 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 27 Sep 2021 16:02:20 +0200 Subject: [PATCH 0534/2410] Add optimization to rtlil back-end for all-x parameter values Signed-off-by: Claire Xenia Wolf --- backends/rtlil/rtlil_backend.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index a6e45b2f2e9..68521d52d58 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -51,15 +51,19 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi } } f << stringf("%d'", width); - for (int i = offset+width-1; i >= offset; i--) { - log_assert(i < (int)data.bits.size()); - switch (data.bits[i]) { - case State::S0: f << stringf("0"); break; - case State::S1: f << stringf("1"); break; - case RTLIL::Sx: f << stringf("x"); break; - case RTLIL::Sz: f << stringf("z"); break; - case RTLIL::Sa: f << stringf("-"); break; - case RTLIL::Sm: f << stringf("m"); break; + if (data.is_fully_undef()) { + f << "x"; + } else { + for (int i = offset+width-1; i >= offset; i--) { + log_assert(i < (int)data.bits.size()); + switch (data.bits[i]) { + case State::S0: f << stringf("0"); break; + case State::S1: f << stringf("1"); break; + case RTLIL::Sx: f << stringf("x"); break; + case RTLIL::Sz: f << stringf("z"); break; + case RTLIL::Sa: f << stringf("-"); break; + case RTLIL::Sm: f << stringf("m"); break; + } } } } else { From 070cad5f4b13fa6c260ace4ef22dace2759ec342 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 27 Sep 2021 16:24:43 +0200 Subject: [PATCH 0535/2410] Prepare for next release cycle --- CHANGELOG | 5 ++++- Makefile | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ab41d689d6b..fe85723af8b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,11 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.10 .. Yosys 0.10-dev +-------------------------- + -Yosys 0.9 .. Yosys 0.9-dev +Yosys 0.9 .. Yosys 0.10 -------------------------- * Various diff --git a/Makefile b/Makefile index 5b7dd169cb5..4b7f7f5eda1 100644 --- a/Makefile +++ b/Makefile @@ -127,12 +127,12 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+4313 +YOSYS_VER := 0.10+0 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 8a4c6e6.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 1cac671.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 7a7df9a3b4996b17bb774377483b15de49aa3d9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Sep 2021 00:53:49 +0000 Subject: [PATCH 0536/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4b7f7f5eda1..032a6259819 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+0 +YOSYS_VER := 0.10+1 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From f9aad606ca9c8f875ce3c3091daf465b73d3f513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 2 Oct 2021 00:42:36 +0200 Subject: [PATCH 0537/2410] simplemap: refactor to use FfData. --- kernel/ff.h | 9 +- passes/techmap/simplemap.cc | 300 +++--------------------------------- passes/techmap/simplemap.h | 7 +- 3 files changed, 26 insertions(+), 290 deletions(-) diff --git a/kernel/ff.h b/kernel/ff.h index 3e83db678bb..e555e15f1e6 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -312,7 +312,8 @@ struct FfData { res.val_arst.bits.push_back(val_arst[i]); if (has_srst) res.val_srst.bits.push_back(val_srst[i]); - res.val_init.bits.push_back(val_init[i]); + if (initvals) + res.val_init.bits.push_back(val_init[i]); } res.width = GetSize(res.sig_q); // Slicing bits out may cause D to become const. @@ -382,12 +383,14 @@ struct FfData { pol_en = pol_arst; } else { // No control inputs left. Turn into a const driver. - initvals->remove_init(sig_q); + if (initvals) + initvals->remove_init(sig_q); module->connect(sig_q, val_init); return nullptr; } } - initvals->set_init(sig_q, val_init); + if (initvals) + initvals->set_init(sig_q, val_init); Cell *cell; if (!is_fine) { if (!has_d) { diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index b65224c717e..69f9da07532 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -19,6 +19,7 @@ #include "simplemap.h" #include "kernel/sigtools.h" +#include "kernel/ff.h" #include #include #include @@ -367,276 +368,13 @@ void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) module->connect(RTLIL::SigSig(sig_y, sig_ab)); } -void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_s = cell->getPort(ID::SET); - RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::S, sig_s[i]); - gate->setPort(ID::R, sig_r[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at(ID::WIDTH).as_int(); - - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = ID($_FF_); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DFF_%c_", clk_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_en = cell->getPort(ID::EN); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::E, sig_en); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_s = cell->getPort(ID::SET); - RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::S, sig_s[i]); - gate->setPort(ID::R, sig_r[i]); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dffsre(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_s = cell->getPort(ID::SET); - RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); - RTLIL::SigSpec sig_e = cell->getPort(ID::EN); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DFFSRE_%c%c%c%c_", clk_pol, set_pol, clr_pol, en_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::S, sig_s[i]); - gate->setPort(ID::R, sig_r[i]); - gate->setPort(ID::E, sig_e); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_adff_sdff(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - bool is_async = cell->type == ID($adff); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char rst_pol = cell->parameters.at(is_async ? ID::ARST_POLARITY : ID::SRST_POLARITY).as_bool() ? 'P' : 'N'; - const char *type = is_async ? "DFF" : "SDFF"; - - std::vector rst_val = cell->parameters.at(is_async ? ID::ARST_VALUE : ID::SRST_VALUE).bits; - while (int(rst_val.size()) < width) - rst_val.push_back(RTLIL::State::S0); - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_rst = cell->getPort(is_async ? ID::ARST : ID::SRST); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type_0 = stringf("$_%s_%c%c0_", type, clk_pol, rst_pol); - IdString gate_type_1 = stringf("$_%s_%c%c1_", type, clk_pol, rst_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::R, sig_rst); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_adffe_sdffe_sdffce(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - bool is_async = cell->type == ID($adffe); - char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char rst_pol = cell->parameters.at(is_async ? ID::ARST_POLARITY : ID::SRST_POLARITY).as_bool() ? 'P' : 'N'; - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - const char *type = is_async ? "DFFE" : cell->type == ID($sdffe) ? "SDFFE" : "SDFFCE"; - - std::vector rst_val = cell->parameters.at(is_async ? ID::ARST_VALUE : ID::SRST_VALUE).bits; - while (int(rst_val.size()) < width) - rst_val.push_back(RTLIL::State::S0); - - RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_rst = cell->getPort(is_async ? ID::ARST : ID::SRST); - RTLIL::SigSpec sig_e = cell->getPort(ID::EN); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type_0 = stringf("$_%s_%c%c0%c_", type, clk_pol, rst_pol, en_pol); - IdString gate_type_1 = stringf("$_%s_%c%c1%c_", type, clk_pol, rst_pol, en_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::C, sig_clk); - gate->setPort(ID::R, sig_rst); - gate->setPort(ID::E, sig_e); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_en = cell->getPort(ID::EN); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DLATCH_%c_", en_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::E, sig_en); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_adlatch(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - char rst_pol = cell->parameters.at(ID::ARST_POLARITY).as_bool() ? 'P' : 'N'; - - std::vector rst_val = cell->parameters.at(ID::ARST_VALUE).bits; - while (int(rst_val.size()) < width) - rst_val.push_back(RTLIL::State::S0); - - RTLIL::SigSpec sig_en = cell->getPort(ID::EN); - RTLIL::SigSpec sig_rst = cell->getPort(ID::ARST); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type_0 = stringf("$_DLATCH_%c%c0_", en_pol, rst_pol); - IdString gate_type_1 = stringf("$_DLATCH_%c%c1_", en_pol, rst_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::E, sig_en); - gate->setPort(ID::R, sig_rst); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); - } -} - -void simplemap_dlatchsr(RTLIL::Module *module, RTLIL::Cell *cell) -{ - int width = cell->parameters.at(ID::WIDTH).as_int(); - char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; - - RTLIL::SigSpec sig_en = cell->getPort(ID::EN); - RTLIL::SigSpec sig_s = cell->getPort(ID::SET); - RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); - RTLIL::SigSpec sig_d = cell->getPort(ID::D); - RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - - IdString gate_type = stringf("$_DLATCHSR_%c%c%c_", en_pol, set_pol, clr_pol); - - for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); - gate->setPort(ID::E, sig_en); - gate->setPort(ID::S, sig_s[i]); - gate->setPort(ID::R, sig_r[i]); - gate->setPort(ID::D, sig_d[i]); - gate->setPort(ID::Q, sig_q[i]); + FfData ff(nullptr, cell); + for (int i = 0; i < ff.width; i++) { + FfData fff = ff.slice({i}); + fff.is_fine = true; + fff.emit(module, NEW_ID); } } @@ -666,20 +404,20 @@ void simplemap_get_mappers(dict mappers[ID($sop)] = simplemap_sop; mappers[ID($slice)] = simplemap_slice; mappers[ID($concat)] = simplemap_concat; - mappers[ID($sr)] = simplemap_sr; + mappers[ID($sr)] = simplemap_ff; mappers[ID($ff)] = simplemap_ff; - mappers[ID($dff)] = simplemap_dff; - mappers[ID($dffe)] = simplemap_dffe; - mappers[ID($dffsr)] = simplemap_dffsr; - mappers[ID($dffsre)] = simplemap_dffsre; - mappers[ID($adff)] = simplemap_adff_sdff; - mappers[ID($sdff)] = simplemap_adff_sdff; - mappers[ID($adffe)] = simplemap_adffe_sdffe_sdffce; - mappers[ID($sdffe)] = simplemap_adffe_sdffe_sdffce; - mappers[ID($sdffce)] = simplemap_adffe_sdffe_sdffce; - mappers[ID($dlatch)] = simplemap_dlatch; - mappers[ID($adlatch)] = simplemap_adlatch; - mappers[ID($dlatchsr)] = simplemap_dlatchsr; + mappers[ID($dff)] = simplemap_ff; + mappers[ID($dffe)] = simplemap_ff; + mappers[ID($dffsr)] = simplemap_ff; + mappers[ID($dffsre)] = simplemap_ff; + mappers[ID($adff)] = simplemap_ff; + mappers[ID($sdff)] = simplemap_ff; + mappers[ID($adffe)] = simplemap_ff; + mappers[ID($sdffe)] = simplemap_ff; + mappers[ID($sdffce)] = simplemap_ff; + mappers[ID($dlatch)] = simplemap_ff; + mappers[ID($adlatch)] = simplemap_ff; + mappers[ID($dlatchsr)] = simplemap_ff; } void simplemap(RTLIL::Module *module, RTLIL::Cell *cell) diff --git a/passes/techmap/simplemap.h b/passes/techmap/simplemap.h index 03a8fb36f89..c7654f68c52 100644 --- a/passes/techmap/simplemap.h +++ b/passes/techmap/simplemap.h @@ -34,12 +34,7 @@ extern void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell); extern void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell); extern void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell); extern void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell); -extern void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell); +extern void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell); extern void simplemap(RTLIL::Module *module, RTLIL::Cell *cell); extern void simplemap_get_mappers(dict &mappers); From fbd70f28f044968fd59740e34652071c4ee01218 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 1 Oct 2021 14:41:11 -0600 Subject: [PATCH 0538/2410] Specify minimum bison version 3.0+ Yosys works with bison 3.0 (or newer), but not bison 2.7 (the previous release). Ideally, we would require "3" rather than "3.0" to give a better error message, but bison 2.3, which still ships with macOS, does not support major-only version requirements. With this change, building with an outdated bison yields: `frontends/rtlil/rtlil_parser.y:25.10-14: require bison 3.0, but have 2.3`. --- frontends/rtlil/rtlil_parser.y | 2 ++ frontends/verilog/verilog_parser.y | 2 ++ 2 files changed, 4 insertions(+) diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index 67aeb10e02c..7d99b2c4220 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -22,6 +22,8 @@ * */ +%require "3.0" + %{ #include #include "frontends/rtlil/rtlil_frontend.h" diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 5eb1115ce9a..171e098a556 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -33,6 +33,8 @@ * */ +%require "3.0" + %{ #include #include From ec2b5548fe9b8d291365a84a0c3fc87654643359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 1 Oct 2021 04:33:00 +0200 Subject: [PATCH 0539/2410] Add $aldff and $aldffe: flip-flops with async load. --- CHANGELOG | 2 + kernel/celltypes.h | 11 ++ kernel/constids.inc | 3 + kernel/rtlil.cc | 110 +++++++++++++ kernel/rtlil.h | 6 + manual/CHAPTER_CellLib.tex | 15 +- techlibs/common/gen_fine_ffs.py | 49 ++++++ techlibs/common/simcells.v | 284 ++++++++++++++++++++++++++++++++ techlibs/common/simlib.v | 49 ++++++ 9 files changed, 527 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fe85723af8b..a6285ddb294 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ List of major changes and improvements between releases Yosys 0.10 .. Yosys 0.10-dev -------------------------- + * Various + - Added $aldff and $aldffe (flip-flops with async load) cells Yosys 0.9 .. Yosys 0.10 -------------------------- diff --git a/kernel/celltypes.h b/kernel/celltypes.h index a977501e3e8..879ac0edc0b 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -142,6 +142,8 @@ struct CellTypes setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::EN}, {ID::Q}); setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q}); setup_type(ID($adffe), {ID::CLK, ID::ARST, ID::D, ID::EN}, {ID::Q}); + setup_type(ID($aldff), {ID::CLK, ID::ALOAD, ID::AD, ID::D}, {ID::Q}); + setup_type(ID($aldffe), {ID::CLK, ID::ALOAD, ID::AD, ID::D, ID::EN}, {ID::Q}); setup_type(ID($sdff), {ID::CLK, ID::SRST, ID::D}, {ID::Q}); setup_type(ID($sdffe), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}); setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}); @@ -224,6 +226,15 @@ struct CellTypes for (auto c4 : list_np) setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + for (auto c1 : list_np) + for (auto c2 : list_np) + setup_type(stringf("$_ALDFF_%c%c_", c1, c2), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + setup_type(stringf("$_ALDFFE_%c%c%c_", c1, c2, c3), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}); + for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_np) diff --git a/kernel/constids.inc b/kernel/constids.inc index 68d10def6c9..8d8e97eb7fb 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -11,9 +11,12 @@ X(abc9_mergeability) X(abc9_scc_id) X(abcgroup) X(ABITS) +X(AD) X(ADDR) X(allconst) X(allseq) +X(ALOAD) +X(ALOAD_POLARITY) X(always_comb) X(always_ff) X(always_latch) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a05023c5293..3778972bcfd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -58,6 +58,8 @@ const pool &RTLIL::builtin_ff_cell_types() { ID($dffsre), ID($adff), ID($adffe), + ID($aldff), + ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), @@ -118,6 +120,18 @@ const pool &RTLIL::builtin_ff_cell_types() { ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_), + ID($_ALDFF_NN_), + ID($_ALDFF_NP_), + ID($_ALDFF_PN_), + ID($_ALDFF_PP_), + ID($_ALDFFE_NNN_), + ID($_ALDFFE_NNP_), + ID($_ALDFFE_NPN_), + ID($_ALDFFE_NPP_), + ID($_ALDFFE_PNN_), + ID($_ALDFFE_PNP_), + ID($_ALDFFE_PPN_), + ID($_ALDFFE_PPP_), ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), @@ -1337,6 +1351,32 @@ namespace { return; } + if (cell->type == ID($aldff)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::ALOAD_POLARITY); + port(ID::CLK, 1); + port(ID::ALOAD, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::AD, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type == ID($aldffe)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::ALOAD_POLARITY); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::ALOAD, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::AD, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatch)) { param_bool(ID::EN_POLARITY); port(ID::EN, 1); @@ -1648,6 +1688,15 @@ namespace { ID($_DFFE_PP0N_), ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_))) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } + if (cell->type.in( + ID($_ALDFF_NN_), ID($_ALDFF_NP_), ID($_ALDFF_PN_), ID($_ALDFF_PP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); check_expected(); return; } + + if (cell->type.in( + ID($_ALDFFE_NNN_), ID($_ALDFFE_NNP_), ID($_ALDFFE_NPN_), ID($_ALDFFE_NPP_), + ID($_ALDFFE_PNN_), ID($_ALDFFE_PNP_), ID($_ALDFFE_PPN_), ID($_ALDFFE_PPP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); port(ID::E,1); check_expected(); return; } + if (cell->type.in( ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) @@ -2675,6 +2724,40 @@ RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec return cell; } +RTLIL::Cell* RTLIL::Module::addAldff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($aldff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::ALOAD, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addAldffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($aldffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ALOAD_POLARITY] = aload_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ALOAD, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) { @@ -2865,6 +2948,33 @@ RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigS return cell; } +RTLIL::Cell* RTLIL::Module::addAldffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::L, sig_aload); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addAldffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::L, sig_aload); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::AD, sig_ad); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 06198b26a6d..e072d5bd1a3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1312,6 +1312,8 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAldff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAldffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = ""); RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); @@ -1349,6 +1351,10 @@ struct RTLIL::Module : public RTLIL::AttrObject bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAldffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAldffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = ""); RTLIL::Cell* addSdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addSdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 74ba224df5c..3c9fb31ccc4 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -287,13 +287,24 @@ \subsection{Registers} Note that the {\tt \$adff} and {\tt \$sdff} cells can only be used when the reset value is constant. +D-type flip-flops with asynchronous load are represented by {\tt \$aldff} cells. As the {\tt \$dff} +cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{ALOAD} +input port for the async load enable pin, a \B{AD} input port with the same width as data for +the async load data, and the following additional parameter: + +\begin{itemize} +\item \B{ALOAD\_POLARITY} \\ +The asynchronous load is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. +\end{itemize} + D-type flip-flops with asynchronous set and reset are represented by {\tt \$dffsr} cells. As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have multi-bit \B{SET} and \B{CLR} input ports and the corresponding polarity parameters, like {\tt \$sr} cells. -D-type flip-flops with enable are represented by {\tt \$dffe}, {\tt \$adffe}, {\tt \$dffsre}, -{\tt \$sdffe}, and {\tt \$sdffce} cells, which are enhanced variants of {\tt \$dff}, {\tt \$adff}, {\tt \$dffsr}, +D-type flip-flops with enable are represented by {\tt \$dffe}, {\tt \$adffe}, {\tt \$aldffe}, {\tt \$dffsre}, +{\tt \$sdffe}, and {\tt \$sdffce} cells, which are enhanced variants of {\tt \$dff}, {\tt \$adff}, {\tt \$aldff}, {\tt \$dffsr}, {\tt \$sdff} (with reset over enable) and {\tt \$sdff} (with enable over reset) cells, respectively. They have the same ports and parameters as their base cell. In addition they also have a single-bit \B{EN} input port for the enable pin and the following parameter: diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py index 5d331e76746..25c6ef171c4 100644 --- a/techlibs/common/gen_fine_ffs.py +++ b/techlibs/common/gen_fine_ffs.py @@ -133,6 +133,55 @@ """ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - {L:0|1} a | a +//- d {C:\\|/} - - | d +//- - - - - | q +//- +module \$_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin + if (L == {L:0|1}) + Q <= AD; + else + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load and {E:negative|positive} +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - {L:0|1} a - | a +//- d {C:\\|/} - - {E:0|1} | d +//- - - - - - | q +//- +module \$_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin + if (L == {L:0|1}) + Q <= AD; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q) //- //- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive} diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 7d9bebe2af0..ad1fdc81756 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -1252,6 +1252,290 @@ always @(posedge C or posedge R) begin end endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_NN_ (D, C, L, AD, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 0 a | a +//- d \ - - | d +//- - - - - | q +//- +module \$_ALDFF_NN_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_NP_ (D, C, L, AD, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 1 a | a +//- d \ - - | d +//- - - - - | q +//- +module \$_ALDFF_NP_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_PN_ (D, C, L, AD, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 0 a | a +//- d / - - | d +//- - - - - | q +//- +module \$_ALDFF_PN_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFF_PP_ (D, C, L, AD, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load. +//- +//- Truth table: D C L AD | Q +//- ----------+--- +//- - - 1 a | a +//- d / - - | d +//- - - - - | q +//- +module \$_ALDFF_PP_ (D, C, L, AD, Q); +input D, C, L, AD; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NNN_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d \ - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_NNN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NNP_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d \ - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_NNP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NPN_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d \ - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_NPN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_NPP_ (D, C, L, AD, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d \ - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_NPP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(negedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PNN_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d / - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_PNN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PNP_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 0 a - | a +//- d / - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_PNP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or negedge L) begin + if (L == 0) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PPN_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load and negative +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d / - - 0 | d +//- - - - - - | q +//- +module \$_ALDFFE_PPN_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_ALDFFE_PPP_ (D, C, L, AD, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity async load and positive +//- polarity clock enable. +//- +//- Truth table: D C L AD E | Q +//- ------------+--- +//- - - 1 a - | a +//- d / - - 1 | d +//- - - - - - | q +//- +module \$_ALDFFE_PPP_ (D, C, L, AD, E, Q); +input D, C, L, AD, E; +output reg Q; +always @(posedge C or posedge L) begin + if (L == 1) + Q <= AD; + else if (E == 1) + Q <= D; +end +endmodule + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- //- $_DFFSR_NNN_ (C, S, R, D, Q) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index cf0839ebef7..e9129f69011 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1890,6 +1890,30 @@ endmodule // -------------------------------------------------------- +module \$aldff (CLK, ALOAD, AD, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter ALOAD_POLARITY = 1'b1; + +input CLK, ALOAD; +input [WIDTH-1:0] AD; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_aload = ALOAD == ALOAD_POLARITY; + +always @(posedge pos_clk, posedge pos_aload) begin + if (pos_aload) + Q <= AD; + else + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + module \$sdff (CLK, SRST, D, Q); parameter WIDTH = 0; @@ -1939,6 +1963,31 @@ endmodule // -------------------------------------------------------- +module \$aldffe (CLK, ALOAD, AD, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; +parameter ALOAD_POLARITY = 1'b1; + +input CLK, ALOAD, EN; +input [WIDTH-1:0] D; +input [WIDTH-1:0] AD; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_aload = ALOAD == ALOAD_POLARITY; + +always @(posedge pos_clk, posedge pos_aload) begin + if (pos_aload) + Q <= AD; + else if (EN == EN_POLARITY) + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + module \$sdffe (CLK, SRST, EN, D, Q); parameter WIDTH = 0; From 63b9df8693840d17def8abcb0e848112283b0231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 1 Oct 2021 23:50:48 +0200 Subject: [PATCH 0540/2410] kernel/ff: Refactor FfData to enable FFs with async load. - *_en is split into *_ce (clock enable) and *_aload (async load aka latch gate enable), so both can be present at once - has_d is removed - has_gclk is added (to have a clear marker for $ff) - d_is_const and val_d leftovers are removed - async2sync, clk2fflogic, opt_dff are updated to operate correctly on FFs with async load --- backends/verilog/verilog_backend.cc | 113 ++++++---- kernel/ff.h | 325 ++++++++++++++++++---------- kernel/ffmerge.cc | 67 ++++-- kernel/mem.cc | 15 +- kernel/satgen.cc | 20 +- passes/memory/memory_dff.cc | 22 +- passes/opt/opt_dff.cc | 229 ++++++++++++-------- passes/sat/async2sync.cc | 61 ++++-- passes/sat/clk2fflogic.cc | 34 +-- passes/techmap/dffunmap.cc | 4 +- 10 files changed, 565 insertions(+), 325 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 47b48a46039..6fb14d7fc84 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1398,7 +1398,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) FfData ff(nullptr, cell); // $ff / $_FF_ cell: not supported. - if (ff.has_d && !ff.has_clk && !ff.has_en) + if (ff.has_gclk) return false; std::string reg_name = cellname(cell); @@ -1419,17 +1419,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) for (int i = 0; i < chunks; i++) { - SigSpec sig_d; + SigSpec sig_d, sig_ad; Const val_arst, val_srst; - std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name; + std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name, sig_aload_name; if (chunky) { reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i); - if (ff.has_d) + if (ff.has_gclk || ff.has_clk) sig_d = ff.sig_d[i]; + if (ff.has_aload) + sig_ad = ff.sig_ad[i]; } else { reg_bit_name = reg_name; - if (ff.has_d) - sig_d = ff.sig_d; + sig_d = ff.sig_d; + sig_ad = ff.sig_ad; } if (ff.has_arst) val_arst = chunky ? ff.val_arst[i] : ff.val_arst; @@ -1437,28 +1439,38 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) val_srst = chunky ? ff.val_srst[i] : ff.val_srst; // If there are constants in the sensitivity list, replace them with an intermediate wire - if (ff.has_sr) { - if (ff.sig_set[i].wire == NULL) - { - sig_set_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str()); - dump_const(f, ff.sig_set[i].data); - f << stringf(";\n"); - } - if (ff.sig_clr[i].wire == NULL) - { - sig_clr_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str()); - dump_const(f, ff.sig_clr[i].data); - f << stringf(";\n"); - } - } else if (ff.has_arst) { - if (ff.sig_arst[i].wire == NULL) - { - sig_arst_name = next_auto_id(); - f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str()); - dump_const(f, ff.sig_arst[i].data); - f << stringf(";\n"); + if (ff.has_clk) { + if (ff.has_sr) { + if (ff.sig_set[i].wire == NULL) + { + sig_set_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str()); + dump_const(f, ff.sig_set[i].data); + f << stringf(";\n"); + } + if (ff.sig_clr[i].wire == NULL) + { + sig_clr_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str()); + dump_const(f, ff.sig_clr[i].data); + f << stringf(";\n"); + } + } else if (ff.has_arst) { + if (ff.sig_arst[0].wire == NULL) + { + sig_arst_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str()); + dump_const(f, ff.sig_arst[0].data); + f << stringf(";\n"); + } + } else if (ff.has_aload) { + if (ff.sig_aload[0].wire == NULL) + { + sig_aload_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_aload_name.c_str()); + dump_const(f, ff.sig_aload[0].data); + f << stringf(";\n"); + } } } @@ -1480,13 +1492,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s", sig_clr_name.c_str()); else dump_sigspec(f, ff.sig_clr[i]); - } else if (ff.has_arst) { f << stringf(", %sedge ", ff.pol_arst ? "pos" : "neg"); - if (ff.sig_arst[i].wire == NULL) + if (ff.sig_arst[0].wire == NULL) f << stringf("%s", sig_arst_name.c_str()); else dump_sigspec(f, ff.sig_arst); + } else if (ff.has_aload) { + f << stringf(", %sedge ", ff.pol_aload ? "pos" : "neg"); + if (ff.sig_aload[0].wire == NULL) + f << stringf("%s", sig_aload_name.c_str()); + else + dump_sigspec(f, ff.sig_aload); } f << stringf(")\n"); @@ -1507,7 +1524,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " else ", indent.c_str()); } else if (ff.has_arst) { f << stringf("if (%s", ff.pol_arst ? "" : "!"); - if (ff.sig_arst[i].wire == NULL) + if (ff.sig_arst[0].wire == NULL) f << stringf("%s", sig_arst_name.c_str()); else dump_sigspec(f, ff.sig_arst); @@ -1515,11 +1532,21 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) dump_sigspec(f, val_arst); f << stringf(";\n"); f << stringf("%s" " else ", indent.c_str()); + } else if (ff.has_aload) { + f << stringf("if (%s", ff.pol_aload ? "" : "!"); + if (ff.sig_aload[0].wire == NULL) + f << stringf("%s", sig_aload_name.c_str()); + else + dump_sigspec(f, ff.sig_aload); + f << stringf(") %s <= ", reg_bit_name.c_str()); + dump_sigspec(f, sig_ad); + f << stringf(";\n"); + f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_srst && ff.has_en && ff.ce_over_srst) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_srst && ff.has_ce && ff.ce_over_srst) { + f << stringf("if (%s", ff.pol_ce ? "" : "!"); + dump_sigspec(f, ff.sig_ce); f << stringf(")\n"); f << stringf("%s" " if (%s", indent.c_str(), ff.pol_srst ? "" : "!"); dump_sigspec(f, ff.sig_srst); @@ -1536,9 +1563,9 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(";\n"); f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_en) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_ce) { + f << stringf("if (%s", ff.pol_ce ? "" : "!"); + dump_sigspec(f, ff.sig_ce); f << stringf(") "); } } @@ -1560,7 +1587,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " else if (%s", indent.c_str(), ff.pol_set ? "" : "!"); dump_sigspec(f, ff.sig_set[i]); f << stringf(") %s = 1'b1;\n", reg_bit_name.c_str()); - if (ff.has_d) + if (ff.has_aload) f << stringf("%s" " else ", indent.c_str()); } else if (ff.has_arst) { f << stringf("if (%s", ff.pol_arst ? "" : "!"); @@ -1568,14 +1595,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(") %s = ", reg_bit_name.c_str()); dump_sigspec(f, val_arst); f << stringf(";\n"); - if (ff.has_d) + if (ff.has_aload) f << stringf("%s" " else ", indent.c_str()); } - if (ff.has_d) { - f << stringf("if (%s", ff.pol_en ? "" : "!"); - dump_sigspec(f, ff.sig_en); + if (ff.has_aload) { + f << stringf("if (%s", ff.pol_aload ? "" : "!"); + dump_sigspec(f, ff.sig_aload); f << stringf(") %s = ", reg_bit_name.c_str()); - dump_sigspec(f, sig_d); + dump_sigspec(f, sig_ad); f << stringf(";\n"); } } diff --git a/kernel/ff.h b/kernel/ff.h index e555e15f1e6..a06eb0a1c83 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -25,55 +25,141 @@ YOSYS_NAMESPACE_BEGIN +// Describes a flip-flop or a latch. +// +// If has_gclk, this is a formal verification FF with implicit global clock: +// Q is simply previous cycle's D. +// +// Otherwise, the FF/latch can have any number of features selected by has_* +// attributes that determine Q's value (in order of decreasing priority): +// +// - on start, register is initialized to val_init +// - if has_sr is present: +// - sig_clr is per-bit async clear, and sets the corresponding bit to 0 +// if active +// - sig_set is per-bit async set, and sets the corresponding bit to 1 +// if active +// - if has_arst is present: +// - sig_arst is whole-reg async reset, and sets the whole register to val_arst +// - if has_aload is present: +// - sig_aload is whole-reg async load (aka latch gate enable), and sets the whole +// register to sig_ad +// - if has_clk is present, and we're currently on a clock edge: +// - if has_ce is present and ce_over_srst is true: +// - ignore clock edge (don't change value) unless sig_ce is active +// - if has_srst is present: +// - sig_srst is whole-reg sync reset and sets the register to val_srst +// - if has_ce is present and ce_over_srst is false: +// - ignore clock edge (don't change value) unless sig_ce is active +// - set whole reg to sig_d +// - if nothing of the above applies, the reg value remains unchanged +// +// Since the yosys FF cell library isn't fully generic, not all combinations +// of the features above can be supported: +// +// - only one of has_srst, has_arst, has_sr can be used +// - if has_clk is used together with has_aload, then has_srst, has_arst, +// has_sr cannot be used +// +// The valid feature combinations are thus: +// +// - has_clk + optional has_ce [dff/dffe] +// - has_clk + optional has_ce + has_arst [adff/adffe] +// - has_clk + optional has_ce + has_aload [aldff/aldffe] +// - has_clk + optional has_ce + has_sr [dffsr/dffsre] +// - has_clk + optional has_ce + has_srst [sdff/sdffe/sdffce] +// - has_aload [dlatch] +// - has_aload + has_arst [adlatch] +// - has_aload + has_sr [dlatchsr] +// - has_sr [sr] +// - has_arst [does not correspond to a native cell, represented as dlatch with const D input] +// - empty set [not a cell — will be emitted as a simple direct connection] + struct FfData { FfInitVals *initvals; + // The FF output. SigSpec sig_q; + // The sync data input, present if has_clk or has_gclk. SigSpec sig_d; + // The async data input, present if has_aload. + SigSpec sig_ad; + // The sync clock, present if has_clk. SigSpec sig_clk; - SigSpec sig_en; + // The clock enable, present if has_ce. + SigSpec sig_ce; + // The async load enable, present if has_aload. + SigSpec sig_aload; + // The async reset, preset if has_arst. SigSpec sig_arst; + // The sync reset, preset if has_srst. SigSpec sig_srst; + // The async clear (per-lane), present if has_sr. SigSpec sig_clr; + // The async set (per-lane), present if has_sr. SigSpec sig_set; - bool has_d; + // True if this is a clocked (edge-sensitive) flip-flop. bool has_clk; - bool has_en; + // True if this is a $ff, exclusive with every other has_*. + bool has_gclk; + // True if this FF has a clock enable. Depends on has_clk. + bool has_ce; + // True if this FF has async load function — this includes D latches. + // If this and has_clk are both set, has_arst and has_sr cannot be set. + bool has_aload; + // True if this FF has sync set/reset. Depends on has_clk, exclusive + // with has_arst, has_sr, has_aload. bool has_srst; + // True if this FF has async set/reset. Exclusive with has_srst, + // has_sr. If this and has_clk are both set, has_aload cannot be set. bool has_arst; + // True if this FF has per-bit async set + clear. Exclusive with + // has_srst, has_arst. If this and has_clk are both set, has_aload + // cannot be set. bool has_sr; + // If has_ce and has_srst are both set, determines their relative + // priorities: if true, inactive ce disables srst; if false, srst + // operates independent of ce. bool ce_over_srst; + // True if this FF is a fine cell, false if it is a coarse cell. + // If true, width must be 1. bool is_fine; + // Polarities, corresponding to sig_*. True means active-high, false + // means active-low. bool pol_clk; - bool pol_en; + bool pol_ce; + bool pol_aload; bool pol_arst; bool pol_srst; bool pol_clr; bool pol_set; + // The value loaded by sig_arst. Const val_arst; + // The value loaded by sig_srst. Const val_srst; + // The initial value at power-up. Const val_init; - Const val_d; - bool d_is_const; + // The FF data width in bits. int width; dict attributes; FfData(FfInitVals *initvals = nullptr, Cell *cell = nullptr) : initvals(initvals) { width = 0; - has_d = true; has_clk = false; - has_en = false; + has_gclk = false; + has_ce = false; + has_aload = false; has_srst = false; has_arst = false; has_sr = false; ce_over_srst = false; is_fine = false; pol_clk = false; - pol_en = false; + pol_aload = false; + pol_ce = false; pol_arst = false; pol_srst = false; pol_clr = false; pol_set = false; - d_is_const = false; if (!cell) return; @@ -88,20 +174,26 @@ struct FfData { std::string type_str = cell->type.str(); if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { - if (cell->type == ID($sr)) { - has_d = false; - } else { + if (cell->type == ID($ff)) { + has_gclk = true; sig_d = cell->getPort(ID::D); - } - if (!cell->type.in(ID($ff), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { + } else if (cell->type == ID($sr)) { + // No data input at all. + } else if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { + has_aload = true; + sig_aload = cell->getPort(ID::EN); + pol_aload = cell->getParam(ID::EN_POLARITY).as_bool(); + sig_ad = cell->getPort(ID::D); + } else { has_clk = true; sig_clk = cell->getPort(ID::CLK); pol_clk = cell->getParam(ID::CLK_POLARITY).as_bool(); + sig_d = cell->getPort(ID::D); } - if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr))) { - has_en = true; - sig_en = cell->getPort(ID::EN); - pol_en = cell->getParam(ID::EN_POLARITY).as_bool(); + if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($sdffe), ID($sdffce))) { + has_ce = true; + sig_ce = cell->getPort(ID::EN); + pol_ce = cell->getParam(ID::EN_POLARITY).as_bool(); } if (cell->type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) { has_sr = true; @@ -125,10 +217,10 @@ struct FfData { } } else if (cell->type == ID($_FF_)) { is_fine = true; + has_gclk = true; sig_d = cell->getPort(ID::D); } else if (type_str.substr(0, 5) == "$_SR_") { is_fine = true; - has_d = false; has_sr = true; pol_set = type_str[5] == 'P'; pol_clr = type_str[6] == 'P'; @@ -146,9 +238,9 @@ struct FfData { has_clk = true; pol_clk = type_str[7] == 'P'; sig_clk = cell->getPort(ID::C); - has_en = true; - pol_en = type_str[8] == 'P'; - sig_en = cell->getPort(ID::E); + has_ce = true; + pol_ce = type_str[8] == 'P'; + sig_ce = cell->getPort(ID::E); } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { is_fine = true; sig_d = cell->getPort(ID::D); @@ -169,9 +261,9 @@ struct FfData { pol_arst = type_str[8] == 'P'; sig_arst = cell->getPort(ID::R); val_arst = type_str[9] == '1' ? State::S1 : State::S0; - has_en = true; - pol_en = type_str[10] == 'P'; - sig_en = cell->getPort(ID::E); + has_ce = true; + pol_ce = type_str[10] == 'P'; + sig_ce = cell->getPort(ID::E); } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { is_fine = true; sig_d = cell->getPort(ID::D); @@ -194,9 +286,9 @@ struct FfData { pol_clr = type_str[11] == 'P'; sig_set = cell->getPort(ID::S); sig_clr = cell->getPort(ID::R); - has_en = true; - pol_en = type_str[12] == 'P'; - sig_en = cell->getPort(ID::E); + has_ce = true; + pol_ce = type_str[12] == 'P'; + sig_ce = cell->getPort(ID::E); } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { is_fine = true; sig_d = cell->getPort(ID::D); @@ -217,9 +309,9 @@ struct FfData { pol_srst = type_str[9] == 'P'; sig_srst = cell->getPort(ID::R); val_srst = type_str[10] == '1' ? State::S1 : State::S0; - has_en = true; - pol_en = type_str[11] == 'P'; - sig_en = cell->getPort(ID::E); + has_ce = true; + pol_ce = type_str[11] == 'P'; + sig_ce = cell->getPort(ID::E); } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { is_fine = true; sig_d = cell->getPort(ID::D); @@ -230,32 +322,35 @@ struct FfData { pol_srst = type_str[10] == 'P'; sig_srst = cell->getPort(ID::R); val_srst = type_str[11] == '1' ? State::S1 : State::S0; - has_en = true; - pol_en = type_str[12] == 'P'; - sig_en = cell->getPort(ID::E); + has_ce = true; + pol_ce = type_str[12] == 'P'; + sig_ce = cell->getPort(ID::E); ce_over_srst = true; } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { is_fine = true; - sig_d = cell->getPort(ID::D); - has_en = true; - pol_en = type_str[9] == 'P'; - sig_en = cell->getPort(ID::E); + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::E); } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { is_fine = true; - sig_d = cell->getPort(ID::D); - has_en = true; - pol_en = type_str[9] == 'P'; - sig_en = cell->getPort(ID::E); + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::E); has_arst = true; pol_arst = type_str[10] == 'P'; sig_arst = cell->getPort(ID::R); val_arst = type_str[11] == '1' ? State::S1 : State::S0; } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { is_fine = true; - sig_d = cell->getPort(ID::D); - has_en = true; - pol_en = type_str[11] == 'P'; - sig_en = cell->getPort(ID::E); + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[11] == 'P'; + sig_aload = cell->getPort(ID::E); has_sr = true; pol_set = type_str[12] == 'P'; pol_clr = type_str[13] == 'P'; @@ -264,17 +359,13 @@ struct FfData { } else { log_assert(0); } - if (has_d && sig_d.is_fully_const()) { - d_is_const = true; - val_d = sig_d.as_const(); - if (has_en && !has_clk && !has_sr && !has_arst) { - // Plain D latches with const D treated specially. - has_en = has_d = false; - has_arst = true; - sig_arst = sig_en; - pol_arst = pol_en; - val_arst = val_d; - } + if (has_aload && !has_clk && !has_sr && !has_arst && sig_ad.is_fully_const()) { + // Plain D latches with const D treated specially. + has_aload = false; + has_arst = true; + sig_arst = sig_aload; + pol_arst = pol_aload; + val_arst = sig_ad.as_const(); } } @@ -282,19 +373,22 @@ struct FfData { FfData slice(const std::vector &bits) { FfData res(initvals); res.sig_clk = sig_clk; - res.sig_en = sig_en; + res.sig_ce = sig_ce; + res.sig_aload = sig_aload; res.sig_arst = sig_arst; res.sig_srst = sig_srst; - res.has_d = has_d; res.has_clk = has_clk; - res.has_en = has_en; + res.has_gclk = has_gclk; + res.has_ce = has_ce; + res.has_aload = has_aload; res.has_arst = has_arst; res.has_srst = has_srst; res.has_sr = has_sr; res.ce_over_srst = ce_over_srst; res.is_fine = is_fine; res.pol_clk = pol_clk; - res.pol_en = pol_en; + res.pol_ce = pol_ce; + res.pol_aload = pol_aload; res.pol_arst = pol_arst; res.pol_srst = pol_srst; res.pol_clr = pol_clr; @@ -302,8 +396,10 @@ struct FfData { res.attributes = attributes; for (int i : bits) { res.sig_q.append(sig_q[i]); - if (has_d) + if (has_clk || has_gclk) res.sig_d.append(sig_d[i]); + if (has_aload) + res.sig_ad.append(sig_ad[i]); if (has_sr) { res.sig_clr.append(sig_clr[i]); res.sig_set.append(sig_set[i]); @@ -316,39 +412,34 @@ struct FfData { res.val_init.bits.push_back(val_init[i]); } res.width = GetSize(res.sig_q); - // Slicing bits out may cause D to become const. - if (has_d && res.sig_d.is_fully_const()) { - res.d_is_const = true; - res.val_d = res.sig_d.as_const(); - } return res; } void unmap_ce(Module *module) { - if (!has_en) + if (!has_ce) return; log_assert(has_clk); if (has_srst && ce_over_srst) unmap_srst(module); if (!is_fine) { - if (pol_en) - sig_d = module->Mux(NEW_ID, sig_q, sig_d, sig_en); + if (pol_ce) + sig_d = module->Mux(NEW_ID, sig_q, sig_d, sig_ce); else - sig_d = module->Mux(NEW_ID, sig_d, sig_q, sig_en); + sig_d = module->Mux(NEW_ID, sig_d, sig_q, sig_ce); } else { - if (pol_en) - sig_d = module->MuxGate(NEW_ID, sig_q, sig_d, sig_en); + if (pol_ce) + sig_d = module->MuxGate(NEW_ID, sig_q, sig_d, sig_ce); else - sig_d = module->MuxGate(NEW_ID, sig_d, sig_q, sig_en); + sig_d = module->MuxGate(NEW_ID, sig_d, sig_q, sig_ce); } - has_en = false; + has_ce = false; } void unmap_srst(Module *module) { if (!has_srst) return; - if (has_en && !ce_over_srst) + if (has_ce && !ce_over_srst) unmap_ce(module); if (!is_fine) { @@ -373,14 +464,14 @@ struct FfData { Cell *emit(Module *module, IdString name) { if (!width) return nullptr; - if (!has_d && !has_sr) { + if (!has_aload && !has_clk && !has_gclk && !has_sr) { if (has_arst) { // Convert this case to a D latch. - has_d = has_en = true; + has_aload = true; has_arst = false; - sig_d = val_arst; - sig_en = sig_arst; - pol_en = pol_arst; + sig_ad = val_arst; + sig_aload = sig_arst; + pol_aload = pol_arst; } else { // No control inputs left. Turn into a const driver. if (initvals) @@ -393,87 +484,93 @@ struct FfData { initvals->set_init(sig_q, val_init); Cell *cell; if (!is_fine) { - if (!has_d) { - log_assert(has_sr); - cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); - } else if (!has_clk && !has_en) { + if (has_gclk) { + log_assert(!has_clk); + log_assert(!has_ce); + log_assert(!has_aload); log_assert(!has_arst); log_assert(!has_srst); log_assert(!has_sr); cell = module->addFf(name, sig_d, sig_q); + } else if (!has_aload && !has_clk) { + log_assert(has_sr); + cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); } else if (!has_clk) { log_assert(!has_srst); if (has_sr) - cell = module->addDlatchsr(name, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_en, pol_set, pol_clr); + cell = module->addDlatchsr(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); else if (has_arst) - cell = module->addAdlatch(name, sig_en, sig_arst, sig_d, sig_q, val_arst, pol_en, pol_arst); + cell = module->addAdlatch(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst); else - cell = module->addDlatch(name, sig_en, sig_d, sig_q, pol_en); + cell = module->addDlatch(name, sig_aload, sig_ad, sig_q, pol_aload); } else { if (has_sr) { - if (has_en) - cell = module->addDffsre(name, sig_clk, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_en, pol_set, pol_clr); + if (has_ce) + cell = module->addDffsre(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); else cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); } else if (has_arst) { - if (has_en) - cell = module->addAdffe(name, sig_clk, sig_en, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_en, pol_arst); + if (has_ce) + cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst); else cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst); } else if (has_srst) { - if (has_en) + if (has_ce) if (ce_over_srst) - cell = module->addSdffce(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_en, pol_srst); + cell = module->addSdffce(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); else - cell = module->addSdffe(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_en, pol_srst); + cell = module->addSdffe(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); else cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst); } else { - if (has_en) - cell = module->addDffe(name, sig_clk, sig_en, sig_d, sig_q, pol_clk, pol_en); + if (has_ce) + cell = module->addDffe(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); else cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk); } } } else { - if (!has_d) { - log_assert(has_sr); - cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); - } else if (!has_clk && !has_en) { + if (has_gclk) { + log_assert(!has_clk); + log_assert(!has_ce); + log_assert(!has_aload); log_assert(!has_arst); log_assert(!has_srst); log_assert(!has_sr); cell = module->addFfGate(name, sig_d, sig_q); + } else if (!has_aload && !has_clk) { + log_assert(has_sr); + cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); } else if (!has_clk) { log_assert(!has_srst); if (has_sr) - cell = module->addDlatchsrGate(name, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_en, pol_set, pol_clr); + cell = module->addDlatchsrGate(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); else if (has_arst) - cell = module->addAdlatchGate(name, sig_en, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_en, pol_arst); + cell = module->addAdlatchGate(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst); else - cell = module->addDlatchGate(name, sig_en, sig_d, sig_q, pol_en); + cell = module->addDlatchGate(name, sig_aload, sig_ad, sig_q, pol_aload); } else { if (has_sr) { - if (has_en) - cell = module->addDffsreGate(name, sig_clk, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_en, pol_set, pol_clr); + if (has_ce) + cell = module->addDffsreGate(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); else cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); } else if (has_arst) { - if (has_en) - cell = module->addAdffeGate(name, sig_clk, sig_en, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_en, pol_arst); + if (has_ce) + cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst); else cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst); } else if (has_srst) { - if (has_en) + if (has_ce) if (ce_over_srst) - cell = module->addSdffceGate(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_en, pol_srst); + cell = module->addSdffceGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); else - cell = module->addSdffeGate(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_en, pol_srst); + cell = module->addSdffeGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); else cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst); } else { - if (has_en) - cell = module->addDffeGate(name, sig_clk, sig_en, sig_d, sig_q, pol_clk, pol_en); + if (has_ce) + cell = module->addDffeGate(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); else cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk); } diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc index 6a29acc960c..7d62a88cfc5 100644 --- a/kernel/ffmerge.cc +++ b/kernel/ffmerge.cc @@ -62,22 +62,28 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool undef_d; if (model_undef) undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1); - if (ff.has_srst && ff.has_en && ff.ce_over_srst) { + if (ff.has_srst && ff.has_ce && ff.ce_over_srst) { int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0); std::vector rval = importDefSigSpec(ff.val_srst, timestep-1); int undef_srst; @@ -1108,21 +1108,21 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) else std::tie(d, undef_d) = mux(srst, undef_srst, rval, undef_rval, d, undef_d); } - if (ff.has_en) { - int en = importDefSigSpec(ff.sig_en, timestep-1).at(0); + if (ff.has_ce) { + int ce = importDefSigSpec(ff.sig_ce, timestep-1).at(0); std::vector old_q = importDefSigSpec(ff.sig_q, timestep-1); - int undef_en; + int undef_ce; std::vector undef_old_q; if (model_undef) { - undef_en = importUndefSigSpec(ff.sig_en, timestep-1).at(0); + undef_ce = importUndefSigSpec(ff.sig_ce, timestep-1).at(0); undef_old_q = importUndefSigSpec(ff.sig_q, timestep-1); } - if (ff.pol_en) - std::tie(d, undef_d) = mux(en, undef_en, old_q, undef_old_q, d, undef_d); + if (ff.pol_ce) + std::tie(d, undef_d) = mux(ce, undef_ce, old_q, undef_old_q, d, undef_d); else - std::tie(d, undef_d) = mux(en, undef_en, d, undef_d, old_q, undef_old_q); + std::tie(d, undef_d) = mux(ce, undef_ce, d, undef_d, old_q, undef_old_q); } - if (ff.has_srst && !(ff.has_en && ff.ce_over_srst)) { + if (ff.has_srst && !(ff.has_ce && ff.ce_over_srst)) { int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0); std::vector rval = importDefSigSpec(ff.val_srst, timestep-1); int undef_srst; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 21962c238c9..b87ecdd9987 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -71,9 +71,9 @@ struct MemQueryCache // port_ren is an upper bound on when we care about the value fetched // from memory this cycle. int ren = ezSAT::CONST_TRUE; - if (ff.has_en) { - ren = qcsat.importSigBit(ff.sig_en); - if (!ff.pol_en) + if (ff.has_ce) { + ren = qcsat.importSigBit(ff.sig_ce); + if (!ff.pol_ce) ren = qcsat.ez->NOT(ren); } if (ff.has_srst) { @@ -347,6 +347,10 @@ struct MemoryDffWorker log("output latches are not supported.\n"); return; } + if (ff.has_aload) { + log("output FF has async load, not supported.\n"); + return; + } if (ff.has_sr) { // Latches and FFs with SR are not supported. log("output FF has both set and reset, not supported.\n"); @@ -491,8 +495,8 @@ struct MemoryDffWorker log("merging output FF to cell.\n"); merger.remove_output_ff(bits); - if (ff.has_en && !ff.pol_en) - ff.sig_en = module->LogicNot(NEW_ID, ff.sig_en); + if (ff.has_ce && !ff.pol_ce) + ff.sig_ce = module->LogicNot(NEW_ID, ff.sig_ce); if (ff.has_arst && !ff.pol_arst) ff.sig_arst = module->LogicNot(NEW_ID, ff.sig_arst); if (ff.has_srst && !ff.pol_srst) @@ -500,8 +504,8 @@ struct MemoryDffWorker port.clk = ff.sig_clk; port.clk_enable = true; port.clk_polarity = ff.pol_clk; - if (ff.has_en) - port.en = ff.sig_en; + if (ff.has_ce) + port.en = ff.sig_ce; else port.en = State::S1; if (ff.has_arst) { @@ -551,6 +555,10 @@ struct MemoryDffWorker log("address latches are not supported.\n"); return; } + if (ff.has_aload) { + log("address FF has async load, not supported.\n"); + return; + } if (ff.has_sr || ff.has_arst) { log("address FF has async set and/or reset, not supported.\n"); return; diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index ddf08392bb8..0e25484b8d3 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -382,6 +382,69 @@ struct OptDffWorker } } + if (ff.has_aload) { + if (ff.sig_aload == (ff.pol_aload ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_aload == State::Sx)) { + // Always-inactive enable — remove. + log("Removing never-active async load on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_aload = false; + changed = true; + } else if (ff.sig_aload == (ff.pol_aload ? State::S1 : State::S0)) { + // Always-active enable. Make a comb circuit, nuke the FF/latch. + log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", + log_id(cell), log_id(cell->type), log_id(module)); + initvals.remove_init(ff.sig_q); + module->remove(cell); + if (ff.has_sr) { + SigSpec tmp; + if (ff.is_fine) { + if (ff.pol_set) + tmp = module->MuxGate(NEW_ID, ff.sig_ad, State::S1, ff.sig_set); + else + tmp = module->MuxGate(NEW_ID, State::S1, ff.sig_ad, ff.sig_set); + if (ff.pol_clr) + module->addMuxGate(NEW_ID, tmp, State::S0, ff.sig_clr, ff.sig_q); + else + module->addMuxGate(NEW_ID, State::S0, tmp, ff.sig_clr, ff.sig_q); + } else { + if (ff.pol_set) + tmp = module->Or(NEW_ID, ff.sig_ad, ff.sig_set); + else + tmp = module->Or(NEW_ID, ff.sig_ad, module->Not(NEW_ID, ff.sig_set)); + if (ff.pol_clr) + module->addAnd(NEW_ID, tmp, module->Not(NEW_ID, ff.sig_clr), ff.sig_q); + else + module->addAnd(NEW_ID, tmp, ff.sig_clr, ff.sig_q); + } + } else if (ff.has_arst) { + if (ff.is_fine) { + if (ff.pol_arst) + module->addMuxGate(NEW_ID, ff.sig_ad, ff.val_arst[0], ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, ff.val_arst[0], ff.sig_ad, ff.sig_arst, ff.sig_q); + } else { + if (ff.pol_arst) + module->addMux(NEW_ID, ff.sig_ad, ff.val_arst, ff.sig_arst, ff.sig_q); + else + module->addMux(NEW_ID, ff.val_arst, ff.sig_ad, ff.sig_arst, ff.sig_q); + } + } else { + module->connect(ff.sig_q, ff.sig_ad); + } + did_something = true; + continue; + } else if (ff.sig_ad.is_fully_const() && !ff.has_arst && !ff.has_sr) { + log("Changing const-value async load to async reset on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_arst = true; + ff.has_aload = false; + ff.sig_arst = ff.sig_aload; + ff.pol_arst = ff.pol_aload; + ff.val_arst = ff.sig_ad.as_const(); + changed = true; + } + } + if (ff.has_arst) { if (ff.sig_arst == (ff.pol_arst ? State::S0 : State::S1)) { // Always-inactive reset — remove. @@ -414,111 +477,63 @@ struct OptDffWorker log_id(cell), log_id(cell->type), log_id(module)); ff.has_srst = false; if (!ff.ce_over_srst) - ff.has_en = false; - ff.sig_d = ff.val_d = ff.val_srst; - ff.d_is_const = true; + ff.has_ce = false; + ff.sig_d = ff.val_srst; changed = true; } } - if (ff.has_en) { - if (ff.sig_en == (ff.pol_en ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_en == State::Sx)) { + if (ff.has_ce) { + if (ff.sig_ce == (ff.pol_ce ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_ce == State::Sx)) { // Always-inactive enable — remove. - if (ff.has_clk && ff.has_srst && !ff.ce_over_srst) { + if (ff.has_srst && !ff.ce_over_srst) { log("Handling never-active EN on %s (%s) from module %s (connecting SRST instead).\n", log_id(cell), log_id(cell->type), log_id(module)); // FF with sync reset — connect the sync reset to D instead. - ff.pol_en = ff.pol_srst; - ff.sig_en = ff.sig_srst; + ff.pol_ce = ff.pol_srst; + ff.sig_ce = ff.sig_srst; ff.has_srst = false; - ff.sig_d = ff.val_d = ff.val_srst; - ff.d_is_const = true; + ff.sig_d = ff.val_srst; changed = true; } else { log("Handling never-active EN on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); - // The D input path is effectively useless, so remove it (this will be a const-input D latch, SR latch, or a const driver). - ff.has_d = ff.has_en = ff.has_clk = false; + // The D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). + ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; } - } else if (ff.sig_en == (ff.pol_en ? State::S1 : State::S0)) { - // Always-active enable. - if (ff.has_clk) { - // For FF, just remove the useless enable. - log("Removing always-active EN on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_en = false; - changed = true; - } else { - // For latches, make a comb circuit, nuke the latch. - log("Handling always-active EN on %s (%s) from module %s (changing to combinatorial circuit).\n", - log_id(cell), log_id(cell->type), log_id(module)); - initvals.remove_init(ff.sig_q); - module->remove(cell); - if (ff.has_sr) { - SigSpec tmp; - if (ff.is_fine) { - if (ff.pol_set) - tmp = module->MuxGate(NEW_ID, ff.sig_d, State::S1, ff.sig_set); - else - tmp = module->MuxGate(NEW_ID, State::S1, ff.sig_d, ff.sig_set); - if (ff.pol_clr) - module->addMuxGate(NEW_ID, tmp, State::S0, ff.sig_clr, ff.sig_q); - else - module->addMuxGate(NEW_ID, State::S0, tmp, ff.sig_clr, ff.sig_q); - } else { - if (ff.pol_set) - tmp = module->Or(NEW_ID, ff.sig_d, ff.sig_set); - else - tmp = module->Or(NEW_ID, ff.sig_d, module->Not(NEW_ID, ff.sig_set)); - if (ff.pol_clr) - module->addAnd(NEW_ID, tmp, module->Not(NEW_ID, ff.sig_clr), ff.sig_q); - else - module->addAnd(NEW_ID, tmp, ff.sig_clr, ff.sig_q); - } - } else if (ff.has_arst) { - if (ff.is_fine) { - if (ff.pol_arst) - module->addMuxGate(NEW_ID, ff.sig_d, ff.val_arst[0], ff.sig_arst, ff.sig_q); - else - module->addMuxGate(NEW_ID, ff.val_arst[0], ff.sig_d, ff.sig_arst, ff.sig_q); - } else { - if (ff.pol_arst) - module->addMux(NEW_ID, ff.sig_d, ff.val_arst, ff.sig_arst, ff.sig_q); - else - module->addMux(NEW_ID, ff.val_arst, ff.sig_d, ff.sig_arst, ff.sig_q); - } - } else { - module->connect(ff.sig_q, ff.sig_d); - } - did_something = true; - continue; - } + } else if (ff.sig_ce == (ff.pol_ce ? State::S1 : State::S0)) { + // Always-active enable. Just remove it. + // For FF, just remove the useless enable. + log("Removing always-active EN on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_ce = false; + changed = true; } } if (ff.has_clk) { if (ff.sig_clk.is_fully_const()) { - // Const clock — the D input path is effectively useless, so remove it (this will be a const-input D latch, SR latch, or a const driver). + // Const clock — the D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). log("Handling const CLK on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); - ff.has_d = ff.has_en = ff.has_clk = ff.has_srst = false; + ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; } } - if (ff.has_d && ff.sig_d == ff.sig_q) { + if ((ff.has_clk || ff.has_gclk) && ff.sig_d == ff.sig_q) { // Q wrapped back to D, can be removed. if (ff.has_clk && ff.has_srst) { // FF with sync reset — connect the sync reset to D instead. log("Handling D = Q on %s (%s) from module %s (conecting SRST instead).\n", log_id(cell), log_id(cell->type), log_id(module)); - if (ff.has_en && ff.ce_over_srst) { - if (!ff.pol_en) { + if (ff.has_ce && ff.ce_over_srst) { + if (!ff.pol_ce) { if (ff.is_fine) - ff.sig_en = module->NotGate(NEW_ID, ff.sig_en); + ff.sig_ce = module->NotGate(NEW_ID, ff.sig_ce); else - ff.sig_en = module->Not(NEW_ID, ff.sig_en); + ff.sig_ce = module->Not(NEW_ID, ff.sig_ce); } if (!ff.pol_srst) { if (ff.is_fine) @@ -527,28 +542,34 @@ struct OptDffWorker ff.sig_srst = module->Not(NEW_ID, ff.sig_srst); } if (ff.is_fine) - ff.sig_en = module->AndGate(NEW_ID, ff.sig_en, ff.sig_srst); + ff.sig_ce = module->AndGate(NEW_ID, ff.sig_ce, ff.sig_srst); else - ff.sig_en = module->And(NEW_ID, ff.sig_en, ff.sig_srst); - ff.pol_en = true; + ff.sig_ce = module->And(NEW_ID, ff.sig_ce, ff.sig_srst); + ff.pol_ce = true; } else { - ff.pol_en = ff.pol_srst; - ff.sig_en = ff.sig_srst; + ff.pol_ce = ff.pol_srst; + ff.sig_ce = ff.sig_srst; } - ff.has_en = true; + ff.has_ce = true; ff.has_srst = false; - ff.sig_d = ff.val_d = ff.val_srst; - ff.d_is_const = true; + ff.sig_d = ff.val_srst; changed = true; } else { // The D input path is effectively useless, so remove it (this will be a const-input D latch, SR latch, or a const driver). log("Handling D = Q on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); - ff.has_d = ff.has_en = ff.has_clk = false; + ff.has_clk = ff.has_ce = ff.has_clk = false; changed = true; } } + if (ff.has_aload && !ff.has_clk && ff.sig_ad == ff.sig_q) { + log("Handling AD = Q on %s (%s) from module %s (removing async load path).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_aload = false; + changed = true; + } + // Now check if any bit can be replaced by a constant. pool removed_sigbits; for (int i = 0; i < ff.width; i++) { @@ -565,7 +586,7 @@ struct OptDffWorker } if (val == State::Sm) continue; - if (ff.has_d) { + if (ff.has_clk || ff.has_gclk) { if (!ff.sig_d[i].wire) { val = combine_const(val, ff.sig_d[i].data); if (val == State::Sm) @@ -593,6 +614,34 @@ struct OptDffWorker continue; } } + if (ff.has_aload) { + if (!ff.sig_ad[i].wire) { + val = combine_const(val, ff.sig_ad[i].data); + if (val == State::Sm) + continue; + } else { + if (!opt.sat) + continue; + // For each register bit, try to prove that it cannot change from the initial value. If so, remove it + if (!modwalker.has_drivers(ff.sig_ad.extract(i))) + continue; + if (val != State::S0 && val != State::S1) + continue; + + int init_sat_pi = qcsat.importSigBit(val); + int q_sat_pi = qcsat.importSigBit(ff.sig_q[i]); + int d_sat_pi = qcsat.importSigBit(ff.sig_ad[i]); + + qcsat.prepare(); + + // Try to find out whether the register bit can change under some circumstances + bool counter_example_found = qcsat.ez->solve(qcsat.ez->IFF(q_sat_pi, init_sat_pi), qcsat.ez->NOT(qcsat.ez->IFF(d_sat_pi, init_sat_pi))); + + // If the register bit cannot change, we can replace it with a constant + if (counter_example_found) + continue; + } + } log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", val ? 1 : 0, i, log_id(cell), log_id(cell->type), log_id(module)); @@ -616,7 +665,7 @@ struct OptDffWorker // The cell has been simplified as much as possible already. Now try to spice it up with enables / sync resets. if (ff.has_clk) { - if (!ff.has_arst && !ff.has_sr && (!ff.has_srst || !ff.has_en || ff.ce_over_srst) && !opt.nosdff) { + if (!ff.has_arst && !ff.has_sr && (!ff.has_srst || !ff.has_ce || ff.ce_over_srst) && !opt.nosdff) { // Try to merge sync resets. std::map> groups; std::vector remaining_indices; @@ -677,7 +726,7 @@ struct OptDffWorker new_ff.has_srst = true; new_ff.sig_srst = srst.first; new_ff.pol_srst = srst.second; - if (new_ff.has_en) + if (new_ff.has_ce) new_ff.ce_over_srst = true; Cell *new_cell = new_ff.emit(module, NEW_ID); if (new_cell) @@ -695,7 +744,7 @@ struct OptDffWorker changed = true; } } - if ((!ff.has_srst || !ff.has_en || !ff.ce_over_srst) && !opt.nodffe) { + if ((!ff.has_srst || !ff.has_ce || !ff.ce_over_srst) && !opt.nodffe) { // Try to merge enables. std::map, std::vector> groups; std::vector remaining_indices; @@ -725,8 +774,8 @@ struct OptDffWorker if (!opt.simple_dffe) patterns = find_muxtree_feedback_patterns(ff.sig_d[i], ff.sig_q[i], pattern_t()); if (!patterns.empty() || !enables.empty()) { - if (ff.has_en) - enables.insert(ctrl_t(ff.sig_en, ff.pol_en)); + if (ff.has_ce) + enables.insert(ctrl_t(ff.sig_ce, ff.pol_ce)); simplify_patterns(patterns); groups[std::make_pair(patterns, enables)].push_back(i); } else @@ -737,9 +786,9 @@ struct OptDffWorker FfData new_ff = ff.slice(it.second); ctrl_t en = make_patterns_logic(it.first.first, it.first.second, ff.is_fine); - new_ff.has_en = true; - new_ff.sig_en = en.first; - new_ff.pol_en = en.second; + new_ff.has_ce = true; + new_ff.sig_ce = en.first; + new_ff.pol_ce = en.second; new_ff.ce_over_srst = false; Cell *new_cell = new_ff.emit(module, NEW_ID); if (new_cell) diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index a2b51677e06..f1b93d08472 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -41,8 +41,6 @@ struct Async2syncPass : public Pass { log("reset value in the next cycle regardless of the data-in value at the time of\n"); log("the clock edge.\n"); log("\n"); - log("Currently only $adff, $dffsr, and $dlatch cells are supported by this pass.\n"); - log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -74,14 +72,11 @@ struct Async2syncPass : public Pass { FfData ff(&initvals, cell); // Skip for $_FF_ and $ff cells. - if (ff.has_d && !ff.has_clk && !ff.has_en) + if (ff.has_gclk) continue; if (ff.has_clk) { - if (!ff.has_sr && !ff.has_arst) - continue; - if (ff.has_sr) { ff.unmap_ce_srst(module); @@ -128,6 +123,39 @@ struct Async2syncPass : public Pass { ff.sig_d = new_d; ff.sig_q = new_q; ff.has_sr = false; + } else if (ff.has_aload) { + ff.unmap_ce_srst(module); + + log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_d), log_signal(ff.sig_q)); + + initvals.remove_init(ff.sig_q); + + Wire *new_d = module->addWire(NEW_ID, ff.width); + Wire *new_q = module->addWire(NEW_ID, ff.width); + + if (ff.pol_aload) { + if (!ff.is_fine) { + module->addMux(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, ff.sig_q); + module->addMux(NEW_ID, ff.sig_d, ff.sig_ad, ff.sig_aload, new_d); + } else { + module->addMuxGate(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, ff.sig_q); + module->addMuxGate(NEW_ID, ff.sig_d, ff.sig_ad, ff.sig_aload, new_d); + } + } else { + if (!ff.is_fine) { + module->addMux(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, ff.sig_q); + module->addMux(NEW_ID, ff.sig_ad, ff.sig_d, ff.sig_aload, new_d); + } else { + module->addMuxGate(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, ff.sig_q); + module->addMuxGate(NEW_ID, ff.sig_ad, ff.sig_d, ff.sig_aload, new_d); + } + } + + ff.sig_d = new_d; + ff.sig_q = new_q; + ff.has_aload = false; } else if (ff.has_arst) { ff.unmap_srst(module); @@ -154,9 +182,12 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_arst = false; ff.has_srst = true; + ff.ce_over_srst = false; ff.val_srst = ff.val_arst; ff.sig_srst = ff.sig_arst; ff.pol_srst = ff.pol_arst; + } else { + continue; } } else @@ -164,25 +195,25 @@ struct Async2syncPass : public Pass { // Latch. log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); initvals.remove_init(ff.sig_q); Wire *new_q = module->addWire(NEW_ID, ff.width); Wire *new_d; - if (ff.has_d) { + if (ff.has_aload) { new_d = module->addWire(NEW_ID, ff.width); - if (ff.pol_en) { + if (ff.pol_aload) { if (!ff.is_fine) - module->addMux(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + module->addMux(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, new_d); else - module->addMuxGate(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + module->addMuxGate(NEW_ID, new_q, ff.sig_ad, ff.sig_aload, new_d); } else { if (!ff.is_fine) - module->addMux(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + module->addMux(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, new_d); else - module->addMuxGate(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + module->addMuxGate(NEW_ID, ff.sig_ad, new_q, ff.sig_aload, new_d); } } else { new_d = new_q; @@ -231,10 +262,10 @@ struct Async2syncPass : public Pass { ff.sig_d = new_d; ff.sig_q = new_q; - ff.has_en = false; + ff.has_aload = false; ff.has_arst = false; ff.has_sr = false; - ff.has_d = true; + ff.has_gclk = true; } IdString name = cell->name; diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index 06208397216..d90206b465a 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -148,7 +148,7 @@ struct Clk2fflogicPass : public Pass { if (RTLIL::builtin_ff_cell_types().count(cell->type)) { FfData ff(&initvals, cell); - if (ff.has_d && !ff.has_clk && !ff.has_en) { + if (ff.has_gclk) { // Already a $ff or $_FF_ cell. continue; } @@ -202,25 +202,27 @@ struct Clk2fflogicPass : public Pass { qval = module->Mux(NEW_ID, past_q, past_d, clock_edge); else qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); - } else if (ff.has_d) { - - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); + } else { + if (ff.has_aload) { + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); + } else { + // $sr. + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); + } + qval = past_q; + } - SigSpec sig_en = wrap_async_control(module, ff.sig_en, ff.pol_en); + if (ff.has_aload) { + SigSpec sig_aload = wrap_async_control(module, ff.sig_aload, ff.pol_aload); if (!ff.is_fine) - qval = module->Mux(NEW_ID, past_q, ff.sig_d, sig_en); + qval = module->Mux(NEW_ID, qval, ff.sig_ad, sig_aload); else - qval = module->MuxGate(NEW_ID, past_q, ff.sig_d, sig_en); - } else { - - log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - - qval = past_q; + qval = module->MuxGate(NEW_ID, qval, ff.sig_ad, sig_aload); } if (ff.has_sr) { diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc index fb107ff75b0..583185e75bc 100644 --- a/passes/techmap/dffunmap.cc +++ b/passes/techmap/dffunmap.cc @@ -84,7 +84,7 @@ struct DffunmapPass : public Pass { continue; if (ce_only) { - if (!ff.has_en) + if (!ff.has_ce) continue; ff.unmap_ce(mod); } else if (srst_only) { @@ -92,7 +92,7 @@ struct DffunmapPass : public Pass { continue; ff.unmap_srst(mod); } else { - if (!ff.has_en && !ff.has_srst) + if (!ff.has_ce && !ff.has_srst) continue; ff.unmap_ce_srst(mod); } From ba0723cad77a327653c080da84dda9f6ef12fad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 2 Oct 2021 00:05:22 +0200 Subject: [PATCH 0541/2410] zinit: Refactor to use FfData. --- passes/techmap/zinit.cc | 139 +++++++++++----------------------------- 1 file changed, 38 insertions(+), 101 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 7c5b73c90d5..8fcc47570a5 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -20,10 +20,19 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" +#include "kernel/ff.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +State invert(State s) { + switch (s) { + case State::S0: return State::S1; + case State::S1: return State::S0; + default: return s; + } +} + struct ZinitPass : public Pass { ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } void help() override @@ -60,123 +69,51 @@ struct ZinitPass : public Pass { SigMap sigmap(module); FfInitVals initvals(&sigmap, module); - pool dff_types = { - // FIXME: It would appear that supporting - // $dffsr/$_DFFSR_* would require a new - // cell type where S has priority over R - ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), ID($adffe), - ID($sdff), ID($sdffe), ID($sdffce), - ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), - /*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/ - ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - // Async set/reset - ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), - ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), - ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), - ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_), - // Sync set/reset - ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), - ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_), - ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), - ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), - ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), - ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_), - ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), - ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), - ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), - ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_) - }; - for (auto cell : module->selected_cells()) { - if (!dff_types.count(cell->type)) + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; - SigSpec sig_d = sigmap(cell->getPort(ID::D)); - SigSpec sig_q = sigmap(cell->getPort(ID::Q)); + FfData ff(&initvals, cell); + if (!ff.width) + continue; - if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) + // Supporting those would require a new cell type where S has priority over R. + if (ff.has_sr) continue; - Const initval = initvals(sig_q); - Const newval = initval; - initvals.remove_init(sig_q); + Wire *new_q = module->addWire(NEW_ID, ff.width); - Wire *initwire = module->addWire(NEW_ID, GetSize(sig_q)); + log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), + log_signal(ff.sig_q), log_signal(ff.val_init)); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) + IdString name = cell->name; + module->remove(cell); + initvals.remove_init(ff.sig_q); + + for (int i = 0; i < ff.width; i++) + if (ff.val_init[i] == State::S1) { - sig_d[i] = module->NotGate(NEW_ID, sig_d[i]); - module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]); - newval[i] = State::S0; + if (ff.has_clk || ff.has_gclk) + ff.sig_d[i] = module->NotGate(NEW_ID, ff.sig_d[i]); + if (ff.has_aload) + ff.sig_ad[i] = module->NotGate(NEW_ID, ff.sig_ad[i]); + if (ff.has_arst) + ff.val_arst[i] = invert(ff.val_arst[i]); + if (ff.has_srst) + ff.val_srst[i] = invert(ff.val_srst[i]); + module->addNotGate(NEW_ID, SigSpec(new_q, i), ff.sig_q[i]); + ff.val_init[i] = State::S0; } else { - module->connect(sig_q[i], SigSpec(initwire, i)); + module->connect(ff.sig_q[i], SigSpec(new_q, i)); if (all_mode) - newval[i] = State::S0; + ff.val_init[i] = State::S0; } - initvals.set_init(initwire, newval); - - log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), - log_signal(sig_q), log_signal(initval)); - - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, initwire); - - if (cell->type.in(ID($adff), ID($adffe))) { - auto val = cell->getParam(ID::ARST_VALUE); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) - val[i] = (val[i] == State::S1 ? State::S0 : State::S1); - cell->setParam(ID::ARST_VALUE, std::move(val)); - } - else if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { - auto val = cell->getParam(ID::SRST_VALUE); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) - val[i] = (val[i] == State::S1 ? State::S0 : State::S1); - cell->setParam(ID::SRST_VALUE, std::move(val)); - } - else if (initval == State::S1) { - std::string t = cell->type.str(); - if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) - { - t[8] = (t[8] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), - ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) - { - t[9] = (t[9] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), - ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), - ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), - ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_))) - { - t[9] = (t[9] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), - ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), - ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), - ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_))) - { - t[10] = (t[10] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), - ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), - ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), - ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_))) - { - t[11] = (t[11] == '0' ? '1' : '0'); - } - cell->type = t; - } + ff.sig_q = new_q; + ff.emit(module, name); } } } From e7d89e653c9d295d3cc9547b83660658e4d1c95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 2 Oct 2021 01:23:43 +0200 Subject: [PATCH 0542/2410] Hook up $aldff support in various passes. --- backends/btor/btor.cc | 2 +- backends/cxxrtl/cxxrtl_backend.cc | 17 +++++++++++- backends/smt2/smt2.cc | 2 +- backends/smv/smv.cc | 2 +- kernel/ff.h | 43 +++++++++++++++++++++++++++++-- passes/cmds/stat.cc | 2 +- passes/opt/opt_expr.cc | 14 ++++++++-- passes/techmap/simplemap.cc | 4 ++- techlibs/common/techmap.v | 2 +- 9 files changed, 77 insertions(+), 11 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 6370b53bd2c..96df54a2c8e 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -865,7 +865,7 @@ struct BtorWorker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n", log_id(cell->type), log_id(module), log_id(cell)); } diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 40e61e5af6e..ff28c20b394 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -206,6 +206,7 @@ bool is_ff_cell(RTLIL::IdString type) return type.in( ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), + ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr)); } @@ -1267,6 +1268,20 @@ struct CxxrtlWorker { dec_indent(); f << indent << "}\n"; } + if (cell->hasPort(ID::ALOAD)) { + // Asynchronous load + f << indent << "if ("; + dump_sigspec_rhs(cell->getPort(ID::ALOAD)); + f << " == value<1> {" << cell->getParam(ID::ALOAD_POLARITY).as_bool() << "u}) {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(cell->getPort(ID::Q)); + f << " = "; + dump_sigspec_rhs(cell->getPort(ID::AD)); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } if (cell->hasPort(ID::SET)) { // Asynchronous set (for individual bits) f << indent; @@ -2573,7 +2588,7 @@ struct CxxrtlWorker { flow.add_node(cell); // Various DFF cells are treated like posedge/negedge processes, see above for details. - if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { + if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { if (is_valid_clock(cell->getPort(ID::CLK))) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index f4482794279..f2fa003bcb6 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -860,7 +860,7 @@ struct Smt2Worker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n", log_id(cell->type), log_id(module), log_id(cell)); } diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index f4723d2a675..7bace69120f 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -578,7 +578,7 @@ struct SmvWorker log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n", log_id(cell->type), log_id(module), log_id(cell)); } - if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") { + if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") { log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n", log_id(cell->type), log_id(module), log_id(cell)); } diff --git a/kernel/ff.h b/kernel/ff.h index a06eb0a1c83..7f01b8a368d 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -173,7 +173,7 @@ struct FfData { std::string type_str = cell->type.str(); - if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { + if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { if (cell->type == ID($ff)) { has_gclk = true; sig_d = cell->getPort(ID::D); @@ -190,7 +190,7 @@ struct FfData { pol_clk = cell->getParam(ID::CLK_POLARITY).as_bool(); sig_d = cell->getPort(ID::D); } - if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($sdffe), ID($sdffce))) { + if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce))) { has_ce = true; sig_ce = cell->getPort(ID::EN); pol_ce = cell->getParam(ID::EN_POLARITY).as_bool(); @@ -202,6 +202,12 @@ struct FfData { pol_clr = cell->getParam(ID::CLR_POLARITY).as_bool(); pol_set = cell->getParam(ID::SET_POLARITY).as_bool(); } + if (cell->type.in(ID($aldff), ID($aldffe))) { + has_aload = true; + sig_aload = cell->getPort(ID::ALOAD); + pol_aload = cell->getParam(ID::ALOAD_POLARITY).as_bool(); + sig_ad = cell->getPort(ID::AD); + } if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) { has_arst = true; sig_arst = cell->getPort(ID::ARST); @@ -264,6 +270,29 @@ struct FfData { has_ce = true; pol_ce = type_str[10] == 'P'; sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 8) == "$_ALDFF_" && type_str.size() == 11) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::L); + sig_ad = cell->getPort(ID::AD); + } else if (type_str.substr(0, 9) == "$_ALDFFE_" && type_str.size() == 13) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_aload = true; + pol_aload = type_str[10] == 'P'; + sig_aload = cell->getPort(ID::L); + sig_ad = cell->getPort(ID::AD); + has_ce = true; + pol_ce = type_str[11] == 'P'; + sig_ce = cell->getPort(ID::E); } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { is_fine = true; sig_d = cell->getPort(ID::D); @@ -514,6 +543,11 @@ struct FfData { cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst); else cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst); + } else if (has_aload) { + if (has_ce) + cell = module->addAldffe(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); + else + cell = module->addAldff(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); } else if (has_srst) { if (has_ce) if (ce_over_srst) @@ -560,6 +594,11 @@ struct FfData { cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst); else cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst); + } else if (has_aload) { + if (has_ce) + cell = module->addAldffeGate(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); + else + cell = module->addAldffGate(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); } else if (has_srst) { if (has_ce) if (ce_over_srst) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 422810526cc..14a27ed9995 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -120,7 +120,7 @@ struct statdata_t else if (cell_type.in( ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), - ID($dlatch), ID($adlatch), ID($dlatchsr))) + ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch), ID($dlatchsr))) cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q))); } diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index cdd821c52e6..be0cd470be5 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -441,7 +441,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (!noclkinv) { - if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2))) + if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2))) handle_polarity_inv(cell, ID::CLK, ID::CLK_POLARITY, assign_map, invert_map); if (cell->type.in(ID($sr), ID($dffsr), ID($dffsre), ID($dlatchsr))) { @@ -452,10 +452,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) handle_polarity_inv(cell, ID::ARST, ID::ARST_POLARITY, assign_map, invert_map); + if (cell->type.in(ID($aldff), ID($aldffe))) + handle_polarity_inv(cell, ID::ALOAD, ID::ALOAD_POLARITY, assign_map, invert_map); + if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) handle_polarity_inv(cell, ID::SRST, ID::SRST_POLARITY, assign_map, invert_map); - if (cell->type.in(ID($dffe), ID($adffe), ID($sdffe), ID($sdffce), ID($dffsre), ID($dlatch), ID($adlatch), ID($dlatchsr))) + if (cell->type.in(ID($dffe), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce), ID($dffsre), ID($dlatch), ID($adlatch), ID($dlatchsr))) handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map); @@ -484,6 +487,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons handle_clkpol_celltype_swap(cell, "$_SDFFCE_?N??_", "$_SDFFCE_?P??_", ID::R, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_SDFFCE_???N_", "$_SDFFCE_???P_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_ALDFF_N?_", "$_ALDFF_P?_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_ALDFF_?N_", "$_ALDFF_?P_", ID::L, assign_map, invert_map); + + handle_clkpol_celltype_swap(cell, "$_ALDFFE_N??_", "$_ALDFFE_P??_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_ALDFFE_?N?_", "$_ALDFFE_?P?_", ID::L, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_ALDFFE_??N_", "$_ALDFFE_??P_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID::C, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID::S, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID::R, assign_map, invert_map); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 69f9da07532..04d7ec87471 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -415,6 +415,8 @@ void simplemap_get_mappers(dict mappers[ID($adffe)] = simplemap_ff; mappers[ID($sdffe)] = simplemap_ff; mappers[ID($sdffce)] = simplemap_ff; + mappers[ID($aldff)] = simplemap_ff; + mappers[ID($aldffe)] = simplemap_ff; mappers[ID($dlatch)] = simplemap_ff; mappers[ID($adlatch)] = simplemap_ff; mappers[ID($dlatchsr)] = simplemap_ff; @@ -450,7 +452,7 @@ struct SimplemapPass : public Pass { log(" $not, $pos, $and, $or, $xor, $xnor\n"); log(" $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool\n"); log(" $logic_not, $logic_and, $logic_or, $mux, $tribuf\n"); - log(" $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $sdff, $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr\n"); + log(" $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $aldff, $aldffe, $sdff, $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index d3dc85f2480..667773e1bfb 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -64,7 +64,7 @@ module _90_simplemap_various; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$sr $ff $dff $dffe $adff $adffe $sdff $sdffe $sdffce $dffsr $dffsre $dlatch $adlatch $dlatchsr" *) +(* techmap_celltype = "$sr $ff $dff $dffe $adff $adffe $aldff $aldffe $sdff $sdffe $sdffce $dffsr $dffsre $dlatch $adlatch $dlatchsr" *) module _90_simplemap_registers; endmodule From f3ef579ac4336bf9b92227e9ead8fa0fe7b236c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 Oct 2021 00:58:23 +0000 Subject: [PATCH 0543/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 032a6259819..25b58229b7a 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+1 +YOSYS_VER := 0.10+10 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From abc5700628cff4fc9334e28fbaccc35c75dfa990 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 4 Oct 2021 16:48:33 +0200 Subject: [PATCH 0544/2410] verific set db_infer_set_reset_registers --- frontends/verific/verific.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 99094f09955..23100375396 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2313,6 +2313,7 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_preserve_user_nets", 1); RuntimeFlags::SetVar("db_allow_external_nets", 1); RuntimeFlags::SetVar("db_infer_wide_operators", 1); + RuntimeFlags::SetVar("db_infer_set_reset_registers",1); RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); From 356ec7bb3980f77d737d9fa6e24e2f0b2159e741 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Oct 2021 00:53:24 +0000 Subject: [PATCH 0545/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 25b58229b7a..eec70dfaa24 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+10 +YOSYS_VER := 0.10+12 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 4e70c3077562e511d6f840c91dd30ade87d66517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 6 Oct 2021 22:16:55 +0200 Subject: [PATCH 0546/2410] FfData: some refactoring. - FfData now keeps track of the module and underlying cell, if any (so calling emit on FfData created from a cell will replace the existing cell) - FfData implementation is split off to its own .cc file for faster compilation - the "flip FF data sense by inserting inverters in front and after" functionality that zinit uses is moved onto FfData class and beefed up to have dffsr support, to support more use cases --- Makefile | 2 +- kernel/ff.cc | 575 ++++++++++++++++++++++++++++++++++++ kernel/ff.h | 472 ++--------------------------- kernel/ffmerge.cc | 2 +- kernel/mem.cc | 8 +- passes/memory/memory_dff.cc | 2 +- passes/opt/opt_dff.cc | 20 +- passes/sat/async2sync.cc | 11 +- passes/sat/clk2fflogic.cc | 37 ++- passes/techmap/dffunmap.cc | 9 +- passes/techmap/simplemap.cc | 4 +- passes/techmap/zinit.cc | 52 +--- tests/arch/xilinx/fsm.ys | 5 +- tests/techmap/zinit.ys | 7 +- 14 files changed, 660 insertions(+), 546 deletions(-) create mode 100644 kernel/ff.cc diff --git a/Makefile b/Makefile index eec70dfaa24..a2cad5dce04 100644 --- a/Makefile +++ b/Makefile @@ -608,7 +608,7 @@ ifneq ($(ABCEXTERNAL),) kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' endif endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' diff --git a/kernel/ff.cc b/kernel/ff.cc new file mode 100644 index 00000000000..c2f1a75a023 --- /dev/null +++ b/kernel/ff.cc @@ -0,0 +1,575 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina Kościelnicka + * + * 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/ff.h" + +USING_YOSYS_NAMESPACE + +FfData::FfData(FfInitVals *initvals, Cell *cell_) : FfData(cell_->module, initvals, cell_->name) +{ + cell = cell_; + sig_q = cell->getPort(ID::Q); + width = GetSize(sig_q); + attributes = cell->attributes; + + if (initvals) + val_init = (*initvals)(sig_q); + + std::string type_str = cell->type.str(); + + if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { + if (cell->type == ID($ff)) { + has_gclk = true; + sig_d = cell->getPort(ID::D); + } else if (cell->type == ID($sr)) { + // No data input at all. + } else if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { + has_aload = true; + sig_aload = cell->getPort(ID::EN); + pol_aload = cell->getParam(ID::EN_POLARITY).as_bool(); + sig_ad = cell->getPort(ID::D); + } else { + has_clk = true; + sig_clk = cell->getPort(ID::CLK); + pol_clk = cell->getParam(ID::CLK_POLARITY).as_bool(); + sig_d = cell->getPort(ID::D); + } + if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce))) { + has_ce = true; + sig_ce = cell->getPort(ID::EN); + pol_ce = cell->getParam(ID::EN_POLARITY).as_bool(); + } + if (cell->type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) { + has_sr = true; + sig_clr = cell->getPort(ID::CLR); + sig_set = cell->getPort(ID::SET); + pol_clr = cell->getParam(ID::CLR_POLARITY).as_bool(); + pol_set = cell->getParam(ID::SET_POLARITY).as_bool(); + } + if (cell->type.in(ID($aldff), ID($aldffe))) { + has_aload = true; + sig_aload = cell->getPort(ID::ALOAD); + pol_aload = cell->getParam(ID::ALOAD_POLARITY).as_bool(); + sig_ad = cell->getPort(ID::AD); + } + if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) { + has_arst = true; + sig_arst = cell->getPort(ID::ARST); + pol_arst = cell->getParam(ID::ARST_POLARITY).as_bool(); + val_arst = cell->getParam(ID::ARST_VALUE); + } + if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { + has_srst = true; + sig_srst = cell->getPort(ID::SRST); + pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool(); + val_srst = cell->getParam(ID::SRST_VALUE); + ce_over_srst = cell->type == ID($sdffce); + } + } else if (cell->type == ID($_FF_)) { + is_fine = true; + has_gclk = true; + sig_d = cell->getPort(ID::D); + } else if (type_str.substr(0, 5) == "$_SR_") { + is_fine = true; + has_sr = true; + pol_set = type_str[5] == 'P'; + pol_clr = type_str[6] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 8) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[6] == 'P'; + sig_clk = cell->getPort(ID::C); + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 10) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_ce = true; + pol_ce = type_str[8] == 'P'; + sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[6] == 'P'; + sig_clk = cell->getPort(ID::C); + has_arst = true; + pol_arst = type_str[7] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[8] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 12) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_arst = true; + pol_arst = type_str[8] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[9] == '1' ? State::S1 : State::S0; + has_ce = true; + pol_ce = type_str[10] == 'P'; + sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 8) == "$_ALDFF_" && type_str.size() == 11) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::L); + sig_ad = cell->getPort(ID::AD); + } else if (type_str.substr(0, 9) == "$_ALDFFE_" && type_str.size() == 13) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_aload = true; + pol_aload = type_str[10] == 'P'; + sig_aload = cell->getPort(ID::L); + sig_ad = cell->getPort(ID::AD); + has_ce = true; + pol_ce = type_str[11] == 'P'; + sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_sr = true; + pol_set = type_str[9] == 'P'; + pol_clr = type_str[10] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else if (type_str.substr(0, 9) == "$_DFFSRE_" && type_str.size() == 14) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_sr = true; + pol_set = type_str[10] == 'P'; + pol_clr = type_str[11] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + has_ce = true; + pol_ce = type_str[12] == 'P'; + sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[8] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[9] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 8) == "$_SDFFE_" && type_str.size() == 13) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[9] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[10] == '1' ? State::S1 : State::S0; + has_ce = true; + pol_ce = type_str[11] == 'P'; + sig_ce = cell->getPort(ID::E); + } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[10] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[11] == '1' ? State::S1 : State::S0; + has_ce = true; + pol_ce = type_str[12] == 'P'; + sig_ce = cell->getPort(ID::E); + ce_over_srst = true; + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { + is_fine = true; + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::E); + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { + is_fine = true; + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[9] == 'P'; + sig_aload = cell->getPort(ID::E); + has_arst = true; + pol_arst = type_str[10] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[11] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { + is_fine = true; + has_aload = true; + sig_ad = cell->getPort(ID::D); + has_aload = true; + pol_aload = type_str[11] == 'P'; + sig_aload = cell->getPort(ID::E); + has_sr = true; + pol_set = type_str[12] == 'P'; + pol_clr = type_str[13] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else { + log_assert(0); + } + if (has_aload && !has_clk && !has_sr && !has_arst && sig_ad.is_fully_const()) { + // Plain D latches with const D treated specially. + has_aload = false; + has_arst = true; + sig_arst = sig_aload; + pol_arst = pol_aload; + val_arst = sig_ad.as_const(); + } +} + +FfData FfData::slice(const std::vector &bits) { + FfData res(module, initvals, NEW_ID); + res.sig_clk = sig_clk; + res.sig_ce = sig_ce; + res.sig_aload = sig_aload; + res.sig_arst = sig_arst; + res.sig_srst = sig_srst; + res.has_clk = has_clk; + res.has_gclk = has_gclk; + res.has_ce = has_ce; + res.has_aload = has_aload; + res.has_arst = has_arst; + res.has_srst = has_srst; + res.has_sr = has_sr; + res.ce_over_srst = ce_over_srst; + res.is_fine = is_fine; + res.pol_clk = pol_clk; + res.pol_ce = pol_ce; + res.pol_aload = pol_aload; + res.pol_arst = pol_arst; + res.pol_srst = pol_srst; + res.pol_clr = pol_clr; + res.pol_set = pol_set; + res.attributes = attributes; + for (int i : bits) { + res.sig_q.append(sig_q[i]); + if (has_clk || has_gclk) + res.sig_d.append(sig_d[i]); + if (has_aload) + res.sig_ad.append(sig_ad[i]); + if (has_sr) { + res.sig_clr.append(sig_clr[i]); + res.sig_set.append(sig_set[i]); + } + if (has_arst) + res.val_arst.bits.push_back(val_arst[i]); + if (has_srst) + res.val_srst.bits.push_back(val_srst[i]); + if (initvals) + res.val_init.bits.push_back(val_init[i]); + } + res.width = GetSize(res.sig_q); + return res; +} + +void FfData::unmap_ce() { + if (!has_ce) + return; + log_assert(has_clk); + if (has_srst && ce_over_srst) + unmap_srst(); + + if (!is_fine) { + if (pol_ce) + sig_d = module->Mux(NEW_ID, sig_q, sig_d, sig_ce); + else + sig_d = module->Mux(NEW_ID, sig_d, sig_q, sig_ce); + } else { + if (pol_ce) + sig_d = module->MuxGate(NEW_ID, sig_q, sig_d, sig_ce); + else + sig_d = module->MuxGate(NEW_ID, sig_d, sig_q, sig_ce); + } + has_ce = false; +} + +void FfData::unmap_srst() { + if (!has_srst) + return; + if (has_ce && !ce_over_srst) + unmap_ce(); + + if (!is_fine) { + if (pol_srst) + sig_d = module->Mux(NEW_ID, sig_d, val_srst, sig_srst); + else + sig_d = module->Mux(NEW_ID, val_srst, sig_d, sig_srst); + } else { + if (pol_srst) + sig_d = module->MuxGate(NEW_ID, sig_d, val_srst[0], sig_srst); + else + sig_d = module->MuxGate(NEW_ID, val_srst[0], sig_d, sig_srst); + } + has_srst = false; +} + +Cell *FfData::emit() { + remove(); + if (!width) + return nullptr; + if (!has_aload && !has_clk && !has_gclk && !has_sr) { + if (has_arst) { + // Convert this case to a D latch. + has_aload = true; + has_arst = false; + sig_ad = val_arst; + sig_aload = sig_arst; + pol_aload = pol_arst; + } else { + // No control inputs left. Turn into a const driver. + module->connect(sig_q, val_init); + return nullptr; + } + } + if (initvals) + initvals->set_init(sig_q, val_init); + if (!is_fine) { + if (has_gclk) { + log_assert(!has_clk); + log_assert(!has_ce); + log_assert(!has_aload); + log_assert(!has_arst); + log_assert(!has_srst); + log_assert(!has_sr); + cell = module->addFf(name, sig_d, sig_q); + } else if (!has_aload && !has_clk) { + log_assert(has_sr); + cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); + } else if (!has_clk) { + log_assert(!has_srst); + if (has_sr) + cell = module->addDlatchsr(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); + else if (has_arst) + cell = module->addAdlatch(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst); + else + cell = module->addDlatch(name, sig_aload, sig_ad, sig_q, pol_aload); + } else { + if (has_sr) { + if (has_ce) + cell = module->addDffsre(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); + else + cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); + } else if (has_arst) { + if (has_ce) + cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst); + else + cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst); + } else if (has_aload) { + if (has_ce) + cell = module->addAldffe(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); + else + cell = module->addAldff(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); + } else if (has_srst) { + if (has_ce) + if (ce_over_srst) + cell = module->addSdffce(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); + else + cell = module->addSdffe(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); + else + cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst); + } else { + if (has_ce) + cell = module->addDffe(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); + else + cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk); + } + } + } else { + if (has_gclk) { + log_assert(!has_clk); + log_assert(!has_ce); + log_assert(!has_aload); + log_assert(!has_arst); + log_assert(!has_srst); + log_assert(!has_sr); + cell = module->addFfGate(name, sig_d, sig_q); + } else if (!has_aload && !has_clk) { + log_assert(has_sr); + cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); + } else if (!has_clk) { + log_assert(!has_srst); + if (has_sr) + cell = module->addDlatchsrGate(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); + else if (has_arst) + cell = module->addAdlatchGate(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst); + else + cell = module->addDlatchGate(name, sig_aload, sig_ad, sig_q, pol_aload); + } else { + if (has_sr) { + if (has_ce) + cell = module->addDffsreGate(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); + else + cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); + } else if (has_arst) { + if (has_ce) + cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst); + else + cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst); + } else if (has_aload) { + if (has_ce) + cell = module->addAldffeGate(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); + else + cell = module->addAldffGate(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); + } else if (has_srst) { + if (has_ce) + if (ce_over_srst) + cell = module->addSdffceGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); + else + cell = module->addSdffeGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); + else + cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst); + } else { + if (has_ce) + cell = module->addDffeGate(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); + else + cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk); + } + } + } + cell->attributes = attributes; + return cell; +} + +void FfData::remove() { + if (cell) { + remove_init(); + module->remove(cell); + cell = nullptr; + } +} + +namespace { + State invert(State s) { + switch (s) { + case State::S0: return State::S1; + case State::S1: return State::S0; + default: return s; + } + } +} + +void FfData::flip_bits(const pool &bits) { + if (!bits.size()) + return; + + remove_init(); + + Wire *new_q = module->addWire(NEW_ID, width); + + for (auto bit: bits) { + if (has_arst) + val_arst[bit] = invert(val_arst[bit]); + if (has_srst) + val_srst[bit] = invert(val_srst[bit]); + val_init[bit] = invert(val_init[bit]); + } + + if (has_sr && cell) { + log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].", log_id(module->name), log_id(cell->name), log_id(cell->type)); + } + + if (is_fine) { + if (has_sr) { + bool new_pol_clr = pol_set; + SigSpec new_sig_clr; + if (pol_set) { + if (pol_clr) { + new_sig_clr = module->AndnotGate(NEW_ID, sig_set, sig_clr); + } else { + new_sig_clr = module->AndGate(NEW_ID, sig_set, sig_clr); + } + } else { + if (pol_clr) { + new_sig_clr = module->OrGate(NEW_ID, sig_set, sig_clr); + } else { + new_sig_clr = module->OrnotGate(NEW_ID, sig_set, sig_clr); + } + } + pol_set = pol_clr; + sig_set = sig_clr; + pol_clr = new_pol_clr; + sig_clr = new_sig_clr; + } + if (has_clk || has_gclk) + sig_d = module->NotGate(NEW_ID, sig_d); + if (has_aload) + sig_ad = module->NotGate(NEW_ID, sig_ad); + module->addNotGate(NEW_ID, new_q, sig_q); + } + else + { + if (has_sr) { + SigSpec not_clr; + if (!pol_clr) { + not_clr = sig_clr; + sig_clr = module->Not(NEW_ID, sig_clr); + pol_clr = true; + } else { + not_clr = module->Not(NEW_ID, sig_clr); + } + if (!pol_set) { + sig_set = module->Not(NEW_ID, sig_set); + pol_set = true; + } + + SigSpec masked_set = module->And(NEW_ID, sig_set, not_clr); + for (auto bit: bits) { + sig_set[bit] = sig_clr[bit]; + sig_clr[bit] = masked_set[bit]; + } + } + + Const mask = Const(State::S0, width); + for (auto bit: bits) + mask.bits[bit] = State::S1; + + if (has_clk || has_gclk) + sig_d = module->Xor(NEW_ID, sig_d, mask); + if (has_aload) + sig_ad = module->Xor(NEW_ID, sig_ad, mask); + module->addXor(NEW_ID, new_q, mask, sig_q); + } + + sig_q = new_q; +} diff --git a/kernel/ff.h b/kernel/ff.h index 7f01b8a368d..3125f67c698 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -76,7 +76,10 @@ YOSYS_NAMESPACE_BEGIN // - empty set [not a cell — will be emitted as a simple direct connection] struct FfData { + Module *module; FfInitVals *initvals; + Cell *cell; + IdString name; // The FF output. SigSpec sig_q; // The sync data input, present if has_clk or has_gclk. @@ -142,7 +145,7 @@ struct FfData { int width; dict attributes; - FfData(FfInitVals *initvals = nullptr, Cell *cell = nullptr) : initvals(initvals) { + FfData(Module *module = nullptr, FfInitVals *initvals = nullptr, IdString name = IdString()) : module(module), initvals(initvals), cell(nullptr), name(name) { width = 0; has_clk = false; has_gclk = false; @@ -160,464 +163,37 @@ struct FfData { pol_srst = false; pol_clr = false; pol_set = false; - - if (!cell) - return; - - sig_q = cell->getPort(ID::Q); - width = GetSize(sig_q); - attributes = cell->attributes; - - if (initvals) - val_init = (*initvals)(sig_q); - - std::string type_str = cell->type.str(); - - if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { - if (cell->type == ID($ff)) { - has_gclk = true; - sig_d = cell->getPort(ID::D); - } else if (cell->type == ID($sr)) { - // No data input at all. - } else if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { - has_aload = true; - sig_aload = cell->getPort(ID::EN); - pol_aload = cell->getParam(ID::EN_POLARITY).as_bool(); - sig_ad = cell->getPort(ID::D); - } else { - has_clk = true; - sig_clk = cell->getPort(ID::CLK); - pol_clk = cell->getParam(ID::CLK_POLARITY).as_bool(); - sig_d = cell->getPort(ID::D); - } - if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce))) { - has_ce = true; - sig_ce = cell->getPort(ID::EN); - pol_ce = cell->getParam(ID::EN_POLARITY).as_bool(); - } - if (cell->type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) { - has_sr = true; - sig_clr = cell->getPort(ID::CLR); - sig_set = cell->getPort(ID::SET); - pol_clr = cell->getParam(ID::CLR_POLARITY).as_bool(); - pol_set = cell->getParam(ID::SET_POLARITY).as_bool(); - } - if (cell->type.in(ID($aldff), ID($aldffe))) { - has_aload = true; - sig_aload = cell->getPort(ID::ALOAD); - pol_aload = cell->getParam(ID::ALOAD_POLARITY).as_bool(); - sig_ad = cell->getPort(ID::AD); - } - if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) { - has_arst = true; - sig_arst = cell->getPort(ID::ARST); - pol_arst = cell->getParam(ID::ARST_POLARITY).as_bool(); - val_arst = cell->getParam(ID::ARST_VALUE); - } - if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { - has_srst = true; - sig_srst = cell->getPort(ID::SRST); - pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool(); - val_srst = cell->getParam(ID::SRST_VALUE); - ce_over_srst = cell->type == ID($sdffce); - } - } else if (cell->type == ID($_FF_)) { - is_fine = true; - has_gclk = true; - sig_d = cell->getPort(ID::D); - } else if (type_str.substr(0, 5) == "$_SR_") { - is_fine = true; - has_sr = true; - pol_set = type_str[5] == 'P'; - pol_clr = type_str[6] == 'P'; - sig_set = cell->getPort(ID::S); - sig_clr = cell->getPort(ID::R); - } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 8) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[6] == 'P'; - sig_clk = cell->getPort(ID::C); - } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 10) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[7] == 'P'; - sig_clk = cell->getPort(ID::C); - has_ce = true; - pol_ce = type_str[8] == 'P'; - sig_ce = cell->getPort(ID::E); - } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[6] == 'P'; - sig_clk = cell->getPort(ID::C); - has_arst = true; - pol_arst = type_str[7] == 'P'; - sig_arst = cell->getPort(ID::R); - val_arst = type_str[8] == '1' ? State::S1 : State::S0; - } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 12) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[7] == 'P'; - sig_clk = cell->getPort(ID::C); - has_arst = true; - pol_arst = type_str[8] == 'P'; - sig_arst = cell->getPort(ID::R); - val_arst = type_str[9] == '1' ? State::S1 : State::S0; - has_ce = true; - pol_ce = type_str[10] == 'P'; - sig_ce = cell->getPort(ID::E); - } else if (type_str.substr(0, 8) == "$_ALDFF_" && type_str.size() == 11) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[8] == 'P'; - sig_clk = cell->getPort(ID::C); - has_aload = true; - pol_aload = type_str[9] == 'P'; - sig_aload = cell->getPort(ID::L); - sig_ad = cell->getPort(ID::AD); - } else if (type_str.substr(0, 9) == "$_ALDFFE_" && type_str.size() == 13) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[9] == 'P'; - sig_clk = cell->getPort(ID::C); - has_aload = true; - pol_aload = type_str[10] == 'P'; - sig_aload = cell->getPort(ID::L); - sig_ad = cell->getPort(ID::AD); - has_ce = true; - pol_ce = type_str[11] == 'P'; - sig_ce = cell->getPort(ID::E); - } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[8] == 'P'; - sig_clk = cell->getPort(ID::C); - has_sr = true; - pol_set = type_str[9] == 'P'; - pol_clr = type_str[10] == 'P'; - sig_set = cell->getPort(ID::S); - sig_clr = cell->getPort(ID::R); - } else if (type_str.substr(0, 9) == "$_DFFSRE_" && type_str.size() == 14) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[9] == 'P'; - sig_clk = cell->getPort(ID::C); - has_sr = true; - pol_set = type_str[10] == 'P'; - pol_clr = type_str[11] == 'P'; - sig_set = cell->getPort(ID::S); - sig_clr = cell->getPort(ID::R); - has_ce = true; - pol_ce = type_str[12] == 'P'; - sig_ce = cell->getPort(ID::E); - } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[7] == 'P'; - sig_clk = cell->getPort(ID::C); - has_srst = true; - pol_srst = type_str[8] == 'P'; - sig_srst = cell->getPort(ID::R); - val_srst = type_str[9] == '1' ? State::S1 : State::S0; - } else if (type_str.substr(0, 8) == "$_SDFFE_" && type_str.size() == 13) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[8] == 'P'; - sig_clk = cell->getPort(ID::C); - has_srst = true; - pol_srst = type_str[9] == 'P'; - sig_srst = cell->getPort(ID::R); - val_srst = type_str[10] == '1' ? State::S1 : State::S0; - has_ce = true; - pol_ce = type_str[11] == 'P'; - sig_ce = cell->getPort(ID::E); - } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { - is_fine = true; - sig_d = cell->getPort(ID::D); - has_clk = true; - pol_clk = type_str[9] == 'P'; - sig_clk = cell->getPort(ID::C); - has_srst = true; - pol_srst = type_str[10] == 'P'; - sig_srst = cell->getPort(ID::R); - val_srst = type_str[11] == '1' ? State::S1 : State::S0; - has_ce = true; - pol_ce = type_str[12] == 'P'; - sig_ce = cell->getPort(ID::E); - ce_over_srst = true; - } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { - is_fine = true; - has_aload = true; - sig_ad = cell->getPort(ID::D); - has_aload = true; - pol_aload = type_str[9] == 'P'; - sig_aload = cell->getPort(ID::E); - } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { - is_fine = true; - has_aload = true; - sig_ad = cell->getPort(ID::D); - has_aload = true; - pol_aload = type_str[9] == 'P'; - sig_aload = cell->getPort(ID::E); - has_arst = true; - pol_arst = type_str[10] == 'P'; - sig_arst = cell->getPort(ID::R); - val_arst = type_str[11] == '1' ? State::S1 : State::S0; - } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { - is_fine = true; - has_aload = true; - sig_ad = cell->getPort(ID::D); - has_aload = true; - pol_aload = type_str[11] == 'P'; - sig_aload = cell->getPort(ID::E); - has_sr = true; - pol_set = type_str[12] == 'P'; - pol_clr = type_str[13] == 'P'; - sig_set = cell->getPort(ID::S); - sig_clr = cell->getPort(ID::R); - } else { - log_assert(0); - } - if (has_aload && !has_clk && !has_sr && !has_arst && sig_ad.is_fully_const()) { - // Plain D latches with const D treated specially. - has_aload = false; - has_arst = true; - sig_arst = sig_aload; - pol_arst = pol_aload; - val_arst = sig_ad.as_const(); - } } - // Returns a FF identical to this one, but only keeping bit indices from the argument. - FfData slice(const std::vector &bits) { - FfData res(initvals); - res.sig_clk = sig_clk; - res.sig_ce = sig_ce; - res.sig_aload = sig_aload; - res.sig_arst = sig_arst; - res.sig_srst = sig_srst; - res.has_clk = has_clk; - res.has_gclk = has_gclk; - res.has_ce = has_ce; - res.has_aload = has_aload; - res.has_arst = has_arst; - res.has_srst = has_srst; - res.has_sr = has_sr; - res.ce_over_srst = ce_over_srst; - res.is_fine = is_fine; - res.pol_clk = pol_clk; - res.pol_ce = pol_ce; - res.pol_aload = pol_aload; - res.pol_arst = pol_arst; - res.pol_srst = pol_srst; - res.pol_clr = pol_clr; - res.pol_set = pol_set; - res.attributes = attributes; - for (int i : bits) { - res.sig_q.append(sig_q[i]); - if (has_clk || has_gclk) - res.sig_d.append(sig_d[i]); - if (has_aload) - res.sig_ad.append(sig_ad[i]); - if (has_sr) { - res.sig_clr.append(sig_clr[i]); - res.sig_set.append(sig_set[i]); - } - if (has_arst) - res.val_arst.bits.push_back(val_arst[i]); - if (has_srst) - res.val_srst.bits.push_back(val_srst[i]); - if (initvals) - res.val_init.bits.push_back(val_init[i]); - } - res.width = GetSize(res.sig_q); - return res; - } + FfData(FfInitVals *initvals, Cell *cell_); - void unmap_ce(Module *module) { - if (!has_ce) - return; - log_assert(has_clk); - if (has_srst && ce_over_srst) - unmap_srst(module); + // Returns a FF identical to this one, but only keeping bit indices from the argument. + FfData slice(const std::vector &bits); - if (!is_fine) { - if (pol_ce) - sig_d = module->Mux(NEW_ID, sig_q, sig_d, sig_ce); - else - sig_d = module->Mux(NEW_ID, sig_d, sig_q, sig_ce); - } else { - if (pol_ce) - sig_d = module->MuxGate(NEW_ID, sig_q, sig_d, sig_ce); - else - sig_d = module->MuxGate(NEW_ID, sig_d, sig_q, sig_ce); - } - has_ce = false; - } + void unmap_ce(); - void unmap_srst(Module *module) { - if (!has_srst) - return; - if (has_ce && !ce_over_srst) - unmap_ce(module); + void unmap_srst(); - if (!is_fine) { - if (pol_srst) - sig_d = module->Mux(NEW_ID, sig_d, val_srst, sig_srst); - else - sig_d = module->Mux(NEW_ID, val_srst, sig_d, sig_srst); - } else { - if (pol_srst) - sig_d = module->MuxGate(NEW_ID, sig_d, val_srst[0], sig_srst); - else - sig_d = module->MuxGate(NEW_ID, val_srst[0], sig_d, sig_srst); - } - has_srst = false; + void unmap_ce_srst() { + unmap_ce(); + unmap_srst(); } - void unmap_ce_srst(Module *module) { - unmap_ce(module); - unmap_srst(module); - } + Cell *emit(); - Cell *emit(Module *module, IdString name) { - if (!width) - return nullptr; - if (!has_aload && !has_clk && !has_gclk && !has_sr) { - if (has_arst) { - // Convert this case to a D latch. - has_aload = true; - has_arst = false; - sig_ad = val_arst; - sig_aload = sig_arst; - pol_aload = pol_arst; - } else { - // No control inputs left. Turn into a const driver. - if (initvals) - initvals->remove_init(sig_q); - module->connect(sig_q, val_init); - return nullptr; - } - } + // Removes init attribute from the Q output, but keeps val_init unchanged. + // It will be automatically reattached on emit. Use this before changing sig_q. + void remove_init() { if (initvals) - initvals->set_init(sig_q, val_init); - Cell *cell; - if (!is_fine) { - if (has_gclk) { - log_assert(!has_clk); - log_assert(!has_ce); - log_assert(!has_aload); - log_assert(!has_arst); - log_assert(!has_srst); - log_assert(!has_sr); - cell = module->addFf(name, sig_d, sig_q); - } else if (!has_aload && !has_clk) { - log_assert(has_sr); - cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); - } else if (!has_clk) { - log_assert(!has_srst); - if (has_sr) - cell = module->addDlatchsr(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); - else if (has_arst) - cell = module->addAdlatch(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst); - else - cell = module->addDlatch(name, sig_aload, sig_ad, sig_q, pol_aload); - } else { - if (has_sr) { - if (has_ce) - cell = module->addDffsre(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); - else - cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); - } else if (has_arst) { - if (has_ce) - cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst); - else - cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst); - } else if (has_aload) { - if (has_ce) - cell = module->addAldffe(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); - else - cell = module->addAldff(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); - } else if (has_srst) { - if (has_ce) - if (ce_over_srst) - cell = module->addSdffce(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); - else - cell = module->addSdffe(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst); - else - cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst); - } else { - if (has_ce) - cell = module->addDffe(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); - else - cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk); - } - } - } else { - if (has_gclk) { - log_assert(!has_clk); - log_assert(!has_ce); - log_assert(!has_aload); - log_assert(!has_arst); - log_assert(!has_srst); - log_assert(!has_sr); - cell = module->addFfGate(name, sig_d, sig_q); - } else if (!has_aload && !has_clk) { - log_assert(has_sr); - cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); - } else if (!has_clk) { - log_assert(!has_srst); - if (has_sr) - cell = module->addDlatchsrGate(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr); - else if (has_arst) - cell = module->addAdlatchGate(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst); - else - cell = module->addDlatchGate(name, sig_aload, sig_ad, sig_q, pol_aload); - } else { - if (has_sr) { - if (has_ce) - cell = module->addDffsreGate(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr); - else - cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); - } else if (has_arst) { - if (has_ce) - cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst); - else - cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst); - } else if (has_aload) { - if (has_ce) - cell = module->addAldffeGate(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload); - else - cell = module->addAldffGate(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload); - } else if (has_srst) { - if (has_ce) - if (ce_over_srst) - cell = module->addSdffceGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); - else - cell = module->addSdffeGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst); - else - cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst); - } else { - if (has_ce) - cell = module->addDffeGate(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce); - else - cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk); - } - } - } - cell->attributes = attributes; - return cell; + initvals->remove_init(sig_q); } + + void remove(); + + // Flip the sense of the given bit slices of the FF: insert inverters on data + // inputs and output, flip the corresponding init/reset bits, swap clr/set + // inputs with proper priority fix. + void flip_bits(const pool &bits); }; YOSYS_NAMESPACE_END diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc index 7d62a88cfc5..4ca5bcbb4bb 100644 --- a/kernel/ffmerge.cc +++ b/kernel/ffmerge.cc @@ -29,7 +29,7 @@ bool FfMergeHelper::is_output_unused(RTLIL::SigSpec sig) { } bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { - ff = FfData(); + ff = FfData(module, initvals, NEW_ID); sigmap->apply(sig); bool found = false; diff --git a/kernel/mem.cc b/kernel/mem.cc index 40659b15b1b..746f667ea77 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -955,7 +955,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { } IdString name = stringf("$%s$rdreg[%d]", memid.c_str(), idx); - FfData ff(initvals); + FfData ff(module, initvals, name); ff.width = GetSize(port.data); ff.has_clk = true; ff.sig_clk = port.clk; @@ -982,7 +982,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { ff.sig_q = port.data; ff.val_init = port.init_value; port.data = async_d; - c = ff.emit(module, name); + c = ff.emit(); } log("Extracted %s FF from read port %d of %s.%s: %s\n", trans_use_addr ? "addr" : "data", @@ -1160,7 +1160,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) { // The FF for storing the bypass enable signal must be carefully // constructed to preserve the overall init/reset/enable behavior // of the whole port. - FfData ff(initvals); + FfData ff(module, initvals, NEW_ID); ff.width = 1; ff.sig_q = cond_q; ff.sig_d = cond; @@ -1189,7 +1189,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) { ff.val_init = State::S0; else ff.val_init = State::Sx; - ff.emit(module, NEW_ID); + ff.emit(); // And the final bypass mux. SigSpec cur = rdata_a.extract(pos, epos-pos); SigSpec other = wdata_q.extract(pos + wsub * width, epos-pos); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index b87ecdd9987..91209d42876 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -581,7 +581,7 @@ struct MemoryDffWorker // Now we're commited to merge it. merger.mark_input_ff(bits); // If the address FF has enable and/or sync reset, unmap it. - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); port.clk = ff.sig_clk; port.en = State::S1; port.addr = ff.sig_d; diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 0e25484b8d3..38faba15ab5 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -275,7 +275,7 @@ struct OptDffWorker bool changed = false; if (!ff.width) { - module->remove(cell); + ff.remove(); did_something = true; continue; } @@ -316,6 +316,7 @@ struct OptDffWorker continue; } ff = ff.slice(keep_bits); + ff.cell = cell; changed = true; } @@ -393,8 +394,7 @@ struct OptDffWorker // Always-active enable. Make a comb circuit, nuke the FF/latch. log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", log_id(cell), log_id(cell->type), log_id(module)); - initvals.remove_init(ff.sig_q); - module->remove(cell); + ff.remove(); if (ff.has_sr) { SigSpec tmp; if (ff.is_fine) { @@ -456,8 +456,7 @@ struct OptDffWorker // Always-active async reset — change to const driver. log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", log_id(cell), log_id(cell->type), log_id(module)); - initvals.remove_init(ff.sig_q); - module->remove(cell); + ff.remove(); module->connect(ff.sig_q, ff.val_arst); did_something = true; continue; @@ -660,6 +659,7 @@ struct OptDffWorker continue; } ff = ff.slice(keep_bits); + ff.cell = cell; changed = true; } @@ -728,7 +728,7 @@ struct OptDffWorker new_ff.pol_srst = srst.second; if (new_ff.has_ce) new_ff.ce_over_srst = true; - Cell *new_cell = new_ff.emit(module, NEW_ID); + Cell *new_cell = new_ff.emit(); if (new_cell) dff_cells.push_back(new_cell); log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", @@ -741,6 +741,7 @@ struct OptDffWorker continue; } else if (GetSize(remaining_indices) != ff.width) { ff = ff.slice(remaining_indices); + ff.cell = cell; changed = true; } } @@ -790,7 +791,7 @@ struct OptDffWorker new_ff.sig_ce = en.first; new_ff.pol_ce = en.second; new_ff.ce_over_srst = false; - Cell *new_cell = new_ff.emit(module, NEW_ID); + Cell *new_cell = new_ff.emit(); if (new_cell) dff_cells.push_back(new_cell); log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", @@ -803,6 +804,7 @@ struct OptDffWorker continue; } else if (GetSize(remaining_indices) != ff.width) { ff = ff.slice(remaining_indices); + ff.cell = cell; changed = true; } } @@ -810,9 +812,7 @@ struct OptDffWorker if (changed) { // Rebuild the FF. - IdString name = cell->name; - module->remove(cell); - ff.emit(module, name); + ff.emit(); did_something = true; } } diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index f1b93d08472..46c76eba960 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -78,7 +78,7 @@ struct Async2syncPass : public Pass { if (ff.has_clk) { if (ff.has_sr) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -124,7 +124,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_sr = false; } else if (ff.has_aload) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -157,7 +157,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_aload = false; } else if (ff.has_arst) { - ff.unmap_srst(module); + ff.unmap_srst(); log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -267,10 +267,7 @@ struct Async2syncPass : public Pass { ff.has_sr = false; ff.has_gclk = true; } - - IdString name = cell->name; - module->remove(cell); - ff.emit(module, name); + ff.emit(); } } } diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index d90206b465a..a292941c8bf 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -153,6 +153,23 @@ struct Clk2fflogicPass : public Pass { continue; } + if (ff.has_clk) { + log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); + } else if (ff.has_aload) { + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); + } else { + // $sr. + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); + } + + ff.remove(); + Wire *past_q = module->addWire(NEW_ID, ff.width); if (!ff.is_fine) { module->addFf(NEW_ID, ff.sig_q, past_q); @@ -163,7 +180,7 @@ struct Clk2fflogicPass : public Pass { initvals.set_init(past_q, ff.val_init); if (ff.has_clk) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); Wire *past_clk = module->addWire(NEW_ID); initvals.set_init(past_clk, ff.pol_clk ? State::S1 : State::S0); @@ -173,10 +190,6 @@ struct Clk2fflogicPass : public Pass { else module->addFfGate(NEW_ID, ff.sig_clk, past_clk); - log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); - SigSpec clock_edge_pattern; if (ff.pol_clk) { @@ -203,16 +216,6 @@ struct Clk2fflogicPass : public Pass { else qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); } else { - if (ff.has_aload) { - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); - } else { - // $sr. - log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - } qval = past_q; } @@ -246,10 +249,6 @@ struct Clk2fflogicPass : public Pass { } else { module->connect(ff.sig_q, qval); } - - initvals.remove_init(ff.sig_q); - module->remove(cell); - continue; } } } diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc index 583185e75bc..7312015f1e5 100644 --- a/passes/techmap/dffunmap.cc +++ b/passes/techmap/dffunmap.cc @@ -86,19 +86,18 @@ struct DffunmapPass : public Pass { if (ce_only) { if (!ff.has_ce) continue; - ff.unmap_ce(mod); + ff.unmap_ce(); } else if (srst_only) { if (!ff.has_srst) continue; - ff.unmap_srst(mod); + ff.unmap_srst(); } else { if (!ff.has_ce && !ff.has_srst) continue; - ff.unmap_ce_srst(mod); + ff.unmap_ce_srst(); } - mod->remove(cell); - ff.emit(mod, name); + ff.emit(); } } } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 04d7ec87471..68f44cf6d75 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -368,13 +368,13 @@ void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) module->connect(RTLIL::SigSig(sig_y, sig_ab)); } -void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell) +void simplemap_ff(RTLIL::Module *, RTLIL::Cell *cell) { FfData ff(nullptr, cell); for (int i = 0; i < ff.width; i++) { FfData fff = ff.slice({i}); fff.is_fine = true; - fff.emit(module, NEW_ID); + fff.emit(); } } diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 8fcc47570a5..cc208c5169c 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -25,14 +25,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -State invert(State s) { - switch (s) { - case State::S0: return State::S1; - case State::S1: return State::S0; - default: return s; - } -} - struct ZinitPass : public Pass { ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } void help() override @@ -75,45 +67,19 @@ struct ZinitPass : public Pass { continue; FfData ff(&initvals, cell); - if (!ff.width) - continue; - - // Supporting those would require a new cell type where S has priority over R. - if (ff.has_sr) - continue; - - Wire *new_q = module->addWire(NEW_ID, ff.width); log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), log_signal(ff.sig_q), log_signal(ff.val_init)); - IdString name = cell->name; - module->remove(cell); - initvals.remove_init(ff.sig_q); - - for (int i = 0; i < ff.width; i++) - if (ff.val_init[i] == State::S1) - { - if (ff.has_clk || ff.has_gclk) - ff.sig_d[i] = module->NotGate(NEW_ID, ff.sig_d[i]); - if (ff.has_aload) - ff.sig_ad[i] = module->NotGate(NEW_ID, ff.sig_ad[i]); - if (ff.has_arst) - ff.val_arst[i] = invert(ff.val_arst[i]); - if (ff.has_srst) - ff.val_srst[i] = invert(ff.val_srst[i]); - module->addNotGate(NEW_ID, SigSpec(new_q, i), ff.sig_q[i]); - ff.val_init[i] = State::S0; - } - else - { - module->connect(ff.sig_q[i], SigSpec(new_q, i)); - if (all_mode) - ff.val_init[i] = State::S0; - } - - ff.sig_q = new_q; - ff.emit(module, name); + pool bits; + for (int i = 0; i < ff.width; i++) { + if (ff.val_init.bits[i] == State::S1) + bits.insert(i); + else if (ff.val_init.bits[i] != State::S0 && all_mode) + ff.val_init.bits[i] = State::S0; + } + ff.flip_bits(bits); + ff.emit(); } } } diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index ace646af48a..3b191962707 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -31,6 +31,7 @@ stat select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 1 t:LUT1 -select -assert-count 8 t:LUT4 +select -assert-max 1 t:LUT3 +select -assert-max 8 t:LUT4 select -assert-count 5 t:MUXF5 -select -assert-none t:BUFG t:FDRE t:LUT1 t:LUT4 t:MUXF5 %% t:* %D +select -assert-none t:BUFG t:FDRE t:LUT1 t:LUT3 t:LUT4 t:MUXF5 %% t:* %D diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys index 1670573dd50..bc07f40e6ce 100644 --- a/tests/techmap/zinit.ys +++ b/tests/techmap/zinit.ys @@ -20,7 +20,8 @@ EOT equiv_opt -assert -multiclock zinit design -load postopt -select -assert-count 20 t:$_NOT_ +select -assert-count 16 t:$_NOT_ +select -assert-count 4 t:$xor select -assert-count 1 w:unused a:init %i select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??1_ %i @@ -52,7 +53,7 @@ design -load postopt select -assert-count 0 t:$_NOT_ select -assert-count 1 w:unused a:init %i -select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i +select -assert-count 1 w:Q a:init=13'bx00x100000000 %i select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??0_ %i select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFF_??1_ %i @@ -142,7 +143,7 @@ EOT zinit select -assert-count 0 t:$_NOT_ -select -assert-count 0 w:Q a:init %i +select -assert-count 1 w:Q a:init=24'b0 %i select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFFE_??0P_ %i select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFFE_??1P_ %i select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$_SDFF_??0_ %i From 772b9a108a7370f090790e1887585cfabbf11ac7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 8 Oct 2021 00:57:28 +0000 Subject: [PATCH 0547/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a2cad5dce04..16035c94e42 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+12 +YOSYS_VER := 0.10+14 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From dc8da76282e806e7ffd632af3e6c11d645ff5699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 8 Oct 2021 14:51:57 +0200 Subject: [PATCH 0548/2410] Fix a regression from #3035. --- kernel/ffmerge.cc | 2 +- tests/memories/trans_addr_enable.v | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/memories/trans_addr_enable.v diff --git a/kernel/ffmerge.cc b/kernel/ffmerge.cc index 4ca5bcbb4bb..c6510841391 100644 --- a/kernel/ffmerge.cc +++ b/kernel/ffmerge.cc @@ -157,7 +157,7 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool> &bits) { - ff = FfData(); + ff = FfData(module, initvals, NEW_ID); sigmap->apply(sig); bool found = false; diff --git a/tests/memories/trans_addr_enable.v b/tests/memories/trans_addr_enable.v new file mode 100644 index 00000000000..f366f41adf5 --- /dev/null +++ b/tests/memories/trans_addr_enable.v @@ -0,0 +1,21 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk + +module top(input clk, we, rae, input [7:0] addr, wd, output [7:0] rd); + +reg [7:0] mem[0:255]; + +reg [7:0] rra; + +always @(posedge clk) begin + if (we) + mem[addr] <= wd; + + if (rae) + rra <= addr; +end + +assign rd = mem[rra]; + +endmodule From 1602a0386419495993f25667c7c6e5fb55010592 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Fri, 8 Oct 2021 16:21:25 +0200 Subject: [PATCH 0549/2410] Add support for $aldff flip-flops to verific importer Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 55 +++++++++++++++++++++++++++++++++++- frontends/verific/verific.h | 1 + 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 23100375396..cbbae7417ce 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -410,6 +410,20 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == PRIM_DFF) + { + VerificClocking clocking(this, inst->GetClock()); + log_assert(clocking.disable_sig == State::S0); + log_assert(clocking.body_net == nullptr); + + if (inst->GetAsyncVal()->IsGnd()) + clocking.addDff(inst_name, net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + else + clocking.addAldff(inst_name, net_map_at(inst->GetAsyncCond()), net_map_at(inst->GetAsyncVal()), + net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + return true; + } + return false; } @@ -792,6 +806,34 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == OPER_WIDE_DFF) + { + VerificClocking clocking(this, inst->GetClock()); + log_assert(clocking.disable_sig == State::S0); + log_assert(clocking.body_net == nullptr); + + RTLIL::SigSpec sig_d = IN; + RTLIL::SigSpec sig_q = OUT; + RTLIL::SigSpec sig_adata = IN1; + RTLIL::SigSpec sig_acond = IN2; + + if (sig_acond.is_fully_const() && !sig_acond.as_bool()) { + cell = clocking.addDff(inst_name, sig_d, sig_q); + import_attributes(cell->attributes, inst); + } else { + int offset = 0, width = 0; + for (offset = 0; offset < GetSize(sig_acond); offset += width) { + for (width = 1; offset+width < GetSize(sig_acond); width++) + if (sig_acond[offset] != sig_acond[offset+width]) break; + cell = clocking.addAldff(inst_name, sig_acond[offset], sig_adata.extract(offset, width), + sig_d.extract(offset, width), sig_q.extract(offset, width)); + import_attributes(cell->attributes, inst); + } + } + + return true; + } + #undef IN #undef IN1 #undef IN2 @@ -1806,6 +1848,17 @@ Cell *VerificClocking::addDffsr(IdString name, RTLIL::SigSpec sig_set, RTLIL::Si return module->addDffsr(name, clock_sig, sig_set, sig_clr, sig_d, sig_q, posedge); } +Cell *VerificClocking::addAldff(IdString name, RTLIL::SigSpec sig_aload, RTLIL::SigSpec sig_adata, SigSpec sig_d, SigSpec sig_q) +{ + log_assert(gclk == false); + log_assert(disable_sig == State::S0); + + if (enable_sig != State::S1) + sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig); + + return module->addAldff(name, clock_sig, sig_aload, sig_d, sig_q, sig_adata, posedge); +} + // ================================================================== struct VerificExtNets @@ -2313,7 +2366,7 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_preserve_user_nets", 1); RuntimeFlags::SetVar("db_allow_external_nets", 1); RuntimeFlags::SetVar("db_infer_wide_operators", 1); - RuntimeFlags::SetVar("db_infer_set_reset_registers",1); + RuntimeFlags::SetVar("db_infer_set_reset_registers", 1); RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index f79d8042ad0..9d5beb787f4 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -50,6 +50,7 @@ struct VerificClocking { RTLIL::Cell *addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const init_value = Const()); RTLIL::Cell *addAdff(IdString name, RTLIL::SigSpec sig_arst, SigSpec sig_d, SigSpec sig_q, Const arst_value); RTLIL::Cell *addDffsr(IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, SigSpec sig_d, SigSpec sig_q); + RTLIL::Cell *addAldff(IdString name, RTLIL::SigSpec sig_aload, RTLIL::SigSpec sig_adata, SigSpec sig_d, SigSpec sig_q); bool property_matches_sequence(const VerificClocking &seq) const { if (clock_net != seq.clock_net) From 34f1df84357e8d053b930970ff53e24f35e1b1b9 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Fri, 8 Oct 2021 17:24:45 +0200 Subject: [PATCH 0550/2410] Fixes and add comments for open FIXME items Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cbbae7417ce..59fdda06839 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -410,13 +410,23 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == PRIM_DLATCHRS) + { + if (inst->GetSet()->IsGnd() && inst->GetReset()->IsGnd()) + module->addDlatch(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + else + module->addDlatchsr(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetSet()), net_map_at(inst->GetReset()), + net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_DFF) { VerificClocking clocking(this, inst->GetClock()); log_assert(clocking.disable_sig == State::S0); log_assert(clocking.body_net == nullptr); - if (inst->GetAsyncVal()->IsGnd()) + if (inst->GetAsyncCond()->IsGnd()) clocking.addDff(inst_name, net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); else clocking.addAldff(inst_name, net_map_at(inst->GetAsyncCond()), net_map_at(inst->GetAsyncVal()), @@ -424,6 +434,8 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr return true; } + // FIXME: PRIM_DLATCH + return false; } @@ -534,6 +546,23 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == PRIM_DFF) + { + VerificClocking clocking(this, inst->GetClock()); + log_assert(clocking.disable_sig == State::S0); + log_assert(clocking.body_net == nullptr); + + if (inst->GetAsyncCond()->IsGnd()) + cell = clocking.addDff(inst_name, net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + else + cell = clocking.addAldff(inst_name, net_map_at(inst->GetAsyncCond()), net_map_at(inst->GetAsyncVal()), + net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + import_attributes(cell->attributes, inst); + return true; + } + + // FIXME: PRIM_DLATCH + #define IN operatorInput(inst) #define IN1 operatorInput1(inst) #define IN2 operatorInput2(inst) @@ -806,6 +835,8 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + // FIXME: OPER_WIDE_DLATCHSR + if (inst->Type() == OPER_WIDE_DFF) { VerificClocking clocking(this, inst->GetClock()); @@ -834,6 +865,8 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + // FIXME: OPER_WIDE_DLATCH + #undef IN #undef IN1 #undef IN2 From d8f6d7b18d23a588fc537f12aef3c4c8ddbe3418 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 9 Oct 2021 00:51:28 +0000 Subject: [PATCH 0551/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 16035c94e42..f90670b0834 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+14 +YOSYS_VER := 0.10+16 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From ff8e999a7112a1975d268e6ebb3e751f6f0364c7 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 9 Oct 2021 13:40:55 +0200 Subject: [PATCH 0552/2410] Split module ports, 20 per line --- backends/verilog/verilog_backend.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 6fb14d7fc84..dc5c188c0a0 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2062,6 +2062,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) dump_attributes(f, indent, module->attributes, '\n', /*modattr=*/true); f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str()); bool keep_running = true; + int cnt = 0; for (int port_id = 1; keep_running; port_id++) { keep_running = false; for (auto wire : module->wires()) { @@ -2070,6 +2071,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) f << stringf(", "); f << stringf("%s", id(wire->name).c_str()); keep_running = true; + if (cnt==20) { f << stringf("\n"); cnt = 0; } else cnt++; continue; } } From 93fbc9fba4400814a859a9d9bfb05b3b92500e31 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 10 Oct 2021 10:01:45 +0200 Subject: [PATCH 0553/2410] Import module attributes from Verific --- frontends/verific/verific.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 23100375396..c03e16eb226 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -917,6 +917,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se } else { log("Importing module %s.\n", RTLIL::id2cstr(module->name)); } + import_attributes(module->attributes, nl, nl); SetIter si; MapIter mi, mi2; From c8074769b081f26b2129910502dd9031acd01a2a Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 11 Oct 2021 10:00:20 +0200 Subject: [PATCH 0554/2410] Add Verific adffe/dffsre/aldffe FIXMEs Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 59fdda06839..b8742e61d5c 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1864,6 +1864,7 @@ Cell *VerificClocking::addAdff(IdString name, RTLIL::SigSpec sig_arst, SigSpec s log_assert(gclk == false); log_assert(disable_sig == State::S0); + // FIXME: Adffe if (enable_sig != State::S1) sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig); @@ -1875,6 +1876,7 @@ Cell *VerificClocking::addDffsr(IdString name, RTLIL::SigSpec sig_set, RTLIL::Si log_assert(gclk == false); log_assert(disable_sig == State::S0); + // FIXME: Dffsre if (enable_sig != State::S1) sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig); @@ -1886,6 +1888,7 @@ Cell *VerificClocking::addAldff(IdString name, RTLIL::SigSpec sig_aload, RTLIL:: log_assert(gclk == false); log_assert(disable_sig == State::S0); + // FIXME: Aldffe if (enable_sig != State::S1) sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig); From a0f5ba850111c6edc471d070057fa07b073141f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Oct 2021 00:57:44 +0000 Subject: [PATCH 0555/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f90670b0834..a3b661c53dd 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+16 +YOSYS_VER := 0.10+25 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 1aa68969660549ae9c0fd683c0a328c499694b49 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 14 Oct 2021 13:04:32 +0200 Subject: [PATCH 0556/2410] Support PRIM_BUFIF1 primitive --- frontends/verific/verific.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 74638dc8d70..fcacbd086df 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -371,7 +371,7 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr return true; } - if (inst->Type() == PRIM_TRI) { + if ((inst->Type() == PRIM_TRI) || (inst->Type() == PRIM_BUFIF1)) { module->addMuxGate(inst_name, RTLIL::State::Sz, net_map_at(inst->GetInput()), net_map_at(inst->GetControl()), net_map_at(inst->GetOutput())); return true; } @@ -497,7 +497,7 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } - if (inst->Type() == PRIM_TRI) { + if ((inst->Type() == PRIM_TRI) || (inst->Type() == PRIM_BUFIF1)) { cell = module->addMux(inst_name, RTLIL::State::Sz, net_map_at(inst->GetInput()), net_map_at(inst->GetControl()), net_map_at(inst->GetOutput())); import_attributes(cell->attributes, inst); return true; From 0dd42d406d3dc5eaa73e19396f4e49cb9182130f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Oct 2021 00:58:22 +0000 Subject: [PATCH 0557/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a3b661c53dd..1b9a65dbe88 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+25 +YOSYS_VER := 0.10+28 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 6253d4ec9e782d0d36ec429fa6ac84d500edbda5 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Thu, 14 Oct 2021 16:56:10 +0200 Subject: [PATCH 0558/2410] CycloneV: Add (passthrough) support for cyclonev_hps_interface_mpu_general_purpose --- techlibs/intel_alm/common/megafunction_bb.v | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index 414d1c9410e..bab665732a9 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -697,3 +697,11 @@ output outclk; endmodule +// HPS interfaces +(* keep *) +module cyclonev_hps_interface_mpu_general_purpose(gp_in, gp_out); + +input [31:0] gp_in; +output [31:0] gp_out; + +endmodule From 6e78a80ff915639c99bf0e4bbd44d4c7f7f20df1 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sun, 17 Oct 2021 20:00:03 +0200 Subject: [PATCH 0559/2410] CycloneV: Add (passthrough) support for cyclonev_oscillator --- techlibs/intel_alm/common/megafunction_bb.v | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index bab665732a9..d4ed9517384 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -697,11 +697,21 @@ output outclk; endmodule +// Internal interfaces +(* keep *) +module cyclonev_oscillator(oscena, clkout, clkout1); + +input oscena; +output clkout; +output clkout1; + +endmodule + // HPS interfaces (* keep *) module cyclonev_hps_interface_mpu_general_purpose(gp_in, gp_out); -input [31:0] gp_in; +input [31:0] gp_in; output [31:0] gp_out; endmodule From 3efc14f5ad856842725a96af0a49c046c622a52d Mon Sep 17 00:00:00 2001 From: Paul Annesley Date: Sun, 17 Oct 2021 12:56:32 +1100 Subject: [PATCH 0560/2410] dfflegalize: remove redundant check for initialized dlatch This if condition is repeated verbatim, and I can't imagine a legitimate way the inputs could change in between. I imagine it's a copy/paste mistake. --- passes/techmap/dfflegalize.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index c1e7e557d92..5210d01eb98 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -718,10 +718,6 @@ flip_dqisr:; goto error; } - if (!(supported_dlatch & ~INIT_X)) { - reason = "initialized dlatch are not supported"; - goto error; - } // If we got here, initialized dlatch is supported, but not this // particular reset+init combination (nor its negation). // The only hope left is breaking down to adff + dff + dlatch + mux. From a15b01a777c7e122e1ebce6920c58faa94b4dba6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 00:56:23 +0000 Subject: [PATCH 0561/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1b9a65dbe88..423edc07db7 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+28 +YOSYS_VER := 0.10+30 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 83887495b80f8dba24c3c81c96cce6f464efb24e Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 19 Oct 2021 10:56:43 +0200 Subject: [PATCH 0562/2410] Fixes in vcdcd.pl for newer Perl versions Signed-off-by: Claire Xenia Wolf --- tests/tools/vcdcd.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tools/vcdcd.pl b/tests/tools/vcdcd.pl index 58a92b44dfb..0f33371fb8b 100755 --- a/tests/tools/vcdcd.pl +++ b/tests/tools/vcdcd.pl @@ -11,7 +11,7 @@ my $opt_width = 0; my $opt_delay = 0; -while (1) +while ($#ARGV >= 0) { if ($ARGV[0] eq '-w') { $opt_width = +$ARGV[1]; @@ -74,10 +74,10 @@ # next unless $net eq "tst_bench_top.i2c_top.byte_controller.bit_controller.cnt"; my %orig_net_names; print "common signal: $net"; - for my $fullname (keys $gold_signals_hash{$net}) { + for my $fullname (keys %{$gold_signals_hash{$net}}) { $orig_net_names{$fullname} = 1; } - for my $fullname (keys $gate_signals_hash{$net}) { + for my $fullname (keys %{$gate_signals_hash{$net}}) { $orig_net_names{$fullname} = 1; } for my $net (sort keys %orig_net_names) { From fe9689c136bc42dbb3ac4e4ecaaa08d7b4721ab4 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 19 Oct 2021 12:33:01 +0200 Subject: [PATCH 0563/2410] Fixed Verific parser error in ice40 cell library non-net output port 'Q' cannot be initialized at declaration in SystemVerilog mode --- techlibs/ice40/cells_sim.v | 84 ++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f33e92488e6..2e1c6807afe 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1,6 +1,6 @@ `timescale 1ps / 1ps -`define SB_DFF_REG reg Q = 0 -// `define SB_DFF_REG reg Q +`define SB_DFF_INIT initial Q = 0; +// `define SB_DFF_INIT `ifndef NO_ICE40_DEFAULT_ASSIGNMENTS `define ICE40_DEFAULT_ASSIGNMENT_V(v) = v @@ -263,9 +263,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFF ( - output `SB_DFF_REG, + output reg Q, input C, D ); + `SB_DFF_INIT + always @(posedge C) Q <= D; `ifdef ICE40_HX @@ -299,9 +301,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFE ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); + `SB_DFF_INIT + always @(posedge C) if (E) Q <= D; @@ -342,9 +346,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFSR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(posedge C) if (R) Q <= 0; @@ -390,9 +396,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(posedge C, posedge R) if (R) Q <= 0; @@ -459,9 +467,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFSS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(posedge C) if (S) Q <= 1; @@ -507,9 +517,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(posedge C, posedge S) if (S) Q <= 1; @@ -576,9 +588,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESR ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(posedge C) if (E) begin if (R) @@ -632,9 +646,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFER ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(posedge C, posedge R) if (R) Q <= 0; @@ -707,9 +723,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFESS ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(posedge C) if (E) begin if (S) @@ -763,9 +781,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFES ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(posedge C, posedge S) if (S) Q <= 1; @@ -840,9 +860,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFN ( - output `SB_DFF_REG, + output reg Q, input C, D ); + `SB_DFF_INIT + always @(negedge C) Q <= D; `ifdef ICE40_HX @@ -876,9 +898,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNE ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, D ); + `SB_DFF_INIT + always @(negedge C) if (E) Q <= D; @@ -919,9 +943,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNSR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(negedge C) if (R) Q <= 0; @@ -967,9 +993,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNR ( - output `SB_DFF_REG, + output reg Q, input C, R, D ); + `SB_DFF_INIT + always @(negedge C, posedge R) if (R) Q <= 0; @@ -1036,9 +1064,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNSS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(negedge C) if (S) Q <= 1; @@ -1084,9 +1114,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNS ( - output `SB_DFF_REG, + output reg Q, input C, S, D ); + `SB_DFF_INIT + always @(negedge C, posedge S) if (S) Q <= 1; @@ -1153,9 +1185,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESR ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(negedge C) if (E) begin if (R) @@ -1209,9 +1243,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNER ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, R, D ); + `SB_DFF_INIT + always @(negedge C, posedge R) if (R) Q <= 0; @@ -1284,9 +1320,11 @@ endmodule (* abc9_flop, lib_whitebox *) module SB_DFFNESS ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(negedge C) if (E) begin if (S) @@ -1340,9 +1378,11 @@ endmodule (* abc9_box, lib_whitebox *) module SB_DFFNES ( - output `SB_DFF_REG, + output reg Q, input C, E `ICE40_DEFAULT_ASSIGNMENT_1, S, D ); + `SB_DFF_INIT + always @(negedge C, posedge S) if (S) Q <= 1; From 69b2b13ddd98e059f75911fef13718cca23002e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Oct 2021 00:56:49 +0000 Subject: [PATCH 0564/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 423edc07db7..807c81b56e6 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+30 +YOSYS_VER := 0.10+36 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 17269ae59bda6bcf60dbc9ad9d00afc69aa05499 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 20 Oct 2021 10:02:58 +0200 Subject: [PATCH 0565/2410] Option to disable verific VHDL support --- Makefile | 5 ++++ frontends/verific/Makefile.inc | 2 ++ frontends/verific/verific.cc | 54 +++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 807c81b56e6..8c291ec7c74 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ ENABLE_EDITLINE := 0 ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 DISABLE_VERIFIC_EXTENSIONS := 0 +DISABLE_VERIFIC_VHDL := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 ENABLE_PROTOBUF := 0 @@ -500,6 +501,10 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree +ifneq ($(DISABLE_VERIFIC_VHDL),1) +VERIFIC_COMPONENTS += vhdl +CXXFLAGS += -DVERIFIC_VHDL_SUPPORT +endif ifneq ($(DISABLE_VERIFIC_EXTENSIONS),1) VERIFIC_COMPONENTS += extensions CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index 972f4f9f12a..c82428613af 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -10,9 +10,11 @@ EXTRA_TARGETS += share/verific share/verific: $(P) rm -rf share/verific.new $(Q) mkdir -p share/verific.new +ifneq ($(DISABLE_VERIFIC_VHDL),1) $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1987/. share/verific.new/vhdl_vdbs_1987 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1993/. share/verific.new/vhdl_vdbs_1993 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008/. share/verific.new/vhdl_vdbs_2008 +endif $(Q) chmod -R a+rX share/verific.new $(Q) mv share/verific.new share/verific diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index fcacbd086df..a265dc8b4f7 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -43,13 +43,16 @@ USING_YOSYS_NAMESPACE #endif #include "veri_file.h" -#include "vhdl_file.h" #include "hier_tree.h" #include "VeriModule.h" #include "VeriWrite.h" -#include "VhdlUnits.h" #include "VeriLibrary.h" +#ifdef VERIFIC_VHDL_SUPPORT +#include "vhdl_file.h" +#include "VhdlUnits.h" +#endif + #ifdef YOSYSHQ_VERIFIC_EXTENSIONS #include "InitialAssertions.h" #endif @@ -175,8 +178,10 @@ void VerificImporter::import_attributes(dict &att return; if (!type_range->IsTypeEnum()) return; +#ifdef VERIFIC_VHDL_SUPPORT if (nl->IsFromVhdl() && strcmp(type_range->GetTypeName(), "STD_LOGIC") == 0) return; +#endif auto type_name = type_range->GetTypeName(); if (!type_name) return; @@ -202,6 +207,7 @@ void VerificImporter::import_attributes(dict &att log_error("Expected TypeRange value '%s' to be of form 'b.\n", v); attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k)); } +#ifdef VERIFIC_VHDL_SUPPORT else if (nl->IsFromVhdl()) { // Expect "" or plain auto p = v; @@ -237,6 +243,7 @@ void VerificImporter::import_attributes(dict &att if (p == nullptr) log_error("Expected TypeRange value '%s' to be of form \"\" or .\n", v); } +#endif } } } @@ -2042,11 +2049,13 @@ void verific_import(Design *design, const std::map &par std::set nl_todo, nl_done; - VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary("work", 1); VeriLibrary *veri_lib = veri_file::GetLibrary("work", 1); Array *netlists = NULL; Array veri_libs, vhdl_libs; +#ifdef VERIFIC_VHDL_SUPPORT + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary("work", 1); if (vhdl_lib) vhdl_libs.InsertLast(vhdl_lib); +#endif if (veri_lib) veri_libs.InsertLast(veri_lib); Map verific_params(STRING_HASH); @@ -2077,12 +2086,13 @@ void verific_import(Design *design, const std::map &par } } +#ifdef VERIFIC_VHDL_SUPPORT if (vhdl_lib) { VhdlDesignUnit *vhdl_unit = vhdl_lib->GetPrimUnit(top.c_str()); if (vhdl_unit) vhdl_units.InsertLast(vhdl_unit); } - +#endif netlists = hier_tree::Elaborate(&veri_modules, &vhdl_units, &verific_params); } @@ -2119,7 +2129,9 @@ void verific_import(Design *design, const std::map &par } veri_file::Reset(); +#ifdef VERIFIC_VHDL_SUPPORT vhdl_file::Reset(); +#endif Libset::Reset(); verific_incdirs.clear(); verific_libdirs.clear(); @@ -2170,11 +2182,13 @@ struct VerificPass : public Pass { log("Like -sv, but define FORMAL instead of SYNTHESIS.\n"); log("\n"); log("\n"); +#ifdef VERIFIC_VHDL_SUPPORT log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files into Verific.\n"); log("\n"); log("\n"); +#endif log(" verific {-f|-F} \n"); log("\n"); log("Load and execute the specified command file.\n"); @@ -2408,17 +2422,18 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); +#ifdef VERIFIC_VHDL_SUPPORT RuntimeFlags::SetVar("vhdl_extract_dualport_rams", 0); RuntimeFlags::SetVar("vhdl_extract_multiport_rams", 1); RuntimeFlags::SetVar("vhdl_support_variable_slice", 1); RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0); - RuntimeFlags::SetVar("veri_preserve_assignments", 1); RuntimeFlags::SetVar("vhdl_preserve_assignments", 1); - - RuntimeFlags::SetVar("veri_preserve_comments",1); //RuntimeFlags::SetVar("vhdl_preserve_comments",1); +#endif + RuntimeFlags::SetVar("veri_preserve_assignments", 1); + RuntimeFlags::SetVar("veri_preserve_comments",1); // Workaround for VIPER #13851 RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); @@ -2600,6 +2615,7 @@ struct VerificPass : public Pass { goto check_error; } +#ifdef VERIFIC_VHDL_SUPPORT if (GetSize(args) > argidx && args[argidx] == "-vhdl87") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str()); for (argidx++; argidx < GetSize(args); argidx++) @@ -2635,6 +2651,7 @@ struct VerificPass : public Pass { verific_import_pending = true; goto check_error; } +#endif #ifdef YOSYSHQ_VERIFIC_FORMALAPPS if (argidx < GetSize(args) && args[argidx] == "-app") @@ -2737,10 +2754,12 @@ struct VerificPass : public Pass { const char* module = nullptr; bool mode_vhdl = false; for (argidx++; argidx < GetSize(args); argidx++) { +#ifdef VERIFIC_VHDL_SUPPORT if (args[argidx] == "-vhdl") { mode_vhdl = true; continue; } +#endif if (args[argidx] == "-verilog") { mode_vhdl = false; continue; @@ -2767,7 +2786,11 @@ struct VerificPass : public Pass { log_cmd_error("Filname must be specified.\n"); if (mode_vhdl) +#ifdef VERIFIC_VHDL_SUPPORT vhdl_file::PrettyPrint(filename, module, work.c_str()); +#else + goto check_error; +#endif else veri_file::PrettyPrint(filename, module, work.c_str()); goto check_error; @@ -2949,11 +2972,13 @@ struct VerificPass : public Pass { { log("Running hier_tree::ElaborateAll().\n"); - VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); Array veri_libs, vhdl_libs; +#ifdef VERIFIC_VHDL_SUPPORT + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); if (vhdl_lib) vhdl_libs.InsertLast(vhdl_lib); +#endif if (veri_lib) veri_libs.InsertLast(veri_lib); Array *netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, ¶meters); @@ -2970,7 +2995,9 @@ struct VerificPass : public Pass { cmd_error(args, argidx, "No top module specified.\n"); VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); +#ifdef VERIFIC_VHDL_SUPPORT VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); +#endif Array veri_modules, vhdl_units; for (; argidx < GetSize(args); argidx++) @@ -2984,14 +3011,14 @@ struct VerificPass : public Pass { veri_modules.InsertLast(veri_module); continue; } - +#ifdef VERIFIC_VHDL_SUPPORT VhdlDesignUnit *vhdl_unit = vhdl_lib ? vhdl_lib->GetPrimUnit(name) : nullptr; if (vhdl_unit) { log("Adding VHDL unit '%s' to elaboration queue.\n", name); vhdl_units.InsertLast(vhdl_unit); continue; } - +#endif log_error("Can't find module/unit '%s'.\n", name); } @@ -3051,7 +3078,9 @@ struct VerificPass : public Pass { } veri_file::Reset(); +#ifdef VERIFIC_VHDL_SUPPORT vhdl_file::Reset(); +#endif Libset::Reset(); verific_incdirs.clear(); verific_libdirs.clear(); @@ -3094,11 +3123,13 @@ struct ReadPass : public Pass { log("the language version (and before file names) to set additional verilog defines.\n"); log("\n"); log("\n"); +#ifdef VERIFIC_VHDL_SUPPORT log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files. (Requires Verific.)\n"); log("\n"); log("\n"); +#endif log(" read {-f|-F} \n"); log("\n"); log("Load and execute the specified command file. (Requires Verific.)\n"); @@ -3181,6 +3212,7 @@ struct ReadPass : public Pass { return; } +#ifdef VERIFIC_VHDL_SUPPORT if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl") { if (use_verific) { args[0] = "verific"; @@ -3190,7 +3222,7 @@ struct ReadPass : public Pass { } return; } - +#endif if (args[1] == "-f" || args[1] == "-F") { if (use_verific) { args[0] = "verific"; From 150ce305f9d51ec92380eb544e64af3770be5bdb Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 20 Oct 2021 12:37:22 +0200 Subject: [PATCH 0566/2410] Forgot to remove from main list --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8c291ec7c74..4140c16f938 100644 --- a/Makefile +++ b/Makefile @@ -500,7 +500,7 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= verilog vhdl database util containers hier_tree +VERIFIC_COMPONENTS ?= verilog database util containers hier_tree ifneq ($(DISABLE_VERIFIC_VHDL),1) VERIFIC_COMPONENTS += vhdl CXXFLAGS += -DVERIFIC_VHDL_SUPPORT From bf79ff5927d3b31faf0099870445e36211878096 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 20 Oct 2021 13:08:08 +0200 Subject: [PATCH 0567/2410] If verific have vhdl lib it is required by other libs --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 4140c16f938..d1795f8131c 100644 --- a/Makefile +++ b/Makefile @@ -504,6 +504,10 @@ VERIFIC_COMPONENTS ?= verilog database util containers hier_tree ifneq ($(DISABLE_VERIFIC_VHDL),1) VERIFIC_COMPONENTS += vhdl CXXFLAGS += -DVERIFIC_VHDL_SUPPORT +else +ifneq ($(wildcard $(VERIFIC_DIR)/vhdl),) +VERIFIC_COMPONENTS += vhdl +endif endif ifneq ($(DISABLE_VERIFIC_EXTENSIONS),1) VERIFIC_COMPONENTS += extensions From 25c4ed3beb1db18d04a109f39a8e69d09bb67091 Mon Sep 17 00:00:00 2001 From: Daniel Huisman Date: Wed, 20 Oct 2021 14:43:30 +0200 Subject: [PATCH 0568/2410] Fix emcc warnings for WebAssembly build --- Makefile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 9afe458fc89..8abfd7124bf 100644 --- a/Makefile +++ b/Makefile @@ -248,14 +248,15 @@ CXX = emcc LD = emcc CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS)) ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" -EMCCFLAGS := -Os -Wno-warn-absolute-paths -EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1 -EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']" -EMCCFLAGS += -s TOTAL_MEMORY=134217728 -EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' +EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths +EMCC_LDFLAGS := --memory-init-file 0 --embed-file share +EMCC_LDFLAGS := -s NO_EXIT_RUNTIME=1 +EMCC_LDFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']" +EMCC_LDFLAGS += -s TOTAL_MEMORY=134217728 +EMCC_LDFLAGS += -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' # https://github.com/kripken/emscripten/blob/master/src/settings.js -CXXFLAGS += $(EMCCFLAGS) -LDFLAGS += $(EMCCFLAGS) +CXXFLAGS += $(EMCC_CXXFLAGS) +LDFLAGS += $(EMCC_LDFLAGS) LDLIBS = EXE = .js @@ -273,7 +274,7 @@ viz.js: wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js mv viz.js.part viz.js -yosysjs-$(YOSYS_VER).zip: yosys.js yosys.wasm viz.js misc/yosysjs/* +yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/* rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip mkdir -p yosysjs-$(YOSYS_VER) cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/ From a0e9d9fef9af0ed83fd0d4aa2622d056674bf164 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Oct 2021 00:59:29 +0000 Subject: [PATCH 0569/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d1795f8131c..66f9638e19b 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+36 +YOSYS_VER := 0.10+40 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From e64456f92025c26f8b66e77901f78eca726d856a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 21 Oct 2021 02:58:10 +0200 Subject: [PATCH 0570/2410] extract_reduce: Refactor and fix input signal construction. Fixes #3047. --- passes/techmap/extract_reduce.cc | 97 +++++++++++--------------------- tests/opt/bug3047.ys | 12 ++++ 2 files changed, 46 insertions(+), 63 deletions(-) create mode 100644 tests/opt/bug3047.ys diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index 07b4200cc54..b2da126abe4 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -224,89 +224,60 @@ struct ExtractReducePass : public Pass if(consumed_cells.count(head_cell)) continue; - pool cur_supercell; + dict sources; + int inner_cells = 0; std::deque bfs_queue = {head_cell}; while (bfs_queue.size()) { Cell* x = bfs_queue.front(); bfs_queue.pop_front(); - cur_supercell.insert(x); + for (auto port: {ID::A, ID::B}) { + auto bit = sigmap(x->getPort(port)[0]); - auto a = sigmap(x->getPort(ID::A)); - log_assert(a.size() == 1); + bool sink_single = sig_to_sink[bit].size() == 1 && !port_sigs.count(bit); - // Must have only one sink unless we're going off chain - // XXX: Check that it is indeed this node? - if( allow_off_chain || (sig_to_sink[a[0]].size() + port_sigs.count(a[0]) == 1) ) - { - Cell* cell_a = sig_to_driver[a[0]]; - if(cell_a && IsRightType(cell_a, gt)) - { - // The cell here is the correct type, and it's definitely driving - // this current cell. - bfs_queue.push_back(cell_a); - } - } - - auto b = sigmap(x->getPort(ID::B)); - log_assert(b.size() == 1); + Cell* drv = sig_to_driver[bit]; + bool drv_ok = drv && drv->type == head_cell->type; - // Must have only one sink - // XXX: Check that it is indeed this node? - if( allow_off_chain || (sig_to_sink[b[0]].size() + port_sigs.count(b[0]) == 1) ) - { - Cell* cell_b = sig_to_driver[b[0]]; - if(cell_b && IsRightType(cell_b, gt)) - { - // The cell here is the correct type, and it's definitely driving only - // this current cell. - bfs_queue.push_back(cell_b); + if (drv_ok && (allow_off_chain || sink_single)) { + inner_cells++; + bfs_queue.push_back(drv); + } else { + sources[bit]++; } } } - log(" Cells:\n"); - for (auto x : cur_supercell) - log(" %s\n", x->name.c_str()); - - if (cur_supercell.size() > 1) + if (inner_cells) { // Worth it to create reduce cell log(" Creating $reduce_* cell!\n"); - pool input_pool; - pool input_pool_intermed; - for (auto x : cur_supercell) - { - input_pool.insert(sigmap(x->getPort(ID::A))[0]); - input_pool.insert(sigmap(x->getPort(ID::B))[0]); - input_pool_intermed.insert(sigmap(x->getPort(ID::Y))[0]); - } - SigSpec input; - for (auto b : input_pool) - if (input_pool_intermed.count(b) == 0) - input.append(b); - SigBit output = sigmap(head_cell->getPort(ID::Y)[0]); - auto new_reduce_cell = module->addCell(NEW_ID, - gt == GateType::And ? ID($reduce_and) : - gt == GateType::Or ? ID($reduce_or) : - gt == GateType::Xor ? ID($reduce_xor) : ""); - new_reduce_cell->setParam(ID::A_SIGNED, 0); - new_reduce_cell->setParam(ID::A_WIDTH, input.size()); - new_reduce_cell->setParam(ID::Y_WIDTH, 1); - new_reduce_cell->setPort(ID::A, input); - new_reduce_cell->setPort(ID::Y, output); - - if(allow_off_chain) - consumed_cells.insert(head_cell); - else - { - for (auto x : cur_supercell) - consumed_cells.insert(x); + SigSpec input; + for (auto it : sources) { + bool cond; + if (head_cell->type == ID($_XOR_)) + cond = it.second & 1; + else + cond = it.second != 0; + if (cond) + input.append(it.first); + } + + if (head_cell->type == ID($_AND_)) { + module->addReduceAnd(NEW_ID, input, output); + } else if (head_cell->type == ID($_OR_)) { + module->addReduceOr(NEW_ID, input, output); + } else if (head_cell->type == ID($_XOR_)) { + module->addReduceXor(NEW_ID, input, output); + } else { + log_assert(false); } + + consumed_cells.insert(head_cell); } } } diff --git a/tests/opt/bug3047.ys b/tests/opt/bug3047.ys new file mode 100644 index 00000000000..6713877ceb7 --- /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 From 16a177560f27c77ba490ac7dbe9eae3d3766ca1e Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Thu, 21 Oct 2021 05:42:47 +0200 Subject: [PATCH 0571/2410] Initial Verific impoter support for {PRIM,WIDE_OPER}_DLATCH{,RS} Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index a265dc8b4f7..6b303e4b66b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -441,7 +441,11 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr return true; } - // FIXME: PRIM_DLATCH + if (inst->Type() == PRIM_DLATCH) + { + module->addDlatch(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + return true; + } return false; } @@ -568,7 +572,18 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } - // FIXME: PRIM_DLATCH + if (inst->Type() == PRIM_DLATCH) + { + if (inst->GetAsyncCond()->IsGnd()) { + cell = module->addDlatch(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + } else { + RTLIL::SigSpec sig_set = module->And(NEW_ID, net_map_at(inst->GetAsyncCond()), net_map_at(inst->GetAsyncVal())); + RTLIL::SigSpec sig_clr = module->And(NEW_ID, net_map_at(inst->GetAsyncCond()), module->Not(NEW_ID, net_map_at(inst->GetAsyncVal()))); + cell = module->addDlatchsr(inst_name, net_map_at(inst->GetControl()), sig_set, sig_clr, net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + } + import_attributes(cell->attributes, inst); + return true; + } #define IN operatorInput(inst) #define IN1 operatorInput1(inst) @@ -842,7 +857,19 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } - // FIXME: OPER_WIDE_DLATCHSR + if (inst->Type() == OPER_WIDE_DLATCHRS) + { + RTLIL::SigSpec sig_set = operatorInport(inst, "set"); + RTLIL::SigSpec sig_reset = operatorInport(inst, "reset"); + + if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_reset.is_fully_const() && !sig_reset.as_bool()) + cell = module->addDlatch(inst_name, net_map_at(inst->GetControl()), IN, OUT); + else + cell = module->addDlatchsr(inst_name, net_map_at(inst->GetControl()), sig_set, sig_reset, IN, OUT); + import_attributes(cell->attributes, inst); + + return true; + } if (inst->Type() == OPER_WIDE_DFF) { @@ -872,7 +899,31 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } - // FIXME: OPER_WIDE_DLATCH + if (inst->Type() == OPER_WIDE_DLATCH) + { + RTLIL::SigSpec sig_d = IN; + RTLIL::SigSpec sig_q = OUT; + RTLIL::SigSpec sig_adata = IN1; + RTLIL::SigSpec sig_acond = IN2; + + if (sig_acond.is_fully_const() && !sig_acond.as_bool()) { + cell = module->addDlatch(inst_name, net_map_at(inst->GetControl()), sig_d, sig_q); + import_attributes(cell->attributes, inst); + } else { + int offset = 0, width = 0; + for (offset = 0; offset < GetSize(sig_acond); offset += width) { + for (width = 1; offset+width < GetSize(sig_acond); width++) + if (sig_acond[offset] != sig_acond[offset+width]) break; + RTLIL::SigSpec sig_set = module->Mux(NEW_ID, RTLIL::SigSpec(0, width), sig_adata.extract(offset, width), sig_acond[offset]); + RTLIL::SigSpec sig_clr = module->Mux(NEW_ID, RTLIL::SigSpec(0, width), module->Not(NEW_ID, sig_adata.extract(offset, width)), sig_acond[offset]); + cell = module->addDlatchsr(inst_name, net_map_at(inst->GetControl()), sig_set, sig_clr, + sig_d.extract(offset, width), sig_q.extract(offset, width)); + import_attributes(cell->attributes, inst); + } + } + + return true; + } #undef IN #undef IN1 From 90b440f870a8ac2c91b3f716f38a4f538cad2549 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Thu, 21 Oct 2021 12:13:35 +0200 Subject: [PATCH 0572/2410] Fix verific.cc PRIM_DLATCH handling Signed-off-by: Claire Xenia Wolf --- frontends/verific/verific.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6b303e4b66b..18fba9b76ac 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -443,7 +443,13 @@ bool VerificImporter::import_netlist_instance_gates(Instance *inst, RTLIL::IdStr if (inst->Type() == PRIM_DLATCH) { - module->addDlatch(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + if (inst->GetAsyncCond()->IsGnd()) { + module->addDlatch(inst_name, net_map_at(inst->GetControl()), net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + } else { + RTLIL::SigSpec sig_set = module->And(NEW_ID, net_map_at(inst->GetAsyncCond()), net_map_at(inst->GetAsyncVal())); + RTLIL::SigSpec sig_clr = module->And(NEW_ID, net_map_at(inst->GetAsyncCond()), module->Not(NEW_ID, net_map_at(inst->GetAsyncVal()))); + module->addDlatchsr(inst_name, net_map_at(inst->GetControl()), sig_set, sig_clr, net_map_at(inst->GetInput()), net_map_at(inst->GetOutput())); + } return true; } From 5cebf6a8efb4f1e9b836db76be0bb2a964932905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 21 Oct 2021 18:26:47 +0200 Subject: [PATCH 0573/2410] Change implicit conversions from bool to Sig* to explicit. Also fixes some completely broken code in extract_reduce. --- kernel/rtlil.h | 4 ++-- passes/techmap/extract_reduce.cc | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e072d5bd1a3..96982d2d96c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -756,7 +756,7 @@ struct RTLIL::SigBit SigBit(); SigBit(RTLIL::State bit); - SigBit(bool bit); + explicit SigBit(bool bit); SigBit(RTLIL::Wire *wire); SigBit(RTLIL::Wire *wire, int offset); SigBit(const RTLIL::SigChunk &chunk); @@ -838,7 +838,7 @@ struct RTLIL::SigSpec SigSpec(const std::vector &bits); SigSpec(const pool &bits); SigSpec(const std::set &bits); - SigSpec(bool bit); + explicit SigSpec(bool bit); SigSpec(RTLIL::SigSpec &&other) { width_ = other.width_; diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index b2da126abe4..892e9a3644b 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -152,10 +152,10 @@ struct ExtractReducePass : public Pass log_assert(y.size() == 1); // Should only continue if there is one fanout back into a cell (not to a port) - if (sig_to_sink[y[0]].size() != 1) + if (sig_to_sink[y].size() != 1 || port_sigs.count(y)) break; - x = *sig_to_sink[y[0]].begin(); + x = *sig_to_sink[y].begin(); } sinks.insert(head_cell); @@ -183,13 +183,15 @@ struct ExtractReducePass : public Pass continue; } + auto xy = sigmap(x->getPort(ID::Y)); + //If this signal drives a port, add it to the sinks //(even though it may not be the end of a chain) - if(port_sigs.count(x) && !consumed_cells.count(x)) + if(port_sigs.count(xy) && !consumed_cells.count(x)) sinks.insert(x); //It's a match, search everything out from it - auto& next = sig_to_sink[x]; + auto& next = sig_to_sink[xy]; for(auto z : next) next_loads.insert(z); } From 52ba31b1c023b571868a396adfe1f43a0f71e867 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Oct 2021 01:00:39 +0000 Subject: [PATCH 0574/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 66f9638e19b..951587aa30c 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+40 +YOSYS_VER := 0.10+46 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From b8624ad2aef941776f5b4a08f66f8d43e70f8467 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 25 Oct 2021 09:04:43 +0200 Subject: [PATCH 0575/2410] Compile option for enabling async load verific support --- Makefile | 4 ++++ frontends/verific/verific.cc | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 951587aa30c..9d806f438fa 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 DISABLE_VERIFIC_EXTENSIONS := 0 DISABLE_VERIFIC_VHDL := 0 +ENABLE_VERIFIC_ASYNC_LOAD := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 ENABLE_PROTOBUF := 0 @@ -501,6 +502,9 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib VERIFIC_COMPONENTS ?= verilog database util containers hier_tree +ifeq ($(ENABLE_VERIFIC_ASYNC_LOAD),1) +CXXFLAGS += -DVERIFIC_ASYNC_LOAD +endif ifneq ($(DISABLE_VERIFIC_VHDL),1) VERIFIC_COMPONENTS += vhdl CXXFLAGS += -DVERIFIC_VHDL_SUPPORT diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 18fba9b76ac..47ddbc66205 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2474,8 +2474,11 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_preserve_user_nets", 1); RuntimeFlags::SetVar("db_allow_external_nets", 1); RuntimeFlags::SetVar("db_infer_wide_operators", 1); +#ifdef VERIFIC_ASYNC_LOAD + RuntimeFlags::SetVar("db_infer_set_reset_registers", 0); +#else RuntimeFlags::SetVar("db_infer_set_reset_registers", 1); - +#endif RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); From ee230f2bb9a2fe473b0ddb6bcfa30a15b0f07c88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Oct 2021 00:51:59 +0000 Subject: [PATCH 0576/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9d806f438fa..de91acbc24d 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+46 +YOSYS_VER := 0.10+48 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From bd16d01c0eed5c96a241e6ee9e56b8f7890319a1 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Tue, 19 Oct 2021 18:43:30 -0600 Subject: [PATCH 0577/2410] Split out logic for reprocessing an AstModule This will enable other features to use same core logic for replacing an existing AstModule with a newly elaborated version. --- frontends/ast/ast.cc | 67 +++++++++++++++++++++++------------ frontends/ast/ast.h | 14 +++++++- kernel/rtlil.cc | 4 +-- kernel/rtlil.h | 2 +- passes/hierarchy/hierarchy.cc | 2 +- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 4fbc238b02d..fe1f9e86146 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -983,8 +983,7 @@ static bool param_has_no_default(const AstNode *param) { (children.size() == 1 && children[0]->type == AST_RANGE); } -// create and add a new AstModule from an AST_MODULE AST node -static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) +static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { log_assert(current_scope.empty()); log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE); @@ -1197,6 +1196,42 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN } design->add(current_module); + return current_module; +} + +RTLIL::Module * +AST_INTERNAL::process_and_replace_module(RTLIL::Design *design, + RTLIL::Module *old_module, + AstNode *new_ast, + AstNode *original_ast) +{ + // The old module will be deleted. Rename and mark for deletion, using + // a static counter to make sure we get a unique name. + static unsigned counter; + std::ostringstream new_name; + new_name << old_module->name.str() + << "_before_process_and_replace_module_" + << counter; + ++counter; + + design->rename(old_module, new_name.str()); + old_module->set_bool_attribute(ID::to_delete); + + // Check if the module was the top module. If it was, we need to remove + // the top attribute and put it on the new module. + bool is_top = false; + if (old_module->get_bool_attribute(ID::initial_top)) { + old_module->attributes.erase(ID::initial_top); + is_top = true; + } + + // Generate RTLIL from AST for the new module and add to the design: + RTLIL::Module* new_module = process_module(design, new_ast, false, original_ast); + + if (is_top) + new_module->set_bool_attribute(ID::top); + + return new_module; } // renames identifiers in tasks and functions within a package @@ -1412,11 +1447,10 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule // When an interface instance is found in a module, the whole RTLIL for the module will be rederived again // from AST. The interface members are copied into the AST module with the prefix of the interface. -void AstModule::reprocess_module(RTLIL::Design *design, const dict &local_interfaces) +void AstModule::expand_interfaces(RTLIL::Design *design, const dict &local_interfaces) { loadconfig(); - bool is_top = false; AstNode *new_ast = ast->clone(); for (auto &intf : local_interfaces) { std::string intfname = intf.first.str(); @@ -1473,28 +1507,15 @@ void AstModule::reprocess_module(RTLIL::Design *design, const dictname.str(); - std::string changed_name = original_name + "_before_replacing_local_interfaces"; - design->rename(this, changed_name); - this->set_bool_attribute(ID::to_delete); + // Generate RTLIL from AST for the new module and add to the design, + // renaming this module to move it out of the way. + RTLIL::Module* new_module = + process_and_replace_module(design, this, new_ast, ast_before_replacing_interface_ports); - // Check if the module was the top module. If it was, we need to remove the top attribute and put it on the - // new module. - if (this->get_bool_attribute(ID::initial_top)) { - this->attributes.erase(ID::initial_top); - is_top = true; - } - - // Generate RTLIL from AST for the new module and add to the design: - process_module(design, new_ast, false, ast_before_replacing_interface_ports); - delete(new_ast); - RTLIL::Module* mod = design->module(original_name); - if (is_top) - mod->set_bool_attribute(ID::top); + delete new_ast; // Set the attribute "interfaces_replaced_in_module" so that it does not happen again. - mod->set_bool_attribute(ID::interfaces_replaced_in_module); + new_module->set_bool_attribute(ID::interfaces_replaced_in_module); } // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 63104bca4b9..66bbdd7b4ee 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -348,7 +348,7 @@ namespace AST RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail) override; RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail) override; std::string derive_common(RTLIL::Design *design, const dict ¶meters, AstNode **new_ast_out, bool quiet = false); - void reprocess_module(RTLIL::Design *design, const dict &local_interfaces) override; + void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces) override; RTLIL::Module *clone() const override; void loadconfig() const; }; @@ -395,6 +395,18 @@ namespace AST_INTERNAL extern dict> current_memwr_visible; struct LookaheadRewriter; struct ProcessGenerator; + + // Create and add a new AstModule from new_ast, then use it to replace + // old_module in design, renaming old_module to move it out of the way. + // Return the new module. + // + // If original_ast is not null, it will be used as the AST node for the + // new module. Otherwise, new_ast will be used. + RTLIL::Module * + process_and_replace_module(RTLIL::Design *design, + RTLIL::Module *old_module, + AST::AstNode *new_ast, + AST::AstNode *original_ast = nullptr); } YOSYS_NAMESPACE_END diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3778972bcfd..9fac575235c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -936,9 +936,9 @@ void RTLIL::Module::makeblackbox() set_bool_attribute(ID::blackbox); } -void RTLIL::Module::reprocess_module(RTLIL::Design *, const dict &) +void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict &) { - log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name)); + log_error("Class doesn't support expand_interfaces (module: `%s')!\n", id2cstr(name)); } RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict &, bool mayfail) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 96982d2d96c..c428f31543a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1160,7 +1160,7 @@ struct RTLIL::Module : public RTLIL::AttrObject virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail = false); virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); virtual size_t count_id(RTLIL::IdString id); - virtual void reprocess_module(RTLIL::Design *design, const dict &local_interfaces); + virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); virtual void sort(); virtual void check(); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 65003658066..1e69ab90336 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -554,7 +554,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // If any interface instances or interface ports were found in the module, we need to rederive it completely: if ((if_expander.interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) { - module->reprocess_module(design, if_expander.interfaces_in_module); + module->expand_interfaces(design, if_expander.interfaces_in_module); return did_something; } From e833c6a418103feb30f0cc3e5c482da00ee9f820 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 19 Oct 2021 18:46:26 -0600 Subject: [PATCH 0578/2410] verilog: use derived module info to elaborate cell connections - Attempt to lookup a derived module if it potentially contains a port connection with elaboration ambiguities - Mark the cell if module has not yet been derived - This can be extended to implement automatic hierarchical port connections in a future change --- CHANGELOG | 8 + README.md | 5 + frontends/ast/ast.cc | 69 ++++++-- frontends/ast/ast.h | 14 +- frontends/ast/genrtlil.cc | 23 ++- frontends/ast/simplify.cc | 226 ++++++++++++++++++++++++-- kernel/constids.inc | 1 + kernel/rtlil.cc | 5 + kernel/rtlil.h | 1 + passes/hierarchy/hierarchy.cc | 4 + passes/techmap/techmap.cc | 4 +- tests/simple/memwr_port_connection.sv | 13 ++ tests/simple/signed_full_slice.v | 29 ++++ tests/verilog/unbased_unsized_tern.sv | 31 ++++ tests/verilog/unbased_unsized_tern.ys | 6 + 15 files changed, 397 insertions(+), 42 deletions(-) create mode 100644 tests/simple/memwr_port_connection.sv create mode 100644 tests/simple/signed_full_slice.v create mode 100644 tests/verilog/unbased_unsized_tern.sv create mode 100644 tests/verilog/unbased_unsized_tern.ys diff --git a/CHANGELOG b/CHANGELOG index a6285ddb294..b980c5a1ad5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,14 @@ Yosys 0.10 .. Yosys 0.10-dev * Various - Added $aldff and $aldffe (flip-flops with async load) cells + * SystemVerilog + - Fixed an issue which prevented writing directly to a memory word via a + connection to an output port + - Fixed an issue which prevented unbased unsized literals (e.g., `'1`) from + filling the width of a cell input + - Fixed an issue where connecting a slice covering the entirety of a signed + signal to a cell input would cause a failed assertion + Yosys 0.9 .. Yosys 0.10 -------------------------- diff --git a/README.md b/README.md index ab656352a9e..cc5c806fb02 100644 --- a/README.md +++ b/README.md @@ -489,6 +489,11 @@ Verilog Attributes and non-standard features for use in blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this functionality. (By default these blocks are ignored.) +- The ``reprocess_after`` internal attribute is used by the Verilog frontend to + mark cells with bindings which might depend on the specified instantiated + module. Modules with such cells will be reprocessed during the ``hierarchy`` + pass once the referenced module definition(s) become available. + Non-standard or SystemVerilog features for formal verification ============================================================== diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index fe1f9e86146..7be8ab5655d 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -854,7 +854,7 @@ RTLIL::Const AstNode::bitsAsConst(int width) return bitsAsConst(width, is_signed); } -RTLIL::Const AstNode::asAttrConst() +RTLIL::Const AstNode::asAttrConst() const { log_assert(type == AST_CONSTANT); @@ -869,8 +869,17 @@ RTLIL::Const AstNode::asAttrConst() return val; } -RTLIL::Const AstNode::asParaConst() +RTLIL::Const AstNode::asParaConst() const { + if (type == AST_REALVALUE) + { + AstNode *strnode = AstNode::mkconst_str(stringf("%f", realvalue)); + RTLIL::Const val = strnode->asAttrConst(); + val.flags |= RTLIL::CONST_FLAG_REAL; + delete strnode; + return val; + } + RTLIL::Const val = asAttrConst(); if (is_signed) val.flags |= RTLIL::CONST_FLAG_SIGNED; @@ -1043,8 +1052,11 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d } } - // TODO(zachjs): make design available to simplify() in the future + // simplify this module or interface using the current design as context + // for lookup up ports and wires within cells + set_simplify_design_context(design); while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } + set_simplify_design_context(nullptr); if (flag_dump_ast2) { log("Dumping AST after simplification:\n"); @@ -1171,6 +1183,9 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d continue; module->attributes[attr.first] = attr.second->asAttrConst(); } + for (const AstNode *node : ast->children) + if (node->type == AST_PARAMETER) + current_module->avail_parameters(node->str); } if (ast->type == AST_INTERFACE) @@ -1445,6 +1460,26 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule } } +// AstModules may contain cells marked with ID::reprocess_after, which indicates +// that it should be reprocessed once the specified module has been elaborated. +bool AstModule::reprocess_if_necessary(RTLIL::Design *design) +{ + for (const RTLIL::Cell *cell : cells()) + { + std::string modname = cell->get_string_attribute(ID::reprocess_after); + if (modname.empty()) + continue; + if (design->module(modname) || design->module("$abstract" + modname)) { + log("Reprocessing module %s because instantiated module %s has become available.\n", + log_id(name), log_id(modname)); + loadconfig(); + process_and_replace_module(design, this, ast, NULL); + return true; + } + } + return false; +} + // When an interface instance is found in a module, the whole RTLIL for the module will be rederived again // from AST. The interface members are copied into the AST module with the prefix of the interface. void AstModule::expand_interfaces(RTLIL::Design *design, const dict &local_interfaces) @@ -1649,6 +1684,17 @@ static std::string serialize_param_value(const RTLIL::Const &val) { return res; } +std::string AST::derived_module_name(std::string stripped_name, const std::vector> ¶meters) { + std::string para_info; + for (const auto &elem : parameters) + para_info += stringf("%s=%s", elem.first.c_str(), serialize_param_value(elem.second).c_str()); + + if (para_info.size() > 60) + return "$paramod$" + sha1(para_info) + stripped_name; + else + return "$paramod" + stripped_name + para_info; +} + // create a new parametric module (when needed) and return the name of the generated module std::string AstModule::derive_common(RTLIL::Design *design, const dict ¶meters, AstNode **new_ast_out, bool quiet) { @@ -1657,9 +1703,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict> named_parameters; for (const auto child : ast->children) { if (child->type != AST_PARAMETER) continue; @@ -1668,25 +1713,21 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictstr.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); + named_parameters.emplace_back(child->str, it->second); continue; } it = parameters.find(stringf("$%d", para_counter)); if (it != parameters.end()) { if (!quiet) log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); + named_parameters.emplace_back(child->str, it->second); continue; } } - std::string modname; - if (parameters.size() == 0) - modname = stripped_name; - else if (para_info.size() > 60) - modname = "$paramod$" + sha1(para_info) + stripped_name; - else - modname = "$paramod" + stripped_name + para_info; + std::string modname = stripped_name; + if (parameters.size()) // not named_parameters to cover hierarchical defparams + modname = derived_module_name(stripped_name, named_parameters); if (design->has(modname)) return modname; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 66bbdd7b4ee..48ec9a0630e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -262,6 +262,7 @@ namespace AST void mem2reg_remove(pool &mem2reg_set, vector &delnodes); void meminfo(int &mem_width, int &mem_size, int &addr_bits); bool detect_latch(const std::string &var); + const RTLIL::Module* lookup_cell_module(); // additional functionality for evaluating constant functions struct varinfo_t { @@ -313,8 +314,8 @@ namespace AST RTLIL::Const bitsAsConst(int width, bool is_signed); RTLIL::Const bitsAsConst(int width = -1); RTLIL::Const bitsAsUnsizedConst(int width); - RTLIL::Const asAttrConst(); - RTLIL::Const asParaConst(); + RTLIL::Const asAttrConst() const; + RTLIL::Const asParaConst() const; uint64_t asInt(bool is_signed); bool bits_only_01() const; bool asBool() const; @@ -349,6 +350,7 @@ namespace AST RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail) override; std::string derive_common(RTLIL::Design *design, const dict ¶meters, AstNode **new_ast_out, bool quiet = false); void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces) override; + bool reprocess_if_necessary(RTLIL::Design *design) override; RTLIL::Module *clone() const override; void loadconfig() const; }; @@ -377,6 +379,14 @@ namespace AST // struct helper exposed from simplify for genrtlil AstNode *make_struct_member_range(AstNode *node, AstNode *member_node); + + // generate standard $paramod... derived module name; parameters should be + // in the order they are declared in the instantiated module + std::string derived_module_name(std::string stripped_name, const std::vector> ¶meters); + + // used to provide simplify() access to the current design for looking up + // modules, ports, wires, etc. + void set_simplify_design_context(const RTLIL::Design *design); } namespace AST_INTERNAL diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c82664b98a4..a68bcd9ee6a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1917,21 +1917,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) continue; } if (child->type == AST_PARASET) { - int extra_const_flags = 0; IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str; - if (child->children[0]->type == AST_REALVALUE) { + const AstNode *value = child->children[0]; + if (value->type == AST_REALVALUE) log_file_warning(filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n", - log_id(cell), log_id(paraname), child->children[0]->realvalue); - extra_const_flags = RTLIL::CONST_FLAG_REAL; - auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue)); - strnode->cloneInto(child->children[0]); - delete strnode; - } - if (child->children[0]->type != AST_CONSTANT) + log_id(cell), log_id(paraname), value->realvalue); + else if (value->type != AST_CONSTANT) log_file_error(filename, location.first_line, "Parameter %s.%s with non-constant value!\n", log_id(cell), log_id(paraname)); - cell->parameters[paraname] = child->children[0]->asParaConst(); - cell->parameters[paraname].flags |= extra_const_flags; + cell->parameters[paraname] = value->asParaConst(); continue; } if (child->type == AST_ARGUMENT) { @@ -1948,7 +1942,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (sig.is_wire()) { // if the resulting SigSpec is a wire, its // signedness should match that of the AstNode - log_assert(arg->is_signed == sig.as_wire()->is_signed); + if (arg->type == AST_IDENTIFIER && arg->id2ast && arg->id2ast->is_signed && !arg->is_signed) + // fully-sliced signed wire will be resolved + // once the module becomes available + log_assert(attributes.count(ID::reprocess_after)); + else + log_assert(arg->is_signed == sig.as_wire()->is_signed); } else if (arg->is_signed) { // non-trivial signed nodes are indirected through // signed wires to enable sign extension diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 607ca9a8b73..64d0fe475ba 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -564,6 +564,115 @@ static std::string prefix_id(const std::string &prefix, const std::string &str) return prefix + str; } +// direct access to this global should be limited to the following two functions +static const RTLIL::Design *simplify_design_context = nullptr; + +void AST::set_simplify_design_context(const RTLIL::Design *design) +{ + log_assert(!simplify_design_context || !design); + simplify_design_context = design; +} + +// lookup the module with the given name in the current design context +static const RTLIL::Module* lookup_module(const std::string &name) +{ + return simplify_design_context->module(name); +} + +const RTLIL::Module* AstNode::lookup_cell_module() +{ + log_assert(type == AST_CELL); + + auto reprocess_after = [this] (const std::string &modname) { + if (!attributes.count(ID::reprocess_after)) + attributes[ID::reprocess_after] = AstNode::mkconst_str(modname); + }; + + const AstNode *celltype = nullptr; + for (const AstNode *child : children) + if (child->type == AST_CELLTYPE) { + celltype = child; + break; + } + log_assert(celltype != nullptr); + + const RTLIL::Module *module = lookup_module(celltype->str); + if (!module) + module = lookup_module("$abstract" + celltype->str); + if (!module) { + if (celltype->str.at(0) != '$') + reprocess_after(celltype->str); + return nullptr; + } + + // build a mapping from true param name to param value + size_t para_counter = 0; + dict cell_params_map; + for (AstNode *child : children) { + if (child->type != AST_PARASET) + continue; + + if (child->str.empty() && para_counter >= module->avail_parameters.size()) + return nullptr; // let hierarchy handle this error + IdString paraname = child->str.empty() ? module->avail_parameters[para_counter++] : child->str; + + const AstNode *value = child->children[0]; + if (value->type != AST_REALVALUE && value->type != AST_CONSTANT) + return nullptr; // let genrtlil handle this error + cell_params_map[paraname] = value->asParaConst(); + } + + // put the parameters in order and generate the derived module name + std::vector> named_parameters; + for (RTLIL::IdString param : module->avail_parameters) { + auto it = cell_params_map.find(param); + if (it != cell_params_map.end()) + named_parameters.emplace_back(it->first, it->second); + } + std::string modname = celltype->str; + if (cell_params_map.size()) // not named_parameters to cover hierarchical defparams + modname = derived_module_name(celltype->str, named_parameters); + + // try to find the resolved module + module = lookup_module(modname); + if (!module) { + reprocess_after(modname); + return nullptr; + } + return module; +} + +// returns whether an expression contains an unbased unsized literal; does not +// check the literal exists in a self-determined context +static bool contains_unbased_unsized(const AstNode *node) +{ + if (node->type == AST_CONSTANT) + return node->is_unsized; + for (const AstNode *child : node->children) + if (contains_unbased_unsized(child)) + return true; + return false; +} + +// adds a wire to the current module with the given name that matches the +// dimensions of the given wire reference +void add_wire_for_ref(const RTLIL::Wire *ref, const std::string &str) +{ + AstNode *left = AstNode::mkconst_int(ref->width - 1 + ref->start_offset, true); + AstNode *right = AstNode::mkconst_int(ref->start_offset, true); + if (ref->upto) + std::swap(left, right); + AstNode *range = new AstNode(AST_RANGE, left, right); + + AstNode *wire = new AstNode(AST_WIRE, range); + wire->is_signed = ref->is_signed; + wire->is_logic = true; + wire->str = str; + + current_ast_mod->children.push_back(wire); + current_scope[str] = wire; +} + // convert the AST into a simpler AST that has all parameters substituted by their // values, unrolled for-loops, expanded generate blocks, etc. when this function // is done with an AST it can be converted into RTLIL using genRTLIL(). @@ -920,19 +1029,110 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } - if (type == AST_ARGUMENT) - { - if (children.size() == 1 && children[0]->type == AST_CONSTANT) - { - // HACK: For port bindings using unbased unsized literals, mark them - // signed so they sign-extend. The hierarchy will still incorrectly - // generate a warning complaining about resizing the expression. - // This also doesn't handle the complex of something like a ternary - // expression bound to a port, where the actual size of the port is - // needed to resolve the expression correctly. - AstNode *arg = children[0]; - if (arg->is_unsized) - arg->is_signed = true; + if (type == AST_CELL) { + bool lookup_suggested = false; + + for (AstNode *child : children) { + // simplify any parameters to constants + if (child->type == AST_PARASET) + while (child->simplify(true, false, false, 1, -1, false, true)) { } + + // look for patterns which _may_ indicate ambiguity requiring + // resolution of the underlying module + if (child->type == AST_ARGUMENT) { + if (child->children.size() != 1) + continue; + const AstNode *value = child->children[0]; + if (value->type == AST_IDENTIFIER) { + const AstNode *elem = value->id2ast; + if (elem == nullptr) { + if (current_scope.count(value->str)) + elem = current_scope.at(value->str); + else + continue; + } + if (elem->type == AST_MEMORY) + // need to determine is the is a read or wire + lookup_suggested = true; + else if (elem->type == AST_WIRE && elem->is_signed && !value->children.empty()) + // this may be a fully sliced signed wire which needs + // to be indirected to produce an unsigned connection + lookup_suggested = true; + } + else if (contains_unbased_unsized(value)) + // unbased unsized literals extend to width of the context + lookup_suggested = true; + } + } + + const RTLIL::Module *module = nullptr; + if (lookup_suggested) + module = lookup_cell_module(); + if (module) { + size_t port_counter = 0; + for (AstNode *child : children) { + if (child->type != AST_ARGUMENT) + continue; + + // determine the full name of port this argument is connected to + RTLIL::IdString port_name; + if (child->str.size()) + port_name = child->str; + else { + if (port_counter >= module->ports.size()) + log_file_error(filename, location.first_line, + "Cell instance has more ports than the module!\n"); + port_name = module->ports[port_counter++]; + } + + // find the port's wire in the underlying module + const RTLIL::Wire *ref = module->wire(port_name); + if (ref == nullptr) + log_file_error(filename, location.first_line, + "Cell instance refers to port %s which does not exist in module %s!.\n", + log_id(port_name), log_id(module->name)); + + // select the argument, if present + log_assert(child->children.size() <= 1); + if (child->children.empty()) + continue; + AstNode *arg = child->children[0]; + + // plain identifiers never need indirection; this also prevents + // adding infinite levels of indirection + if (arg->type == AST_IDENTIFIER && arg->children.empty()) + continue; + + // only add indirection for standard inputs or outputs + if (ref->port_input == ref->port_output) + continue; + + did_something = true; + + // create the indirection wire + std::stringstream sstr; + sstr << "$indirect$" << ref->name.c_str() << "$" << filename << ":" << location.first_line << "$" << (autoidx++); + std::string tmp_str = sstr.str(); + add_wire_for_ref(ref, tmp_str); + + AstNode *asgn = new AstNode(AST_ASSIGN); + current_ast_mod->children.push_back(asgn); + + AstNode *ident = new AstNode(AST_IDENTIFIER); + ident->str = tmp_str; + child->children[0] = ident->clone(); + + if (ref->port_input && !ref->port_output) { + asgn->children.push_back(ident); + asgn->children.push_back(arg); + } else { + log_assert(!ref->port_input && ref->port_output); + asgn->children.push_back(arg); + asgn->children.push_back(ident); + } + } + + } } diff --git a/kernel/constids.inc b/kernel/constids.inc index 8d8e97eb7fb..8ccb6008904 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -163,6 +163,7 @@ X(RD_TRANSPARENCY_MASK) X(RD_TRANSPARENT) X(RD_WIDE_CONTINUATION) X(reg) +X(reprocess_after) X(S) X(SET) X(SET_POLARITY) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9fac575235c..88153a38056 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -941,6 +941,11 @@ void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict &, bool mayfail) { if (mayfail) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c428f31543a..68481b81ccd 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1161,6 +1161,7 @@ struct RTLIL::Module : public RTLIL::AttrObject virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); virtual size_t count_id(RTLIL::IdString id); virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); + virtual bool reprocess_if_necessary(RTLIL::Design *design); virtual void sort(); virtual void check(); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 1e69ab90336..440881f19cb 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -558,6 +558,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check return did_something; } + // Now that modules have been derived, we may want to reprocess this + // module given the additional available context. + if (module->reprocess_if_necessary(design)) + return true; for (auto &it : array_cells) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a69a6d460cc..5cd78fe28e9 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -377,10 +377,12 @@ struct TechmapWorker if (c->attributes.count(ID::src)) c->add_strpool_attribute(ID::src, extra_src_attrs); - if (techmap_replace_cell) + if (techmap_replace_cell) { for (auto attr : cell->attributes) if (!c->attributes.count(attr.first)) c->attributes[attr.first] = attr.second; + c->attributes.erase(ID::reprocess_after); + } } for (auto &it : tpl->connections()) { diff --git a/tests/simple/memwr_port_connection.sv b/tests/simple/memwr_port_connection.sv new file mode 100644 index 00000000000..5bf414e081c --- /dev/null +++ b/tests/simple/memwr_port_connection.sv @@ -0,0 +1,13 @@ +module producer( + output logic [3:0] out +); + assign out = 4'hA; +endmodule + +module top( + output logic [3:0] out +); + logic [3:0] v[0:0]; + producer p(v[0]); + assign out = v[0]; +endmodule diff --git a/tests/simple/signed_full_slice.v b/tests/simple/signed_full_slice.v new file mode 100644 index 00000000000..f8a33157885 --- /dev/null +++ b/tests/simple/signed_full_slice.v @@ -0,0 +1,29 @@ +module pass_through_a( + input wire [31:0] inp, + output wire [31:0] out +); + assign out[31:0] = inp[31:0]; +endmodule + +module top_a( + input wire signed [31:0] inp, + output wire signed [31:0] out +); + pass_through_a pt(inp[31:0], out[31:0]); +endmodule + +// tests both module declaration orderings + +module top_b( + input wire signed [31:0] inp, + output wire signed [31:0] out +); + pass_through_b pt(inp[31:0], out[31:0]); +endmodule + +module pass_through_b( + input wire [31:0] inp, + output wire [31:0] out +); + assign out[31:0] = inp[31:0]; +endmodule diff --git a/tests/verilog/unbased_unsized_tern.sv b/tests/verilog/unbased_unsized_tern.sv new file mode 100644 index 00000000000..ad849339410 --- /dev/null +++ b/tests/verilog/unbased_unsized_tern.sv @@ -0,0 +1,31 @@ +module pass_through #( + parameter WIDTH = 1 +) ( + input logic [WIDTH-1:0] inp, + output logic [WIDTH-1:0] out +); + assign out = inp; +endmodule + +module gate ( + input logic inp, + output logic [63:0] + out1, out2, out3, out4 +); + pass_through #(40) pt1('1, out1); + pass_through #(40) pt2(inp ? '1 : '0, out2); + pass_through #(40) pt3(inp ? '1 : 2'b10, out3); + pass_through #(40) pt4(inp ? '1 : inp, out4); +endmodule + +module gold ( + input logic inp, + output logic [63:0] + out1, out2, out3, out4 +); + localparam ONES = 40'hFF_FFFF_FFFF; + pass_through #(40) pt1(ONES, out1); + pass_through #(40) pt2(inp ? ONES : 0, out2); + pass_through #(40) pt3(inp ? ONES : 2'sb10, out3); + pass_through #(40) pt4(inp ? ONES : inp, out4); +endmodule diff --git a/tests/verilog/unbased_unsized_tern.ys b/tests/verilog/unbased_unsized_tern.ys new file mode 100644 index 00000000000..5ef63c559e3 --- /dev/null +++ b/tests/verilog/unbased_unsized_tern.ys @@ -0,0 +1,6 @@ +read_verilog -sv unbased_unsized_tern.sv +hierarchy +proc +equiv_make gold gate equiv +equiv_simple +equiv_status -assert From bdf153d06c3673b93bbc3fd07999e0a19747417b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Oct 2021 00:51:44 +0000 Subject: [PATCH 0579/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index de91acbc24d..c919c9563bd 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+48 +YOSYS_VER := 0.10+51 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 0a0df8d38c8ef74b95d9649be5a78c18a928bf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 27 Oct 2021 10:14:07 +0200 Subject: [PATCH 0580/2410] dfflegalize: Refactor, add aldff support. --- kernel/ff.cc | 192 +- kernel/ff.h | 17 +- passes/techmap/dfflegalize.cc | 1862 ++++++++++---------- tests/techmap/dfflegalize_adff_init.ys | 26 +- tests/techmap/dfflegalize_adlatch_init.ys | 4 +- tests/techmap/dfflegalize_dff.ys | 17 +- tests/techmap/dfflegalize_dff_init.ys | 40 +- tests/techmap/dfflegalize_dlatch_const.ys | 8 +- tests/techmap/dfflegalize_dlatchsr_init.ys | 8 +- tests/techmap/dfflegalize_minsrst.ys | 4 +- tests/techmap/dfflegalize_sr.ys | 2 +- tests/techmap/dfflegalize_sr_init.ys | 10 +- 12 files changed, 1137 insertions(+), 1053 deletions(-) diff --git a/kernel/ff.cc b/kernel/ff.cc index c2f1a75a023..c43482bd242 100644 --- a/kernel/ff.cc +++ b/kernel/ff.cc @@ -303,6 +303,190 @@ FfData FfData::slice(const std::vector &bits) { return res; } +void FfData::add_dummy_ce() { + if (has_ce) + return; + has_ce = true; + pol_ce = true; + sig_ce = State::S1; + ce_over_srst = false; +} + +void FfData::add_dummy_srst() { + if (has_srst) + return; + has_srst = true; + pol_srst = true; + sig_srst = State::S0; + val_srst = Const(State::Sx, width); + ce_over_srst = false; +} + +void FfData::add_dummy_arst() { + if (has_arst) + return; + has_arst = true; + pol_arst = true; + sig_arst = State::S0; + val_arst = Const(State::Sx, width); +} + +void FfData::add_dummy_aload() { + if (has_aload) + return; + has_aload = true; + pol_aload = true; + sig_aload = State::S0; + sig_ad = Const(State::Sx, width); +} + +void FfData::add_dummy_sr() { + if (has_sr) + return; + has_sr = true; + pol_clr = true; + pol_set = true; + sig_clr = Const(State::S0, width); + sig_set = Const(State::S0, width); +} + +void FfData::add_dummy_clk() { + if (has_clk) + return; + has_clk = true; + pol_clk = true; + sig_clk = State::S0; + sig_d = Const(State::Sx, width); +} + +void FfData::arst_to_aload() { + log_assert(has_arst); + log_assert(!has_aload); + pol_aload = pol_arst; + sig_aload = sig_arst; + sig_ad = val_arst; + has_aload = true; + has_arst = false; +} + +void FfData::arst_to_sr() { + log_assert(has_arst); + log_assert(!has_sr); + pol_clr = pol_arst; + pol_set = pol_arst; + sig_clr = Const(pol_arst ? State::S0 : State::S1, width); + sig_set = Const(pol_arst ? State::S0 : State::S1, width); + has_sr = true; + has_arst = false; + for (int i = 0; i < width; i++) { + if (val_arst[i] == State::S1) + sig_set[i] = sig_arst; + else + sig_clr[i] = sig_arst; + } +} + +void FfData::aload_to_sr() { + log_assert(has_aload); + log_assert(!has_sr); + has_sr = true; + has_aload = false; + if (!is_fine) { + pol_clr = false; + pol_set = true; + if (pol_aload) { + sig_clr = module->Mux(NEW_ID, Const(State::S1, width), sig_ad, sig_aload); + sig_set = module->Mux(NEW_ID, Const(State::S0, width), sig_ad, sig_aload); + } else { + sig_clr = module->Mux(NEW_ID, sig_ad, Const(State::S1, width), sig_aload); + sig_set = module->Mux(NEW_ID, sig_ad, Const(State::S0, width), sig_aload); + } + } else { + pol_clr = pol_aload; + pol_set = pol_aload; + if (pol_aload) { + sig_clr = module->AndnotGate(NEW_ID, sig_aload, sig_ad); + sig_set = module->AndGate(NEW_ID, sig_aload, sig_ad); + } else { + sig_clr = module->OrGate(NEW_ID, sig_aload, sig_ad); + sig_set = module->OrnotGate(NEW_ID, sig_aload, sig_ad); + } + } +} + +void FfData::convert_ce_over_srst(bool val) { + if (!has_ce || !has_srst || ce_over_srst == val) + return; + if (val) { + // sdffe to sdffce + if (!is_fine) { + if (pol_ce) { + if (pol_srst) { + sig_ce = module->Or(NEW_ID, sig_ce, sig_srst); + } else { + SigSpec tmp = module->Not(NEW_ID, sig_srst); + sig_ce = module->Or(NEW_ID, sig_ce, tmp); + } + } else { + if (pol_srst) { + SigSpec tmp = module->Not(NEW_ID, sig_srst); + sig_ce = module->And(NEW_ID, sig_ce, tmp); + } else { + sig_ce = module->And(NEW_ID, sig_ce, sig_srst); + } + } + } else { + if (pol_ce) { + if (pol_srst) { + sig_ce = module->OrGate(NEW_ID, sig_ce, sig_srst); + } else { + sig_ce = module->OrnotGate(NEW_ID, sig_ce, sig_srst); + } + } else { + if (pol_srst) { + sig_ce = module->AndnotGate(NEW_ID, sig_ce, sig_srst); + } else { + sig_ce = module->AndGate(NEW_ID, sig_ce, sig_srst); + } + } + } + } else { + // sdffce to sdffe + if (!is_fine) { + if (pol_srst) { + if (pol_ce) { + sig_srst = cell->module->And(NEW_ID, sig_srst, sig_ce); + } else { + SigSpec tmp = module->Not(NEW_ID, sig_ce); + sig_srst = cell->module->And(NEW_ID, sig_srst, tmp); + } + } else { + if (pol_ce) { + SigSpec tmp = module->Not(NEW_ID, sig_ce); + sig_srst = cell->module->Or(NEW_ID, sig_srst, tmp); + } else { + sig_srst = cell->module->Or(NEW_ID, sig_srst, sig_ce); + } + } + } else { + if (pol_srst) { + if (pol_ce) { + sig_srst = cell->module->AndGate(NEW_ID, sig_srst, sig_ce); + } else { + sig_srst = cell->module->AndnotGate(NEW_ID, sig_srst, sig_ce); + } + } else { + if (pol_ce) { + sig_srst = cell->module->OrnotGate(NEW_ID, sig_srst, sig_ce); + } else { + sig_srst = cell->module->OrGate(NEW_ID, sig_srst, sig_ce); + } + } + } + } + ce_over_srst = val; +} + void FfData::unmap_ce() { if (!has_ce) return; @@ -351,11 +535,7 @@ Cell *FfData::emit() { if (!has_aload && !has_clk && !has_gclk && !has_sr) { if (has_arst) { // Convert this case to a D latch. - has_aload = true; - has_arst = false; - sig_ad = val_arst; - sig_aload = sig_arst; - pol_aload = pol_arst; + arst_to_aload(); } else { // No control inputs left. Turn into a const driver. module->connect(sig_q, val_init); @@ -506,7 +686,7 @@ void FfData::flip_bits(const pool &bits) { } if (has_sr && cell) { - log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].", log_id(module->name), log_id(cell->name), log_id(cell->type)); + log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", log_id(module->name), log_id(cell->name), log_id(cell->type)); } if (is_fine) { diff --git a/kernel/ff.h b/kernel/ff.h index 3125f67c698..5a629d5dd6c 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -170,8 +170,23 @@ struct FfData { // Returns a FF identical to this one, but only keeping bit indices from the argument. FfData slice(const std::vector &bits); - void unmap_ce(); + void add_dummy_ce(); + void add_dummy_srst(); + void add_dummy_arst(); + void add_dummy_aload(); + void add_dummy_sr(); + void add_dummy_clk(); + + void arst_to_aload(); + void arst_to_sr(); + + void aload_to_sr(); + // Given a FF with both has_ce and has_srst, sets ce_over_srst to the given value and + // fixes up control signals appropriately to preserve semantics. + void convert_ce_over_srst(bool val); + + void unmap_ce(); void unmap_srst(); void unmap_ce_srst() { diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index 5210d01eb98..1d99caa3a54 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" +#include "kernel/ff.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -27,38 +28,42 @@ PRIVATE_NAMESPACE_BEGIN enum FfType { FF_DFF, FF_DFFE, - FF_ADFF0, - FF_ADFF1, - FF_ADFFE0, - FF_ADFFE1, + FF_ADFF, + FF_ADFFE, + FF_ALDFF, + FF_ALDFFE, FF_DFFSR, FF_DFFSRE, - FF_SDFF0, - FF_SDFF1, - FF_SDFFE0, - FF_SDFFE1, - FF_SDFFCE0, - FF_SDFFCE1, + FF_SDFF, + FF_SDFFE, + FF_SDFFCE, + FF_RLATCH, FF_SR, FF_DLATCH, - FF_ADLATCH0, - FF_ADLATCH1, + FF_ADLATCH, FF_DLATCHSR, NUM_FFTYPES, }; enum FfNeg { - NEG_R = 0x1, - NEG_S = 0x2, - NEG_E = 0x4, - NEG_C = 0x8, - NUM_NEG = 0x10, + NEG_CE = 0x1, + NEG_R = 0x2, + NEG_S = 0x4, + NEG_L = 0x8, + NEG_C = 0x10, + NUM_NEG = 0x20, }; enum FfInit { INIT_X = 0x1, INIT_0 = 0x2, INIT_1 = 0x4, + INIT_X_R0 = 0x10, + INIT_0_R0 = 0x20, + INIT_1_R0 = 0x40, + INIT_X_R1 = 0x100, + INIT_0_R1 = 0x200, + INIT_1_R1 = 0x400, }; struct DffLegalizePass : public Pass { @@ -101,6 +106,8 @@ struct DffLegalizePass : public Pass { log("- $_DFFE_[NP][NP]_\n"); log("- $_DFF_[NP][NP][01]_\n"); log("- $_DFFE_[NP][NP][01][NP]_\n"); + log("- $_ALDFF_[NP][NP]_\n"); + log("- $_ALDFFE_[NP][NP][NP]_\n"); log("- $_DFFSR_[NP][NP][NP]_\n"); log("- $_DFFSRE_[NP][NP][NP][NP]_\n"); log("- $_SDFF_[NP][NP][01]_\n"); @@ -151,18 +158,30 @@ struct DffLegalizePass : public Pass { int supported_cells[NUM_FFTYPES]; // Aggregated for all *dff* cells. int supported_dff; + // Aggregated for all *dffe* cells. + int supported_dffe; // Aggregated for all dffsr* cells. int supported_dffsr; - // Aggregated for all adff* cells. - int supported_adff0; - int supported_adff1; + // Aggregated for all aldff cells. + int supported_aldff; + // Aggregated for all aldffe cells. + int supported_aldffe; + // Aggregated for all adff* cells and trivial emulations. + int supported_adff; + // Aggregated for all adffe* cells and trivial emulations. + int supported_adffe; // Aggregated for all sdff* cells. - int supported_sdff0; - int supported_sdff1; + int supported_sdff; // Aggregated for all ways to obtain a SR latch. int supported_sr; + int supported_sr_plain; // Aggregated for all *dlatch* cells. int supported_dlatch; + int supported_dlatch_plain; + // Aggregated for all ways to obtain an R latch. + int supported_rlatch; + // Aggregated for all adlatch cells and trivial emulations. + int supported_adlatch; int mince; int minsrst; @@ -179,732 +198,794 @@ struct DffLegalizePass : public Pass { res |= INIT_1; if (mask & INIT_1) res |= INIT_0; + if (mask & INIT_X_R0) + res |= INIT_X_R1; + if (mask & INIT_0_R0) + res |= INIT_1_R1; + if (mask & INIT_1_R0) + res |= INIT_0_R1; + if (mask & INIT_X_R1) + res |= INIT_X_R0; + if (mask & INIT_0_R1) + res |= INIT_1_R0; + if (mask & INIT_1_R1) + res |= INIT_0_R0; return res; } - void handle_ff(Cell *cell) { - std::string type_str = cell->type.str(); - - FfType ff_type; - int ff_neg = 0; - SigSpec sig_d; - SigSpec sig_q; - SigSpec sig_c; - SigSpec sig_e; - SigSpec sig_r; - SigSpec sig_s; - bool has_srst = false; - - if (cell->hasPort(ID::D)) - sig_d = cell->getPort(ID::D); - if (cell->hasPort(ID::Q)) - sig_q = cell->getPort(ID::Q); - if (cell->hasPort(ID::C)) - sig_c = cell->getPort(ID::C); - if (cell->hasPort(ID::E)) - sig_e = cell->getPort(ID::E); - if (cell->hasPort(ID::R)) - sig_r = cell->getPort(ID::R); - if (cell->hasPort(ID::S)) - sig_s = cell->getPort(ID::S); - - if (type_str.substr(0, 5) == "$_SR_") { - ff_type = FF_SR; - if (type_str[5] == 'N') - ff_neg |= NEG_S; - if (type_str[6] == 'N') - ff_neg |= NEG_R; - } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 8) { - ff_type = FF_DFF; - if (type_str[6] == 'N') - ff_neg |= NEG_C; - } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 10) { - ff_type = FF_DFFE; - if (type_str[7] == 'N') - ff_neg |= NEG_C; - if (type_str[8] == 'N') - ff_neg |= NEG_E; - } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { - ff_type = type_str[8] == '1' ? FF_ADFF1 : FF_ADFF0; - if (type_str[6] == 'N') - ff_neg |= NEG_C; - if (type_str[7] == 'N') - ff_neg |= NEG_R; - } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 12) { - ff_type = type_str[9] == '1' ? FF_ADFFE1 : FF_ADFFE0; - if (type_str[7] == 'N') - ff_neg |= NEG_C; - if (type_str[8] == 'N') - ff_neg |= NEG_R; - if (type_str[10] == 'N') - ff_neg |= NEG_E; - } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { - ff_type = FF_DFFSR; - if (type_str[8] == 'N') - ff_neg |= NEG_C; - if (type_str[9] == 'N') - ff_neg |= NEG_S; - if (type_str[10] == 'N') - ff_neg |= NEG_R; - } else if (type_str.substr(0, 9) == "$_DFFSRE_" && type_str.size() == 14) { - ff_type = FF_DFFSRE; - if (type_str[9] == 'N') - ff_neg |= NEG_C; - if (type_str[10] == 'N') - ff_neg |= NEG_S; - if (type_str[11] == 'N') - ff_neg |= NEG_R; - if (type_str[12] == 'N') - ff_neg |= NEG_E; - } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { - ff_type = type_str[9] == '1' ? FF_SDFF1 : FF_SDFF0; - if (type_str[7] == 'N') - ff_neg |= NEG_C; - if (type_str[8] == 'N') - ff_neg |= NEG_R; - has_srst = true; - } else if (type_str.substr(0, 8) == "$_SDFFE_" && type_str.size() == 13) { - ff_type = type_str[10] == '1' ? FF_SDFFE1 : FF_SDFFE0; - if (type_str[8] == 'N') - ff_neg |= NEG_C; - if (type_str[9] == 'N') - ff_neg |= NEG_R; - if (type_str[11] == 'N') - ff_neg |= NEG_E; - has_srst = true; - } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { - ff_type = type_str[11] == '1' ? FF_SDFFCE1 : FF_SDFFCE0; - if (type_str[9] == 'N') - ff_neg |= NEG_C; - if (type_str[10] == 'N') - ff_neg |= NEG_R; - if (type_str[12] == 'N') - ff_neg |= NEG_E; - has_srst = true; - } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { - ff_type = FF_DLATCH; - if (type_str[9] == 'N') - ff_neg |= NEG_E; - } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { - ff_type = type_str[11] == '1' ? FF_ADLATCH1 : FF_ADLATCH0; - if (type_str[9] == 'N') - ff_neg |= NEG_E; - if (type_str[10] == 'N') - ff_neg |= NEG_R; - } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { - ff_type = FF_DLATCHSR; - if (type_str[11] == 'N') - ff_neg |= NEG_E; - if (type_str[12] == 'N') - ff_neg |= NEG_S; - if (type_str[13] == 'N') - ff_neg |= NEG_R; + int get_ff_type(const FfData &ff) { + if (ff.has_clk) { + if (ff.has_sr) { + return ff.has_ce ? FF_DFFSRE : FF_DFFSR; + } else if (ff.has_arst) { + return ff.has_ce ? FF_ADFFE : FF_ADFF; + } else if (ff.has_aload) { + return ff.has_ce ? FF_ALDFFE : FF_ALDFF; + } else if (ff.has_srst) { + if (ff.has_ce) + return ff.ce_over_srst ? FF_SDFFCE : FF_SDFFE; + else + return FF_SDFF; + } else { + return ff.has_ce ? FF_DFFE : FF_DFF; + } } else { - log_warning("Ignoring unknown ff type %s [%s.%s].\n", log_id(cell->type), log_id(cell->module->name), log_id(cell->name)); - return; + if (ff.has_aload) { + if (ff.has_sr) + return FF_DLATCHSR; + else if (ff.has_arst) + return FF_ADLATCH; + else + return FF_DLATCH; + } else { + if (ff.has_sr) { + return FF_SR; + } else if (ff.has_arst) { + return FF_RLATCH; + } else { + log_assert(0); + return 0; + } + } } + } - State initval = initvals(sig_q[0]); - - FfInit initmask = INIT_X; - if (initval == State::S0) - initmask = INIT_0; - else if (initval == State::S1) - initmask = INIT_1; - const char *reason; + int get_initmask(FfData &ff) { + int res = 0; + if (ff.val_init[0] == State::S0) + res = INIT_0; + else if (ff.val_init[0] == State::S1) + res = INIT_1; + else + res = INIT_X; + if (ff.has_arst) { + if (ff.val_arst[0] == State::S0) + res <<= 4; + else if (ff.val_arst[0] == State::S1) + res <<= 8; + } else if (ff.has_srst) { + if (ff.val_srst[0] == State::S0) + res <<= 4; + else if (ff.val_srst[0] == State::S1) + res <<= 8; + } + return res; + } - bool kill_ce = mince && GetSize(sig_c) && GetSize(sig_e) && sig_e[0].wire && ce_used[sig_e[0]] < mince; - bool kill_srst = minsrst && has_srst && sig_r[0].wire && srst_used[sig_r[0]] < minsrst; + void fail_ff(const FfData &ff, const char *reason) { + log_error("FF %s.%s (type %s) cannot be legalized: %s\n", log_id(ff.module->name), log_id(ff.cell->name), log_id(ff.cell->type), reason); + } - while (!(supported_cells[ff_type] & initmask) || kill_ce || kill_srst) { - // Well, cell is not directly supported. Decide how to deal with it. + bool try_flip(FfData &ff, int supported_mask) { + int initmask = get_initmask(ff); + if (supported_mask & initmask) + return true; + if (supported_mask & flip_initmask(initmask)) { + ff.flip_bits({0}); + return true; + } + return false; + } - if (ff_type == FF_DFF || ff_type == FF_DFFE) { - if (kill_ce) { - ff_type = FF_DFF; - goto unmap_enable; - } - if (!(supported_dff & initmask)) { - // This init value is not supported at all... - if (supported_dff & flip_initmask(initmask)) { - // The other one is, though. Negate D, Q, and init. -flip_dqi: - if (initval == State::S0) { - initval = State::S1; - initmask = INIT_1; - } else if (initval == State::S1) { - initval = State::S0; - initmask = INIT_0; - } - if (ff_type != FF_SR) - sig_d = cell->module->NotGate(NEW_ID, sig_d[0]); - SigBit new_q = SigSpec(cell->module->addWire(NEW_ID))[0]; - cell->module->addNotGate(NEW_ID, new_q, sig_q[0]); - initvals.remove_init(sig_q[0]); - initvals.set_init(new_q, initval); - sig_q = new_q; - continue; - } - if (!supported_dff) - reason = "dffs are not supported"; - else - reason = "initialized dffs are not supported"; - goto error; - } + void emulate_split_init_arst(FfData &ff) { + ff.remove(); - // Some DFF is supported with this init val. Just pick a type. - if (ff_type == FF_DFF) { - // Try adding a set or reset pin. - for (auto new_type: {FF_SDFF0, FF_SDFF1, FF_ADFF0, FF_ADFF1}) - if (supported_cells[new_type] & initmask) { - ff_type = new_type; - sig_r = State::S0; - goto cell_ok; - } - // Try adding both. - if (supported_cells[FF_DFFSR] & initmask) { - ff_type = FF_DFFSR; - sig_r = State::S0; - sig_s = State::S0; - break; - } - // Nope. Will need to add enable and go the DFFE route. - sig_e = State::S1; - if (supported_cells[FF_DFFE] & initmask) { - ff_type = FF_DFFE; - break; - } - } - // Try adding a set or reset pin. - for (auto new_type: {FF_SDFFE0, FF_SDFFE1, FF_SDFFCE0, FF_SDFFCE1, FF_ADFFE0, FF_ADFFE1}) - if (supported_cells[new_type] & initmask) { - ff_type = new_type; - sig_r = State::S0; - goto cell_ok; - } - // Try adding both. - if (supported_cells[FF_DFFSRE] & initmask) { - ff_type = FF_DFFSRE; - sig_r = State::S0; - sig_s = State::S0; - break; - } + FfData ff_dff(ff.module, &initvals, NEW_ID); + ff_dff.width = ff.width; + ff_dff.has_aload = ff.has_aload; + ff_dff.sig_aload = ff.sig_aload; + ff_dff.pol_aload = ff.pol_aload; + ff_dff.sig_ad = ff.sig_ad; + ff_dff.has_clk = ff.has_clk; + ff_dff.sig_clk = ff.sig_clk; + ff_dff.pol_clk = ff.pol_clk; + ff_dff.sig_d = ff.sig_d; + ff_dff.has_ce = ff.has_ce; + ff_dff.sig_ce = ff.sig_ce; + ff_dff.pol_ce = ff.pol_ce; + ff_dff.sig_q = ff.module->addWire(NEW_ID, ff.width); + ff_dff.val_init = ff.val_init; + ff_dff.is_fine = ff.is_fine; + + FfData ff_adff(ff.module, &initvals, NEW_ID); + ff_adff.width = ff.width; + ff_adff.has_aload = ff.has_aload; + ff_adff.sig_aload = ff.sig_aload; + ff_adff.pol_aload = ff.pol_aload; + ff_adff.sig_ad = ff.sig_ad; + ff_adff.has_clk = ff.has_clk; + ff_adff.sig_clk = ff.sig_clk; + ff_adff.pol_clk = ff.pol_clk; + ff_adff.sig_d = ff.sig_d; + ff_adff.has_ce = ff.has_ce; + ff_adff.sig_ce = ff.sig_ce; + ff_adff.pol_ce = ff.pol_ce; + ff_adff.sig_q = ff.module->addWire(NEW_ID, ff.width); + ff_adff.val_init = Const(State::Sx, ff.width); + ff_adff.has_arst = true; + ff_adff.sig_arst = ff.sig_arst; + ff_adff.pol_arst = ff.pol_arst; + ff_adff.val_arst = ff.val_arst; + ff_adff.is_fine = ff.is_fine; + + FfData ff_sel(ff.module, &initvals, NEW_ID); + ff_sel.width = 1; + ff_sel.sig_q = ff.module->addWire(NEW_ID); + ff_sel.has_arst = true; + ff_sel.sig_arst = ff.sig_arst; + ff_sel.pol_arst = ff.pol_arst; + ff_sel.val_arst = State::S1; + ff_sel.val_init = State::S0; + ff_sel.is_fine = ff.is_fine; - // Seems that no DFFs with enable are supported. - // The enable input needs to be unmapped. - // This should not be reached if we started from plain DFF. - log_assert(ff_type == FF_DFFE); - ff_type = FF_DFF; -unmap_enable: - if (ff_neg & NEG_E) - sig_d = cell->module->MuxGate(NEW_ID, sig_d[0], sig_q[0], sig_e[0]); + if (ff.is_fine) + ff.module->addMuxGate(NEW_ID, ff_dff.sig_q, ff_adff.sig_q, ff_sel.sig_q, ff.sig_q); + else + ff.module->addMux(NEW_ID, ff_dff.sig_q, ff_adff.sig_q, ff_sel.sig_q, ff.sig_q); + + legalize_ff(ff_dff); + legalize_ff(ff_adff); + legalize_ff(ff_sel); + } + + void emulate_split_set_clr(FfData &ff) { + // No native DFFSR. However, if we can conjure + // a SR latch and ADFF, it can still be emulated. + int initmask = get_initmask(ff); + int flipmask = flip_initmask(initmask); + bool init_clr = true; + bool init_set = true; + State initsel = State::Sx; + int supported_arst = ff.has_clk ? supported_adff : supported_adlatch; + bool init_clr_ok = (supported_arst & initmask << 4) || (supported_arst & flipmask << 8); + bool init_set_ok = (supported_arst & initmask << 8) || (supported_arst & flipmask << 4); + if (init_clr_ok && init_set_ok && supported_sr) { + // OK + } else if (init_clr_ok && (supported_sr & INIT_0)) { + init_set = false; + initsel = State::S0; + } else if (init_set_ok && (supported_sr & INIT_1)) { + init_clr = false; + initsel = State::S1; + } else if (init_clr_ok && (supported_sr & INIT_1)) { + init_set = false; + initsel = State::S0; + } else if (init_set_ok && (supported_sr & INIT_0)) { + init_clr = false; + initsel = State::S1; + } else { + if (ff.has_clk) { + if (!supported_dffsr) + fail_ff(ff, "dffs with async set and reset are not supported"); else - sig_d = cell->module->MuxGate(NEW_ID, sig_q[0], sig_d[0], sig_e[0]); - ff_neg &= ~NEG_E; - sig_e = SigSpec(); - kill_ce = false; - // Now try again as plain DFF. - continue; - } else if (ff_type == FF_ADFF0 || ff_type == FF_ADFF1 || ff_type == FF_ADFFE0 || ff_type == FF_ADFFE1) { - bool has_set = ff_type == FF_ADFF1 || ff_type == FF_ADFFE1; - bool has_en = ff_type == FF_ADFFE0 || ff_type == FF_ADFFE1; - if (kill_ce) { - ff_type = has_set ? FF_ADFF1 : FF_ADFF0; - goto unmap_enable; - } - if (!has_en && (supported_cells[has_set ? FF_ADFFE1 : FF_ADFFE0] & initmask)) { - // Just add enable. - sig_e = State::S1; - ff_type = has_set ? FF_ADFFE1 : FF_ADFFE0; - break; - } - if (supported_cells[has_en ? FF_DFFSRE : FF_DFFSR] & initmask) { -adff_to_dffsr: - // Throw in a set/reset, retry in DFFSR/DFFSRE branch. - if (has_set) { - sig_s = sig_r; - sig_r = State::S0; - if (ff_neg & NEG_R) { - ff_neg &= ~NEG_R; - ff_neg |= NEG_S; - } - } else { - sig_s = State::S0; - } - if (has_en) - ff_type = FF_DFFSRE; - else - ff_type = FF_DFFSR; - continue; - } - if (has_en && (supported_cells[has_set ? FF_ADFF1 : FF_ADFF0] & initmask)) { - // Unmap enable. - ff_type = has_set ? FF_ADFF1 : FF_ADFF0; - goto unmap_enable; - } - if (supported_dffsr & initmask) { - goto adff_to_dffsr; - } - log_assert(!((has_set ? supported_adff1 : supported_adff0) & initmask)); - // Alright, so this particular combination of initval and - // resetval is not natively supported. First, try flipping - // them both to see whether this helps. - int flipmask = flip_initmask(initmask); - if ((has_set ? supported_adff0 : supported_adff1) & flipmask) { - // Checks out, do it. - ff_type = has_en ? (has_set ? FF_ADFFE0 : FF_ADFFE1) : (has_set ? FF_ADFF0 : FF_ADFF1); - goto flip_dqi; - } + fail_ff(ff, "initialized dffs with async set and reset are not supported"); + } else { + if (!supported_cells[FF_DLATCHSR]) + fail_ff(ff, "dlatch with async set and reset are not supported"); + else + fail_ff(ff, "initialized dlatch with async set and reset are not supported"); + } + } - if (!supported_adff0 && !supported_adff1) { - reason = "dffs with async set or reset are not supported"; - goto error; - } - if (!(supported_dff & ~INIT_X)) { - reason = "initialized dffs are not supported"; - goto error; - } - // If we got here, initialized dff is supported, but not this - // particular reset+init combination (nor its negation). - // The only hope left is breaking down to adff + dff + dlatch + mux. - if (!(supported_dlatch & ~INIT_X)) { - reason = "unsupported initial value and async reset value combination"; - goto error; - } + // If we have to unmap enable anyway, do it before breakdown. + if (ff.has_ce && !supported_cells[FF_ADFFE]) + ff.unmap_ce(); - // If we have to unmap enable anyway, do it before breakdown. - if (has_en && !supported_cells[FF_ADFFE0] && !supported_cells[FF_ADFFE1]) { - ff_type = has_set ? FF_ADFF1 : FF_ADFF0; - goto unmap_enable; - } + log_warning("Emulating async set + reset with several FFs and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); - log_warning("Emulating mismatched async reset and init with several FFs and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); - initvals.remove_init(sig_q[0]); - Wire *adff_q = cell->module->addWire(NEW_ID); - Wire *dff_q = cell->module->addWire(NEW_ID); - Wire *sel_q = cell->module->addWire(NEW_ID); - initvals.set_init(SigBit(dff_q, 0), initval); - initvals.set_init(SigBit(sel_q, 0), State::S0); - Cell *cell_dff; - Cell *cell_adff; - Cell *cell_sel; - if (!has_en) { - cell_dff = cell->module->addDffGate(NEW_ID, sig_c, sig_d, dff_q, !(ff_neg & NEG_C)); - cell_adff = cell->module->addAdffGate(NEW_ID, sig_c, sig_r, sig_d, adff_q, has_set, !(ff_neg & NEG_C), !(ff_neg & NEG_R)); - } else { - cell_dff = cell->module->addDffeGate(NEW_ID, sig_c, sig_e, sig_d, dff_q, !(ff_neg & NEG_C), !(ff_neg & NEG_E)); - cell_adff = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_r, sig_d, adff_q, has_set, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_R)); - } - cell_sel = cell->module->addDlatchGate(NEW_ID, sig_r, State::S1, sel_q, !(ff_neg & NEG_R)); - cell->module->addMuxGate(NEW_ID, dff_q, adff_q, sel_q, sig_q); - - // Bye, cell. - cell->module->remove(cell); - handle_ff(cell_dff); - handle_ff(cell_adff); - handle_ff(cell_sel); - return; - } else if (ff_type == FF_DFFSR || ff_type == FF_DFFSRE) { - if (kill_ce) { - ff_type = FF_DFFSR; - goto unmap_enable; - } - // First, see if mapping/unmapping enable will help. - if (supported_cells[FF_DFFSRE] & initmask) { - ff_type = FF_DFFSRE; - sig_e = State::S1; - break; - } - if (supported_cells[FF_DFFSR] & initmask) { - ff_type = FF_DFFSR; - goto unmap_enable; - } - if (supported_dffsr & flip_initmask(initmask)) { -flip_dqisr:; - log_warning("Flipping D/Q/init and inserting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type)); - SigSpec new_r; - bool neg_r = (ff_neg & NEG_R); - bool neg_s = (ff_neg & NEG_S); - if (!(ff_neg & NEG_S)) { - if (!(ff_neg & NEG_R)) - new_r = cell->module->AndnotGate(NEW_ID, sig_s, sig_r); - else - new_r = cell->module->AndGate(NEW_ID, sig_s, sig_r); - } else { - if (!(ff_neg & NEG_R)) - new_r = cell->module->OrGate(NEW_ID, sig_s, sig_r); - else - new_r = cell->module->OrnotGate(NEW_ID, sig_s, sig_r); - } - ff_neg &= ~(NEG_R | NEG_S); - if (neg_r) - ff_neg |= NEG_S; - if (neg_s) - ff_neg |= NEG_R; - sig_s = sig_r; - sig_r = new_r; - goto flip_dqi; - } - // No native DFFSR. However, if we can conjure - // a SR latch and ADFF, it can still be emulated. - int flipmask = flip_initmask(initmask); - bool init0 = true; - bool init1 = true; - State initsel = State::Sx; - if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && ((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && supported_sr) { - // OK - } else if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && (supported_sr & INIT_0)) { - init1 = false; - initsel = State::S0; - } else if (((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && (supported_sr & INIT_1)) { - init0 = false; - initsel = State::S1; - } else if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && (supported_sr & INIT_1)) { - init1 = false; - initsel = State::S0; - } else if (((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && (supported_sr & INIT_0)) { - init0 = false; - initsel = State::S1; - } else { - if (!supported_dffsr) - reason = "dffs with async set and reset are not supported"; - else - reason = "initialized dffs with async set and reset are not supported"; - goto error; - } + log_assert(ff.width == 1); + ff.remove(); - // If we have to unmap enable anyway, do it before breakdown. - if (ff_type == FF_DFFSRE && !supported_cells[FF_ADFFE0] && !supported_cells[FF_ADFFE1]) { - ff_type = FF_DFFSR; - goto unmap_enable; - } + FfData ff_clr(ff.module, &initvals, NEW_ID); + ff_clr.width = ff.width; + ff_clr.has_aload = ff.has_aload; + ff_clr.sig_aload = ff.sig_aload; + ff_clr.pol_aload = ff.pol_aload; + ff_clr.sig_ad = ff.sig_ad; + ff_clr.has_clk = ff.has_clk; + ff_clr.sig_clk = ff.sig_clk; + ff_clr.pol_clk = ff.pol_clk; + ff_clr.sig_d = ff.sig_d; + ff_clr.has_ce = ff.has_ce; + ff_clr.sig_ce = ff.sig_ce; + ff_clr.pol_ce = ff.pol_ce; + ff_clr.has_arst = true; + ff_clr.sig_arst = ff.sig_clr; + ff_clr.pol_arst = ff.pol_clr; + ff_clr.val_arst = Const(State::S0, ff.width); + ff_clr.sig_q = ff.module->addWire(NEW_ID, ff.width); + ff_clr.val_init = init_clr ? ff.val_init : Const(State::Sx, ff.width); + ff_clr.is_fine = ff.is_fine; - log_warning("Emulating async set + reset with several FFs and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); - initvals.remove_init(sig_q[0]); - Wire *adff0_q = cell->module->addWire(NEW_ID); - Wire *adff1_q = cell->module->addWire(NEW_ID); - Wire *sel_q = cell->module->addWire(NEW_ID); - if (init0) - initvals.set_init(SigBit(adff0_q, 0), initval); - if (init1) - initvals.set_init(SigBit(adff1_q, 0), initval); - initvals.set_init(SigBit(sel_q, 0), initsel); - Cell *cell_adff0; - Cell *cell_adff1; - Cell *cell_sel; - if (ff_type == FF_DFFSR) { - cell_adff0 = cell->module->addAdffGate(NEW_ID, sig_c, sig_r, sig_d, adff0_q, false, !(ff_neg & NEG_C), !(ff_neg & NEG_R)); - cell_adff1 = cell->module->addAdffGate(NEW_ID, sig_c, sig_s, sig_d, adff1_q, true, !(ff_neg & NEG_C), !(ff_neg & NEG_S)); - } else { - cell_adff0 = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_r, sig_d, adff0_q, false, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_R)); - cell_adff1 = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_s, sig_d, adff1_q, true, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_S)); - } - cell_sel = cell->module->addSrGate(NEW_ID, sig_s, sig_r, sel_q, !(ff_neg & NEG_S), !(ff_neg & NEG_R)); - cell->module->addMuxGate(NEW_ID, adff0_q, adff1_q, sel_q, sig_q); - - // Bye, cell. - cell->module->remove(cell); - handle_ff(cell_adff0); - handle_ff(cell_adff1); - handle_ff(cell_sel); + FfData ff_set(ff.module, &initvals, NEW_ID); + ff_set.width = ff.width; + ff_set.has_aload = ff.has_aload; + ff_set.sig_aload = ff.sig_aload; + ff_set.pol_aload = ff.pol_aload; + ff_set.sig_ad = ff.sig_ad; + ff_set.has_clk = ff.has_clk; + ff_set.sig_clk = ff.sig_clk; + ff_set.pol_clk = ff.pol_clk; + ff_set.sig_d = ff.sig_d; + ff_set.has_ce = ff.has_ce; + ff_set.sig_ce = ff.sig_ce; + ff_set.pol_ce = ff.pol_ce; + ff_set.has_arst = true; + ff_set.sig_arst = ff.sig_set; + ff_set.pol_arst = ff.pol_set; + ff_set.val_arst = Const(State::S1, ff.width); + ff_set.sig_q = ff.module->addWire(NEW_ID, ff.width); + ff_set.val_init = init_set ? ff.val_init : Const(State::Sx, ff.width); + ff_set.is_fine = ff.is_fine; + + FfData ff_sel(ff.module, &initvals, NEW_ID); + ff_sel.width = ff.width; + ff_sel.has_sr = true; + ff_sel.pol_clr = ff.pol_clr; + ff_sel.pol_set = ff.pol_set; + ff_sel.sig_clr = ff.sig_clr; + ff_sel.sig_set = ff.sig_set; + ff_sel.sig_q = ff.module->addWire(NEW_ID, ff.width); + ff_sel.val_init = Const(initsel, ff.width); + ff_sel.is_fine = ff.is_fine; + + if (!ff.is_fine) + ff.module->addMux(NEW_ID, ff_clr.sig_q, ff_set.sig_q, ff_sel.sig_q, ff.sig_q); + else + ff.module->addMuxGate(NEW_ID, ff_clr.sig_q, ff_set.sig_q, ff_sel.sig_q, ff.sig_q); + + legalize_ff(ff_clr); + legalize_ff(ff_set); + legalize_ff(ff_sel); + } + + void legalize_dff(FfData &ff) { + if (!try_flip(ff, supported_dff)) { + if (!supported_dff) + fail_ff(ff, "D flip-flops are not supported"); + else + fail_ff(ff, "initialized D flip-flops are not supported"); + } + + int initmask = get_initmask(ff); + // Some DFF is supported with this init val. Just pick a type. + if (ff.has_ce && !(supported_dffe & initmask)) { + ff.unmap_ce(); + } + + if (!ff.has_ce) { + if (supported_cells[FF_DFF] & initmask) { + legalize_finish(ff); return; - } else if (ff_type == FF_SR) { - if (supported_cells[FF_ADLATCH0] & initmask || supported_cells[FF_ADLATCH1] & flip_initmask(initmask)) { - // Convert to ADLATCH0. May get converted to ADLATCH1. - ff_type = FF_ADLATCH0; - sig_e = sig_s; - sig_d = State::S1; - if (ff_neg & NEG_S) { - ff_neg &= ~NEG_S; - ff_neg |= NEG_E; - } - continue; - } else if (supported_cells[FF_DLATCHSR] & initmask) { - // Upgrade to DLATCHSR. - ff_type = FF_DLATCHSR; - sig_e = State::S0; - sig_d = State::Sx; - break; - } else if (supported_dffsr & initmask) { - // Upgrade to DFFSR. May get further upgraded to DFFSRE. - ff_type = FF_DFFSR; - sig_c = State::S0; - sig_d = State::Sx; - continue; - } else if (supported_sr & flip_initmask(initmask)) { - goto flip_dqisr; - } else { - if (!supported_sr) - reason = "sr latches are not supported"; - else - reason = "initialized sr latches are not supported"; - goto error; - } - } else if (ff_type == FF_DLATCH) { - if (!(supported_dlatch & initmask)) { - // This init value is not supported at all... - if (supported_dlatch & flip_initmask(initmask)) - goto flip_dqi; - - if ((sig_d == State::S0 && (supported_adff0 & initmask)) || - (sig_d == State::S1 && (supported_adff1 & initmask)) || - (sig_d == State::S0 && (supported_adff1 & flip_initmask(initmask))) || - (sig_d == State::S1 && (supported_adff0 & flip_initmask(initmask))) - ) { - // Special case: const-D dlatch can be converted into adff with const clock. - ff_type = (sig_d == State::S0) ? FF_ADFF0 : FF_ADFF1; - if (ff_neg & NEG_E) { - ff_neg &= ~NEG_E; - ff_neg |= NEG_R; - } - sig_r = sig_e; - sig_d = State::Sx; - sig_c = State::S1; - continue; - } + } + // Try adding a set or reset pin. + if (supported_cells[FF_SDFF] & initmask) { + ff.add_dummy_srst(); + legalize_finish(ff); + return; + } + if (supported_cells[FF_ADFF] & initmask) { + ff.add_dummy_arst(); + legalize_finish(ff); + return; + } + // Try adding async load. + if (supported_cells[FF_ALDFF] & initmask) { + ff.add_dummy_aload(); + legalize_finish(ff); + return; + } + // Try adding both. + if (supported_cells[FF_DFFSR] & initmask) { + ff.add_dummy_sr(); + legalize_finish(ff); + return; + } + // Nope. Will need to add enable and go the DFFE route. + ff.add_dummy_ce(); + } + if (supported_cells[FF_DFFE] & initmask) { + legalize_finish(ff); + return; + } + // Try adding a set or reset pin. + if (supported_cells[FF_SDFFCE] & initmask) { + ff.add_dummy_srst(); + ff.ce_over_srst = true; + legalize_finish(ff); + return; + } + if (supported_cells[FF_SDFFE] & initmask) { + ff.add_dummy_srst(); + legalize_finish(ff); + return; + } + if (supported_cells[FF_ADFFE] & initmask) { + ff.add_dummy_arst(); + legalize_finish(ff); + return; + } + if (supported_cells[FF_ALDFFE] & initmask) { + ff.add_dummy_aload(); + legalize_finish(ff); + return; + } + // Try adding both. + if (supported_cells[FF_DFFSRE] & initmask) { + ff.add_dummy_sr(); + legalize_finish(ff); + return; + } + log_assert(0); + } - if (!supported_dlatch) - reason = "dlatch are not supported"; - else - reason = "initialized dlatch are not supported"; - goto error; - } + void legalize_sdffce(FfData &ff) { + if (!try_flip(ff, supported_cells[FF_SDFFCE] | supported_cells[FF_SDFFE])) { + ff.unmap_srst(); + legalize_dff(ff); + return; + } - // Some DLATCH is supported with this init val. Just pick a type. - if (supported_cells[FF_ADLATCH0] & initmask) { - ff_type = FF_ADLATCH0; - sig_r = State::S0; - break; - } - if (supported_cells[FF_ADLATCH1] & initmask) { - ff_type = FF_ADLATCH1; - sig_r = State::S0; - break; - } - if (supported_cells[FF_DLATCHSR] & initmask) { - ff_type = FF_DLATCHSR; - sig_r = State::S0; - sig_s = State::S0; - break; - } + int initmask = get_initmask(ff); + if (supported_cells[FF_SDFFCE] & initmask) { + // OK + } else if (supported_cells[FF_SDFFE] & initmask) { + ff.convert_ce_over_srst(false); + } else { + log_assert(0); + } + legalize_finish(ff); + } + + void legalize_sdff(FfData &ff) { + if (!try_flip(ff, supported_sdff)) { + ff.unmap_srst(); + legalize_dff(ff); + return; + } + + int initmask = get_initmask(ff); + if (!ff.has_ce) { + if (supported_cells[FF_SDFF] & initmask) { + // OK + } else if (supported_cells[FF_SDFFE] & initmask) { + ff.add_dummy_ce(); + } else if (supported_cells[FF_SDFFCE] & initmask) { + ff.add_dummy_ce(); + ff.ce_over_srst = true; + } else { log_assert(0); - } else if (ff_type == FF_ADLATCH0 || ff_type == FF_ADLATCH1) { - if (supported_cells[FF_DLATCHSR] & initmask) { - if (ff_type == FF_ADLATCH1) { - sig_s = sig_r; - sig_r = State::S0; - if (ff_neg & NEG_R) { - ff_neg &= ~NEG_R; - ff_neg |= NEG_S; - } - } else { - sig_s = State::S0; - } - ff_type = FF_DLATCHSR; - break; - } - FfType flip_type = ff_type == FF_ADLATCH0 ? FF_ADLATCH1 : FF_ADLATCH0; - if ((supported_cells[flip_type] | supported_cells[FF_DLATCHSR]) & flip_initmask(initmask)) { - ff_type = flip_type; - goto flip_dqi; - } + } + } else { + log_assert(!ff.ce_over_srst); + if (supported_cells[FF_SDFFE] & initmask) { + // OK + } else if (supported_cells[FF_SDFFCE] & initmask) { + ff.convert_ce_over_srst(true); + } else if (supported_cells[FF_SDFF] & initmask) { + ff.unmap_ce(); + } else { + log_assert(0); + } + } + legalize_finish(ff); + } - if (!supported_cells[FF_ADLATCH0] && !supported_cells[FF_ADLATCH1] && !supported_cells[FF_DLATCHSR]) { - reason = "dlatch with async set or reset are not supported"; - goto error; - } - if (!(supported_dlatch & ~INIT_X)) { - reason = "initialized dlatch are not supported"; - goto error; - } + void legalize_adff(FfData &ff) { + if (!try_flip(ff, supported_adff)) { + if (!supported_adff) + fail_ff(ff, "dffs with async set or reset are not supported"); + if (!(supported_dff & (INIT_0 | INIT_1))) + fail_ff(ff, "initialized dffs are not supported"); + + // If we got here, initialized dff is supported, but not this + // particular reset+init combination (nor its negation). + // The only hope left is breaking down to adff + dff + dlatch + mux. + + if (!((supported_rlatch) & (INIT_0_R1 | INIT_1_R0))) + fail_ff(ff, "unsupported initial value and async reset value combination"); + + // If we have to unmap enable anyway, do it before breakdown. + if (ff.has_ce && !supported_cells[FF_ADFFE]) + ff.unmap_ce(); + + if (ff.cell) + log_warning("Emulating mismatched async reset and init with several FFs and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); + emulate_split_init_arst(ff); + return; + } - // If we got here, initialized dlatch is supported, but not this - // particular reset+init combination (nor its negation). - // The only hope left is breaking down to adff + dff + dlatch + mux. - - log_warning("Emulating mismatched async reset and init with several latches and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); - initvals.remove_init(sig_q[0]); - Wire *adlatch_q = cell->module->addWire(NEW_ID); - Wire *dlatch_q = cell->module->addWire(NEW_ID); - Wire *sel_q = cell->module->addWire(NEW_ID); - initvals.set_init(SigBit(dlatch_q, 0), initval); - initvals.set_init(SigBit(sel_q, 0), State::S0); - Cell *cell_dlatch; - Cell *cell_adlatch; - Cell *cell_sel; - cell_dlatch = cell->module->addDlatchGate(NEW_ID, sig_e, sig_d, dlatch_q, !(ff_neg & NEG_E)); - cell_adlatch = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_r, sig_d, adlatch_q, ff_type == FF_ADLATCH1, !(ff_neg & NEG_E), !(ff_neg & NEG_R)); - cell_sel = cell->module->addDlatchGate(NEW_ID, sig_r, State::S1, sel_q, !(ff_neg & NEG_R)); - cell->module->addMuxGate(NEW_ID, dlatch_q, adlatch_q, sel_q, sig_q); - - // Bye, cell. - cell->module->remove(cell); - handle_ff(cell_dlatch); - handle_ff(cell_adlatch); - handle_ff(cell_sel); + int initmask = get_initmask(ff); + if (ff.has_ce && !(supported_adffe & initmask)) { + ff.unmap_ce(); + } + + if (!ff.has_ce) { + if (supported_cells[FF_ADFF] & initmask) { + legalize_finish(ff); return; - } else if (ff_type == FF_DLATCHSR) { - if (supported_cells[FF_DLATCHSR] & flip_initmask(initmask)) { - goto flip_dqisr; - } - // No native DFFSR. However, if we can conjure - // a SR latch and ADFF, it can still be emulated. - int flipmask = flip_initmask(initmask); - bool init0 = true; - bool init1 = true; - State initsel = State::Sx; - if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && ((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && supported_sr) { - // OK - } else if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && (supported_sr & INIT_0)) { - init1 = false; - initsel = State::S0; - } else if (((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && (supported_sr & INIT_1)) { - init0 = false; - initsel = State::S1; - } else if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && (supported_sr & INIT_1)) { - init1 = false; - initsel = State::S0; - } else if (((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && (supported_sr & INIT_0)) { - init0 = false; - initsel = State::S1; - } else { - if (!supported_cells[FF_DLATCHSR]) - reason = "dlatch with async set and reset are not supported"; - else - reason = "initialized dlatch with async set and reset are not supported"; - goto error; - } + } + // Try converting to async load. + if (supported_cells[FF_ALDFF] & initmask) { + ff.arst_to_aload(); + legalize_finish(ff); + return; + } + // Try convertint to SR. + if (supported_cells[FF_DFFSR] & initmask) { + ff.arst_to_sr(); + legalize_finish(ff); + return; + } + ff.add_dummy_ce(); + } + if (supported_cells[FF_ADFFE] & initmask) { + legalize_finish(ff); + return; + } + // Try converting to async load. + if (supported_cells[FF_ALDFFE] & initmask) { + ff.arst_to_aload(); + legalize_finish(ff); + return; + } + // Try convertint to SR. + if (supported_cells[FF_DFFSRE] & initmask) { + ff.arst_to_sr(); + legalize_finish(ff); + return; + } + log_assert(0); + } + + void legalize_aldff(FfData &ff) { + if (!try_flip(ff, supported_aldff)) { + ff.aload_to_sr(); + emulate_split_set_clr(ff); + return; + } + + int initmask = get_initmask(ff); + if (ff.has_ce && !(supported_aldffe & initmask)) { + ff.unmap_ce(); + } - log_warning("Emulating async set + reset with several latches and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); - initvals.remove_init(sig_q[0]); - Wire *adlatch0_q = cell->module->addWire(NEW_ID); - Wire *adlatch1_q = cell->module->addWire(NEW_ID); - Wire *sel_q = cell->module->addWire(NEW_ID); - if (init0) - initvals.set_init(SigBit(adlatch0_q, 0), initval); - if (init1) - initvals.set_init(SigBit(adlatch1_q, 0), initval); - initvals.set_init(SigBit(sel_q, 0), initsel); - Cell *cell_adlatch0; - Cell *cell_adlatch1; - Cell *cell_sel; - cell_adlatch0 = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_r, sig_d, adlatch0_q, false, !(ff_neg & NEG_E), !(ff_neg & NEG_R)); - cell_adlatch1 = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_s, sig_d, adlatch1_q, true, !(ff_neg & NEG_E), !(ff_neg & NEG_S)); - cell_sel = cell->module->addSrGate(NEW_ID, sig_s, sig_r, sel_q, !(ff_neg & NEG_S), !(ff_neg & NEG_R)); - cell->module->addMuxGate(NEW_ID, adlatch0_q, adlatch1_q, sel_q, sig_q); - - // Bye, cell. - cell->module->remove(cell); - handle_ff(cell_adlatch0); - handle_ff(cell_adlatch1); - handle_ff(cell_sel); + if (!ff.has_ce) { + if (supported_cells[FF_ALDFF] & initmask) { + legalize_finish(ff); return; - } else if (ff_type == FF_SDFF0 || ff_type == FF_SDFF1 || ff_type == FF_SDFFE0 || ff_type == FF_SDFFE1 || ff_type == FF_SDFFCE0 || ff_type == FF_SDFFCE1) { - bool has_set = ff_type == FF_SDFF1 || ff_type == FF_SDFFE1 || ff_type == FF_SDFFCE1; - bool has_en = ff_type == FF_SDFFE0 || ff_type == FF_SDFFE1; - bool has_ce = ff_type == FF_SDFFCE0 || ff_type == FF_SDFFCE1; - - if (has_en) { - if (kill_ce || kill_srst) { - ff_type = has_set ? FF_SDFF1 : FF_SDFF0; - goto unmap_enable; - } - } else if (has_ce) { - if (kill_ce || kill_srst) - goto unmap_srst; - } else { - log_assert(!kill_ce); - if (kill_srst) - goto unmap_srst; - } + } + if (supported_cells[FF_DFFSR] & initmask) { + ff.aload_to_sr(); + legalize_finish(ff); + return; + } + ff.add_dummy_ce(); + } + if (supported_cells[FF_ALDFFE] & initmask) { + legalize_finish(ff); + return; + } + if (supported_cells[FF_DFFSRE] & initmask) { + ff.aload_to_sr(); + legalize_finish(ff); + return; + } + log_assert(0); + } - if (!has_ce) { - if (!has_en && (supported_cells[has_set ? FF_SDFFE1 : FF_SDFFE0] & initmask)) { - // Just add enable. - sig_e = State::S1; - ff_type = has_set ? FF_SDFFE1 : FF_SDFFE0; - break; - } - if (!has_en && (supported_cells[has_set ? FF_SDFFCE1 : FF_SDFFCE0] & initmask)) { - // Just add enable. - sig_e = State::S1; - ff_type = has_set ? FF_SDFFCE1 : FF_SDFFCE0; - break; - } - if (has_en && (supported_cells[has_set ? FF_SDFFCE1 : FF_SDFFCE0] & initmask)) { - // Convert sdffe to sdffce - if (!(ff_neg & NEG_E)) { - if (!(ff_neg & NEG_R)) - sig_e = cell->module->OrGate(NEW_ID, sig_e, sig_r); - else - sig_e = cell->module->OrnotGate(NEW_ID, sig_e, sig_r); - } else { - if (!(ff_neg & NEG_R)) - sig_e = cell->module->AndnotGate(NEW_ID, sig_e, sig_r); - else - sig_e = cell->module->AndGate(NEW_ID, sig_e, sig_r); - } - ff_type = has_set ? FF_SDFFCE1 : FF_SDFFCE0; - break; - } - if (has_en && (supported_cells[has_set ? FF_SDFF1 : FF_SDFF0] & initmask)) { - // Unmap enable. - ff_type = has_set ? FF_SDFF1 : FF_SDFF0; - goto unmap_enable; - } - log_assert(!((has_set ? supported_sdff1 : supported_sdff0) & initmask)); - } else { - if ((has_set ? supported_sdff1 : supported_sdff0) & initmask) { - // Convert sdffce to sdffe, which may be further converted to sdff. - if (!(ff_neg & NEG_R)) { - if (!(ff_neg & NEG_E)) - sig_r = cell->module->AndGate(NEW_ID, sig_r, sig_e); - else - sig_r = cell->module->AndnotGate(NEW_ID, sig_r, sig_e); - } else { - if (!(ff_neg & NEG_E)) - sig_r = cell->module->OrnotGate(NEW_ID, sig_r, sig_e); - else - sig_r = cell->module->OrGate(NEW_ID, sig_r, sig_e); - } - ff_type = has_set ? FF_SDFFE1 : FF_SDFFE0; - continue; - } + void legalize_dffsr(FfData &ff) { + if (!try_flip(ff, supported_dffsr)) { + emulate_split_set_clr(ff); + return; + } + + int initmask = get_initmask(ff); + if (ff.has_ce && !(supported_cells[FF_DFFSRE] & initmask)) { + ff.unmap_ce(); + } + + if (!ff.has_ce) { + if (supported_cells[FF_DFFSR] & initmask) { + legalize_finish(ff); + return; + } + ff.add_dummy_ce(); + } + + log_assert(supported_cells[FF_DFFSRE] & initmask); + legalize_finish(ff); + } + + void legalize_dlatch(FfData &ff) { + if (!try_flip(ff, supported_dlatch)) { + if (!supported_dlatch) + fail_ff(ff, "D latches are not supported"); + else + fail_ff(ff, "initialized D latches are not supported"); + } + + int initmask = get_initmask(ff); + // Some DLATCH is supported with this init val. Just pick a type. + if (supported_cells[FF_DLATCH] & initmask) { + legalize_finish(ff); + } else if (supported_cells[FF_ADLATCH] & initmask) { + ff.add_dummy_arst(); + legalize_finish(ff); + } else if (supported_cells[FF_DLATCHSR] & initmask) { + ff.add_dummy_sr(); + legalize_finish(ff); + } else if (supported_cells[FF_ALDFF] & initmask) { + ff.add_dummy_clk(); + legalize_finish(ff); + } else if (supported_cells[FF_ALDFFE] & initmask) { + ff.add_dummy_clk(); + ff.add_dummy_ce(); + legalize_finish(ff); + } else if (supported_sr & initmask) { + ff.aload_to_sr(); + legalize_sr(ff); + } else { + log_assert(0); + } + } + + void legalize_adlatch(FfData &ff) { + if (!try_flip(ff, supported_adlatch)) { + if (!supported_adlatch) + fail_ff(ff, "D latches with async set or reset are not supported"); + if (!(supported_dlatch & (INIT_0 | INIT_1))) + fail_ff(ff, "initialized D latches are not supported"); + + // If we got here, initialized dlatch is supported, but not this + // particular reset+init combination (nor its negation). + // The only hope left is breaking down to adlatch + dlatch + dlatch + mux. + + if (ff.cell) + log_warning("Emulating mismatched async reset and init with several latches and a mux for %s.%s\n", log_id(ff.module->name), log_id(ff.cell->name)); + ff.remove(); + + emulate_split_init_arst(ff); + return; + } + int initmask = get_initmask(ff); + if (supported_cells[FF_ADLATCH] & initmask) { + // OK + } else if (supported_cells[FF_DLATCHSR] & initmask) { + ff.arst_to_sr(); + } else { + log_assert(0); + } + legalize_finish(ff); + } + + void legalize_dlatchsr(FfData &ff) { + if (!try_flip(ff, supported_cells[FF_DLATCHSR])) { + emulate_split_set_clr(ff); + return; + } + legalize_finish(ff); + } + + void legalize_rlatch(FfData &ff) { + if (!try_flip(ff, supported_rlatch)) { + if (!supported_dlatch) + fail_ff(ff, "D latches are not supported"); + else + fail_ff(ff, "initialized D latches are not supported"); + } + + int initmask = get_initmask(ff); + if (((supported_dlatch_plain & 7) * 0x111) & initmask) { + ff.arst_to_aload(); + legalize_dlatch(ff); + } else if (supported_sr & initmask) { + ff.arst_to_sr(); + legalize_sr(ff); + } else if (supported_adff & initmask) { + ff.add_dummy_clk(); + legalize_adff(ff); + } else { + log_assert(0); + } + } + + void legalize_sr(FfData &ff) { + if (!try_flip(ff, supported_sr)) { + if (!supported_sr) + fail_ff(ff, "sr latches are not supported"); + else + fail_ff(ff, "initialized sr latches are not supported"); + } + int initmask = get_initmask(ff); + if (supported_cells[FF_SR] & initmask) { + // OK + } else if (supported_cells[FF_DLATCHSR] & initmask) { + // Upgrade to DLATCHSR. + ff.add_dummy_aload(); + } else if (supported_cells[FF_DFFSR] & initmask) { + // Upgrade to DFFSR. + ff.add_dummy_clk(); + } else if (supported_cells[FF_DFFSRE] & initmask) { + // Upgrade to DFFSRE. + ff.add_dummy_clk(); + ff.add_dummy_ce(); + } else if (supported_cells[FF_ADLATCH] & (initmask << 4)) { + ff.has_sr = false; + ff.has_aload = true; + ff.has_arst = true; + ff.pol_arst = ff.pol_clr; + ff.sig_arst = ff.sig_clr; + ff.sig_aload = ff.sig_set; + ff.pol_aload = ff.pol_set; + ff.sig_ad = State::S1; + ff.val_arst = State::S0; + } else if (supported_cells[FF_ADLATCH] & (flip_initmask(initmask) << 8)) { + ff.has_sr = false; + ff.has_aload = true; + ff.has_arst = true; + ff.pol_arst = ff.pol_clr; + ff.sig_arst = ff.sig_clr; + ff.sig_aload = ff.sig_set; + ff.pol_aload = ff.pol_set; + ff.sig_ad = State::S0; + ff.val_arst = State::S1; + ff.remove_init(); + Wire *new_q = ff.module->addWire(NEW_ID); + if (ff.is_fine) + ff.module->addNotGate(NEW_ID, new_q, ff.sig_q); + else + ff.module->addNot(NEW_ID, new_q, ff.sig_q); + ff.sig_q = new_q; + if (ff.val_init == State::S0) + ff.val_init = State::S1; + else if (ff.val_init == State::S1) + ff.val_init = State::S0; + } else { + log_assert(0); + } + legalize_finish(ff); + } + + void fixup_reset_x(FfData &ff, int supported) { + for (int i = 0; i < ff.width; i++) { + int mask; + if (ff.val_init[i] == State::S0) + mask = INIT_0; + else if (ff.val_init[i] == State::S1) + mask = INIT_1; + else + mask = INIT_X; + if (ff.has_arst) { + if (ff.val_arst[i] == State::Sx) { + if (!(supported & (mask << 8))) + ff.val_arst[i] = State::S0; + if (!(supported & (mask << 4))) + ff.val_arst[i] = State::S1; } - // Alright, so this particular combination of initval and - // resetval is not natively supported. First, try flipping - // them both to see whether this helps. - if ((has_set ? supported_sdff0 : supported_sdff1) & flip_initmask(initmask)) { - // Checks out, do it. - ff_type = has_ce ? (has_set ? FF_SDFFCE0 : FF_SDFFCE1) : has_en ? (has_set ? FF_SDFFE0 : FF_SDFFE1) : (has_set ? FF_SDFF0 : FF_SDFF1); - goto flip_dqi; + } + if (ff.has_srst) { + if (ff.val_srst[i] == State::Sx) { + if (!(supported & (mask << 8))) + ff.val_srst[i] = State::S0; + if (!(supported & (mask << 4))) + ff.val_srst[i] = State::S1; } + } + } + } - // Nope. No way to get SDFF* of the right kind, so unmap it. - // For SDFFE, the enable has to be unmapped first. - if (has_en) { - ff_type = has_set ? FF_SDFF1 : FF_SDFF0; - goto unmap_enable; - } -unmap_srst: - if (has_ce) - ff_type = FF_DFFE; - else - ff_type = FF_DFF; - if (ff_neg & NEG_R) - sig_d = cell->module->MuxGate(NEW_ID, has_set ? State::S1 : State::S0, sig_d[0], sig_r[0]); + void legalize_ff(FfData &ff) { + if (ff.has_gclk) + return; + + // TODO: consider supporting coarse as well. + if (!ff.is_fine) + return; + + if (mince && ff.has_ce && ff.sig_ce[0].wire && ce_used[ff.sig_ce[0]] < mince) + ff.unmap_ce(); + if (minsrst && ff.has_srst && ff.sig_srst[0].wire && srst_used[ff.sig_srst[0]] < minsrst) + ff.unmap_srst(); + + if (ff.has_clk) { + if (ff.has_sr) { + legalize_dffsr(ff); + } else if (ff.has_aload) { + legalize_aldff(ff); + } else if (ff.has_arst) { + legalize_adff(ff); + } else if (ff.has_srst) { + if (ff.has_ce && ff.ce_over_srst) + legalize_sdffce(ff); else - sig_d = cell->module->MuxGate(NEW_ID, sig_d[0], has_set ? State::S1 : State::S0, sig_r[0]); - ff_neg &= ~NEG_R; - sig_r = SigSpec(); - kill_srst = false; - continue; + legalize_sdff(ff); + } else { + legalize_dff(ff); + } + } else if (ff.has_aload) { + if (ff.has_sr) { + legalize_dlatchsr(ff); + } else if (ff.has_arst) { + legalize_adlatch(ff); + } else { + legalize_dlatch(ff); + } + } else { + if (ff.has_sr) { + legalize_sr(ff); + } else if (ff.has_arst) { + legalize_rlatch(ff); } else { log_assert(0); } } -cell_ok: + } + + void flip_pol(FfData &ff, SigSpec &sig, bool &pol) { + if (sig == State::S0) { + sig = State::S1; + } else if (sig == State::S1) { + sig = State::S0; + } else if (ff.is_fine) { + sig = ff.module->NotGate(NEW_ID, sig); + } else { + sig = ff.module->Not(NEW_ID, sig); + } + pol = !pol; + } + void legalize_finish(FfData &ff) { + int ff_type = get_ff_type(ff); + int initmask = get_initmask(ff); + log_assert(supported_cells[ff_type] & initmask); + int ff_neg = 0; + if (ff.has_sr) { + if (!ff.pol_clr) + ff_neg |= NEG_R; + if (!ff.pol_set) + ff_neg |= NEG_S; + } + if (ff.has_arst) { + if (!ff.pol_arst) + ff_neg |= NEG_R; + } + if (ff.has_srst) { + if (!ff.pol_srst) + ff_neg |= NEG_R; + } + if (ff.has_aload) { + if (!ff.pol_aload) + ff_neg |= NEG_L; + } + if (ff.has_clk) { + if (!ff.pol_clk) + ff_neg |= NEG_C; + } + if (ff.has_ce) { + if (!ff.pol_ce) + ff_neg |= NEG_CE; + } if (!(supported_cells_neg[ff_type][ff_neg] & initmask)) { // Cell is supported, but not with those polarities. // Will need to add some inverters. @@ -917,182 +998,27 @@ flip_dqisr:; if (supported_cells_neg[ff_type][ff_neg ^ xneg] & initmask) break; log_assert(xneg < NUM_NEG); - if (xneg & NEG_R) - sig_r = cell->module->NotGate(NEW_ID, sig_r[0]); - if (xneg & NEG_S) - sig_s = cell->module->NotGate(NEW_ID, sig_s[0]); - if (xneg & NEG_E) - sig_e = cell->module->NotGate(NEW_ID, sig_e[0]); + if (xneg & NEG_CE) + flip_pol(ff, ff.sig_ce, ff.pol_ce); + if (ff.has_sr) { + if (xneg & NEG_R) + flip_pol(ff, ff.sig_clr, ff.pol_clr); + if (xneg & NEG_S) + flip_pol(ff, ff.sig_set, ff.pol_set); + } + if (ff.has_arst && xneg & NEG_R) + flip_pol(ff, ff.sig_arst, ff.pol_arst); + if (ff.has_srst && xneg & NEG_R) + flip_pol(ff, ff.sig_srst, ff.pol_srst); + if (xneg & NEG_L) + flip_pol(ff, ff.sig_aload, ff.pol_aload); if (xneg & NEG_C) - sig_c = cell->module->NotGate(NEW_ID, sig_c[0]); + flip_pol(ff, ff.sig_clk, ff.pol_clk); ff_neg ^= xneg; } - cell->unsetPort(ID::D); - cell->unsetPort(ID::Q); - cell->unsetPort(ID::C); - cell->unsetPort(ID::E); - cell->unsetPort(ID::S); - cell->unsetPort(ID::R); - switch (ff_type) { - case FF_DFF: - cell->type = IdString(stringf("$_DFF_%c_", - (ff_neg & NEG_C) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - break; - case FF_DFFE: - cell->type = IdString(stringf("$_DFFE_%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::E, sig_e); - break; - case FF_ADFF0: - case FF_ADFF1: - cell->type = IdString(stringf("$_DFF_%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_ADFF1) ? '1' : '0' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::R, sig_r); - break; - case FF_ADFFE0: - case FF_ADFFE1: - cell->type = IdString(stringf("$_DFFE_%c%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_ADFFE1) ? '1' : '0', - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::R, sig_r); - break; - case FF_DFFSR: - cell->type = IdString(stringf("$_DFFSR_%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_S) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::S, sig_s); - cell->setPort(ID::R, sig_r); - break; - case FF_DFFSRE: - cell->type = IdString(stringf("$_DFFSRE_%c%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_S) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::S, sig_s); - cell->setPort(ID::R, sig_r); - break; - case FF_SDFF0: - case FF_SDFF1: - cell->type = IdString(stringf("$_SDFF_%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_SDFF1) ? '1' : '0' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::R, sig_r); - break; - case FF_SDFFE0: - case FF_SDFFE1: - cell->type = IdString(stringf("$_SDFFE_%c%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_SDFFE1) ? '1' : '0', - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::R, sig_r); - break; - case FF_SDFFCE0: - case FF_SDFFCE1: - cell->type = IdString(stringf("$_SDFFCE_%c%c%c%c_", - (ff_neg & NEG_C) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_SDFFCE1) ? '1' : '0', - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::C, sig_c); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::R, sig_r); - break; - case FF_DLATCH: - cell->type = IdString(stringf("$_DLATCH_%c_", - (ff_neg & NEG_E) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::E, sig_e); - break; - case FF_ADLATCH0: - case FF_ADLATCH1: - cell->type = IdString(stringf("$_DLATCH_%c%c%c_", - (ff_neg & NEG_E) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P', - (ff_type == FF_ADLATCH1) ? '1' : '0' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::R, sig_r); - break; - case FF_DLATCHSR: - cell->type = IdString(stringf("$_DLATCHSR_%c%c%c_", - (ff_neg & NEG_E) ? 'N' : 'P', - (ff_neg & NEG_S) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P' - )); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::E, sig_e); - cell->setPort(ID::S, sig_s); - cell->setPort(ID::R, sig_r); - break; - case FF_SR: - cell->type = IdString(stringf("$_SR_%c%c_", - (ff_neg & NEG_S) ? 'N' : 'P', - (ff_neg & NEG_R) ? 'N' : 'P' - )); - cell->setPort(ID::Q, sig_q); - cell->setPort(ID::S, sig_s); - cell->setPort(ID::R, sig_r); - break; - default: - log_assert(0); - } - return; - -error: - log_error("FF %s.%s (type %s) cannot be legalized: %s\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type), reason); + fixup_reset_x(ff, supported_cells_neg[ff_type][ff_neg]); + ff.emit(); } void execute(std::vector args, RTLIL::Design *design) override @@ -1114,79 +1040,83 @@ flip_dqisr:; if (args[argidx] == "-cell" && argidx + 2 < args.size()) { std::string celltype = args[++argidx]; std::string inittype = args[++argidx]; - enum FfType ff_type[2] = {NUM_FFTYPES, NUM_FFTYPES}; + enum FfType ff_type; char pol_c = 0; - char pol_e = 0; + char pol_l = 0; char pol_s = 0; char pol_r = 0; + char pol_ce = 0; char srval = 0; if (celltype.substr(0, 5) == "$_SR_" && celltype.size() == 8 && celltype[7] == '_') { - ff_type[0] = FF_SR; + ff_type = FF_SR; pol_s = celltype[5]; pol_r = celltype[6]; } else if (celltype.substr(0, 6) == "$_DFF_" && celltype.size() == 8 && celltype[7] == '_') { - ff_type[0] = FF_DFF; + ff_type = FF_DFF; pol_c = celltype[6]; } else if (celltype.substr(0, 7) == "$_DFFE_" && celltype.size() == 10 && celltype[9] == '_') { - ff_type[0] = FF_DFFE; + ff_type = FF_DFFE; pol_c = celltype[7]; - pol_e = celltype[8]; + pol_ce = celltype[8]; } else if (celltype.substr(0, 6) == "$_DFF_" && celltype.size() == 10 && celltype[9] == '_') { - ff_type[0] = FF_ADFF0; - ff_type[1] = FF_ADFF1; + ff_type = FF_ADFF; pol_c = celltype[6]; pol_r = celltype[7]; srval = celltype[8]; } else if (celltype.substr(0, 7) == "$_DFFE_" && celltype.size() == 12 && celltype[11] == '_') { - ff_type[0] = FF_ADFFE0; - ff_type[1] = FF_ADFFE1; + ff_type = FF_ADFFE; pol_c = celltype[7]; pol_r = celltype[8]; srval = celltype[9]; - pol_e = celltype[10]; + pol_ce = celltype[10]; + } else if (celltype.substr(0, 8) == "$_ALDFF_" && celltype.size() == 11 && celltype[10] == '_') { + ff_type = FF_ALDFF; + pol_c = celltype[8]; + pol_l = celltype[9]; + } else if (celltype.substr(0, 9) == "$_ALDFFE_" && celltype.size() == 13 && celltype[12] == '_') { + ff_type = FF_ALDFFE; + pol_c = celltype[9]; + pol_l = celltype[10]; + pol_ce = celltype[11]; } else if (celltype.substr(0, 8) == "$_DFFSR_" && celltype.size() == 12 && celltype[11] == '_') { - ff_type[0] = FF_DFFSR; + ff_type = FF_DFFSR; pol_c = celltype[8]; pol_s = celltype[9]; pol_r = celltype[10]; } else if (celltype.substr(0, 9) == "$_DFFSRE_" && celltype.size() == 14 && celltype[13] == '_') { - ff_type[0] = FF_DFFSRE; + ff_type = FF_DFFSRE; pol_c = celltype[9]; pol_s = celltype[10]; pol_r = celltype[11]; - pol_e = celltype[12]; + pol_ce = celltype[12]; } else if (celltype.substr(0, 7) == "$_SDFF_" && celltype.size() == 11 && celltype[10] == '_') { - ff_type[0] = FF_SDFF0; - ff_type[1] = FF_SDFF1; + ff_type = FF_SDFF; pol_c = celltype[7]; pol_r = celltype[8]; srval = celltype[9]; } else if (celltype.substr(0, 8) == "$_SDFFE_" && celltype.size() == 13 && celltype[12] == '_') { - ff_type[0] = FF_SDFFE0; - ff_type[1] = FF_SDFFE1; + ff_type = FF_SDFFE; pol_c = celltype[8]; pol_r = celltype[9]; srval = celltype[10]; - pol_e = celltype[11]; + pol_ce = celltype[11]; } else if (celltype.substr(0, 9) == "$_SDFFCE_" && celltype.size() == 14 && celltype[13] == '_') { - ff_type[0] = FF_SDFFCE0; - ff_type[1] = FF_SDFFCE1; + ff_type = FF_SDFFCE; pol_c = celltype[9]; pol_r = celltype[10]; srval = celltype[11]; - pol_e = celltype[12]; + pol_ce = celltype[12]; } else if (celltype.substr(0, 9) == "$_DLATCH_" && celltype.size() == 11 && celltype[10] == '_') { - ff_type[0] = FF_DLATCH; - pol_e = celltype[9]; + ff_type = FF_DLATCH; + pol_l = celltype[9]; } else if (celltype.substr(0, 9) == "$_DLATCH_" && celltype.size() == 13 && celltype[12] == '_') { - ff_type[0] = FF_ADLATCH0; - ff_type[1] = FF_ADLATCH1; - pol_e = celltype[9]; + ff_type = FF_ADLATCH; + pol_l = celltype[9]; pol_r = celltype[10]; srval = celltype[11]; } else if (celltype.substr(0, 11) == "$_DLATCHSR_" && celltype.size() == 15 && celltype[14] == '_') { - ff_type[0] = FF_DLATCHSR; - pol_e = celltype[11]; + ff_type = FF_DLATCHSR; + pol_l = celltype[11]; pol_s = celltype[12]; pol_r = celltype[13]; } else { @@ -1197,9 +1127,10 @@ flip_dqisr:; int match = 0; for (auto pair : { std::make_pair(pol_c, NEG_C), - std::make_pair(pol_e, NEG_E), + std::make_pair(pol_l, NEG_L), std::make_pair(pol_s, NEG_S), std::make_pair(pol_r, NEG_R), + std::make_pair(pol_ce, NEG_CE), }) { if (pair.first == 'N') { mask |= pair.second; @@ -1210,40 +1141,33 @@ flip_dqisr:; goto unrecognized; } } + int initmask; + if (inittype == "x") { + initmask = 0x111; + } else if (inittype == "0") { + initmask = 0x333; + } else if (inittype == "1") { + initmask = 0x555; + } else if (inittype == "r") { + if (srval == 0) + log_error("init type r not valid for cell type %s.\n", celltype.c_str()); + initmask = 0x537; + } else if (inittype == "01") { + initmask = 0x777; + } else { + log_error("unrecognized init type %s for cell type %s.\n", inittype.c_str(), celltype.c_str()); + } if (srval == '0') { - ff_type[1] = NUM_FFTYPES; + initmask &= 0x0ff; } else if (srval == '1') { - ff_type[0] = NUM_FFTYPES; + initmask &= 0xf0f; } else if (srval != 0 && srval != '?') { goto unrecognized; } - for (int i = 0; i < 2; i++) { - if (ff_type[i] == NUM_FFTYPES) - continue; - int initmask; - if (inittype == "x") { - initmask = INIT_X; - } else if (inittype == "0") { - initmask = INIT_X | INIT_0; - } else if (inittype == "1") { - initmask = INIT_X | INIT_1; - } else if (inittype == "r") { - if (srval == 0) - log_error("init type r not valid for cell type %s.\n", celltype.c_str()); - if (i == 0) - initmask = INIT_X | INIT_0; - else - initmask = INIT_X | INIT_1; - } else if (inittype == "01") { - initmask = INIT_X | INIT_0 | INIT_1; - } else { - log_error("unrecognized init type %s for cell type %s.\n", inittype.c_str(), celltype.c_str()); - } - for (int neg = 0; neg < NUM_NEG; neg++) - if ((neg & mask) == match) - supported_cells_neg[ff_type[i]][neg] |= initmask; - supported_cells[ff_type[i]] |= initmask; - } + for (int neg = 0; neg < NUM_NEG; neg++) + if ((neg & mask) == match) + supported_cells_neg[ff_type][neg] |= initmask; + supported_cells[ff_type] |= initmask; continue; } else if (args[argidx] == "-mince" && argidx + 1 < args.size()) { mince = atoi(args[++argidx].c_str()); @@ -1256,13 +1180,21 @@ flip_dqisr:; } extra_args(args, argidx, design); supported_dffsr = supported_cells[FF_DFFSR] | supported_cells[FF_DFFSRE]; - supported_adff0 = supported_cells[FF_ADFF0] | supported_cells[FF_ADFFE0] | supported_dffsr; - supported_adff1 = supported_cells[FF_ADFF1] | supported_cells[FF_ADFFE1] | supported_dffsr; - supported_sdff0 = supported_cells[FF_SDFF0] | supported_cells[FF_SDFFE0] | supported_cells[FF_SDFFCE0]; - supported_sdff1 = supported_cells[FF_SDFF1] | supported_cells[FF_SDFFE1] | supported_cells[FF_SDFFCE1]; - supported_dff = supported_cells[FF_DFF] | supported_cells[FF_DFFE] | supported_dffsr | supported_adff0 | supported_adff1 | supported_sdff0 | supported_sdff1; - supported_sr = supported_dffsr | supported_cells[FF_DLATCHSR] | supported_cells[FF_SR] | supported_cells[FF_ADLATCH0] | flip_initmask(supported_cells[FF_ADLATCH1]); - supported_dlatch = supported_cells[FF_DLATCH] | supported_cells[FF_ADLATCH0] | supported_cells[FF_ADLATCH1] | supported_cells[FF_DLATCHSR]; + supported_aldff = supported_cells[FF_ALDFF] | supported_cells[FF_ALDFFE] | supported_dffsr; + supported_aldffe = supported_cells[FF_ALDFFE] | supported_cells[FF_DFFSRE]; + supported_adff = supported_cells[FF_ADFF] | supported_cells[FF_ADFFE] | supported_dffsr | supported_aldff; + supported_adffe = supported_cells[FF_ADFFE] | supported_cells[FF_ALDFFE] | supported_cells[FF_DFFSRE]; + supported_sdff = supported_cells[FF_SDFF] | supported_cells[FF_SDFFE] | supported_cells[FF_SDFFCE]; + supported_dff = supported_cells[FF_DFF] | supported_cells[FF_DFFE] | supported_adff | supported_sdff; + supported_dffe = supported_cells[FF_DFFE] | supported_cells[FF_DFFSRE] | supported_cells[FF_ALDFFE] | supported_cells[FF_ADFFE] | supported_cells[FF_SDFFE] | supported_cells[FF_SDFFCE]; + supported_sr_plain = supported_dffsr | supported_cells[FF_DLATCHSR] | supported_cells[FF_SR]; + supported_sr = supported_sr_plain; + supported_sr |= (supported_cells[FF_ADLATCH] >> 4 & 7) * 0x111; + supported_sr |= (flip_initmask(supported_cells[FF_ADLATCH]) >> 4 & 7) * 0x111; + supported_dlatch_plain = supported_cells[FF_DLATCH] | supported_cells[FF_ADLATCH] | supported_cells[FF_DLATCHSR] | supported_cells[FF_ALDFF] | supported_cells[FF_ALDFFE]; + supported_dlatch = supported_dlatch_plain | supported_sr_plain; + supported_rlatch = supported_adff | (supported_dlatch & 7) * 0x111; + supported_adlatch = supported_cells[FF_ADLATCH] | supported_cells[FF_DLATCHSR]; for (auto module : design->selected_modules()) { @@ -1277,36 +1209,20 @@ flip_dqisr:; if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; - if (cell->hasPort(ID::C) && cell->hasPort(ID::E)) { - SigSpec sig = cell->getPort(ID::E); - // Do not count const enable signals. - if (GetSize(sig) == 1 && sig[0].wire) - ce_used[sig[0]]++; - } - if (cell->type.str().substr(0, 6) == "$_SDFF") { - SigSpec sig = cell->getPort(ID::R); - // Do not count const srst signals. - if (GetSize(sig) == 1 && sig[0].wire) - srst_used[sig[0]]++; - } + FfData ff(&initvals, cell); + if (ff.has_ce && ff.sig_ce[0].wire) + ce_used[ff.sig_ce[0]] += ff.width; + if (ff.has_srst && ff.sig_srst[0].wire) + srst_used[ff.sig_srst[0]] += ff.width; } } - - // First gather FF cells, then iterate over them later. - // We may need to split an FF into several cells. - std::vector ff_cells; - for (auto cell : module->selected_cells()) { - // Early exit for non-FFs. if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; - - ff_cells.push_back(cell); + FfData ff(&initvals, cell); + legalize_ff(ff); } - - for (auto cell: ff_cells) - handle_ff(cell); } sigmap.clear(); diff --git a/tests/techmap/dfflegalize_adff_init.ys b/tests/techmap/dfflegalize_adff_init.ys index 7764e15a5fb..27798ac5240 100644 --- a/tests/techmap/dfflegalize_adff_init.ys +++ b/tests/techmap/dfflegalize_adff_init.ys @@ -144,9 +144,9 @@ design -load orig dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_DLATCH_P_ 1 select -assert-count 2 adff0/t:$_NOT_ -select -assert-count 16 adff1/t:$_NOT_ +select -assert-count 13 adff1/t:$_NOT_ select -assert-count 3 adffe0/t:$_NOT_ -select -assert-count 22 adffe1/t:$_NOT_ +select -assert-count 18 adffe1/t:$_NOT_ select -assert-count 0 adff0/t:$_MUX_ select -assert-count 3 adff1/t:$_MUX_ select -assert-count 0 adffe0/t:$_MUX_ @@ -164,9 +164,9 @@ select -assert-none t:$_DFFE_PP0P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t design -load orig dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_DLATCH_P_ 1 -select -assert-count 16 adff0/t:$_NOT_ +select -assert-count 13 adff0/t:$_NOT_ select -assert-count 8 adff1/t:$_NOT_ -select -assert-count 22 adffe0/t:$_NOT_ +select -assert-count 18 adffe0/t:$_NOT_ select -assert-count 11 adffe1/t:$_NOT_ select -assert-count 3 adff0/t:$_MUX_ select -assert-count 0 adff1/t:$_MUX_ @@ -185,31 +185,27 @@ select -assert-none t:$_DFFE_PP0P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t design -load orig dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_DLATCH_P_ 1 -select -assert-count 16 adff0/t:$_NOT_ +select -assert-count 10 adff0/t:$_NOT_ select -assert-count 2 adff1/t:$_NOT_ -select -assert-count 22 adffe0/t:$_NOT_ +select -assert-count 14 adffe0/t:$_NOT_ select -assert-count 3 adffe1/t:$_NOT_ select -assert-count 3 adff0/t:$_MUX_ select -assert-count 0 adff1/t:$_MUX_ select -assert-count 4 adffe0/t:$_MUX_ select -assert-count 0 adffe1/t:$_MUX_ -select -assert-count 6 adff0/t:$_DFFE_PP1P_ +select -assert-count 9 adff0/t:$_DFFE_PP1P_ select -assert-count 3 adff1/t:$_DFFE_PP1P_ -select -assert-count 8 adffe0/t:$_DFFE_PP1P_ +select -assert-count 12 adffe0/t:$_DFFE_PP1P_ select -assert-count 4 adffe1/t:$_DFFE_PP1P_ -select -assert-count 3 adff0/t:$_DLATCH_P_ -select -assert-count 0 adff1/t:$_DLATCH_P_ -select -assert-count 4 adffe0/t:$_DLATCH_P_ -select -assert-count 0 adffe1/t:$_DLATCH_P_ -select -assert-none t:$_DFFE_PP1P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i +select -assert-none t:$_DFFE_PP1P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i design -load orig dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_DLATCH_P_ 1 select -assert-count 8 adff0/t:$_NOT_ -select -assert-count 16 adff1/t:$_NOT_ +select -assert-count 13 adff1/t:$_NOT_ select -assert-count 11 adffe0/t:$_NOT_ -select -assert-count 22 adffe1/t:$_NOT_ +select -assert-count 18 adffe1/t:$_NOT_ select -assert-count 0 adff0/t:$_MUX_ select -assert-count 3 adff1/t:$_MUX_ select -assert-count 0 adffe0/t:$_MUX_ diff --git a/tests/techmap/dfflegalize_adlatch_init.ys b/tests/techmap/dfflegalize_adlatch_init.ys index 7b22ea0c0b0..a55082d1d53 100644 --- a/tests/techmap/dfflegalize_adlatch_init.ys +++ b/tests/techmap/dfflegalize_adlatch_init.ys @@ -45,7 +45,7 @@ select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i design -load orig dfflegalize -cell $_DLATCH_PP0_ 1 -select -assert-count 16 adlatch0/t:$_NOT_ +select -assert-count 13 adlatch0/t:$_NOT_ select -assert-count 8 adlatch1/t:$_NOT_ select -assert-count 3 adlatch0/t:$_MUX_ select -assert-count 0 adlatch1/t:$_MUX_ @@ -68,7 +68,7 @@ design -load orig dfflegalize -cell $_DLATCH_PP1_ 1 select -assert-count 8 adlatch0/t:$_NOT_ -select -assert-count 16 adlatch1/t:$_NOT_ +select -assert-count 13 adlatch1/t:$_NOT_ select -assert-count 0 adlatch0/t:$_MUX_ select -assert-count 3 adlatch1/t:$_MUX_ select -assert-count 3 adlatch0/t:$_DLATCH_PP1_ diff --git a/tests/techmap/dfflegalize_dff.ys b/tests/techmap/dfflegalize_dff.ys index 63ab478652c..4022da5f450 100644 --- a/tests/techmap/dfflegalize_dff.ys +++ b/tests/techmap/dfflegalize_dff.ys @@ -237,25 +237,18 @@ select -assert-count 2 sdff0/t:$_NOT_ select -assert-count 8 sdff1/t:$_NOT_ select -assert-count 2 sdffe0/t:$_NOT_ select -assert-count 10 sdffe1/t:$_NOT_ -select -assert-count 2 sdffce0/t:$_NOT_ -select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ select -assert-count 0 dff/t:$_MUX_ select -assert-count 3 dffe/t:$_MUX_ select -assert-count 0 sdff0/t:$_MUX_ select -assert-count 0 sdff1/t:$_MUX_ select -assert-count 4 sdffe0/t:$_MUX_ select -assert-count 4 sdffe1/t:$_MUX_ -select -assert-count 4 sdffce0/t:$_MUX_ -select -assert-count 4 sdffce1/t:$_MUX_ -select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* sdffce1/* %u %n %i -select -assert-count 2 sdffce0/t:$_AND_ -select -assert-count 2 sdffce1/t:$_AND_ -select -assert-count 1 sdffce0/t:$_ORNOT_ -select -assert-count 1 sdffce1/t:$_ORNOT_ -select -assert-count 1 sdffce0/t:$_ANDNOT_ -select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ select -assert-count 27 t:$_SDFF_PP0_ -select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i # Convert everything to SDFFEs. diff --git a/tests/techmap/dfflegalize_dff_init.ys b/tests/techmap/dfflegalize_dff_init.ys index 741ac39d0c8..ccde4c32410 100644 --- a/tests/techmap/dfflegalize_dff_init.ys +++ b/tests/techmap/dfflegalize_dff_init.ys @@ -476,7 +476,7 @@ select -assert-count 2 sdff0/t:$_NOT_ select -assert-count 1 sdff1/t:$_NOT_ select -assert-count 2 sdffe0/t:$_NOT_ select -assert-count 1 sdffe1/t:$_NOT_ -select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ select -assert-count 1 sdffce1/t:$_NOT_ select -assert-count 0 dff/t:$_MUX_ select -assert-count 3 dffe/t:$_MUX_ @@ -484,14 +484,10 @@ select -assert-count 0 sdff0/t:$_MUX_ select -assert-count 3 sdff1/t:$_MUX_ select -assert-count 4 sdffe0/t:$_MUX_ select -assert-count 8 sdffe1/t:$_MUX_ -select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ select -assert-count 8 sdffce1/t:$_MUX_ -select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i -select -assert-count 2 sdffce0/t:$_AND_ -select -assert-count 1 sdffce0/t:$_ORNOT_ -select -assert-count 1 sdffce0/t:$_ANDNOT_ select -assert-count 27 t:$_SDFF_PP0_ -select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i design -load orig dfflegalize -cell $_SDFF_PP0_ 1 @@ -503,7 +499,7 @@ select -assert-count 8 sdff1/t:$_NOT_ select -assert-count 9 sdffe0/t:$_NOT_ select -assert-count 10 sdffe1/t:$_NOT_ select -assert-count 9 sdffce0/t:$_NOT_ -select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ select -assert-count 0 dff/t:$_MUX_ select -assert-count 3 dffe/t:$_MUX_ select -assert-count 3 sdff0/t:$_MUX_ @@ -511,13 +507,9 @@ select -assert-count 0 sdff1/t:$_MUX_ select -assert-count 8 sdffe0/t:$_MUX_ select -assert-count 4 sdffe1/t:$_MUX_ select -assert-count 8 sdffce0/t:$_MUX_ -select -assert-count 4 sdffce1/t:$_MUX_ -select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i -select -assert-count 2 sdffce1/t:$_AND_ -select -assert-count 1 sdffce1/t:$_ORNOT_ -select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 8 sdffce1/t:$_MUX_ select -assert-count 27 t:$_SDFF_PP0_ -select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i design -load orig dfflegalize -cell $_SDFF_PP1_ 0 @@ -529,7 +521,7 @@ select -assert-count 2 sdff1/t:$_NOT_ select -assert-count 1 sdffe0/t:$_NOT_ select -assert-count 2 sdffe1/t:$_NOT_ select -assert-count 1 sdffce0/t:$_NOT_ -select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ select -assert-count 0 dff/t:$_MUX_ select -assert-count 3 dffe/t:$_MUX_ select -assert-count 3 sdff0/t:$_MUX_ @@ -537,13 +529,9 @@ select -assert-count 0 sdff1/t:$_MUX_ select -assert-count 8 sdffe0/t:$_MUX_ select -assert-count 4 sdffe1/t:$_MUX_ select -assert-count 8 sdffce0/t:$_MUX_ -select -assert-count 4 sdffce1/t:$_MUX_ -select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i -select -assert-count 2 sdffce1/t:$_AND_ -select -assert-count 1 sdffce1/t:$_ORNOT_ -select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 8 sdffce1/t:$_MUX_ select -assert-count 27 t:$_SDFF_PP1_ -select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i +select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i design -load orig dfflegalize -cell $_SDFF_PP1_ 1 @@ -554,7 +542,7 @@ select -assert-count 8 sdff0/t:$_NOT_ select -assert-count 7 sdff1/t:$_NOT_ select -assert-count 10 sdffe0/t:$_NOT_ select -assert-count 9 sdffe1/t:$_NOT_ -select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ select -assert-count 9 sdffce1/t:$_NOT_ select -assert-count 0 dff/t:$_MUX_ select -assert-count 3 dffe/t:$_MUX_ @@ -562,14 +550,10 @@ select -assert-count 0 sdff0/t:$_MUX_ select -assert-count 3 sdff1/t:$_MUX_ select -assert-count 4 sdffe0/t:$_MUX_ select -assert-count 8 sdffe1/t:$_MUX_ -select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ select -assert-count 8 sdffce1/t:$_MUX_ -select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i -select -assert-count 2 sdffce0/t:$_AND_ -select -assert-count 1 sdffce0/t:$_ORNOT_ -select -assert-count 1 sdffce0/t:$_ANDNOT_ select -assert-count 27 t:$_SDFF_PP1_ -select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i +select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i # Convert everything to SDFFEs. diff --git a/tests/techmap/dfflegalize_dlatch_const.ys b/tests/techmap/dfflegalize_dlatch_const.ys index f30a534fde3..1596922490a 100644 --- a/tests/techmap/dfflegalize_dlatch_const.ys +++ b/tests/techmap/dfflegalize_dlatch_const.ys @@ -24,14 +24,14 @@ equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 design -load orig dfflegalize -cell $_DFF_PP0_ 01 -select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_NOT_ select -assert-count 8 t:$_DFF_PP0_ select -assert-none t:$_DFF_PP0_ t:$_NOT_ %% %n t:* %i design -load orig dfflegalize -cell $_DFF_PP?_ 0 -select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_NOT_ select -assert-count 4 t:$_DFF_PP0_ select -assert-count 4 t:$_DFF_PP1_ select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_NOT_ %% %n t:* %i @@ -41,13 +41,13 @@ select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_NOT_ %% %n t:* %i design -load orig dfflegalize -cell $_DFFSRE_PPPP_ 0 -select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_NOT_ select -assert-count 8 t:$_DFFSRE_PPPP_ select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i design -load orig dfflegalize -cell $_DFFSRE_PPPP_ 1 -select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_NOT_ select -assert-count 8 t:$_DFFSRE_PPPP_ select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatchsr_init.ys b/tests/techmap/dfflegalize_dlatchsr_init.ys index 2d33634d172..b38a9eb3b8e 100644 --- a/tests/techmap/dfflegalize_dlatchsr_init.ys +++ b/tests/techmap/dfflegalize_dlatchsr_init.ys @@ -66,8 +66,8 @@ select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_O design -load orig dfflegalize -cell $_DLATCH_PP1_ 0 -select -assert-count 22 dlatchsr0/t:$_NOT_ -select -assert-count 26 dlatchsr1/t:$_NOT_ +select -assert-count 18 dlatchsr0/t:$_NOT_ +select -assert-count 22 dlatchsr1/t:$_NOT_ select -assert-count 4 dlatchsr0/t:$_MUX_ select -assert-count 4 dlatchsr1/t:$_MUX_ select -assert-count 12 dlatchsr0/t:$_DLATCH_PP1_ @@ -81,8 +81,8 @@ select -assert-none t:$_DLATCH_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_O design -load orig dfflegalize -cell $_DLATCH_PP1_ 1 -select -assert-count 22 dlatchsr0/t:$_NOT_ -select -assert-count 26 dlatchsr1/t:$_NOT_ +select -assert-count 18 dlatchsr0/t:$_NOT_ +select -assert-count 22 dlatchsr1/t:$_NOT_ select -assert-count 4 dlatchsr0/t:$_MUX_ select -assert-count 4 dlatchsr1/t:$_MUX_ select -assert-count 12 dlatchsr0/t:$_DLATCH_PP1_ diff --git a/tests/techmap/dfflegalize_minsrst.ys b/tests/techmap/dfflegalize_minsrst.ys index 0fc40dc0893..689066147d5 100644 --- a/tests/techmap/dfflegalize_minsrst.ys +++ b/tests/techmap/dfflegalize_minsrst.ys @@ -23,9 +23,9 @@ design -load postopt select -assert-count 5 t:$_SDFF_PP0_ select -assert-count 1 t:$_SDFF_PP1_ -select -assert-count 3 t:$_SDFFE_PP0P_ +select -assert-count 1 t:$_SDFFE_PP0P_ select -assert-count 1 t:$_SDFFE_PP1P_ -select -assert-count 1 t:$_SDFFCE_PP0P_ +select -assert-count 3 t:$_SDFFCE_PP0P_ select -assert-count 1 t:$_SDFFCE_PP1P_ select -assert-count 8 t:$_MUX_ select -assert-count 0 n:ff0 %ci %ci t:$_MUX_ %i diff --git a/tests/techmap/dfflegalize_sr.ys b/tests/techmap/dfflegalize_sr.ys index 27e83be9196..ee59a6e3cf7 100644 --- a/tests/techmap/dfflegalize_sr.ys +++ b/tests/techmap/dfflegalize_sr.ys @@ -39,7 +39,7 @@ select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ %% %n t:* %i design -load orig dfflegalize -cell $_DLATCH_PP1_ x -select -assert-count 8 t:$_NOT_ +select -assert-count 5 t:$_NOT_ select -assert-count 3 t:$_DLATCH_PP1_ select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_sr_init.ys b/tests/techmap/dfflegalize_sr_init.ys index 52b797b9ecd..9d724de2987 100644 --- a/tests/techmap/dfflegalize_sr_init.ys +++ b/tests/techmap/dfflegalize_sr_init.ys @@ -12,7 +12,7 @@ $_SR_PN_ ff1 (.R(R), .S(S), .Q(Q[1])); $_SR_NP_ ff2 (.R(R), .S(S), .Q(Q[2])); endmodule -module top(input C, E, R, D, output [5:0] Q); +module top(input R, S, output [5:0] Q); sr0 sr0_(.S(S), .R(R), .Q(Q[2:0])); sr1 sr1_(.S(S), .R(R), .Q(Q[5:3])); endmodule @@ -103,8 +103,8 @@ select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* design -load orig dfflegalize -cell $_DLATCH_PP1_ 0 -select -assert-count 11 sr0/t:$_NOT_ -select -assert-count 8 sr1/t:$_NOT_ +select -assert-count 8 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ select -assert-count 3 sr0/t:$_DLATCH_PP1_ select -assert-count 3 sr1/t:$_DLATCH_PP1_ select -assert-count 1 sr0/t:$_ANDNOT_ @@ -118,8 +118,8 @@ select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* design -load orig dfflegalize -cell $_DLATCH_PP1_ 1 -select -assert-count 8 sr0/t:$_NOT_ -select -assert-count 11 sr1/t:$_NOT_ +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 8 sr1/t:$_NOT_ select -assert-count 3 sr0/t:$_DLATCH_PP1_ select -assert-count 3 sr1/t:$_DLATCH_PP1_ select -assert-count 0 sr0/t:$_ANDNOT_ From 54c79af64f8c84b8a9d8c1be2be5a6862910c2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 27 Oct 2021 13:14:34 +0200 Subject: [PATCH 0581/2410] dfflegalize: Add tests targetting aldff. --- tests/techmap/dfflegalize_adff.ys | 32 ++++++++ tests/techmap/dfflegalize_adff_init.ys | 58 ++++++++++++++ tests/techmap/dfflegalize_dff.ys | 52 +++++++++++++ tests/techmap/dfflegalize_dff_init.ys | 98 ++++++++++++++++++++++++ tests/techmap/dfflegalize_dlatch.ys | 22 ++++++ tests/techmap/dfflegalize_dlatch_init.ys | 38 +++++++++ tests/techmap/dfflegalize_inv.ys | 27 +++++-- 7 files changed, 320 insertions(+), 7 deletions(-) diff --git a/tests/techmap/dfflegalize_adff.ys b/tests/techmap/dfflegalize_adff.ys index 135ae0ab781..fc579e7d625 100644 --- a/tests/techmap/dfflegalize_adff.ys +++ b/tests/techmap/dfflegalize_adff.ys @@ -39,6 +39,8 @@ design -save orig flatten equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x @@ -73,6 +75,36 @@ select -assert-count 14 t:$_DFFE_PP0P_ select -assert-none t:$_DFFE_PP0P_ t:$_NOT_ top/* %% %n t:* %i +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 2 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 3 adffe1/t:$_NOT_ +select -assert-count 14 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ top/* %% %n t:* %i + + # Convert everything to DFFSRs. design -load orig diff --git a/tests/techmap/dfflegalize_adff_init.ys b/tests/techmap/dfflegalize_adff_init.ys index 27798ac5240..25ed5930762 100644 --- a/tests/techmap/dfflegalize_adff_init.ys +++ b/tests/techmap/dfflegalize_adff_init.ys @@ -45,6 +45,10 @@ equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_DLATCH_P_ equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_DLATCH_P_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_DLATCH_P_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 @@ -221,6 +225,60 @@ select -assert-count 4 adffe1/t:$_DLATCH_P_ select -assert-none t:$_DFFE_PP1P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 0 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 2 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 1 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 10 adffe0/t:$_NOT_ +select -assert-count 10 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 0 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 3 adffe1/t:$_NOT_ +select -assert-count 14 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 1 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 11 adffe0/t:$_NOT_ +select -assert-count 11 adffe1/t:$_NOT_ +select -assert-count 14 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ top/* %% %n t:* %i + + # Convert everything to DFFSRs. design -load orig diff --git a/tests/techmap/dfflegalize_dff.ys b/tests/techmap/dfflegalize_dff.ys index 4022da5f450..374289678ca 100644 --- a/tests/techmap/dfflegalize_dff.ys +++ b/tests/techmap/dfflegalize_dff.ys @@ -70,6 +70,8 @@ equiv_opt -assert -multiclock dfflegalize -cell $_DFF_P_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP0_ x @@ -176,6 +178,56 @@ select -assert-count 27 t:$_DFFE_PP0P_ select -assert-none t:$_DFFE_PP0P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + # Convert everything to DFFSRs. design -load orig diff --git a/tests/techmap/dfflegalize_dff_init.ys b/tests/techmap/dfflegalize_dff_init.ys index ccde4c32410..a170249c713 100644 --- a/tests/techmap/dfflegalize_dff_init.ys +++ b/tests/techmap/dfflegalize_dff_init.ys @@ -78,6 +78,10 @@ equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 @@ -371,6 +375,100 @@ select -assert-count 27 t:$_DFFE_PP1P_ select -assert-none t:$_DFFE_PP1P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + # Convert everything to DFFSRs. design -load orig diff --git a/tests/techmap/dfflegalize_dlatch.ys b/tests/techmap/dfflegalize_dlatch.ys index b68ea741ea0..11683bc1ad4 100644 --- a/tests/techmap/dfflegalize_dlatch.ys +++ b/tests/techmap/dfflegalize_dlatch.ys @@ -11,6 +11,8 @@ design -save orig equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_P_ x equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ x equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ x # Convert everything to DFFs. @@ -40,3 +42,23 @@ dfflegalize -cell $_DLATCHSR_PPP_ x select -assert-count 1 t:$_NOT_ select -assert-count 2 t:$_DLATCHSR_PPP_ select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ x + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ x + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatch_init.ys b/tests/techmap/dfflegalize_dlatch_init.ys index ccc9e41d750..9324c66913e 100644 --- a/tests/techmap/dfflegalize_dlatch_init.ys +++ b/tests/techmap/dfflegalize_dlatch_init.ys @@ -16,6 +16,10 @@ equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 1 equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 0 equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFF_PP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_ALDFFE_PPP_ 1 # Convert everything to DFFs. @@ -80,3 +84,37 @@ dfflegalize -cell $_DLATCHSR_PPP_ 1 select -assert-count 5 t:$_NOT_ select -assert-count 2 t:$_DLATCHSR_PPP_ select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ALDFFs. + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFF_PP_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_ALDFF_PP_ +select -assert-none t:$_ALDFF_PP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ALDFFEs. + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_ALDFFE_PPP_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_ALDFFE_PPP_ +select -assert-none t:$_ALDFFE_PPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_inv.ys b/tests/techmap/dfflegalize_inv.ys index cb42e01a800..a74d7416138 100644 --- a/tests/techmap/dfflegalize_inv.ys +++ b/tests/techmap/dfflegalize_inv.ys @@ -2,7 +2,7 @@ read_verilog -icells < Date: Wed, 27 Oct 2021 13:37:26 +0200 Subject: [PATCH 0582/2410] dfflegalize: Add tests for aldff lowering. --- tests/techmap/dfflegalize_aldff.ys | 92 +++++++++++++++ tests/techmap/dfflegalize_aldff_init.ys | 148 ++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 tests/techmap/dfflegalize_aldff.ys create mode 100644 tests/techmap/dfflegalize_aldff_init.ys diff --git a/tests/techmap/dfflegalize_aldff.ys b/tests/techmap/dfflegalize_aldff.ys new file mode 100644 index 00000000000..1ee9e3af61a --- /dev/null +++ b/tests/techmap/dfflegalize_aldff.ys @@ -0,0 +1,92 @@ +read_verilog -icells < Date: Sat, 2 Oct 2021 02:34:13 +0200 Subject: [PATCH 0583/2410] proc_dff: Emit $aldff. --- passes/proc/proc_dff.cc | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index da2a14c82f8..234671df5e9 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -143,48 +143,23 @@ void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); } -void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_out, +void gen_aldff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_out, bool clk_polarity, bool set_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec set, RTLIL::Process *proc) { std::stringstream sstr; sstr << "$procdff$" << (autoidx++); - RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size()); - RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); - RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size()); - - RTLIL::Cell *inv_set = mod->addCell(NEW_ID, ID($not)); - inv_set->parameters[ID::A_SIGNED] = RTLIL::Const(0); - inv_set->parameters[ID::A_WIDTH] = RTLIL::Const(sig_in.size()); - inv_set->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_in.size()); - inv_set->setPort(ID::A, sig_set); - inv_set->setPort(ID::Y, sig_set_inv); - - RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, ID($mux)); - mux_sr_set->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size()); - mux_sr_set->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size())); - mux_sr_set->setPort(set_polarity ? ID::B : ID::A, sig_set); - mux_sr_set->setPort(ID::Y, sig_sr_set); - mux_sr_set->setPort(ID::S, set); - - RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, ID($mux)); - mux_sr_clr->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size()); - mux_sr_clr->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size())); - mux_sr_clr->setPort(set_polarity ? ID::B : ID::A, sig_set_inv); - mux_sr_clr->setPort(ID::Y, sig_sr_clr); - mux_sr_clr->setPort(ID::S, set); - - RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr)); + RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($aldff)); cell->attributes = proc->attributes; + cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size()); + cell->parameters[ID::ALOAD_POLARITY] = RTLIL::Const(set_polarity, 1); cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1); - cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1); - cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1); cell->setPort(ID::D, sig_in); cell->setPort(ID::Q, sig_out); + cell->setPort(ID::AD, sig_set); cell->setPort(ID::CLK, clk); - cell->setPort(ID::SET, sig_sr_set); - cell->setPort(ID::CLR, sig_sr_clr); + cell->setPort(ID::ALOAD, set); log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative"); @@ -355,7 +330,7 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) else if (!rstval.is_fully_const() && !ce.eval(rstval)) { log_warning("Async reset value `%s' is not constant!\n", log_signal(rstval)); - gen_dffsr(mod, insig, rstval, sig_q, + gen_aldff(mod, insig, rstval, sig_q, sync_edge->type == RTLIL::SyncType::STp, sync_level && sync_level->type == RTLIL::SyncType::ST1, sync_edge->signal, sync_level->signal, proc); From 32673edfeae7878a902883575d6b369a5ed8b0a5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 27 Oct 2021 15:55:43 +0200 Subject: [PATCH 0584/2410] Revert "Compile option for enabling async load verific support" This reverts commit b8624ad2aef941776f5b4a08f66f8d43e70f8467. --- Makefile | 4 ---- frontends/verific/verific.cc | 5 +---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Makefile b/Makefile index c919c9563bd..f72106750db 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,6 @@ ENABLE_GHDL := 0 ENABLE_VERIFIC := 0 DISABLE_VERIFIC_EXTENSIONS := 0 DISABLE_VERIFIC_VHDL := 0 -ENABLE_VERIFIC_ASYNC_LOAD := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 ENABLE_PROTOBUF := 0 @@ -502,9 +501,6 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib VERIFIC_COMPONENTS ?= verilog database util containers hier_tree -ifeq ($(ENABLE_VERIFIC_ASYNC_LOAD),1) -CXXFLAGS += -DVERIFIC_ASYNC_LOAD -endif ifneq ($(DISABLE_VERIFIC_VHDL),1) VERIFIC_COMPONENTS += vhdl CXXFLAGS += -DVERIFIC_VHDL_SUPPORT diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 47ddbc66205..18fba9b76ac 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2474,11 +2474,8 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_preserve_user_nets", 1); RuntimeFlags::SetVar("db_allow_external_nets", 1); RuntimeFlags::SetVar("db_infer_wide_operators", 1); -#ifdef VERIFIC_ASYNC_LOAD - RuntimeFlags::SetVar("db_infer_set_reset_registers", 0); -#else RuntimeFlags::SetVar("db_infer_set_reset_registers", 1); -#endif + RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); From f7cc388bb57b66a97ece786697de6c992072a438 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 27 Oct 2021 15:56:56 +0200 Subject: [PATCH 0585/2410] Enable async load dff emit by default in Verific --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 18fba9b76ac..2d0574cf978 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2474,7 +2474,7 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_preserve_user_nets", 1); RuntimeFlags::SetVar("db_allow_external_nets", 1); RuntimeFlags::SetVar("db_infer_wide_operators", 1); - RuntimeFlags::SetVar("db_infer_set_reset_registers", 1); + RuntimeFlags::SetVar("db_infer_set_reset_registers", 0); RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); From e14302a3ea2781dca2dfa3933be18c8e26654dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 27 Oct 2021 14:04:21 +0200 Subject: [PATCH 0586/2410] ecp5: Add support for mapping aldff. --- techlibs/ecp5/cells_map.v | 13 ++++++------- techlibs/ecp5/synth_ecp5.cc | 13 +++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index dc83d96dc00..4944ece4569 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -88,14 +88,13 @@ module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -`ifdef ASYNC_PRLD -module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule -module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule +module \$_ALDFF_NP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFF_PP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule -module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule - -module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule -`endif +module \$_ALDFFE_NPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_NPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule `include "cells_ff.vh" `include "cells_io.vh" diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index dc67fc71b52..eb8ba8b9d11 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -88,7 +88,7 @@ struct SynthEcp5Pass : public ScriptPass log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); log("\n"); log(" -asyncprld\n"); - log(" use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)\n"); + log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); log("\n"); log(" -abc2\n"); log(" run two passes of 'abc' for slightly improved logic density\n"); @@ -318,16 +318,17 @@ struct SynthEcp5Pass : public ScriptPass } else if (!nodffe) { dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r"; } - dfflegalize_args += " -cell $_DLATCH_?_ x"; if (help_mode) { - dfflegalize_args += " [-cell $_DFFSR_?PP_ x]"; + dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]"; } else if (asyncprld) { - dfflegalize_args += " -cell $_DFFSR_?PP_ x"; + dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x"; + } else { + dfflegalize_args += " -cell $_DLATCH_?_ x"; } - run("dfflegalize" + dfflegalize_args, "($_DFFSR_*_ only if -asyncprld, $_*DFFE_* only if not -nodffe)"); + run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)"); if ((abc9 && dff) || help_mode) run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)"); - run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); + run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); run("ecp5_gsr"); From 5f00bf2d7d2da1933fe7a8861a904aa5c77a7580 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Oct 2021 00:52:35 +0000 Subject: [PATCH 0587/2410] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f72106750db..c485d7f2177 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.10+51 +YOSYS_VER := 0.10+60 GIT_REV := $(shell git -C $(YOSYS_SRC) rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 55f07fe56f3bba9fea6b2ba3a446c5a199014136 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 29 Oct 2021 13:10:50 +0200 Subject: [PATCH 0588/2410] Update command reference part of manual --- manual/command-reference-manual.tex | 1838 +++++++++++++++++++++------ 1 file changed, 1471 insertions(+), 367 deletions(-) diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index 960078cc770..b3ab02b9741 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -60,7 +60,7 @@ \section{abc -- use ABC for technology mapping} strash; dretime; if for -sop: - strash; dretime; cover -I {I} -P {P} + strash; dretime; cover {I} {P} otherwise: strash; dretime; map @@ -241,8 +241,8 @@ \section{abc9 -- use ABC9 for technology mapping} specified). -dff - also pass $_ABC9_FF_ cells through to ABC. modules with many clock - domains are marked as such and automatically partitioned by ABC. + also pass $_DFF_[NP]_ cells through to ABC. modules with many clock + domains are supported and automatically partitioned by ABC. -nocleanup when this option is used, the temporary files created by this pass @@ -265,28 +265,64 @@ \section{abc9 -- use ABC9 for technology mapping} [1] http://www.eecs.berkeley.edu/~alanmi/abc/ + check: + abc9_ops -check [-dff] (option if -dff) + + map: + abc9_ops -prep_hier [-dff] (option if -dff) + scc -specify -set_attr abc9_scc_id {} + abc9_ops -prep_bypass [-prep_dff] (option if -dff) + design -stash $abc9 + design -load $abc9_map + proc + wbflip + techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop + opt -nodffe -nosdff + abc9_ops -prep_dff_submod (only if -dff) + setattr -set submod "$abc9_flop" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d (only if -dff) + submod (only if -dff) + setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop (only if -dff) + foreach module in design + rename _$abc9_flop _TECHMAP_REPLACE_ (only if -dff) + abc9_ops -prep_dff_unmap (only if -dff) + design -copy-to $abc9 =*_$abc9_flop (only if -dff) + delete =*_$abc9_flop (only if -dff) + design -stash $abc9_map + design -load $abc9 + design -delete $abc9 + techmap -wb -max_iter 1 -map %$abc9_map -map +/abc9_map.v [-D DFF] (option if -dff) + design -delete $abc9_map + pre: - abc9_ops -check - scc -set_attr abc9_scc_id {} - abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff] (option for -dff) + read_verilog -icells -lib -specify +/abc9_model.v + abc9_ops -break_scc -prep_delays -prep_xaiger [-dff] (option for -dff) abc9_ops -prep_lut (skip if -lut or -luts) - abc9_ops -prep_box [-dff] (skip if -box) - select -set abc9_holes A:abc9_holes - flatten -wb @abc9_holes - techmap @abc9_holes - abc9_ops -prep_dff (only if -dff) - opt -purge @abc9_holes + abc9_ops -prep_box (skip if -box) + design -stash $abc9 + design -load $abc9_holes + techmap -wb -map %$abc9 -map +/techmap.v + opt -purge aigmap - wbflip @abc9_holes + design -stash $abc9_holes + design -load $abc9 + design -delete $abc9 - map: + exe: + aigmap foreach module in selection abc9_ops -write_lut /input.lut (skip if '-lut' or '-luts') - abc9_ops -write_box /input.box - write_xaiger -map /input.sym /input.xaig - abc9_exe [options] -cwd [-lut /input.lut] -box /input.box + abc9_ops -write_box /input.box (skip if '-box') + write_xaiger -map /input.sym [-dff] /input.xaig + abc9_exe [options] -cwd -lut [/input.lut] -box [/input.box] read_aiger -xaiger -wideports -module_name $abc9 -map /input.sym /output.aig - abc9_ops -reintegrate + abc9_ops -reintegrate [-dff] + + unmap: + techmap -wb -map %$abc9_unmap -map +/abc9_unmap.v + design -delete $abc9_unmap + design -delete $abc9_holes + delete =*_$abc9_byp + setattr -mod -unset abc9_box_id \end{lstlisting} \section{abc9\_exe -- use ABC9 for technology mapping} @@ -375,30 +411,56 @@ \section{abc9\_ops -- helper functions for ABC9} check that the design is valid, e.g. (* abc9_box_id *) values are unique, (* abc9_carry *) is only given for one input/output port, etc. + -prep_hier + derive all used (* abc9_box *) or (* abc9_flop *) (if -dff option) + whitebox modules. with (* abc9_flop *) modules, only those containing + $dff/$_DFF_[NP]_ cells with zero initial state -- due to an ABC limitation + -- will be derived. + + -prep_bypass + create techmap rules in the '$abc9_map' and '$abc9_unmap' designs for + bypassing sequential (* abc9_box *) modules using a combinatorial box + (named *_$abc9_byp). bypassing is necessary if sequential elements (e.g. + $dff, $mem, etc.) are discovered inside so that any combinatorial paths + will be correctly captured. this bypass box will only contain ports that + are referenced by a simple path declaration ($specify2 cell) inside a + specify block. + + -prep_dff + select all (* abc9_flop *) modules instantiated in the design and store + in the named selection '$abc9_flops'. + + -prep_dff_submod + within (* abc9_flop *) modules, rewrite all edge-sensitive path + declarations and $setup() timing checks ($specify3 and $specrule cells) + that share a 'DST' port with the $_DFF_[NP]_.Q port from this 'Q' port to + the DFF's 'D' port. this is to prepare such specify cells to be moved + into the flop box. + + -prep_dff_unmap + populate the '$abc9_unmap' design with techmap rules for mapping *_$abc9_flop + cells back into their derived cell types (where the rules created by + -prep_hier will then map back to the original cell with parameters). + -prep_delays insert `$__ABC9_DELAY' blackbox cells into the design to account for certain required times. - -mark_scc + -break_scc for an arbitrarily chosen cell in each unique SCC of each selected module - (tagged with an (* abc9_scc_id = *) attribute), temporarily mark all - wires driven by this cell's outputs with a (* keep *) attribute in order - to break the SCC. this temporary attribute will be removed on -reintegrate. + (tagged with an (* abc9_scc_id = *) attribute) interrupt all wires + driven by this cell's outputs with a temporary $__ABC9_SCC_BREAKER cell + to break the SCC. -prep_xaiger prepare the design for XAIGER output. this includes computing the - topological ordering of ABC9 boxes, as well as preparing the - '$holes' module that contains the logic behaviour of ABC9 - whiteboxes. + topological ordering of ABC9 boxes, as well as preparing the '$abc9_holes' + design that contains the logic behaviour of ABC9 whiteboxes. -dff consider flop cells (those instantiating modules marked with (* abc9_flop *)) during -prep_{delays,xaiger,box}. - -prep_dff - compute the clock domain and initial value of each flop in the design. - process the '$holes' module to support clock-enable functionality. - -prep_lut pre-compute the lut library by analysing all modules marked with (* abc9_lut= *). @@ -522,8 +584,6 @@ \section{async2sync -- convert async FF inputs to sync circuits} a reset deasserts with the clock edge, then the FF output will still drive the reset value in the next cycle regardless of the data-in value at the time of the clock edge. - -Currently only $adff, $dffsr, and $dlatch cells are supported by this pass. \end{lstlisting} \section{attrmap -- renaming attributes} @@ -609,24 +669,24 @@ \section{blackbox -- convert modules into blackbox modules} \section{bugpoint -- minimize testcases} \label{cmd:bugpoint} \begin{lstlisting}[numbers=left,frame=single] - bugpoint [options] + bugpoint [options] [-script | -command ""] -This command minimizes testcases that crash Yosys. It removes an arbitrary part -of the design and recursively invokes Yosys with a given script, repeating these -steps while it can find a smaller design that still causes a crash. Once this -command finishes, it replaces the current design with the smallest testcase it -was able to produce. +This command minimizes the current design that is known to crash Yosys with the +given script into a smaller testcase. It does this by removing an arbitrary part +of the design and recursively invokes a new Yosys process with this modified design +and the same script, repeating these steps while it can find a smaller design that +still causes a crash. Once this command finishes, it replaces the current design +with the smallest testcase it was able to produce. +In order to save the reduced testcase you must write this out to a file with +another command after `bugpoint` like `write_rtlil` or `write_verilog`. -It is possible to specify the kinds of design part that will be removed. If none -are specified, all parts of design will be removed. + -script | -command "" + use this script file or command to crash Yosys. required. -yosys use this Yosys binary. if not specified, `yosys` is used. - -script - use this script to crash Yosys. required. - - -grep + -grep "" only consider crashes that place this string in the log file. -fast @@ -639,18 +699,29 @@ \section{bugpoint -- minimize testcases} finishing. produces smaller and more useful testcases, but may fail to produce any testcase at all if the crash is related to dangling wires. +It is possible to constrain which parts of the design will be considered for +removal. Unless one or more of the following options are specified, all parts +will be considered. + -modules - try to remove modules. + try to remove modules. modules with a (* bugpoint_keep *) attribute + will be skipped. -ports - try to remove module ports. + try to remove module ports. ports with a (* bugpoint_keep *) attribute + will be skipped (useful for clocks, resets, etc.) -cells - try to remove cells. + try to remove cells. cells with a (* bugpoint_keep *) attribute will + be skipped. -connections try to reconnect ports to 'x. + -processes + try to remove processes. processes with a (* bugpoint_keep *) attribute + will be skipped. + -assigns try to remove process assigns from cases. @@ -693,30 +764,28 @@ \section{check -- check for obvious problems in the design} This pass identifies the following problems in the current design: - - combinatorial loops - - - two or more conflicting drivers for one wire - - - used wires that do not have a driver + - combinatorial loops + - two or more conflicting drivers for one wire + - used wires that do not have a driver Options: - -noinit - Also check for wires which have the 'init' attribute set. + -noinit + also check for wires which have the 'init' attribute set - -initdrv - Also check for wires that have the 'init' attribute set and are not - driven by an FF cell type. + -initdrv + also check for wires that have the 'init' attribute set and are not + driven by an FF cell type - -mapped - Also check for internal cells that have not been mapped to cells of the - target architecture. + -mapped + also check for internal cells that have not been mapped to cells of the + target architecture - -allow-tbuf - Modify the -mapped behavior to still allow $_TBUF_ cells. + -allow-tbuf + modify the -mapped behavior to still allow $_TBUF_ cells - -assert - Produce a runtime error if any problems are found in the current design. + -assert + produce a runtime error if any problems are found in the current design \end{lstlisting} \section{chformal -- change formal constraints of the design} @@ -807,30 +876,32 @@ \section{clk2fflogic -- convert clocked FFs to generic \$ff cells} multiple clocks. \end{lstlisting} -\section{clkbufmap -- insert global buffers on clock networks} +\section{clkbufmap -- insert clock buffers on clock networks} \label{cmd:clkbufmap} \begin{lstlisting}[numbers=left,frame=single] clkbufmap [options] [selection] -Inserts global buffers between nets connected to clock inputs and their drivers. +Inserts clock buffers between nets connected to clock inputs and their drivers. In the absence of any selection, all wires without the 'clkbuf_inhibit' -attribute will be considered for global buffer insertion. +attribute will be considered for clock buffer insertion. Alternatively, to consider all wires without the 'buffer_type' attribute set to 'none' or 'bufr' one would specify: 'w:* a:buffer_type=none a:buffer_type=bufr %u %d' as the selection. -buf : - Specifies the cell type to use for the global buffers + Specifies the cell type to use for the clock buffers and its port names. The first port will be connected to the clock network sinks, and the second will be connected - to the actual clock source. This option is required. + to the actual clock source. -inpad : If specified, a PAD cell of the given type is inserted on clock nets that are also top module's inputs (in addition - to the global buffer). + to the clock buffer, if any). + +At least one of -buf or -inpad should be specified. \end{lstlisting} \section{connect -- create or remove connections} @@ -849,7 +920,7 @@ \section{connect -- create or remove connections} Unconnect all existing drivers for the specified expression. - connect [-nomap] -port + connect [-nomap] [-assert] -port Connect the specified cell port to the specified cell port. @@ -861,6 +932,9 @@ \section{connect -- create or remove connections} The connect command operates in one module only. Either only one module must be selected or an active module must be set using the 'cd' command. +The -assert option verifies that the connection already exists, instead of +making it. + This command does not operate on module with processes. \end{lstlisting} @@ -895,7 +969,7 @@ \section{connect\_rpc -- connect to RPC frontend} -> {"method": "derive", "module": ", "parameters": { "": {"type": "[unsigned|signed|string|real]", "value": ""}, ...}} - <- {"frontend": "[ilang|verilog|...]","source": ""}} + <- {"frontend": "[rtlil|verilog|...]","source": ""}} <- {"error": ""} request for the module to be derived for a specific set of parameters. starts with \ for named parameters, and with $ @@ -1105,61 +1179,10 @@ \section{design -- save, restore and reset current design} The Verilog front-end remembers defined macros and top-level declarations between calls to 'read_verilog'. This command resets this memory. -\end{lstlisting} - -\section{determine\_init -- Determine the init value of cells} -\label{cmd:determine_init} -\begin{lstlisting}[numbers=left,frame=single] - determine_init [selection] - -Determine the init value of cells that doesn't allow unknown init value. -\end{lstlisting} - -\section{dff2dffe -- transform \$dff cells to \$dffe cells} -\label{cmd:dff2dffe} -\begin{lstlisting}[numbers=left,frame=single] - dff2dffe [options] [selection] -This pass transforms $dff cells driven by a tree of multiplexers with one or -more feedback paths to $dffe cells. It also works on gate-level cells such as -$_DFF_P_, $_DFF_N_ and $_MUX_. + design -delete - -unmap - operate in the opposite direction: replace $dffe cells with combinations - of $dff and $mux cells. the options below are ignored in unmap mode. - - -unmap-mince N - Same as -unmap but only unmap $dffe where the clock enable port - signal is used by less $dffe than the specified number - - -direct - map directly to external gate type. can - be any internal gate-level FF cell (except $_DFFE_??_). the - is the cell type name for a cell with an - identical interface to the , except it - also has an high-active enable port 'E'. - Usually is an intermediate cell type - that is then translated to the final type using 'techmap'. - - -direct-match - like -direct for all DFF cell types matching the expression. - this will use $__DFFE_* as matching the - internal gate type $_DFF_*_, and $__DFFSE_* for those matching - $_DFFS_*_, except for $_DFF_[NP]_, which is converted to - $_DFFE_[NP]_. -\end{lstlisting} - -\section{dff2dffs -- process sync set/reset with SR over CE priority} -\label{cmd:dff2dffs} -\begin{lstlisting}[numbers=left,frame=single] - dff2dffs [options] [selection] - -Merge synchronous set/reset $_MUX_ cells to create $__DFFS_[NP][NP][01], to be run before -dff2dffe for SR over CE priority. - - -match-init - Disallow merging synchronous set/reset that has polarity opposite of the - output wire's init attribute (if any). +Delete the design previously saved under the given name. \end{lstlisting} \section{dffinit -- set INIT param on FF cells} @@ -1190,10 +1213,76 @@ \section{dffinit -- set INIT param on FF cells} the already defined initial value. \end{lstlisting} +\section{dfflegalize -- convert FFs to types supported by the target} +\label{cmd:dfflegalize} +\begin{lstlisting}[numbers=left,frame=single] + dfflegalize [options] [selection] + +Converts FFs to types supported by the target. + + -cell + specifies a supported group of FF cells. + is a yosys internal fine cell name, where ? characters can be + as a wildcard matching any character. specifies + which initialization values these FF cells can support, and can + be one of: + + - x (no init value supported) + - 0 + - 1 + - r (init value has to match reset value, only for some FF types) + - 01 (both 0 and 1 supported). + + -mince + specifies a minimum number of FFs that should be using any given + clock enable signal. If a clock enable signal doesn't meet this + threshold, it is unmapped into soft logic. + + -minsrst + specifies a minimum number of FFs that should be using any given + sync set/reset signal. If a sync set/reset signal doesn't meet this + threshold, it is unmapped into soft logic. + +The following cells are supported by this pass (ie. will be ingested, +and can be specified as allowed targets): + +- $_DFF_[NP]_ +- $_DFFE_[NP][NP]_ +- $_DFF_[NP][NP][01]_ +- $_DFFE_[NP][NP][01][NP]_ +- $_ALDFF_[NP][NP]_ +- $_ALDFFE_[NP][NP][NP]_ +- $_DFFSR_[NP][NP][NP]_ +- $_DFFSRE_[NP][NP][NP][NP]_ +- $_SDFF_[NP][NP][01]_ +- $_SDFFE_[NP][NP][01][NP]_ +- $_SDFFCE_[NP][NP][01][NP]_ +- $_SR_[NP][NP]_ +- $_DLATCH_[NP]_ +- $_DLATCH_[NP][NP][01]_ +- $_DLATCHSR_[NP][NP][NP]_ + +The following transformations are performed by this pass: +- upconversion from a less capable cell to a more capable cell, if the less capable cell is not supported (eg. dff -> dffe, or adff -> dffsr) +- unmapping FFs with clock enable (due to unsupported cell type or -mince) +- unmapping FFs with sync reset (due to unsupported cell type or -minsrst) +- adding inverters on the control pins (due to unsupported polarity) +- adding inverters on the D and Q pins and inverting the init/reset values + (due to unsupported init or reset value) +- converting sr into adlatch (by tying D to 1 and using E as set input) +- emulating unsupported dffsr cell by adff + adff + sr + mux +- emulating unsupported dlatchsr cell by adlatch + adlatch + sr + mux +- emulating adff when the (reset, init) value combination is unsupported by + dff + adff + dlatch + mux +- emulating adlatch when the (reset, init) value combination is unsupported by +- dlatch + adlatch + dlatch + mux +If the pass is unable to realize a given cell type (eg. adff when only plain dffis available), an error is raised. +\end{lstlisting} + \section{dfflibmap -- technology mapping of flip-flops} \label{cmd:dfflibmap} \begin{lstlisting}[numbers=left,frame=single] - dfflibmap [-prepare] -liberty [selection] + dfflibmap [-prepare] [-map-only] [-info] -liberty [selection] Map internal flip-flop cells to the flip-flop cells in the technology library specified in the given liberty file. @@ -1203,16 +1292,40 @@ \section{dfflibmap -- technology mapping of flip-flops} When called with -prepare, this command will convert the internal FF cells to the internal cell types that best match the cells found in the given -liberty file. +liberty file, but won't actually map them to the target cells. + +When called with -map-only, this command will only map internal cell +types that are already of exactly the right type to match the target +cells, leaving remaining internal cells untouched. + +When called with -info, this command will only print the target cell +list, along with their associated internal cell types, and the argumentsthat would be passed to the dfflegalize pass. The design will not be +changed. +\end{lstlisting} + +\section{dffunmap -- unmap clock enable and synchronous reset from FFs} +\label{cmd:dffunmap} +\begin{lstlisting}[numbers=left,frame=single] + dffunmap [options] [selection] + +This pass transforms FF types with clock enable and/or synchronous reset into +their base type (with neither clock enable nor sync reset) by emulating the clock +enable and synchronous reset with multiplexers on the cell input. + + -ce-only + unmap only clock enables, leave synchronous resets alone. + + -srst-only + unmap only synchronous resets, leave clock enables alone. \end{lstlisting} -\section{dump -- print parts of the design in ilang format} +\section{dump -- print parts of the design in RTLIL format} \label{cmd:dump} \begin{lstlisting}[numbers=left,frame=single] dump [options] [selection] Write the selected parts of the design to the console or specified file in -ilang format. +RTLIL format. -m also dump the module headers, even if only parts of a single @@ -1241,16 +1354,6 @@ \section{echo -- turning echoing back of commands on and off} Do not print all commands to log before executing them. (default) \end{lstlisting} -\section{ecp5\_ffinit -- ECP5: handle FF init values} -\label{cmd:ecp5_ffinit} -\begin{lstlisting}[numbers=left,frame=single] - ecp5_ffinit [options] [selection] - -Remove init values for FF output signals when equal to reset value. -If reset is not used, set the reset value to the init value, otherwise -unmap out the reset (if not an async reset). -\end{lstlisting} - \section{ecp5\_gsr -- ECP5: handle GSR} \label{cmd:ecp5_gsr} \begin{lstlisting}[numbers=left,frame=single] @@ -1281,14 +1384,6 @@ \section{efinix\_fixcarry -- Efinix: fix carry chain} Add Efinix adders to fix carry chain if needed. \end{lstlisting} -\section{efinix\_gbuf -- Efinix: insert global clock buffers} -\label{cmd:efinix_gbuf} -\begin{lstlisting}[numbers=left,frame=single] - efinix_gbuf [options] [selection] - -Add Efinix global clock buffers to top module as needed. -\end{lstlisting} - \section{equiv\_add -- add a \$equiv cell} \label{cmd:equiv_add} \begin{lstlisting}[numbers=left,frame=single] @@ -1632,7 +1727,7 @@ \section{extract -- find subcircuits and replace them with cells} This pass looks for subcircuits that are isomorphic to any of the modules in the given map file and replaces them with instances of this modules. The -map file can be a Verilog source file (*.v) or an ilang file (*.il). +map file can be a Verilog source file (*.v) or an RTLIL source file (*.il). -map use the modules in this file as reference. This option can be used @@ -1687,7 +1782,7 @@ \section{extract -- find subcircuits and replace them with cells} the following options are to be used instead of the -map option. -mine - mine for frequent subcircuits and write them to the given ilang file + mine for frequent subcircuits and write them to the given RTLIL file -mine_cells_span only mine for subcircuits with the specified number of cells @@ -2124,9 +2219,9 @@ \section{hierarchy -- check, expand and clean up design hierarchy} In parametric designs, a module might exists in several variations with different parameter values. This pass looks at all modules in the current -design an re-runs the language frontends for the parametric modules as +design and re-runs the language frontends for the parametric modules as needed. It also resolves assignments to wired logic data types (wand/wor), -resolves positional module parameters, unroll array instances, and more. +resolves positional module parameters, unrolls array instances, and more. -check also check the design hierarchy. this generates an error when @@ -2252,23 +2347,6 @@ \section{ice40\_dsp -- iCE40: map multipliers} the accumulator to an arbitrary value can be inferred to use the {C,D} input. \end{lstlisting} -\section{ice40\_ffinit -- iCE40: handle FF init values} -\label{cmd:ice40_ffinit} -\begin{lstlisting}[numbers=left,frame=single] - ice40_ffinit [options] [selection] - -Remove zero init values for FF output signals. Add inverters to implement -nonzero init values. -\end{lstlisting} - -\section{ice40\_ffssr -- iCE40: merge synchronous set/reset into FF cells} -\label{cmd:ice40_ffssr} -\begin{lstlisting}[numbers=left,frame=single] - ice40_ffssr [options] [selection] - -Merge synchronous set/reset $_MUX_ cells into iCE40 FFs. -\end{lstlisting} - \section{ice40\_opt -- iCE40: perform simple optimizations} \label{cmd:ice40_opt} \begin{lstlisting}[numbers=left,frame=single] @@ -2280,7 +2358,7 @@ \section{ice40\_opt -- iCE40: perform simple optimizations} opt_expr -mux_undef -undriven [-full] opt_merge - opt_rmdff + opt_dff opt_clean while \end{lstlisting} @@ -2440,10 +2518,16 @@ \section{logger -- set logger properties} do not print warnings for the specified experimental feature -expect - expect log,warning or error to appear. In case of error return code is 0. + expect log, warning or error to appear. matched errors will terminate + with exit code 0. -expect-no-warnings gives error in case there is at least one warning that is not expected. + + -check-expected + verifies that the patterns previously set up by -expect have actually + been met, then clears the expected log list. If this is not called + manually, the check will happen at yosys exist time instead. \end{lstlisting} \section{ls -- list modules or objects in modules} @@ -2488,16 +2572,19 @@ \section{maccmap -- mapping macc cells} \section{memory -- translate memories to basic cells} \label{cmd:memory} \begin{lstlisting}[numbers=left,frame=single] - memory [-nomap] [-nordff] [-memx] [-bram ] [selection] + memory [-nomap] [-nordff] [-nowiden] [-nosat] [-memx] [-bram ] [selection] This pass calls all the other memory_* passes in a useful order: opt_mem - memory_dff [-nordff] (-memx implies -nordff) - opt_clean - memory_share + opt_mem_priority + opt_mem_feedback + memory_dff (skipped if called with -nordff or -memx) opt_clean + memory_share [-nowiden] [-nosat] + opt_mem_widen memory_memx (when called with -memx) + opt_clean memory_collect memory_bram -rules (when called with -bram) memory_map (skipped if called with -nomap) @@ -2616,17 +2703,14 @@ \section{memory\_collect -- creating multi-port memory cells} memory cells. \end{lstlisting} -\section{memory\_dff -- merge input/output DFFs into memories} +\section{memory\_dff -- merge input/output DFFs into memory read ports} \label{cmd:memory_dff} \begin{lstlisting}[numbers=left,frame=single] memory_dff [options] [selection] -This pass detects DFFs at memory ports and merges them into the memory port. +This pass detects DFFs at memory read ports and merges them into the memory port. I.e. it consumes an asynchronous memory port and the flip-flops at its interface and yields a synchronous memory port. - - -nordfff - do not merge registers on read ports \end{lstlisting} \section{memory\_map -- translate multiport memories to basic cells} @@ -2659,34 +2743,42 @@ \section{memory\_memx -- emulate vlog sim behavior for mem ports} behavior for out-of-bounds memory reads and writes. \end{lstlisting} +\section{memory\_narrow -- split up wide memory ports} +\label{cmd:memory_narrow} +\begin{lstlisting}[numbers=left,frame=single] + memory_narrow [options] [selection] + +This pass splits up wide memory ports into several narrow ports. +\end{lstlisting} + \section{memory\_nordff -- extract read port FFs from memories} \label{cmd:memory_nordff} \begin{lstlisting}[numbers=left,frame=single] memory_nordff [options] [selection] This pass extracts FFs from memory read ports. This results in a netlist -similar to what one would get from calling memory_dff with -nordff. +similar to what one would get from not calling memory_dff. \end{lstlisting} \section{memory\_share -- consolidate memory ports} \label{cmd:memory_share} \begin{lstlisting}[numbers=left,frame=single] - memory_share [selection] + memory_share [-nosat] [-nowiden] [selection] This pass merges share-able memory ports into single memory ports. The following methods are used to consolidate the number of memory ports: - - When write ports are connected to async read ports accessing the same - address, then this feedback path is converted to a write port with - byte/part enable signals. - - When multiple write ports access the same address then this is converted to a single write port with a more complex data and/or enable logic path. + - When multiple read or write ports access adjacent aligned addresses, they are + merged to a single wide read or write port. This transformation can be + disabled with the "-nowiden" option. + - When multiple write ports are never accessed at the same time (a SAT solver is used to determine this), then the ports are merged into a single - write port. + write port. This transformation can be disabled with the "-nosat" option. Note that in addition to the algorithms implemented in this pass, the $memrd and $memwr cells are also subject to generic resource sharing passes (and other @@ -2893,27 +2985,27 @@ \section{opt -- perform simple optimizations} a series of trivial optimizations and cleanups. This pass executes the other passes in the following order: - opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc] + opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc] opt_merge [-share_all] -nomux do opt_muxtree opt_reduce [-fine] [-full] opt_merge [-share_all] - opt_share (-full only) - opt_rmdff [-keepdc] [-sat] + opt_share (-full only) + opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] (except when called with -noff) opt_clean [-purge] - opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc] + opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc] while When called with -fast the following script is used instead: do - opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc] + opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc] opt_merge [-share_all] - opt_rmdff [-keepdc] [-sat] + opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] (except when called with -noff) opt_clean [-purge] - while + while Note: Options in square brackets (such as [-keepdc]) are passed through to the opt_* commands when given to 'opt'. @@ -2944,6 +3036,35 @@ \section{opt\_demorgan -- Optimize reductions with DeMorgan equivalents} overall gate count of the circuit \end{lstlisting} +\section{opt\_dff -- perform DFF optimizations} +\label{cmd:opt_dff} +\begin{lstlisting}[numbers=left,frame=single] + opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] [selection] + +This pass converts flip-flops to a more suitable type by merging clock enables +and synchronous reset multiplexers, removing unused control inputs, or potentially +removes the flip-flop altogether, converting it to a constant driver. + + -nodffe + disables dff -> dffe conversion, and other transforms recognizing clock enable + + -nosdff + disables dff -> sdff conversion, and other transforms recognizing sync resets + + -simple-dffe + only enables clock enable recognition transform for obvious cases + + -sat + additionally invoke SAT solver to detect and remove flip-flops (with + non-constant inputs) that can also be replaced with a constant driver + + -keepdc + some optimizations change the behavior of the circuit with respect to + don't-care bits. for example in 'a+0' a single x-bit in 'a' will cause + all result bits to be set to x. this behavior changes when 'a+0' is + replaced by 'a'. the -keepdc option disables all such optimizations. +\end{lstlisting} + \section{opt\_expr -- perform const folding and simple expression rewriting} \label{cmd:opt_expr} \begin{lstlisting}[numbers=left,frame=single] @@ -2961,8 +3082,8 @@ \section{opt\_expr -- perform const folding and simple expression rewriting} -undriven replace undriven nets with undef (x) constants - -clkinv - optimize clock inverters by changing FF types + -noclkinv + do not optimize clock inverters by changing FF types -fine perform fine-grain optimizations @@ -3018,6 +3139,38 @@ \section{opt\_mem -- optimize memories} This pass performs various optimizations on memories in the design. \end{lstlisting} +\section{opt\_mem\_feedback -- convert memory read-to-write port feedback paths to write enables} +\label{cmd:opt_mem_feedback} +\begin{lstlisting}[numbers=left,frame=single] + opt_mem_feedback [selection] + +This pass detects cases where an asynchronous read port is only connected via +a mux tree to a write port with the same address. When such a connection is +found, it is replaced with a new condition on an enable signal, allowing +for removal of the read port. +\end{lstlisting} + +\section{opt\_mem\_priority -- remove priority relations between write ports that can never collide} +\label{cmd:opt_mem_priority} +\begin{lstlisting}[numbers=left,frame=single] + opt_mem_priority [selection] + +This pass detects cases where one memory write port has priority over another +even though they can never collide with each other — ie. there can never be +a situation where a given memory bit is written by both ports at the same +time, for example because of always-different addresses, or mutually exclusive +enable signals. In such cases, the priority relation is removed. +\end{lstlisting} + +\section{opt\_mem\_widen -- optimize memories where all ports are wide} +\label{cmd:opt_mem_widen} +\begin{lstlisting}[numbers=left,frame=single] + opt_mem_widen [options] [selection] + +This pass looks for memories where all ports are wide and adjusts the base +memory width up until that stops being the case. +\end{lstlisting} + \section{opt\_merge -- consolidate identical cells} \label{cmd:opt_merge} \begin{lstlisting}[numbers=left,frame=single] @@ -3065,19 +3218,6 @@ \section{opt\_reduce -- simplify large MUXes and AND/OR gates} alias for -fine \end{lstlisting} -\section{opt\_rmdff -- remove DFFs with constant inputs} -\label{cmd:opt_rmdff} -\begin{lstlisting}[numbers=left,frame=single] - opt_rmdff [-keepdc] [-sat] [selection] - -This pass identifies flip-flops with constant inputs and replaces them with -a constant driver. - - -sat - additionally invoke SAT solver to detect and remove flip-flops (with - non-constant inputs) that can also be replaced with a constant driver -\end{lstlisting} - \section{opt\_share -- merge mutually exclusive cells of the same type that share an input signal} \label{cmd:opt_share} \begin{lstlisting}[numbers=left,frame=single] @@ -3224,7 +3364,7 @@ \section{prep -- generic synthesis script} do not run any of the memory_* passes -rdff - do not pass -nordff to 'memory_dff'. This enables merging of FFs into + call 'memory_dff'. This enables merging of FFs into memory read ports. -nokeepdc @@ -3247,19 +3387,27 @@ \section{prep -- generic synthesis script} opt_expr -keepdc opt_clean check - opt -keepdc + opt -noff -keepdc wreduce -keepdc [-memx] - memory_dff [-nordff] + memory_dff (if -rdff) memory_memx (if -memx) opt_clean memory_collect - opt -keepdc -fast + opt -noff -keepdc -fast check: stat check \end{lstlisting} +\section{printattrs -- print attributes of selected objects} +\label{cmd:printattrs} +\begin{lstlisting}[numbers=left,frame=single] + printattrs [selection] + +Print all attributes of the selected objects. +\end{lstlisting} + \section{proc -- translate processes to netlists} \label{cmd:proc} \begin{lstlisting}[numbers=left,frame=single] @@ -3275,19 +3423,27 @@ \section{proc -- translate processes to netlists} proc_mux proc_dlatch proc_dff + proc_memwr proc_clean + opt_expr -keepdc This replaces the processes in the design with multiplexers, flip-flops and latches. The following options are supported: + -nomux + Will omit the proc_mux pass. + -global_arst [!] This option is passed through to proc_arst. -ifx This option is passed through to proc_mux. proc_rmdead is not executed in -ifx mode. + + -noopt + Will omit the opt_expr pass. \end{lstlisting} \section{proc\_arst -- detect asynchronous resets} @@ -3347,6 +3503,14 @@ \section{proc\_init -- convert initial block to init attributes} respective wire. \end{lstlisting} +\section{proc\_memwr -- extract memory writes from processes} +\label{cmd:proc_memwr} +\begin{lstlisting}[numbers=left,frame=single] + proc_memwr [selection] + +This pass converts memory writes in processes into $memwr cells. +\end{lstlisting} + \section{proc\_mux -- convert decision trees to multiplexers} \label{cmd:proc_mux} \begin{lstlisting}[numbers=left,frame=single] @@ -3377,6 +3541,78 @@ \section{proc\_rmdead -- eliminate dead trees in decision trees} This pass identifies unreachable branches in decision trees and removes them. \end{lstlisting} +\section{qbfsat -- solve a 2QBF-SAT problem in the circuit} +\label{cmd:qbfsat} +\begin{lstlisting}[numbers=left,frame=single] + qbfsat [options] [selection] + +This command solves an "exists-forall" 2QBF-SAT problem defined over the currently +selected module. Existentially-quantified variables are declared by assigning a wire +"$anyconst". Universally-quantified variables may be explicitly declared by assigning +a wire "$allconst", but module inputs will be treated as universally-quantified +variables by default. + + -nocleanup + Do not delete temporary files and directories. Useful for debugging. + + -dump-final-smt2 + Pass the --dump-smt2 option to yosys-smtbmc. + + -assume-outputs + Add an "$assume" cell for the conjunction of all one-bit module output wires. + + -assume-negative-polarity + When adding $assume cells for one-bit module output wires, assume they are + negative polarity signals and should always be low, for example like the + miters created with the `miter` command. + + -nooptimize + Ignore "\minimize" and "\maximize" attributes, do not emit "(maximize)" or + "(minimize)" in the SMT-LIBv2, and generally make no attempt to optimize anything. + + -nobisection + If a wire is marked with the "\minimize" or "\maximize" attribute, do not + attempt to optimize that value with the default iterated solving and threshold + bisection approach. Instead, have yosys-smtbmc emit a "(minimize)" or "(maximize)" + command in the SMT-LIBv2 output and hope that the solver supports optimizing + quantified bitvector problems. + + -solver + Use a particular solver. Choose one of: "z3", "yices", and "cvc4". + (default: yices) + + -solver-option + Set the specified solver option in the SMT-LIBv2 problem file. + + -timeout + Set the per-iteration timeout in seconds. + (default: no timeout) + + -O0, -O1, -O2 + Control the use of ABC to simplify the QBF-SAT problem before solving. + + -sat + Generate an error if the solver does not return "sat". + + -unsat + Generate an error if the solver does not return "unsat". + + -show-smtbmc + Print the output from yosys-smtbmc. + + -specialize + If the problem is satisfiable, replace each "$anyconst" cell with its + corresponding constant value from the model produced by the solver. + + -specialize-from-file + Do not run the solver, but instead only attempt to replace each "$anyconst" + cell in the current module with a constant value provided by the specified file. + + -write-solution + If the problem is satisfiable, write the corresponding constant value for each + "$anyconst" cell from the model produced by the solver to the specified file. +\end{lstlisting} + \section{qwp -- quadratic wirelength placer} \label{cmd:qwp} \begin{lstlisting}[numbers=left,frame=single] @@ -3418,9 +3654,10 @@ \section{read -- load HDL designs} the language version (and before file names) to set additional verilog defines. - read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} .. + read {-f|-F} -Load the specified VHDL files. (Requires Verific.) +Load and execute the specified command file. (Requires Verific.) +Check verific command for more information about supported commands in file. read -define [=].. @@ -3486,24 +3723,10 @@ \section{read\_blif -- read BLIF file} multi-bit port 'name'. \end{lstlisting} -\section{read\_ilang -- read modules from ilang file} +\section{read\_ilang -- (deprecated) alias of read\_rtlil} \label{cmd:read_ilang} \begin{lstlisting}[numbers=left,frame=single] - read_ilang [filename] - -Load modules from an ilang file to the current design. (ilang is a text -representation of a design in yosys's internal format.) - - -nooverwrite - ignore re-definitions of modules. (the default behavior is to - create an error message if the existing module is not a blackbox - module, and overwrite the existing module if it is a blackbox module.) - - -overwrite - overwrite existing modules with the same name - - -lib - only create empty blackbox modules +See `help read_rtlil`. \end{lstlisting} \section{read\_json -- read JSON file} @@ -3547,6 +3770,26 @@ \section{read\_liberty -- read cells from liberty file} set the specified attribute (to the value 1) on all loaded modules \end{lstlisting} +\section{read\_rtlil -- read modules from RTLIL file} +\label{cmd:read_rtlil} +\begin{lstlisting}[numbers=left,frame=single] + read_rtlil [filename] + +Load modules from an RTLIL file to the current design. (RTLIL is a text +representation of a design in yosys's internal format.) + + -nooverwrite + ignore re-definitions of modules. (the default behavior is to + create an error message if the existing module is not a blackbox + module, and overwrite the existing module if it is a blackbox module.) + + -overwrite + overwrite existing modules with the same name + + -lib + only create empty blackbox modules +\end{lstlisting} + \section{read\_verilog -- read modules from Verilog file} \label{cmd:read_verilog} \begin{lstlisting}[numbers=left,frame=single] @@ -3563,6 +3806,9 @@ \section{read\_verilog -- read modules from Verilog file} enable support for SystemVerilog assertions and some Yosys extensions replace the implicit -D SYNTHESIS with -D FORMAL + -nosynthesis + don't add implicit -D SYNTHESIS + -noassert ignore assert() statements @@ -3704,8 +3950,8 @@ \section{read\_verilog -- read modules from Verilog file} the syntax of the code, rather than to rely on read_verilog for that. Depending on if read_verilog is run in -formal mode, either the macro -SYNTHESIS or FORMAL is defined automatically. In addition, read_verilog -always defines the macro YOSYS. +SYNTHESIS or FORMAL is defined automatically, unless -nosynthesis is used. +In addition, read_verilog always defines the macro YOSYS. See the Yosys README file for a list of non-standard Verilog features supported by the Yosys Verilog front-end. @@ -3955,7 +4201,7 @@ \section{scc -- detect strongly connected components (logic loops)} design. -expect - expect to find exactly SSCs. A different number of SSCs will + expect to find exactly SCCs. A different number of SCCs will produce an error. -max_depth @@ -3980,6 +4226,9 @@ \section{scc -- detect strongly connected components (logic loops)} -select replace the current selection with a selection of all cells and wires that are part of a found logic loop + + -specify + examine specify rules to detect logic loops in whitebox/blackbox cells \end{lstlisting} \section{scratchpad -- get/set values in the scratchpad} @@ -4043,6 +4292,7 @@ \section{select -- modify and view the list of selected objects} \label{cmd:select} \begin{lstlisting}[numbers=left,frame=single] select [ -add | -del | -set ] {-read | } + select [ -unset ] select [ ] {-read | } select [ -list | -write | -count | -clear ] select -module @@ -4065,6 +4315,9 @@ \section{select -- modify and view the list of selected objects} under the given name (see @ below). to save the current selection, use "select -set %" + -unset + do not modify the current selection. instead remove a previously saved + selection under the given name (see @ below). -assert-none do not modify the current selection. instead assert that the given selection is empty. i.e. produce an error if any object matching the @@ -4135,6 +4388,8 @@ \section{select -- modify and view the list of selected objects} select the specified object(s) from the current module +By default, patterns will not match black/white-box modules or theircontents. To include such objects, prefix the pattern with '='. + A can be a module name, wildcard expression (*, ?, [..]) matching module names, or one of the following: @@ -4321,17 +4576,6 @@ \section{setundef -- replace undef values with defined constants} replace undef in cell parameters \end{lstlisting} -\section{sf2\_iobs -- SF2: insert IO buffers} -\label{cmd:sf2_iobs} -\begin{lstlisting}[numbers=left,frame=single] - sf2_iobs [options] [selection] - -Add SF2 I/O buffers and global buffers to top module as needed. - - -clkbuf - Insert PAD->global_net clock buffers -\end{lstlisting} - \section{share -- perform sat-based resource sharing} \label{cmd:share} \begin{lstlisting}[numbers=left,frame=single] @@ -4413,7 +4657,7 @@ \section{show -- generate schematics using graphviz} generate a .dot file, or other strings such as 'svg' or 'ps' to generate files in other formats (this calls the 'dot' command). - -lib + -lib Use the specified library file for determining whether cell ports are inputs or outputs. This option can be used multiple times to specify more than one library. @@ -4567,6 +4811,9 @@ \section{sim -- simulate the circuit} -zinit zero-initialize all uninitialized regs and memories + -timescale + include the specified timescale declaration in the vcd + -n number of cycles to simulate (default: 20) @@ -4591,7 +4838,7 @@ \section{simplemap -- mapping simple coarse-grain cells} $not, $pos, $and, $or, $xor, $xnor $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool $logic_not, $logic_and, $logic_or, $mux, $tribuf - $sr, $ff, $dff, $dffsr, $adff, $dlatch + $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $aldff, $aldffe, $sdff, $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr \end{lstlisting} \section{splice -- create explicit splicing cells} @@ -4783,6 +5030,8 @@ \section{synth -- generic synthesis script} opt_expr opt_clean check + opt -nodffe -nosdff + fsm (unless -nofsm) opt wreduce peepopt @@ -4791,8 +5040,6 @@ \section{synth -- generic synthesis script} alumacc (unless -noalumacc) share (unless -noshare) opt - fsm (unless -nofsm) - opt -fast memory -nomap opt_clean @@ -4860,12 +5107,12 @@ \section{synth\_achronix -- synthesis for Acrhonix Speedster22i FPGAs.} opt -fast -mux_undef -undriven -fine -full memory_map opt -undriven -fine - dff2dffe -direct-match $_DFF_* opt -fine techmap -map +/techmap.v opt -full clean -purge setundef -undriven -zero + dfflegalize -cell $_DFF_P_ x abc -markgroups -dff -D 1 (only if -retime) map_luts: @@ -4881,6 +5128,7 @@ \section{synth\_achronix -- synthesis for Acrhonix Speedster22i FPGAs.} hierarchy -check stat check -noinit + blackbox =A:whitebox vout: write_verilog -nodec -attr2comment -defparam -renameprefix syn_ @@ -4950,8 +5198,8 @@ \section{synth\_anlogic -- synthesis for Anlogic FPGAs} abc -dff -D 1 (only if -retime) map_ffs: + dfflegalize -cell $_DFFE_P??P_ r -cell $_SDFFE_P??P_ r -cell $_DLATCH_N??_ r techmap -D NO_LUT -map +/anlogic/cells_map.v - dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit opt_expr -mux_undef simplemap @@ -4971,6 +5219,7 @@ \section{synth\_anlogic -- synthesis for Anlogic FPGAs} hierarchy -check stat check -noinit + blackbox =A:whitebox edif: write_edif @@ -5060,6 +5309,7 @@ \section{synth\_coolrunner2 -- synthesis for Xilinx Coolrunner-II CPLDs} hierarchy -check stat check -noinit + blackbox =A:whitebox json: write_json @@ -5126,6 +5376,7 @@ \section{synth\_easic -- synthesis for eASIC platform} hierarchy -check stat check -noinit + blackbox =A:whitebox vlog: write_verilog -noexpr -attr2comment @@ -5161,6 +5412,9 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} -noflatten do not flatten design before synthesis + -dff + run 'abc'/'abc9' with -dff option + -retime run 'abc' with '-dff -D 1' options @@ -5180,7 +5434,7 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} do not use PFU muxes to implement LUTs larger than LUT4s -asyncprld - use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL) + use async PRLD mode to implement ALDFF (EXPERIMENTAL) -abc2 run two passes of 'abc' for slightly improved logic density @@ -5210,6 +5464,8 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} opt_expr opt_clean check + opt -nodffe -nosdff + fsm opt wreduce peepopt @@ -5222,8 +5478,6 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} chtype -set $mul t:$__soft_mul (unless -nodsp) alumacc opt - fsm - opt -fast memory -nomap opt_clean @@ -5246,25 +5500,24 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} abc -dff -D 1 (only if -retime) map_ffs: - dff2dffs opt_clean - dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_* - techmap -D NO_LUT [-D ASYNC_PRLD] -map +/ecp5/cells_map.v + dfflegalize -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r] [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x] ($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe) + zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF* (only if -abc9 and -dff) + techmap -D NO_LUT -map +/ecp5/cells_map.v opt_expr -undriven -mux_undef simplemap - ecp5_ffinit ecp5_gsr attrmvcp -copy -attr syn_useioff opt_clean map_luts: abc (only if -abc2) - techmap -map +/ecp5/latches_map.v - abc -lut 4:7 -dress + techmap -map +/ecp5/latches_map.v (skip if -asyncprld) + abc -dress -lut 4:7 clean map_cells: - techmap -map +/ecp5/cells_map.v (with -D NO_LUT in vpr mode) + techmap -map +/ecp5/cells_map.v (skip if -vpr) opt_lut_ins -tech ecp5 clean @@ -5273,6 +5526,7 @@ \section{synth\_ecp5 -- synthesis for ECP5 FPGAs} hierarchy -check stat check -noinit + blackbox =A:whitebox blif: opt_clean -purge (vpr mode) @@ -5348,8 +5602,8 @@ \section{synth\_efinix -- synthesis for Efinix FPGAs} abc -dff -D 1 (only if -retime) map_ffs: + dfflegalize -cell $_DFFE_????_ 0 -cell $_SDFFE_????_ 0 -cell $_SDFFCE_????_ 0 -cell $_DLATCH_?_ x techmap -D NO_LUT -map +/efinix/cells_map.v - dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit opt_expr -mux_undef simplemap @@ -5362,7 +5616,8 @@ \section{synth\_efinix -- synthesis for Efinix FPGAs} clean map_gbuf: - efinix_gbuf + clkbufmap -buf $__EFX_GBUF O:I + techmap -map +/efinix/gbuf_map.v efinix_fixcarry clean @@ -5370,6 +5625,7 @@ \section{synth\_efinix -- synthesis for Efinix FPGAs} hierarchy -check stat check -noinit + blackbox =A:whitebox edif: write_edif @@ -5392,6 +5648,11 @@ \section{synth\_gowin -- synthesis for Gowin FPGAs} write the design to the specified Verilog netlist file. writing of an output file is omitted if this parameter is not specified. + -json + write the design to the specified JSON netlist file. writing of an + output file is omitted if this parameter is not specified. + This disables features not yet supported by nexpnr-gowin. + -run : only run the commands between the labels (see below). an empty from label is synonymous to 'begin', and empty to label is @@ -5418,11 +5679,17 @@ \section{synth\_gowin -- synthesis for Gowin FPGAs} -noiopads do not emit IOB at top level ports + -noalu + do not use ALU cells + + -abc9 + use new ABC9 flow (EXPERIMENTAL) + The following commands are executed by this synthesis command: begin: - read_verilog -lib +/gowin/cells_sim.v + read_verilog -specify -lib +/gowin/cells_sim.v hierarchy -check -top flatten: (unless -noflatten) @@ -5441,7 +5708,7 @@ \section{synth\_gowin -- synthesis for Gowin FPGAs} map_lutram: (skip if -nolutram) memory_bram -rules +/gowin/lutrams.txt techmap -map +/gowin/lutrams_map.v - determine_init + setundef -params -zero t:RAM16S4 map_ffram: opt -fast -mux_undef -undriven -fine @@ -5453,11 +5720,11 @@ \section{synth\_gowin -- synthesis for Gowin FPGAs} opt -fast abc -dff -D 1 (only if -retime) splitnets + iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O -toutpad $__GW_TBUF OE:I:O -tinoutpad $__GW_IOBUF OE:O:I:IO (unless -noiopads) map_ffs: - dff2dffs -match-init opt_clean - dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_* + dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r techmap -map +/gowin/cells_map.v opt_expr -mux_undef simplemap @@ -5471,16 +5738,18 @@ \section{synth\_gowin -- synthesis for Gowin FPGAs} opt_lut_ins -tech gowin setundef -undriven -params -zero hilomap -singleton -hicell VCC V -locell GND G - iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O -toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO (unless -noiopads) clean + autoname check: hierarchy -check stat check -noinit + blackbox =A:whitebox vout: write_verilog -decimal -attr2comment -defparam -renameprefix gen + write_json \end{lstlisting} \section{synth\_greenpak4 -- synthesis for GreenPAK4 FPGAs} @@ -5537,7 +5806,7 @@ \section{synth\_greenpak4 -- synthesis for GreenPAK4 FPGAs} opt -undriven -fine techmap -map +/techmap.v -map +/greenpak4/cells_latch.v dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib - opt -fast + opt -fast -noclkinv -noff abc -dff -D 1 (only if -retime) map_luts: @@ -5564,6 +5833,7 @@ \section{synth\_greenpak4 -- synthesis for GreenPAK4 FPGAs} hierarchy -check stat check -noinit + blackbox =A:whitebox json: write_json @@ -5603,6 +5873,9 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} -noflatten do not flatten design before synthesis + -dff + run 'abc'/'abc9' with -dff option + -retime run 'abc' with '-dff -D 1' options @@ -5655,6 +5928,8 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} opt_expr opt_clean check + opt -nodffe -nosdff + fsm opt wreduce peepopt @@ -5675,8 +5950,6 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} chtype -set $mul t:$__soft_mul (if -dsp) alumacc opt - fsm - opt -fast memory -nomap opt_clean @@ -5698,12 +5971,10 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} ice40_opt map_ffs: - dff2dffe -direct-match $_DFF_* - techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v + dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_SDFF_?P?_ 0 -cell $_SDFFCE_?P?P_ 0 -cell $_DLATCH_?_ x -mince -1 + techmap -map +/ice40/ff_map.v opt_expr -mux_undef simplemap - ice40_ffinit - ice40_ffssr ice40_opt -full map_luts: @@ -5713,14 +5984,14 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} simplemap (if -noabc or -flowmap) techmap -map +/gate2lut.v -D LUT_WIDTH=4 (only if -noabc) flowmap -maxlut 4 (only if -flowmap) - abc -dress -lut 4 (skip if -noabc) + abc -dress -lut 4 (skip if -noabc) ice40_wrapcarry -unwrap - techmap -D NO_LUT -map +/ice40/cells_map.v + techmap -map +/ice40/ff_map.v clean - opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0 + opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 -dlogic SB_CARRY:CO=3 map_cells: - techmap -map +/ice40/cells_map.v (with -D NO_LUT in vpr mode) + techmap -map +/ice40/cells_map.v (skip if -vpr) clean check: @@ -5728,6 +5999,7 @@ \section{synth\_ice40 -- synthesis for iCE40 FPGAs} hierarchy -check stat check -noinit + blackbox =A:whitebox blif: opt_clean -purge (vpr mode) @@ -5748,11 +6020,11 @@ \section{synth\_intel -- synthesis for Intel (Altera) FPGAs.} This command runs synthesis for Intel FPGAs. - -family + -family generate the synthesis netlist for the specified family. MAX10 is the default target if no family argument specified. For Cyclone IV GX devices, use cycloneiv argument; for Cyclone IV E, use cycloneive. - Cyclone V and Arria 10 GX devices are experimental. + For Cyclone V and Cyclone 10 GX, use the synth_intel_alm backend instead. -top use the specified module as top module (default='top') @@ -5812,14 +6084,16 @@ \section{synth\_intel -- synthesis for Intel (Altera) FPGAs.} opt -fast -mux_undef -undriven -fine -full memory_map opt -undriven -fine - dff2dffe -direct-match $_DFF_* - opt -fine techmap -map +/techmap.v opt -full clean -purge setundef -undriven -zero abc -markgroups -dff -D 1 (only if -retime) + map_ffs: + dfflegalize -cell $_DFFE_PN0P_ 01 + techmap -map +/intel/common/ff_map.v + map_luts: abc -lut 4 clean @@ -5827,13 +6101,13 @@ \section{synth\_intel -- synthesis for Intel (Altera) FPGAs.} map_cells: iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I (if -iopads) techmap -map +/intel/max10/cells_map.v - dffinit -highlow -ff dffeas q power_up clean -purge check: hierarchy -check stat check -noinit + blackbox =A:whitebox vqm: write_verilog -attr2comment -defparam -nohex -decimal -renameprefix syn_ @@ -5846,60 +6120,549 @@ \section{synth\_intel -- synthesis for Intel (Altera) FPGAs.} WARNING: THE 'synth_intel' COMMAND IS EXPERIMENTAL. \end{lstlisting} -\section{synth\_sf2 -- synthesis for SmartFusion2 and IGLOO2 FPGAs} -\label{cmd:synth_sf2} +\section{synth\_intel\_alm -- synthesis for ALM-based Intel (Altera) FPGAs.} +\label{cmd:synth_intel_alm} \begin{lstlisting}[numbers=left,frame=single] - synth_sf2 [options] + synth_intel_alm [options] -This command runs synthesis for SmartFusion2 and IGLOO2 FPGAs. +This command runs synthesis for ALM-based Intel FPGAs. -top use the specified module as top module - -edif - write the design to the specified EDIF file. writing of an output file - is omitted if this parameter is not specified. + -family + target one of: + "cyclonev" - Cyclone V (default) + "cyclone10gx" - Cyclone 10GX - -vlog - write the design to the specified Verilog file. writing of an output file - is omitted if this parameter is not specified. + -vqm + write the design to the specified Verilog Quartus Mapping File. Writing of an + output file is omitted if this parameter is not specified. Implies -quartus. - -json - write the design to the specified JSON file. writing of an output file - is omitted if this parameter is not specified. + -noflatten + do not flatten design before synthesis; useful for per-module area statistics + + -quartus + output a netlist using Quartus cells instead of MISTRAL_* cells + + -dff + pass DFFs to ABC to perform sequential logic optimisations (EXPERIMENTAL) -run : only run the commands between the labels (see below). an empty from label is synonymous to 'begin', and empty to label is synonymous to the end of the command list. - -noflatten - do not flatten design before synthesis + -nolutram + do not use LUT RAM cells in output netlist - -noiobs - run synthesis in "block mode", i.e. do not insert IO buffers + -nobram + do not use block RAM cells in output netlist - -clkbuf - insert direct PAD->global_net buffers + -nodsp + do not map multipliers to MISTRAL_MUL cells - -retime - run 'abc' with '-dff -D 1' options + -noiopad + do not instantiate IO buffers + -noclkbuf + do not insert global clock buffers The following commands are executed by this synthesis command: begin: - read_verilog -lib +/sf2/cells_sim.v + read_verilog -specify -lib -D +/intel_alm/common/alm_sim.v + read_verilog -specify -lib -D +/intel_alm/common/dff_sim.v + read_verilog -specify -lib -D +/intel_alm/common/dsp_sim.v + read_verilog -specify -lib -D +/intel_alm/common/mem_sim.v + read_verilog -specify -lib -D +/intel_alm/common/misc_sim.v + read_verilog -specify -lib -D -icells +/intel_alm/common/abc9_model.v + read_verilog -lib +/intel/common/altpll_bb.v + read_verilog -lib +/intel_alm/common/megafunction_bb.v hierarchy -check -top - flatten: (unless -noflatten) + coarse: proc - flatten + flatten (skip if -noflatten) tribuf -logic deminout - - coarse: - synth -run coarse + opt_expr + opt_clean + check + opt -nodffe -nosdff + fsm + opt + wreduce + peepopt + opt_clean + share + techmap -map +/cmp2lut.v -D LUT_WIDTH=6 + opt_expr + opt_clean + techmap -map +/mul2dsp.v [...] (unless -nodsp) + alumacc + iopadmap -bits -outpad MISTRAL_OB I:PAD -inpad MISTRAL_IB O:PAD -toutpad MISTRAL_IO OE:O:PAD -tinoutpad MISTRAL_IO OE:O:I:PAD A:top (unless -noiopad) + techmap -map +/intel_alm/common/arith_alm_map.v -map +/intel_alm/common/dsp_map.v + opt + memory -nomap + opt_clean + + map_bram: (skip if -nobram) + memory_bram -rules +/intel_alm/common/bram_.txt + techmap -map +/intel_alm/common/bram__map.v + + map_lutram: (skip if -nolutram) + memory_bram -rules +/intel_alm/common/lutram_mlab.txt (for Cyclone V / Cyclone 10GX) + + map_ffram: + memory_map + opt -full + + map_ffs: + techmap + dfflegalize -cell $_DFFE_PN0P_ 0 -cell $_SDFFCE_PP0P_ 0 + techmap -map +/intel_alm/common/dff_map.v + opt -full -undriven -mux_undef + clean -purge + clkbufmap -buf MISTRAL_CLKBUF Q:A (unless -noclkbuf) + + map_luts: + techmap -map +/intel_alm/common/abc9_map.v + abc9 [-dff] -maxlut 6 -W 600 + techmap -map +/intel_alm/common/abc9_unmap.v + techmap -map +/intel_alm/common/alm_map.v + opt -fast + autoname + clean + + check: + hierarchy -check + stat + check + blackbox =A:whitebox + + quartus: + rename -hide w:*[* w:*]* + setundef -zero + hilomap -singleton -hicell __MISTRAL_VCC Q -locell __MISTRAL_GND Q + techmap -D -map +/intel_alm/common/quartus_rename.v + + vqm: + write_verilog -attr2comment -defparam -nohex -decimal +\end{lstlisting} + +\section{synth\_machxo2 -- synthesis for MachXO2 FPGAs. This work is experimental.} +\label{cmd:synth_machxo2} +\begin{lstlisting}[numbers=left,frame=single] + synth_machxo2 [options] + +This command runs synthesis for MachXO2 FPGAs. + + -top + use the specified module as top module + + -blif + write the design to the specified BLIF file. writing of an output file + is omitted if this parameter is not specified. + + -edif + write the design to the specified EDIF file. writing of an output file + is omitted if this parameter is not specified. + + -json + write the design to the specified JSON file. writing of an output file + is omitted if this parameter is not specified. + + -run : + only run the commands between the labels (see below). an empty + from label is synonymous to 'begin', and empty to label is + synonymous to the end of the command list. + + -noflatten + do not flatten design before synthesis + + -noiopad + do not insert IO buffers + + -vpr + generate an output netlist (and BLIF file) suitable for VPR + (this feature is experimental and incomplete) + + +The following commands are executed by this synthesis command: + + begin: + read_verilog -lib -icells +/machxo2/cells_sim.v + hierarchy -check -top + + flatten: (unless -noflatten) + proc + flatten + tribuf -logic + deminout + + coarse: + synth -run coarse + + fine: + memory_map + opt -full + techmap -map +/techmap.v + opt -fast + + map_ios: (unless -noiopad) + iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD OE:I:O -tinoutpad $__FACADE_TINOUTPAD OE:O:I:B A:top + attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B] + attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I] + + map_ffs: + dfflegalize -cell $_DFF_P_ 0 + + map_luts: + abc -lut 4 -dress + clean + + map_cells: + techmap -map +/machxo2/cells_map.v + clean + + check: + hierarchy -check + stat + blackbox =A:whitebox + + blif: + opt_clean -purge (vpr mode) + write_blif -attr -cname -conn -param (vpr mode) + write_blif -gates -attr -param (non-vpr mode) + + edif: + write_edif + + json: + write_json +\end{lstlisting} + +\section{synth\_nexus -- synthesis for Lattice Nexus FPGAs} +\label{cmd:synth_nexus} +\begin{lstlisting}[numbers=left,frame=single] + synth_nexus [options] + +This command runs synthesis for Lattice Nexus FPGAs. + + -top + use the specified module as top module + + -family + run synthesis for the specified Nexus device + supported values: lifcl, lfd2nx + + -json + write the design to the specified JSON file. writing of an output file + is omitted if this parameter is not specified. + + -vm + write the design to the specified structural Verilog file. writing of + an output file is omitted if this parameter is not specified. + + -run : + only run the commands between the labels (see below). an empty + from label is synonymous to 'begin', and empty to label is + synonymous to the end of the command list. + + -noflatten + do not flatten design before synthesis + + -dff + run 'abc'/'abc9' with -dff option + + -retime + run 'abc' with '-dff -D 1' options + + -noccu2 + do not use CCU2 cells in output netlist + + -nodffe + do not use flipflops with CE in output netlist + + -nolram + do not use large RAM cells in output netlist + note that large RAM must be explicitly requested with a (* lram *) + attribute on the memory. + + -nobram + do not use block RAM cells in output netlist + + -nolutram + do not use LUT RAM cells in output netlist + + -nowidelut + do not use PFU muxes to implement LUTs larger than LUT4s + + -noiopad + do not insert IO buffers + + -nodsp + do not infer DSP multipliers + + -abc9 + use new ABC9 flow (EXPERIMENTAL) + +The following commands are executed by this synthesis command: + + begin: + read_verilog -lib -specify +/nexus/cells_sim.v +/nexus/cells_xtra.v + hierarchy -check -top + + coarse: + proc + flatten + tribuf -logic + deminout + opt_expr + opt_clean + check + opt -nodffe -nosdff + fsm + opt + wreduce + peepopt + opt_clean + share + techmap -map +/cmp2lut.v -D LUT_WIDTH=4 + opt_expr + opt_clean + techmap -map +/mul2dsp.v [...] (unless -nodsp) + techmap -map +/nexus/dsp_map.v (unless -nodsp) + alumacc + opt + memory -nomap + opt_clean + + map_lram: (skip if -nolram) + memory_bram -rules +/nexus/lrams.txt + setundef -zero -params t:$__NX_PDPSC512K + techmap -map +/nexus/lrams_map.v + + map_bram: (skip if -nobram) + memory_bram -rules +/nexus/brams.txt + setundef -zero -params t:$__NX_PDP16K + techmap -map +/nexus/brams_map.v + + map_lutram: (skip if -nolutram) + memory_bram -rules +/nexus/lutrams.txt + setundef -zero -params t:$__NEXUS_DPR16X4 + techmap -map +/nexus/lutrams_map.v + + map_ffram: + opt -fast -mux_undef -undriven -fine + memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block -attr syn_ramstyle=auto -attr syn_ramstyle=registers -attr syn_romstyle=auto -attr syn_romstyle=logic + opt -undriven -fine + + map_gates: + techmap -map +/techmap.v -map +/nexus/arith_map.v + iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad $__NX_TOUTPAD OE:I:O -tinoutpad $__NX_TINOUTPAD OE:O:I:B A:top (skip if '-noiopad') + opt -fast + abc -dff -D 1 (only if -retime) + + map_ffs: + opt_clean + dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PP?_ r -cell $_SDFF_PP?_ r -cell $_DLATCH_?_ x [-cell $_DFFE_PP_ 01 -cell $_DFFE_PP?P_ r -cell $_SDFFE_PP?P_ r] ($_*DFFE_* only if not -nodffe) + zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF* (only if -abc9 and -dff + techmap -D NO_LUT -map +/nexus/cells_map.v + opt_expr -undriven -mux_undef + simplemap + attrmvcp -copy -attr syn_useioff + opt_clean + + map_luts: + techmap -map +/nexus/latches_map.v + abc -dress -lut 4:5 + clean + + map_cells: + techmap -map +/nexus/cells_map.v + setundef -zero + hilomap -singleton -hicell VHI Z -locell VLO Z + clean + + check: + autoname + hierarchy -check + stat + check -noinit + blackbox =A:whitebox + + json: + write_json + + vm: + write_verilog +\end{lstlisting} + +\section{synth\_quicklogic -- Synthesis for QuickLogic FPGAs} +\label{cmd:synth_quicklogic} +\begin{lstlisting}[numbers=left,frame=single] + synth_quicklogic [options] +This command runs synthesis for QuickLogic FPGAs + + -top + use the specified module as top module + + -family + run synthesis for the specified QuickLogic architecture + generate the synthesis netlist for the specified family. + supported values: + - pp3: PolarPro 3 + + -blif + write the design to the specified BLIF file. writing of an output file + is omitted if this parameter is not specified. + + -verilog + write the design to the specified verilog file. writing of an output file + is omitted if this parameter is not specified. + + -abc + use old ABC flow, which has generally worse mapping results but is less + likely to have bugs. + +The following commands are executed by this synthesis command: + + begin: + read_verilog -lib -specify +/quicklogic/cells_sim.v +/quicklogic/pp3_cells_sim.v + read_verilog -lib -specify +/quicklogic/lut_sim.v + hierarchy -check -top + + coarse: + proc + flatten + tribuf -logic + deminout + opt_expr + opt_clean + check + opt -nodffe -nosdff + fsm + opt + wreduce + peepopt + opt_clean + share + techmap -map +/cmp2lut.v -D LUT_WIDTH=4 + opt_expr + opt_clean + alumacc + pmuxtree + opt + memory -nomap + opt_clean + + map_ffram: + opt -fast -mux_undef -undriven -fine + memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block -attr syn_ramstyle=auto -attr syn_ramstyle=registers -attr syn_romstyle=auto -attr syn_romstyle=logic + opt -undriven -fine + + map_gates: + techmap + opt -fast + muxcover -mux8 -mux4 + + map_ffs: + opt_expr + dfflegalize -cell $_DFFSRE_PPPP_ 0 -cell $_DLATCH_?_ x + techmap -map +/quicklogic/pp3_cells_map.v -map +/quicklogic/pp3_ffs_map.v + opt_expr -mux_undef + + map_luts: + techmap -map +/quicklogic/pp3_latches_map.v + read_verilog -lib -specify -icells +/quicklogic/abc9_model.v + techmap -map +/quicklogic/abc9_map.v + abc9 -maxlut 4 -dff + techmap -map +/quicklogic/abc9_unmap.v + clean + + map_cells: + techmap -map +/quicklogic/pp3_lut_map.v + clean + + check: + autoname + hierarchy -check + stat + check -noinit + + iomap: + clkbufmap -inpad ckpad Q:P + iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top + + finalize: + setundef -zero -params -undriven + hilomap -hicell logic_1 A -locell logic_0 A -singleton A:top + opt_clean -purge + check + blackbox =A:whitebox + + blif: + write_blif -attr -param -auto-top + + verilog: +\end{lstlisting} + +\section{synth\_sf2 -- synthesis for SmartFusion2 and IGLOO2 FPGAs} +\label{cmd:synth_sf2} +\begin{lstlisting}[numbers=left,frame=single] + synth_sf2 [options] + +This command runs synthesis for SmartFusion2 and IGLOO2 FPGAs. + + -top + use the specified module as top module + + -edif + write the design to the specified EDIF file. writing of an output file + is omitted if this parameter is not specified. + + -vlog + write the design to the specified Verilog file. writing of an output file + is omitted if this parameter is not specified. + + -json + write the design to the specified JSON file. writing of an output file + is omitted if this parameter is not specified. + + -run : + only run the commands between the labels (see below). an empty + from label is synonymous to 'begin', and empty to label is + synonymous to the end of the command list. + + -noflatten + do not flatten design before synthesis + + -noiobs + run synthesis in "block mode", i.e. do not insert IO buffers + + -clkbuf + insert direct PAD->global_net buffers + + -retime + run 'abc' with '-dff -D 1' options + + +The following commands are executed by this synthesis command: + + begin: + read_verilog -lib +/sf2/cells_sim.v + hierarchy -check -top + + flatten: (unless -noflatten) + proc + flatten + tribuf -logic + deminout + + coarse: + synth -run coarse fine: opt -fast -mux_undef -undriven -fine @@ -5910,6 +6673,7 @@ \section{synth\_sf2 -- synthesis for SmartFusion2 and IGLOO2 FPGAs} abc -dff -D 1 (only if -retime) map_ffs: + dfflegalize -cell $_DFFE_PN?P_ x -cell $_SDFFCE_PN?P_ x -cell $_DLATCH_PN?_ x techmap -D NO_LUT -map +/sf2/cells_map.v opt_expr -mux_undef simplemap @@ -5923,13 +6687,15 @@ \section{synth\_sf2 -- synthesis for SmartFusion2 and IGLOO2 FPGAs} clean map_iobs: - sf2_iobs [-clkbuf] (unless -noiobs) + clkbufmap -buf CLKINT Y:A [-inpad CLKBUF Y:PAD] (unless -noiobs, -inpad only passed if -clkbuf) + iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD (unless -noiobs clean check: hierarchy -check stat check -noinit + blackbox =A:whitebox edif: write_edif -gndvccy @@ -5981,10 +6747,6 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} write the design to the specified BLIF file. writing of an output file is omitted if this parameter is not specified. - -vpr - generate an output netlist (and BLIF file) suitable for VPR - (this feature is experimental and incomplete) - -ise generate an output netlist suitable for ISE @@ -6055,6 +6817,8 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} opt_expr opt_clean check + opt -nodffe -nosdff + fsm opt wreduce [-keepdc] (option for '-widemux') peepopt @@ -6079,8 +6843,6 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} alumacc share opt - fsm - opt -fast memory -nomap opt_clean @@ -6097,14 +6859,12 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} techmap -map +/xilinx/lutrams_map.v map_ffram: - simplemap t:$dff t:$adff t:$mux - dff2dffs [-match-init] (-match-init for xc6s only) opt -fast -full memory_map fine: - dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_* - muxcover ('-widemux' only) + simplemap t:$mux ('-widemux' only) + muxcover ('-widemux' only) opt -full xilinx_srl -variable -minlen 3 (skip if '-nosrl') techmap -map +/techmap.v -D LUT_SIZE=[46] [-map +/xilinx/mux_map.v] -map +/xilinx/arith_map.v @@ -6116,14 +6876,17 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} clean map_ffs: - techmap -map +/xilinx/{family}_ff_map.v ('-abc9' only) + dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_SDFFE_?P?P_ 01 -cell $_DLATCH_?P?_ 01 (for xc6v, xc7, xcu, xcup) + zinit -all w:* t:$_SDFFE_* ('-dff' only) + techmap -map +/xilinx/ff_map.v ('-abc9' only) map_luts: - opt_expr -mux_undef - abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1] (option for 'nowidelut', '-dff', '-retime') + opt_expr -mux_undef -noclkinv + abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1] (option for '-nowidelut', '-dff', '-retime') clean + techmap -map +/xilinx/ff_map.v (only if not '-abc9') xilinx_srl -fixed -minlen 3 (skip if '-nosrl') - techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/{family}_ff_map.v -D LUT_WIDTH=[46] + techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -D LUT_WIDTH=[46] xilinx_dffopt [-lut4] opt_lut_ins -tech xilinx @@ -6136,6 +6899,7 @@ \section{synth\_xilinx -- synthesis for Xilinx FPGAs} hierarchy -check stat -tech xilinx check -noinit + blackbox =A:whitebox edif: write_edif -pvector bra @@ -6167,7 +6931,7 @@ \section{techmap -- generic technology mapper} techmap [-map filename] [selection] This pass implements a very simple technology mapper that replaces cells in -the design with implementations given in form of a Verilog or ilang source +the design with implementations given in form of a Verilog or RTLIL source file. -map filename @@ -6210,7 +6974,9 @@ \section{techmap -- generic technology mapper} When a module in the map file has the 'techmap_celltype' attribute set, it will match cells with a type that match the text value of this attribute. Otherwise -the module name will be used to match the cell. +the module name will be used to match the cell. Multiple space-separated cell +types can be listed, and wildcards using [] will be expanded (ie. "$_DFF_[PN]_" +is the same as "$_DFF_P_ $_DFF_N_"). When a module in the map file has the 'techmap_simplemap' attribute set, techmap will use 'simplemap' (see 'help simplemap') to map cells matching the module. @@ -6279,6 +7045,10 @@ \section{techmap -- generic technology mapper} When a parameter with this name exists, it will be set to the type name of the cell that matches the module. + _TECHMAP_CELLNAME_ + When a parameter with this name exists, it will be set to the name + of the cell that matches the module. + _TECHMAP_CONSTMSK__ _TECHMAP_CONSTVAL__ When this pair of parameters is available in a module for a port, then @@ -6404,12 +7174,12 @@ \section{test\_cell -- automatically test the implementation of a cell type} -s {positive_integer} use this value as rng seed value (default = unix time). - -f {ilang_file} - don't generate circuits. instead load the specified ilang file. + -f {rtlil_file} + don't generate circuits. instead load the specified RTLIL file. -w {filename_prefix} don't test anything. just generate the circuits and write them - to ilang files with the specified prefix + to RTLIL files with the specified prefix -map {filename} pass this option to techmap. @@ -6546,9 +7316,30 @@ \section{verific -- load Verilog and VHDL designs using Verific} Like -sv, but define FORMAL instead of SYNTHESIS. - verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} .. + verific {-f|-F} + +Load and execute the specified command file. + +Command file parser supports following commands: + +define - defines macro + -u - upper case all identifier (makes Verilog parser case insensitive) + -v - register library name (file) + -y - register library name (directory) + +incdir - specify include dir + +libext - specify library extension + +liborder - add library in ordered list + +librescan - unresolved modules will be always searched starting with the first + library specified by -y/-v options. + -f/-file - nested -f option + -F - nested -F option -Load the specified VHDL files into Verific. + parse mode: + -ams + +systemverilogext + +v2k + +verilog1995ext + +verilog2001ext + -sverilog verific [-work ] {-sv|-vhdl|...} @@ -6655,8 +7446,64 @@ \section{verific -- load Verilog and VHDL designs using Verific} Dump the Verific netlist as a verilog file. + verific [-work ] -pp [options] [].. + +Pretty print design (or just module) to the specified file from the +specified library. (default library when -work is not present: "work") + +Pretty print options: + + -verilog + Save output for Verilog/SystemVerilog design modules (default). + + -vhdl + Save output for VHDL design units. + + + verific -app .. + +Execute YosysHQ formal application on loaded Verilog files. + +Application options: + + -module + Run formal application only on specified module. + + -blacklist + Do not run application on modules from files that match the filename + or filename and line number if provided in such format. + Parameter can also contain comma separated list of file locations. + + -blfile + Do not run application on locations specified in file, they can represent filename + or filename and location in file. + +Applications: + + WARNING: Applications only available in commercial build. + + + verific -template .. + +Generate template for specified top module of loaded design. + +Template options: + + -out + Specifies output file for generated template, by default output is stdout + + -chparam name value + Generate template using this parameter value. Otherwise default parameter + values will be used for templat generate functionality. This option + can be specified multiple times to override multiple parameters. + String values must be passed in double quotes ("). + +Templates: + + WARNING: Templates only available in commercial build. + Use YosysHQ Tabby CAD Suite if you need Yosys+Verific. -https://www.yosyshq.com/\n"); +https://www.yosyshq.com/ Contact office@yosyshq.com for free evaluation binaries of YosysHQ Tabby CAD Suite. @@ -6858,6 +7705,9 @@ \section{write\_btor -- write design to BTOR file} -i Create additional info file with auxiliary information + + -x + Output symbols for internal netnames (starting with '$') \end{lstlisting} \section{write\_cxxrtl -- convert design to C++ RTL simulation} @@ -6865,25 +7715,189 @@ \section{write\_cxxrtl -- convert design to C++ RTL simulation} \begin{lstlisting}[numbers=left,frame=single] write_cxxrtl [options] [filename] -Write C++ code for simulating the design. The generated code requires a driver; -the following simple driver is provided as an example: +Write C++ code that simulates the design. The generated code requires a driver +that instantiates the design, toggles its clock, and interacts with its ports. + +The following driver may be used as an example for a design with a single clock +driving rising edge triggered flip-flops: #include "top.cc" int main() { cxxrtl_design::p_top top; + top.step(); while (1) { - top.p_clk.next = value<1> {1u}; + /* user logic */ + top.p_clk.set(false); top.step(); - top.p_clk.next = value<1> {0u}; + top.p_clk.set(true); top.step(); } } +Note that CXXRTL simulations, just like the hardware they are simulating, are +subject to race conditions. If, in the example above, the user logic would run +simultaneously with the rising edge of the clock, the design would malfunction. + +This backend supports replacing parts of the design with black boxes implemented +in C++. If a module marked as a CXXRTL black box, its implementation is ignored, +and the generated code consists only of an interface and a factory function. +The driver must implement the factory function that creates an implementation of +the black box, taking into account the parameters it is instantiated with. + +For example, the following Verilog code defines a CXXRTL black box interface for +a synchronous debug sink: + + (* cxxrtl_blackbox *) + module debug(...); + (* cxxrtl_edge = "p" *) input clk; + input en; + input [7:0] i_data; + (* cxxrtl_sync *) output [7:0] o_data; + endmodule + +For this HDL interface, this backend will generate the following C++ interface: + + struct bb_p_debug : public module { + value<1> p_clk; + bool posedge_p_clk() const { /* ... */ } + value<1> p_en; + value<8> p_i_data; + wire<8> p_o_data; + + bool eval() override; + bool commit() override; + + static std::unique_ptr + create(std::string name, metadata_map parameters, metadata_map attributes); + }; + +The `create' function must be implemented by the driver. For example, it could +always provide an implementation logging the values to standard error stream: + + namespace cxxrtl_design { + + struct stderr_debug : public bb_p_debug { + bool eval() override { + if (posedge_p_clk() && p_en) + fprintf(stderr, "debug: %02x\n", p_i_data.data[0]); + p_o_data.next = p_i_data; + return bb_p_debug::eval(); + } + }; + + std::unique_ptr + bb_p_debug::create(std::string name, cxxrtl::metadata_map parameters, + cxxrtl::metadata_map attributes) { + return std::make_unique(); + } + + } + +For complex applications of black boxes, it is possible to parameterize their +port widths. For example, the following Verilog code defines a CXXRTL black box +interface for a configurable width debug sink: + + (* cxxrtl_blackbox, cxxrtl_template = "WIDTH" *) + module debug(...); + parameter WIDTH = 8; + (* cxxrtl_edge = "p" *) input clk; + input en; + (* cxxrtl_width = "WIDTH" *) input [WIDTH - 1:0] i_data; + (* cxxrtl_width = "WIDTH" *) output [WIDTH - 1:0] o_data; + endmodule + +For this parametric HDL interface, this backend will generate the following C++ +interface (only the differences are shown): + + template + struct bb_p_debug : public module { + // ... + value p_i_data; + wire p_o_data; + // ... + static std::unique_ptr> + create(std::string name, metadata_map parameters, metadata_map attributes); + }; + +The `create' function must be implemented by the driver, specialized for every +possible combination of template parameters. (Specialization is necessary to +enable separate compilation of generated code and black box implementations.) + + template + struct stderr_debug : public bb_p_debug { + // ... + }; + + template<> + std::unique_ptr> + bb_p_debug<8>::create(std::string name, cxxrtl::metadata_map parameters, + cxxrtl::metadata_map attributes) { + return std::make_unique>(); + } + +The following attributes are recognized by this backend: + + cxxrtl_blackbox + only valid on modules. if specified, the module contents are ignored, + and the generated code includes only the module interface and a factory + function, which will be called to instantiate the module. + + cxxrtl_edge + only valid on inputs of black boxes. must be one of "p", "n", "a". + if specified on signal `clk`, the generated code includes edge detectors + `posedge_p_clk()` (if "p"), `negedge_p_clk()` (if "n"), or both (if + "a"), simplifying implementation of clocked black boxes. + + cxxrtl_template + only valid on black boxes. must contain a space separated sequence of + identifiers that have a corresponding black box parameters. for each + of them, the generated code includes a `size_t` template parameter. + + cxxrtl_width + only valid on ports of black boxes. must be a constant expression, which + is directly inserted into generated code. + + cxxrtl_comb, cxxrtl_sync + only valid on outputs of black boxes. if specified, indicates that every + bit of the output port is driven, correspondingly, by combinatorial or + synchronous logic. this knowledge is used for scheduling optimizations. + if neither is specified, the output will be pessimistically treated as + driven by both combinatorial and synchronous logic. + The following options are supported by this backend: + -print-wire-types, -print-debug-wire-types + enable additional debug logging, for pass developers. + + -header + generate separate interface (.h) and implementation (.cc) files. + if specified, the backend must be called with a filename, and filename + of the interface is derived from filename of the implementation. + otherwise, interface and implementation are generated together. + + -namespace + place the generated code into namespace . if not specified, + "cxxrtl_design" is used. + + -nohierarchy + use design hierarchy as-is. in most designs, a top module should be + present as it is exposed through the C API and has unbuffered outputs + for improved performance; it will be determined automatically if absent. + + -noflatten + don't flatten the design. fully flattened designs can evaluate within + one delta cycle if they have no combinatorial feedback. + note that the debug interface and waveform dumps use full hierarchical + names for all wires even in flattened designs. + + -noproc + don't convert processes to netlists. in most designs, converting + processes significantly improves evaluation performance at the cost of + slight increase in compilation time. + -O - set the optimization level. the default is -O5. higher optimization + set the optimization level. the default is -O6. higher optimization levels dramatically decrease compile and run time, and highest level possible for a design should be used. @@ -6891,19 +7905,45 @@ \section{write\_cxxrtl -- convert design to C++ RTL simulation} no optimization. -O1 - elide internal wires if possible. + unbuffer internal wires if possible. -O2 like -O1, and localize internal wires if possible. -O3 - like -O2, and elide public wires not marked (*keep*) if possible. + like -O2, and inline internal wires if possible. -O4 - like -O3, and localize public wires not marked (*keep*) if possible. + like -O3, and unbuffer public wires not marked (*keep*) if possible. -O5 - like -O4, and run `splitnets -driver; opt_clean -purge` first. + like -O4, and localize public wires not marked (*keep*) if possible. + + -O6 + like -O5, and inline public wires not marked (*keep*) if possible. + + -g + set the debug level. the default is -g4. higher debug levels provide + more visibility and generate more code, but do not pessimize evaluation. + + -g0 + no debug information. the C API is disabled. + + -g1 + include bare minimum of debug information necessary to access all design + state. the C API is enabled. + + -g2 + like -g1, but include debug information for all public wires that are + directly accessible through the C++ interface. + + -g3 + like -g2, and include debug information for public wires that are tied + to a constant or another public wire. + + -g4 + like -g3, and compute debug information on demand for all public wires + that were optimized out. \end{lstlisting} \section{write\_edif -- write design to EDIF netlist file} @@ -6928,6 +7968,9 @@ \section{write\_edif -- write design to EDIF netlist file} -attrprop create EDIF properties for cell attributes + -keep + create extra KEEP nets by allowing a cell to drive multiple nets. + -pvector {par|bra|ang} sets the delimiting character for module port rename clauses to parentheses, square brackets, or angle brackets. @@ -6966,16 +8009,10 @@ \section{write\_firrtl -- write design to a FIRRTL file} pmuxtree \end{lstlisting} -\section{write\_ilang -- write design to ilang file} +\section{write\_ilang -- (deprecated) alias of write\_rtlil} \label{cmd:write_ilang} \begin{lstlisting}[numbers=left,frame=single] - write_ilang [filename] - -Write the current design to an 'ilang' file. (ilang is a text representation -of a design in yosys's internal format.) - - -selected - only write selected parts of the design. +See `help write_rtlil`. \end{lstlisting} \section{write\_intersynth -- write design to InterSynth netlist file} @@ -6990,7 +8027,7 @@ \section{write\_intersynth -- write design to InterSynth netlist file} do not generate celltypes and conntypes commands. i.e. just output the netlists. this is used for postsilicon synthesis. - -lib + -lib Use the specified library file for determining whether cell ports are inputs or outputs. This option can be used multiple times to specify more than one library. @@ -7020,8 +8057,17 @@ \section{write\_json -- write design to a JSON file} The general syntax of the JSON output created by this command is as follows: { + "creator": "Yosys ", "modules": { : { + "attributes": { + : , + ... + }, + "parameter_default_values": { + : , + ... + }, "ports": { : , ... @@ -7030,6 +8076,10 @@ \section{write\_json -- write design to a JSON file} : , ... }, + "memories": { + : , + ... + }, "netnames": { : , ... @@ -7046,13 +8096,16 @@ \section{write\_json -- write design to a JSON file} { "direction": <"input" | "output" | "inout">, "bits": + "offset": + "upto": <1 if the port bit indexing is MSB-first> } -And is: +The "offset" and "upto" fields are skipped if their value would be 0.They don't affect connection semantics, and are only used to preserve originalHDL bit indexing.And is: { "hide_name": <1 | 0>, "type": , + "model": , "parameters": { : , ... @@ -7071,11 +8124,26 @@ \section{write\_json -- write design to a JSON file} }, } +And is: + + { + "hide_name": <1 | 0>, + "attributes": { + : , + ... + }, + "width": + "start_offset": + "size": + } + And is: { "hide_name": <1 | 0>, "bits": + "offset": + "upto": <1 if the port bit indexing is MSB-first> } The "hide_name" fields are set to 1 when the name of this cell or net is @@ -7102,8 +8170,13 @@ \section{write\_json -- write design to a JSON file} Translates to the following JSON output: { + "creator": "Yosys 0.9+2406 (git sha1 fb1168d8, clang 9.0.1 -fPIC -Os)", "modules": { "test": { + "attributes": { + "cells_not_processed": "00000000000000000000000000000001", + "src": "test.v:1.1-4.10" + }, "ports": { "x": { "direction": "input", @@ -7119,33 +8192,34 @@ \section{write\_json -- write design to a JSON file} "hide_name": 0, "type": "foo", "parameters": { - "Q": 1337, - "P": 42 + "P": "00000000000000000000000000101010", + "Q": "00000000000000000000010100111001" }, "attributes": { - "keep": 1, - "src": "test.v:2" + "keep": "00000000000000000000000000000001", + "module_not_derived": "00000000000000000000000000000001", + "src": "test.v:3.1-3.55" }, "connections": { - "C": [ 2, 2, 2, 2, "0", "1", "0", "1" ], + "A": [ 3, 2 ], "B": [ 2, 3 ], - "A": [ 3, 2 ] + "C": [ 2, 2, 2, 2, "0", "1", "0", "1" ] } } }, "netnames": { - "y": { + "x": { "hide_name": 0, - "bits": [ 3 ], + "bits": [ 2 ], "attributes": { - "src": "test.v:1" + "src": "test.v:1.19-1.20" } }, - "x": { + "y": { "hide_name": 0, - "bits": [ 2 ], + "bits": [ 3 ], "attributes": { - "src": "test.v:1" + "src": "test.v:1.22-1.23" } } } @@ -7211,6 +8285,18 @@ \section{write\_json -- write design to a JSON file} format. A program processing this format must ignore all unknown fields. \end{lstlisting} +\section{write\_rtlil -- write design to RTLIL file} +\label{cmd:write_rtlil} +\begin{lstlisting}[numbers=left,frame=single] + write_rtlil [filename] + +Write the current design to an RTLIL file. (RTLIL is a text representation +of a design in yosys's internal format.) + + -selected + only write selected parts of the design. +\end{lstlisting} + \section{write\_simplec -- convert design to simple C code} \label{cmd:write_simplec} \begin{lstlisting}[numbers=left,frame=single] @@ -7335,8 +8421,12 @@ \section{write\_smt2 -- write design to SMT-LIBv2 file} use the given template file. the line containing only the token '%%' is replaced with the regular output of this command. + -solver-option