From 85f1c2dcbe1ebd3fa609f2a9a558810dfcc8484c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 29 Jun 2019 21:42:20 -0700 Subject: Cleanup SRL inference/make more consistent --- techlibs/xilinx/cells_map.v | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 9a316fc96..89671c0fc 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -56,7 +56,6 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o localparam [DEPTH-1:0] INIT_R = brev(INIT); parameter _TECHMAP_CONSTMSK_L_ = 0; - parameter _TECHMAP_CONSTVAL_L_ = 0; wire CE; generate @@ -129,26 +128,33 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o MUXF8 fpga_mux_2 (.O(Q), .I0(T7), .I1(T8), .S(L[6])); end end - else if (DEPTH <= 129 && ~&_TECHMAP_CONSTMSK_L_) begin - // Handle cases where fixed-length depth is - // just 1 over a convenient value - \$__XILINX_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q)); + // For fixed length, if just 1 over a convenient value, decompose + else if (DEPTH <= 129 && &_TECHMAP_CONSTMSK_L_) begin + wire T; + \$__XILINX_SHREG_ #(.DEPTH(DEPTH-1), .INIT(INIT[DEPTH-1:1]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(D), .L({32{1'b1}}), .E(E), .Q(T)); + \$__XILINX_SHREG_ #(.DEPTH(1), .INIT(INIT[0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(T), .L(L), .E(E), .Q(Q)); end + // For variable length, if just 1 over a convenient value, then bump up one more + else if (DEPTH < 129 && ~&_TECHMAP_CONSTMSK_L_) + \$__XILINX_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q)); else begin - localparam lower_clog2 = $clog2((DEPTH+1)/2); - localparam lower_depth = 2 ** lower_clog2; - wire T0, T1, T2, T3; - if (&_TECHMAP_CONSTMSK_L_) begin - \$__XILINX_SHREG_ #(.DEPTH(lower_depth), .INIT(INIT[DEPTH-1:DEPTH-lower_depth]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_0 (.C(C), .D(D), .L(lower_depth-1), .E(E), .Q(T0)); - \$__XILINX_SHREG_ #(.DEPTH(DEPTH-lower_depth), .INIT(INIT[DEPTH-lower_depth-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T0), .L(DEPTH-lower_depth-1), .E(E), .Q(Q), .SO(T3)); - end - else begin - \$__XILINX_SHREG_ #(.DEPTH(lower_depth), .INIT(INIT[DEPTH-1:DEPTH-lower_depth]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_0 (.C(C), .D(D), .L(L[lower_clog2-1:0]), .E(E), .Q(T0), .SO(T1)); - \$__XILINX_SHREG_ #(.DEPTH(DEPTH-lower_depth), .INIT(INIT[DEPTH-lower_depth-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T1), .L(L[lower_clog2-1:0]), .E(E), .Q(T2), .SO(T3)); - assign Q = L[lower_clog2] ? T2 : T0; - end - if (DEPTH == 2 * lower_depth) - assign SO = T3; + localparam depth0 = 128; + localparam num_srl128 = DEPTH / depth0; + localparam depthN = DEPTH % depth0; + wire [num_srl128 + (depthN > 0 ? 1 : 0) - 1:0] T; + wire [num_srl128 + (depthN > 0 ? 1 : 0) :0] S; + assign S[0] = D; + genvar i; + for (i = 0; i < num_srl128; i++) + \$__XILINX_SHREG_ #(.DEPTH(depth0), .INIT(INIT[DEPTH-1-i*depth0-:depth0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(S[i]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[i]), .SO(S[i+1])); + + if (depthN > 0) + \$__XILINX_SHREG_ #(.DEPTH(depthN), .INIT(INIT[depthN-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(S[num_srl128]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[num_srl128])); + + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T[num_srl128 + (depthN > 0 ? 1 : 0) - 1]; + else + assign Q = T[L[DEPTH-1:$clog2(depth0)]]; end endgenerate endmodule -- cgit v1.2.3 From c58998a7d2c1066ea28cabe9bc6e1e52bb6668f0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 10:48:10 -0700 Subject: atoi -> stoi as per @daveshah1 --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 0a30848aa..c18c3918f 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -194,7 +194,7 @@ struct SynthXilinxPass : public ScriptPass continue; } if (args[argidx] == "-widemux" && argidx+1 < args.size()) { - widemux = atoi(args[++argidx].c_str()); + widemux = std::stoi(args[++argidx]); continue; } if (args[argidx] == "-abc9") { -- cgit v1.2.3 From dbe1326573e878f4f9d4fc80ce1afcd0f7d84ec6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 11:08:20 -0700 Subject: Parametric muxcover costs as per @daveshah1 --- techlibs/xilinx/synth_xilinx.cc | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index c18c3918f..f43923afb 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -280,23 +280,21 @@ struct SynthXilinxPass : public ScriptPass } else if (widemux > 0) { run("simplemap t:$mux"); - std::string muxcover_args = " -nodecode"; + constexpr int cost_mux2 = 100; + std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { - // NB: Cost of mux2 is 100; mux8 should cost between 3 and 4 - // of those so that 4:1 muxes and below are implemented - // out of mux2s - case 5: muxcover_args += " -mux8=350 -mux16=400"; break; - case 6: muxcover_args += " -mux8=450 -mux16=500"; break; - case 7: muxcover_args += " -mux8=550 -mux16=600"; break; - case 8: muxcover_args += " -mux8=650 -mux16=700"; break; - case 9: muxcover_args += " -mux16=750"; break; - case 10: muxcover_args += " -mux16=850"; break; - case 11: muxcover_args += " -mux16=950"; break; - case 12: muxcover_args += " -mux16=1050"; break; - case 13: muxcover_args += " -mux16=1150"; break; - case 14: muxcover_args += " -mux16=1250"; break; - case 15: muxcover_args += " -mux16=1350"; break; - default: muxcover_args += " -mux16=1450"; break; + case 5: + case 6: + case 7: + case 8: muxcover_args += stringf(" -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + default: muxcover_args += stringf(" -mux16=%d", cost_mux2*(widemux-1)-1); break; } run("muxcover " + muxcover_args); } -- cgit v1.2.3 From 0944acf3affd8c6b161a2381b37eed3931c801a5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 11:29:21 -0700 Subject: synth_xilinx -widemux=2 is minimum now --- techlibs/xilinx/synth_xilinx.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index f43923afb..4f597de4d 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -79,7 +79,7 @@ struct SynthXilinxPass : public ScriptPass log("\n"); log(" -widemux \n"); log(" enable inference of hard multiplexer resources (MuxFx) for muxes at or\n"); - log(" above this number of inputs (minimum value 5).\n"); + log(" above this number of inputs (minimum value 2).\n"); log(" default: 0 (no inference)\n"); log("\n"); log(" -run :\n"); @@ -208,8 +208,8 @@ struct SynthXilinxPass : public ScriptPass if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s") log_cmd_error("Invalid Xilinx -family setting: %s\n", family.c_str()); - if (widemux != 0 && widemux < 5) - log_cmd_error("-widemux value must be 0 or >= 5.\n"); + if (widemux != 0 && widemux < 2) + log_cmd_error("-widemux value must be 0 or >= 2.\n"); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); @@ -252,7 +252,7 @@ struct SynthXilinxPass : public ScriptPass // so attempt to convert $pmux-es to the former // Also: wide multiplexer inference benefits from this too if (!(nosrl && widemux == 0) || help_mode) - run("pmux2shiftx", "(skip if '-nosrl' and '-widemux' < 5)"); + run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); } if (check_label("bram", "(skip if '-nobram')")) { @@ -283,6 +283,9 @@ struct SynthXilinxPass : public ScriptPass constexpr int cost_mux2 = 100; std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { + case 2: + case 3: + case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; case 5: case 6: case 7: -- cgit v1.2.3 From 895ca501734d2f33b61f118a288832b55a366bd2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 12:03:38 -0700 Subject: Fixes for 2:1 muxes --- techlibs/xilinx/cells_map.v | 33 +++++++++++++++++++++++++++++---- techlibs/xilinx/synth_xilinx.cc | 2 +- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 27e860801..e12dd2833 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -193,6 +193,14 @@ module \$__XILINX_SHIFTX (A, B, Y); else if (A_WIDTH < `MIN_MUX_INPUTS) begin wire _TECHMAP_FAIL_ = 1; end + else if (A_WIDTH == 2) begin + MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); + end + else if (A_WIDTH <= 2 ** 2) begin + wire [4-1:0] T; + assign T = {{(4-A_WIDTH){1'bx}}, A}; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(T[0]), .I1(T[1]), .I2(T[2]), .I3(T[3]), .S0(B[0]), .S1(B[1]), .O(Y)); + end else if (A_WIDTH <= 2 ** 3) begin localparam a_width0 = 2 ** 2; localparam a_widthN = A_WIDTH - a_width0; @@ -251,15 +259,32 @@ module _90__XILINX_SHIFTX (A, B, Y); \$shiftx #(.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)); endmodule +module \$_MUX_ (A, B, S, Y); + input A, B, S; + output Y; + generate + if (`MIN_MUX_INPUTS == 2) + \$__XILINX_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(2), .B_WIDTH(1), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({B,A}), .B(S), .Y(Y)); + else + wire _TECHMAP_FAIL_ = 1; + endgenerate +endmodule + +module \$_MUX4_ (A, B, C, D, S, T, Y); + input A, B, C, D, S, T; + output Y; + \$__XILINX_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({D,C,B,A}), .B({T,S}), .Y(Y)); +endmodule + 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; + input A, B, C, D, E, F, G, H, S, T, U; + output Y; \$__XILINX_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(3), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({H,G,F,E,D,C,B,A}), .B({U,T,S}), .Y(Y)); endmodule module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y); -input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V; -output Y; + input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V; + output Y; \$__XILINX_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(16), .B_WIDTH(4), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A}), .B({V,U,T,S}), .Y(Y)); endmodule `endif diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 4f597de4d..62bfaaaf1 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -283,7 +283,7 @@ struct SynthXilinxPass : public ScriptPass constexpr int cost_mux2 = 100; std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { - case 2: + case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break; case 3: case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; case 5: -- cgit v1.2.3 From baf47e496f35cb90e5c7181079d38c04907c42da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 17:04:39 -0700 Subject: Add synth_xilinx -widemux recommended value --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 62bfaaaf1..7836f9f3e 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -79,7 +79,7 @@ struct SynthXilinxPass : public ScriptPass log("\n"); log(" -widemux \n"); log(" enable inference of hard multiplexer resources (MuxFx) for muxes at or\n"); - log(" above this number of inputs (minimum value 2).\n"); + log(" above this number of inputs (minimum value 2, recommended value >= 5).\n"); log(" default: 0 (no inference)\n"); log("\n"); log(" -run :\n"); -- cgit v1.2.3 From 78914e2e0e0a92e65cb1594c4858bc2225322ade Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 17:06:22 -0700 Subject: Capitalisation --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 7836f9f3e..b404dc8e7 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -78,7 +78,7 @@ struct SynthXilinxPass : public ScriptPass log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n"); log("\n"); log(" -widemux \n"); - log(" enable inference of hard multiplexer resources (MuxFx) for muxes at or\n"); + log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n"); log(" above this number of inputs (minimum value 2, recommended value >= 5).\n"); log(" default: 0 (no inference)\n"); log("\n"); -- cgit v1.2.3 From 3f86407cc32e20a8885c73f959082c5c0449bf9a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 17:06:35 -0700 Subject: Map $__XILINX_SHIFTX in a more balanced manner --- techlibs/xilinx/cells_map.v | 85 ++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 36 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index e12dd2833..d48a3f15c 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -197,49 +197,62 @@ module \$__XILINX_SHIFTX (A, B, Y); MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); end else if (A_WIDTH <= 2 ** 2) begin - wire [4-1:0] T; - assign T = {{(4-A_WIDTH){1'bx}}, A}; - \$__XILINX_MUXF78 fpga_hard_mux (.I0(T[0]), .I1(T[1]), .I2(T[2]), .I3(T[3]), .S0(B[0]), .S1(B[1]), .O(Y)); + wire [4-1:0] Ax = {{(4-A_WIDTH){A[A_WIDTH-1]}}, A}; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[1]), .I2(Ax[2]), .I3(Ax[3]), .S0(B[0]), .S1(B[1]), .O(Y)); end else if (A_WIDTH <= 2 ** 3) begin - localparam a_width0 = 2 ** 2; - localparam a_widthN = A_WIDTH - a_width0; - wire T0, T1; - \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(2), .Y_WIDTH(Y_WIDTH)) fpga_soft_mux (.A(A[a_width0-1:0]), .B(B[2-1:0]), .Y(T0)); - if (a_widthN > 1) - \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_soft_mux_last (.A(A[A_WIDTH-1:a_width0]), .B(B[$clog2(a_widthN)-1:0]), .Y(T1)); - else - assign T1 = A[A_WIDTH-1]; - MUXF7 fpga_hard_mux (.I0(T0), .I1(T1), .S(B[2]), .O(Y)); + // Rather than extend with 1'bx which gets flattened to 1'b0 + // causing the "don't care" state to get lost, extend with MSB + // so that we can recognise again later when mapping MUXF78 + wire [8-1:0] Ax = {{(8-A_WIDTH){A[A_WIDTH-1]}}, A}; + wire T0 = B[0] ? Ax[1] : Ax[0]; + wire T1 = B[0] ? Ax[3] : Ax[2]; + wire T2 = B[0] ? Ax[5] : Ax[4]; + wire T3 = B[0] ? Ax[7] : Ax[6]; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T1), .I2(T2), .I3(T3), .S0(B[1]), .S1(B[2]), .O(Y)); end else if (A_WIDTH <= 2 ** 4) begin - localparam a_width0 = 2 ** 2; - localparam num_mux8 = A_WIDTH / a_width0; - localparam a_widthN = A_WIDTH % a_width0; - wire [a_width0-1:0] T; - for (i = 0; i < a_width0; i++) - if (i < num_mux8) - \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(2), .Y_WIDTH(Y_WIDTH)) fpga_mux (.A(A[i*a_width0+:a_width0]), .B(B[2-1:0]), .Y(T[i])); - else if (i == num_mux8 && a_widthN > 1) - \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_mux_last (.A(A[A_WIDTH-1-:a_widthN]), .B(B[$clog2(a_widthN)-1:0]), .Y(T[i])); - else - assign T[i] = A[A_WIDTH-1]; - \$__XILINX_MUXF78 fpga_hard_mux (.I0(T[0]), .I1(T[1]), .I2(T[2]), .I3(T[3]), .S0(B[2]), .S1(B[3]), .O(Y)); + // Rather than extend with 1'bx which gets flattened to 1'b0 + // causing the "don't care" state to get lost, extend with MSB + // so that we can recognise again later when mapping MUXF78 + wire [16-1:0] Ax = {{(16-A_WIDTH){A[A_WIDTH-1]}}, A}; + wire T0 = B[1] ? B[0] ? Ax[ 3] : Ax[ 2] + : B[0] ? Ax[ 1] : Ax[ 0]; + wire T1 = B[1] ? B[0] ? Ax[ 7] : Ax[ 6] + : B[0] ? Ax[ 5] : Ax[ 4]; + wire T2 = B[1] ? B[0] ? Ax[11] : Ax[10] + : B[0] ? Ax[ 9] : Ax[ 8]; + wire T3 = B[1] ? B[0] ? Ax[15] : Ax[14] + : B[0] ? Ax[13] : Ax[12]; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T1), .I2(T2), .I3(T3), .S0(B[2]), .S1(B[3]), .O(Y)); end else begin - localparam a_width0 = 2 ** 4; - localparam num_mux16 = A_WIDTH / a_width0; - localparam a_widthN = A_WIDTH % a_width0; - wire [num_mux16 + (a_widthN > 0 ? 1 : 0) - 1:0] T; + localparam num_mux16 = (A_WIDTH+15) / 16; + localparam clog2_num_mux16 = $clog2(num_mux16); + wire [num_mux16-1:0] T; + wire [num_mux16*16-1:0] Ax = {{(num_mux16*16-A_WIDTH){1'bx}}, A}; for (i = 0; i < num_mux16; i++) - \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(4), .Y_WIDTH(Y_WIDTH)) fpga_soft_mux (.A(A[i*a_width0+:a_width0]), .B(B[4-1:0]), .Y(T[i])); - if (a_widthN > 0) begin - if (a_widthN > 1) - \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_soft_mux_last (.A(A[A_WIDTH-1-:a_widthN]), .B(B[$clog2(a_widthN)-1:0]), .Y(T[num_mux16])); - else - assign T[num_mux16] = A[A_WIDTH-1]; - end - \$__XILINX_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(num_mux16 + (a_widthN > 0 ? 1 : 0)), .B_WIDTH(B_WIDTH-4), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(T), .B(B[B_WIDTH-1:4]), .Y(Y)); + \$__XILINX_SHIFTX #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(16), + .B_WIDTH(4), + .Y_WIDTH(Y_WIDTH) + ) fpga_mux ( + .A(Ax[i*16+:16]), + .B(B[3:0]), + .Y(T[i]) + ); + \$__XILINX_SHIFTX #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(num_mux16), + .B_WIDTH(clog2_num_mux16), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(T), + .B(B[B_WIDTH-1-:clog2_num_mux16]), + .Y(Y)); end endgenerate endmodule -- cgit v1.2.3 From 7f964859ec99500e471853f5914b6e5b7c35a031 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 19:23:24 -0700 Subject: synth_xilinx to call "synth -run coarse" with "-keepdc" --- techlibs/xilinx/synth_xilinx.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b404dc8e7..15a37a439 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -240,9 +240,9 @@ struct SynthXilinxPass : public ScriptPass if (check_label("coarse")) { if (help_mode) - run("synth -run coarse [-flatten]", "(with '-flatten')"); + run("synth -keepdc -run coarse [-flatten]", "(with '-flatten')"); else - run("synth -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); + run("synth -keepdc -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); if (widemux > 0 || help_mode) run("muxpack", " ('-widemux' only)"); -- cgit v1.2.3 From de404535538fe4d2548be82724515961e6e92519 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 22:56:19 -0700 Subject: Reword --- techlibs/xilinx/cells_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index d48a3f15c..63095880e 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -202,7 +202,7 @@ module \$__XILINX_SHIFTX (A, B, Y); end else if (A_WIDTH <= 2 ** 3) begin // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" state to get lost, extend with MSB + // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 wire [8-1:0] Ax = {{(8-A_WIDTH){A[A_WIDTH-1]}}, A}; wire T0 = B[0] ? Ax[1] : Ax[0]; @@ -213,7 +213,7 @@ module \$__XILINX_SHIFTX (A, B, Y); end else if (A_WIDTH <= 2 ** 4) begin // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" state to get lost, extend with MSB + // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 wire [16-1:0] Ax = {{(16-A_WIDTH){A[A_WIDTH-1]}}, A}; wire T0 = B[1] ? B[0] ? Ax[ 3] : Ax[ 2] -- cgit v1.2.3 From 939a225f921efc4276121fe957f545a98d252fa0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 23:02:57 -0700 Subject: Less thinking --- techlibs/xilinx/cells_map.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 63095880e..7c67c7a79 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -196,11 +196,11 @@ module \$__XILINX_SHIFTX (A, B, Y); else if (A_WIDTH == 2) begin MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); end - else if (A_WIDTH <= 2 ** 2) begin + else if (A_WIDTH <= 4) begin wire [4-1:0] Ax = {{(4-A_WIDTH){A[A_WIDTH-1]}}, A}; \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[1]), .I2(Ax[2]), .I3(Ax[3]), .S0(B[0]), .S1(B[1]), .O(Y)); end - else if (A_WIDTH <= 2 ** 3) begin + else if (A_WIDTH <= 8) begin // Rather than extend with 1'bx which gets flattened to 1'b0 // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 @@ -211,7 +211,7 @@ module \$__XILINX_SHIFTX (A, B, Y); wire T3 = B[0] ? Ax[7] : Ax[6]; \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T1), .I2(T2), .I3(T3), .S0(B[1]), .S1(B[2]), .O(Y)); end - else if (A_WIDTH <= 2 ** 4) begin + else if (A_WIDTH <= 16) begin // Rather than extend with 1'bx which gets flattened to 1'b0 // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 -- cgit v1.2.3 From d4ab43d9403899dcae74a24e71385fd959de98f8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 23:05:48 -0700 Subject: Add one more comment --- techlibs/xilinx/cells_map.v | 3 +++ 1 file changed, 3 insertions(+) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 7c67c7a79..39427cc90 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -197,6 +197,9 @@ module \$__XILINX_SHIFTX (A, B, Y); MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); end else if (A_WIDTH <= 4) begin + // Rather than extend with 1'bx which gets flattened to 1'b0 + // causing the "don't care" status to get lost, extend with MSB + // so that we can recognise again later when mapping MUXF78 wire [4-1:0] Ax = {{(4-A_WIDTH){A[A_WIDTH-1]}}, A}; \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[1]), .I2(Ax[2]), .I3(Ax[3]), .S0(B[0]), .S1(B[1]), .O(Y)); end -- cgit v1.2.3 From 45da3ada7babc8f2b23a8b23ce25430a98e2e58e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 23:49:16 -0700 Subject: Do not call opt -mux_undef (part of -full) before muxcover --- techlibs/xilinx/synth_xilinx.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 15a37a439..6eab74a21 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -270,7 +270,11 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("fine")) { - run("opt -fast -full"); + if (widemux > 0) + run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover + // performs less efficiently + else + run("opt -fast -full"); run("memory_map"); run("dffsr2dff"); run("dff2dffe"); -- cgit v1.2.3 From 6951e3207063f66814e765d7d72e553b8b8eace1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 23:51:13 -0700 Subject: Decompose mux inputs in delay-orientated (rather than area) fashion --- techlibs/xilinx/cells_map.v | 48 ++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 39427cc90..35eea9858 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -200,34 +200,46 @@ module \$__XILINX_SHIFTX (A, B, Y); // Rather than extend with 1'bx which gets flattened to 1'b0 // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 - wire [4-1:0] Ax = {{(4-A_WIDTH){A[A_WIDTH-1]}}, A}; - \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[1]), .I2(Ax[2]), .I3(Ax[3]), .S0(B[0]), .S1(B[1]), .O(Y)); + wire [4-1:0] Ax; + if (A_WIDTH == 4) + assign Ax = A; + else + assign Ax = {A[1-:4-A_WIDTH], A}; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y)); end else if (A_WIDTH <= 8) begin // Rather than extend with 1'bx which gets flattened to 1'b0 // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 - wire [8-1:0] Ax = {{(8-A_WIDTH){A[A_WIDTH-1]}}, A}; - wire T0 = B[0] ? Ax[1] : Ax[0]; - wire T1 = B[0] ? Ax[3] : Ax[2]; - wire T2 = B[0] ? Ax[5] : Ax[4]; - wire T3 = B[0] ? Ax[7] : Ax[6]; - \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T1), .I2(T2), .I3(T3), .S0(B[1]), .S1(B[2]), .O(Y)); + wire [8-1:0] Ax; + if (A_WIDTH == 8) + assign Ax = A; + else + assign Ax = {A[3-:8-A_WIDTH], A}; + wire T0 = B[2] ? Ax[4] : Ax[0]; + wire T1 = B[2] ? Ax[5] : Ax[1]; + wire T2 = B[2] ? Ax[6] : Ax[2]; + wire T3 = B[2] ? Ax[7] : Ax[3]; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y)); end else if (A_WIDTH <= 16) begin // Rather than extend with 1'bx which gets flattened to 1'b0 // causing the "don't care" status to get lost, extend with MSB // so that we can recognise again later when mapping MUXF78 - wire [16-1:0] Ax = {{(16-A_WIDTH){A[A_WIDTH-1]}}, A}; - wire T0 = B[1] ? B[0] ? Ax[ 3] : Ax[ 2] - : B[0] ? Ax[ 1] : Ax[ 0]; - wire T1 = B[1] ? B[0] ? Ax[ 7] : Ax[ 6] - : B[0] ? Ax[ 5] : Ax[ 4]; - wire T2 = B[1] ? B[0] ? Ax[11] : Ax[10] - : B[0] ? Ax[ 9] : Ax[ 8]; - wire T3 = B[1] ? B[0] ? Ax[15] : Ax[14] - : B[0] ? Ax[13] : Ax[12]; - \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T1), .I2(T2), .I3(T3), .S0(B[2]), .S1(B[3]), .O(Y)); + wire [16-1:0] Ax; + if (A_WIDTH == 16) + assign Ax = A; + else + assign Ax = {A[7-:8-A_WIDTH], A}; + wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4] + : B[3] ? Ax[ 8] : Ax[0]; + wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5] + : B[3] ? Ax[ 9] : Ax[1]; + wire T2 = B[2] ? B[3] ? Ax[14] : Ax[6] + : B[3] ? Ax[10] : Ax[2]; + wire T3 = B[2] ? B[3] ? Ax[15] : Ax[7] + : B[3] ? Ax[11] : Ax[3]; + \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y)); end else begin localparam num_mux16 = (A_WIDTH+15) / 16; -- cgit v1.2.3 From 667199d46013d116bdbeb9be8592a77503a470e2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 09:16:00 -0700 Subject: Fix spacing --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 6eab74a21..abdf7f9cc 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -287,7 +287,7 @@ struct SynthXilinxPass : public ScriptPass constexpr int cost_mux2 = 100; std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { - case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break; + case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break; case 3: case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; case 5: -- cgit v1.2.3 From bc84f7dd10ad44118fd6d800cb7a896069fd223d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 09:22:12 -0700 Subject: Fix spacing --- techlibs/xilinx/synth_xilinx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index abdf7f9cc..2a77ce397 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -270,7 +270,7 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("fine")) { - if (widemux > 0) + if (widemux > 0) run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover // performs less efficiently else -- cgit v1.2.3 From 737340327fd8bae4a3b958d85cb14eecb767ed67 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 10:15:02 -0700 Subject: Revert "synth_xilinx to call "synth -run coarse" with "-keepdc"" This reverts commit 7f964859ec99500e471853f5914b6e5b7c35a031. --- techlibs/xilinx/synth_xilinx.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2a77ce397..8da6df57e 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -240,9 +240,9 @@ struct SynthXilinxPass : public ScriptPass if (check_label("coarse")) { if (help_mode) - run("synth -keepdc -run coarse [-flatten]", "(with '-flatten')"); + run("synth -run coarse [-flatten]", "(with '-flatten')"); else - run("synth -keepdc -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); + run("synth -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); if (widemux > 0 || help_mode) run("muxpack", " ('-widemux' only)"); -- cgit v1.2.3 From c68b9092100280dbc059526a88f9d8e2902ff6a3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 10:21:54 -0700 Subject: synth_xilinx to call commands of synth -coarse directly --- techlibs/xilinx/synth_xilinx.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 8da6df57e..0152af481 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -239,10 +239,25 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("coarse")) { + run("proc"); + if (help_mode || flatten) + run("flatten", "(if -flatten)"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt"); if (help_mode) - run("synth -run coarse [-flatten]", "(with '-flatten')"); + run("wreduce [-keepdc]", "(option for '-widemux')"); else - run("synth -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); + run("wreduce" + std::string(widemux > 0 ? " -keepdc" : "")); + run("peepopt"); + run("opt_clean"); + run("alumacc"); + run("share"); + run("opt"); + run("fsm"); + run("opt -fast"); + run("memory -nomap"); if (widemux > 0 || help_mode) run("muxpack", " ('-widemux' only)"); @@ -253,6 +268,8 @@ struct SynthXilinxPass : public ScriptPass // Also: wide multiplexer inference benefits from this too if (!(nosrl && widemux == 0) || help_mode) run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); + + run("opt_clean"); } if (check_label("bram", "(skip if '-nobram')")) { @@ -344,7 +361,7 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_luts")) { run("opt_expr -mux_undef"); if (help_mode) - run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(skip if 'nowidelut', only for '-retime')"); + run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')"); else if (abc9) { if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); -- cgit v1.2.3 From c8649953431d3789296c4a7c1bd559ec136af6e3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 10:38:07 -0700 Subject: Fix typo and comments --- techlibs/xilinx/cells_map.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index d3f6a60cc..233a56003 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -204,7 +204,7 @@ module \$__XILINX_SHIFTX (A, B, Y); end else if (A_WIDTH <= 4) begin // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSB + // causing the "don't care" status to get lost, extend with MSBs // so that we can recognise again later when mapping MUXF78 wire [4-1:0] Ax; if (A_WIDTH == 4) @@ -215,7 +215,7 @@ module \$__XILINX_SHIFTX (A, B, Y); end else if (A_WIDTH <= 8) begin // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSB + // causing the "don't care" status to get lost, extend with MSBs // so that we can recognise again later when mapping MUXF78 wire [8-1:0] Ax; if (A_WIDTH == 8) @@ -230,13 +230,13 @@ module \$__XILINX_SHIFTX (A, B, Y); end else if (A_WIDTH <= 16) begin // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSB + // causing the "don't care" status to get lost, extend with MSBs // so that we can recognise again later when mapping MUXF78 wire [16-1:0] Ax; if (A_WIDTH == 16) assign Ax = A; else - assign Ax = {A[7-:8-A_WIDTH], A}; + assign Ax = {A[7-:16-A_WIDTH], A}; wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4] : B[3] ? Ax[ 8] : Ax[0]; wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5] -- cgit v1.2.3 From 93522b0ae15466297e45edecf55f7e33c4ebcc1c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 10:59:37 -0700 Subject: Extend during mux decomposition with 1'bx --- techlibs/xilinx/cells_map.v | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 233a56003..e81ff8f53 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -203,25 +203,11 @@ module \$__XILINX_SHIFTX (A, B, Y); MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); end else if (A_WIDTH <= 4) begin - // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSBs - // so that we can recognise again later when mapping MUXF78 - wire [4-1:0] Ax; - if (A_WIDTH == 4) - assign Ax = A; - else - assign Ax = {A[1-:4-A_WIDTH], A}; + wire [4-1:0] Ax = {{{4-A_WIDTH}{1'bx}}, A}; \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y)); end else if (A_WIDTH <= 8) begin - // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSBs - // so that we can recognise again later when mapping MUXF78 - wire [8-1:0] Ax; - if (A_WIDTH == 8) - assign Ax = A; - else - assign Ax = {A[3-:8-A_WIDTH], A}; + wire [8-1:0] Ax = {{{8-A_WIDTH}{1'bx}}, A}; wire T0 = B[2] ? Ax[4] : Ax[0]; wire T1 = B[2] ? Ax[5] : Ax[1]; wire T2 = B[2] ? Ax[6] : Ax[2]; @@ -229,14 +215,7 @@ module \$__XILINX_SHIFTX (A, B, Y); \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y)); end else if (A_WIDTH <= 16) begin - // Rather than extend with 1'bx which gets flattened to 1'b0 - // causing the "don't care" status to get lost, extend with MSBs - // so that we can recognise again later when mapping MUXF78 - wire [16-1:0] Ax; - if (A_WIDTH == 16) - assign Ax = A; - else - assign Ax = {A[7-:16-A_WIDTH], A}; + wire [16-1:0] Ax = {{{16-A_WIDTH}{1'bx}}, A}; wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4] : B[3] ? Ax[ 8] : Ax[0]; wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5] -- cgit v1.2.3 From b1a048a703b12bc02433d8c2c98b4b35cc799979 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 12:35:41 -0700 Subject: Extend using A[1] to preserve don't care --- techlibs/xilinx/cells_map.v | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index e81ff8f53..f20fe253e 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -203,7 +203,15 @@ module \$__XILINX_SHIFTX (A, B, Y); MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); end else if (A_WIDTH <= 4) begin - wire [4-1:0] Ax = {{{4-A_WIDTH}{1'bx}}, A}; + wire [4-1:0] Ax; + if (A_WIDTH == 4) + assign Ax = A; + else + // Rather than extend with 1'bx which gets flattened to 1'b0 + // causing the "don't care" status to get lost, extend with + // the same driver of F7B.I0 so that we can optimise F7B away + // later + assign Ax = {A[1], A}; \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y)); end else if (A_WIDTH <= 8) begin -- cgit v1.2.3 From 5b48b18d29dabfaa3aa51fc4946f14b0ea8954e2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 14:28:54 -0700 Subject: Restore missing techmap -map +/cmp2lut.v with LUT_WIDTH=6 --- techlibs/xilinx/synth_xilinx.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 0152af481..7e10a392a 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -2,6 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf + * (C) 2019 Eddie Hung * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -252,6 +253,7 @@ struct SynthXilinxPass : public ScriptPass run("wreduce" + std::string(widemux > 0 ? " -keepdc" : "")); run("peepopt"); run("opt_clean"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6"); run("alumacc"); run("share"); run("opt"); -- cgit v1.2.3 From c55530b90197302e7c27eb106094fa74a178fc67 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 14:29:58 -0700 Subject: Restore opt_clean back to original place --- techlibs/xilinx/synth_xilinx.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 7e10a392a..c4877c8af 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -260,6 +260,7 @@ struct SynthXilinxPass : public ScriptPass run("fsm"); run("opt -fast"); run("memory -nomap"); + run("opt_clean"); if (widemux > 0 || help_mode) run("muxpack", " ('-widemux' only)"); @@ -270,8 +271,6 @@ struct SynthXilinxPass : public ScriptPass // Also: wide multiplexer inference benefits from this too if (!(nosrl && widemux == 0) || help_mode) run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); - - run("opt_clean"); } if (check_label("bram", "(skip if '-nobram')")) { -- cgit v1.2.3 From e573d024a257a6cf8925784f6f22d192a1f24693 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 21:26:38 -0700 Subject: Call muxpack and pmux2shiftx before cmp2lut --- techlibs/xilinx/synth_xilinx.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index c4877c8af..ef7660288 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -253,14 +253,6 @@ struct SynthXilinxPass : public ScriptPass run("wreduce" + std::string(widemux > 0 ? " -keepdc" : "")); run("peepopt"); run("opt_clean"); - run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6"); - run("alumacc"); - run("share"); - run("opt"); - run("fsm"); - run("opt -fast"); - run("memory -nomap"); - run("opt_clean"); if (widemux > 0 || help_mode) run("muxpack", " ('-widemux' only)"); @@ -269,8 +261,19 @@ struct SynthXilinxPass : public ScriptPass // cells for identifying variable-length shift registers, // so attempt to convert $pmux-es to the former // Also: wide multiplexer inference benefits from this too - if (!(nosrl && widemux == 0) || help_mode) + if (!(nosrl && widemux == 0) || help_mode) { run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); + run("clean", " (skip if '-nosrl' and '-widemux=0')"); + } + + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6"); + run("alumacc"); + run("share"); + run("opt"); + run("fsm"); + run("opt -fast"); + run("memory -nomap"); + run("opt_clean"); } if (check_label("bram", "(skip if '-nobram')")) { -- cgit v1.2.3 From 521971e32ef54fa64474a8ed1c2748572901aaf5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 12:20:04 -0700 Subject: Add some ASCII art explaining mux decomposition --- techlibs/xilinx/cells_map.v | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index f20fe253e..82399be08 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -214,6 +214,27 @@ module \$__XILINX_SHIFTX (A, B, Y); assign Ax = {A[1], A}; \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y)); end + // Note that the following decompositions are 'backwards' in that + // the LSBs are placed on the hard resources, and the soft resources + // are used for MSBs. + // This has the effect of more effectively utilising the hard mux; + // take for example a 5:1 multiplexer, currently this would map as: + // + // A[0] \___ __ A[0] \__ __ + // A[4] / \| \ whereas the more A[1] / \| \ + // A[1] _____| | obvious mapping A[2] \___| | + // A[2] _____| |-- of MSBs to hard A[3] / | |__ + // A[3]______| | resources would A[4] ____| | + // |__/ lead to: 1'bx ____| | + // || |__/ + // || || + // B[1:0] B[1:2] + // + // Expectation would be that the 'forward' mapping (right) is more + // area efficient (consider a 9:1 multiplexer using 2x4:1 multiplexers + // on its I0 and I1 inputs, and A[8] and 1'bx on its I2 and I3 inputs) + // but that the 'backwards' mapping (left) is more delay efficient + // since smaller LUTs are faster than wider ones. else if (A_WIDTH <= 8) begin wire [8-1:0] Ax = {{{8-A_WIDTH}{1'bx}}, A}; wire T0 = B[2] ? Ax[4] : Ax[0]; -- cgit v1.2.3 From 58bb84e5b22ba66310fd54fecdbf5817138a5fd1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 12:32:33 -0700 Subject: Add some spacing --- techlibs/xilinx/cells_map.v | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 82399be08..2eb9fa2c1 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -220,15 +220,15 @@ module \$__XILINX_SHIFTX (A, B, Y); // This has the effect of more effectively utilising the hard mux; // take for example a 5:1 multiplexer, currently this would map as: // - // A[0] \___ __ A[0] \__ __ - // A[4] / \| \ whereas the more A[1] / \| \ - // A[1] _____| | obvious mapping A[2] \___| | - // A[2] _____| |-- of MSBs to hard A[3] / | |__ - // A[3]______| | resources would A[4] ____| | - // |__/ lead to: 1'bx ____| | - // || |__/ - // || || - // B[1:0] B[1:2] + // A[0] \___ __ A[0] \__ __ + // A[4] / \| \ whereas the more A[1] / \| \ + // A[1] _____| | obvious mapping A[2] \___| | + // A[2] _____| |-- of MSBs to hard A[3] / | |__ + // A[3]______| | resources would A[4] ____| | + // |__/ lead to: 1'bx ____| | + // || |__/ + // || || + // B[1:0] B[1:2] // // Expectation would be that the 'forward' mapping (right) is more // area efficient (consider a 9:1 multiplexer using 2x4:1 multiplexers -- cgit v1.2.3 From 6bbd286e033ed25bb49684316a86d6227dec4cd7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 10 Jul 2019 12:47:48 -0700 Subject: Error out if -abc9 and -retime specified --- techlibs/xilinx/synth_xilinx.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'techlibs/xilinx') diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b7c32d2e0..22c4a1a1b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -25,8 +25,8 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define XC7_WIRE_DELAY "300" // Number with which ABC will map a 6-input gate - // to one LUT6 (instead of a LUT5 + LUT2) +#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) struct SynthXilinxPass : public ScriptPass { @@ -195,11 +195,14 @@ struct SynthXilinxPass : public ScriptPass extra_args(args, argidx, design); if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s") - log_cmd_error("Invalid Xilinx -family setting: %s\n", family.c_str()); + log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str()); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + if (abc9 && retime) + log_cmd_error("-retime option not currently compatible with -abc9!\n"); + log_header(design, "Executing SYNTH_XILINX pass.\n"); log_push(); @@ -297,9 +300,9 @@ struct SynthXilinxPass : public ScriptPass if (family != "xc7") log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n"); if (nowidelut) - run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : "")); + run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); else - run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : "")); + run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY)); } else { if (nowidelut) -- cgit v1.2.3