diff options
Diffstat (limited to 'techlibs')
27 files changed, 801 insertions, 184 deletions
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index e41c0fe97..555de9fba 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -75,13 +75,16 @@ struct SynthPass : public ScriptPass 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(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_module, fsm_opts, memory_opts; + string top_module, fsm_opts, memory_opts, abc; bool autotop, flatten, noalumacc, nofsm, noabc, noshare; int lut; @@ -98,6 +101,7 @@ struct SynthPass : public ScriptPass nofsm = false; noabc = false; noshare = false; + abc = "abc"; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -159,6 +163,10 @@ struct SynthPass : public ScriptPass noshare = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } break; } extra_args(args, argidx, design); @@ -166,6 +174,9 @@ struct SynthPass : public ScriptPass if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + if (abc == "abc9" && !lut) + log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)"); + log_header(design, "Executing SYNTH pass.\n"); log_push(); @@ -241,15 +252,15 @@ struct SynthPass : public ScriptPass #ifdef YOSYS_ENABLE_ABC if (help_mode) { - run("abc -fast", " (unless -noabc, unless -lut)"); - run("abc -fast -lut k", "(unless -noabc, if -lut)"); + run(abc + " -fast", " (unless -noabc, unless -lut)"); + run(abc + " -fast -lut k", "(unless -noabc, if -lut)"); } else { if (lut) - run(stringf("abc -fast -lut %d", lut)); + run(stringf("%s -fast -lut %d", abc.c_str(), lut)); else - run("abc -fast"); + run(abc + " -fast"); } run("opt -fast", " (unless -noabc)"); #endif diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 4db087e87..eee3b418f 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -11,6 +11,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.box)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.lut)) + EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk .SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk diff --git a/techlibs/ecp5/abc_5g.box b/techlibs/ecp5/abc_5g.box new file mode 100644 index 000000000..72af6d9cb --- /dev/null +++ b/techlibs/ecp5/abc_5g.box @@ -0,0 +1,36 @@ +# Box 1 : CCU2C (2xCARRY + 2xLUT4) +# Outputs: S0, S1, COUT +# name ID w/b ins outs +CCU2C 1 1 9 3 + +#A0 A1 B0 B1 C0 C1 D0 D1 CIN +379 - 379 - 275 - 141 - 257 +630 379 630 379 526 275 392 141 273 +516 516 516 516 412 412 278 278 43 + +# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram) +# Outputs: DO0, DO1, DO2, DO3, DO4 +# name ID w/b ins outs +TRELLIS_DPR16X4 2 0 14 4 + +#DI0 DI1 DI2 DI3 RAD0 RAD1 RAD2 RAD3 WAD0 WAD1 WAD2 WAD3 WCK WRE +- - - - 141 379 275 379 - - - - - - +- - - - 141 379 275 379 - - - - - - +- - - - 141 379 275 379 - - - - - - +- - - - 141 379 275 379 - - - - - - + +# Box 3 : PFUMX (MUX2) +# Outputs: Z +# name ID w/b ins outs +PFUMX 3 1 3 1 + +#ALUT BLUT C0 +98 98 151 + +# Box 4 : L6MUX21 (MUX2) +# Outputs: Z +# name ID w/b ins outs +L6MUX21 4 1 3 1 + +#D0 D1 SD +140 141 148 diff --git a/techlibs/ecp5/abc_5g.lut b/techlibs/ecp5/abc_5g.lut new file mode 100644 index 000000000..e8aa9b35d --- /dev/null +++ b/techlibs/ecp5/abc_5g.lut @@ -0,0 +1,25 @@ +# ECP5-5G LUT library for ABC +# Note that ECP5 architecture assigns difference +# in LUT input delay to interconnect, so this is +# considered too + + +# Simple LUTs +# area D C B A +1 1 141 +2 1 141 275 +3 1 141 275 379 +4 1 141 275 379 379 + +# LUT5 = 2x LUT4 + PFUMX +# area M0 D C B A +5 2 151 239 373 477 477 + +# LUT6 = 2x LUT5 + MUX2 +# area M1 M0 D C B A +6 4 148 292 380 514 618 618 + +# LUT7 = 2x LUT6 + MUX2 +# area M2 M1 M0 D C B A +7 8 148 289 433 521 655 759 759 + diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index f6c71a03d..53a89e8a3 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -70,80 +70,107 @@ module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; + + // Need to swap input ordering, and fix init accordingly, + // to match ABC's expectation of LUT inputs in non-decreasing + // delay order + localparam P_WIDTH = WIDTH < 4 ? 4 : WIDTH; + function [P_WIDTH-1:0] permute_index; + input [P_WIDTH-1:0] i; + integer j; + begin + permute_index = 0; + for (j = 0; j < P_WIDTH; j = j + 1) + permute_index[P_WIDTH-1 - j] = i[j]; + end + endfunction + + function [2**P_WIDTH-1:0] permute_init; + input [2**P_WIDTH-1:0] orig; + integer i; + begin + permute_init = 0; + for (i = 0; i < 2**P_WIDTH; i = i + 1) + permute_init[i] = orig[permute_index(i)]; + end + endfunction + + parameter [2**P_WIDTH-1:0] P_LUT = permute_init(LUT); + input [WIDTH-1:0] A; output Y; generate if (WIDTH == 1) begin - LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(A[0]), .B(1'b0), .C(1'b0), .D(1'b0)); + LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(1'b0), .D(A[0])); end else if (WIDTH == 2) begin - LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(A[0]), .B(A[1]), .C(1'b0), .D(1'b0)); + LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(A[1]), .D(A[0])); end else if (WIDTH == 3) begin - LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(A[0]), .B(A[1]), .C(A[2]), .D(1'b0)); + LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(A[2]), .C(A[1]), .D(A[0])); end else if (WIDTH == 4) begin - LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(A[3]), .B(A[2]), .C(A[1]), .D(A[0])); `ifndef NO_PFUMUX end else if (WIDTH == 5) begin wire f0, f1; - LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y)); + LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), + .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1])); + LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), + .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1])); + PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[0]), .Z(Y)); end else if (WIDTH == 6) begin wire f0, f1, f2, f3, g0, g1; - LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); - PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); - L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y)); + LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), + .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); + LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), + .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); + + LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2), + .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); + LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3), + .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[1]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[1]), .Z(g1)); + L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[0]), .Z(Y)); end else if (WIDTH == 7) begin wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1; - LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7), - .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); - - PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); - PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); - PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2)); - PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3)); - L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0)); - L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1)); - L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y)); + LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + + LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + + LUT4 #(.INIT(P_LUT[79:64])) lut4 (.Z(f4), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + LUT4 #(.INIT(P_LUT[95:80])) lut5 (.Z(f5), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + + LUT4 #(.INIT(P_LUT[111: 96])) lut6 (.Z(f6), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + LUT4 #(.INIT(P_LUT[127:112])) lut7 (.Z(f7), + .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[2]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[2]), .Z(g1)); + PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[2]), .Z(g2)); + PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[2]), .Z(g3)); + L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[1]), .Z(h0)); + L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[1]), .Z(h1)); + L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[0]), .Z(Y)); `endif end else begin wire _TECHMAP_FAIL_ = 1; diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 1e4002ee0..430aadbd7 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -9,15 +9,17 @@ module LUT4(input A, B, C, D, output Z); endmodule // --------------------------------------- - +(* abc_box_id=4, lib_whitebox *) module L6MUX21 (input D0, D1, SD, output Z); assign Z = SD ? D1 : D0; endmodule // --------------------------------------- - -module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, - output S0, S1, COUT); +(* abc_box_id=1, abc_carry, lib_whitebox *) +module CCU2C((* abc_carry_in *) input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + (* abc_carry_out *) output COUT); parameter [15:0] INIT0 = 16'h0000; parameter [15:0] INIT1 = 16'h0000; @@ -26,9 +28,13 @@ module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, // First half wire LUT4_0, LUT2_0; +`ifdef _ABC + assign LUT4_0 = INIT0[{D0, C0, B0, A0}]; + assign LUT2_0 = INIT0[{2'b00, B0, A0}]; +`else LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); - +`endif wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; assign S0 = LUT4_0 ^ gated_cin_0; @@ -37,9 +43,13 @@ module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, // Second half wire LUT4_1, LUT2_1; +`ifdef _ABC + assign LUT4_1 = INIT1[{D1, C1, B1, A1}]; + assign LUT2_1 = INIT1[{2'b00, B1, A1}]; +`else LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); - +`endif wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; assign S1 = LUT4_1 ^ gated_cin_1; @@ -90,13 +100,13 @@ module TRELLIS_RAM16X2 ( endmodule // --------------------------------------- - +(* abc_box_id=3, lib_whitebox *) module PFUMX (input ALUT, BLUT, C0, output Z); assign Z = C0 ? ALUT : BLUT; endmodule // --------------------------------------- - +(* abc_box_id=2 *) module TRELLIS_DPR16X4 ( input [3:0] DI, input [3:0] WAD, @@ -203,7 +213,7 @@ endmodule // --------------------------------------- -module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); +module TRELLIS_FF(input CLK, LSR, CE, DI, M, (* abc_flop_q *) output reg Q); parameter GSR = "ENABLED"; parameter [127:0] CEMUX = "1"; parameter CLKMUX = "CLK"; @@ -464,13 +474,13 @@ module DP16KD( input ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, input CEA, OCEA, CLKA, WEA, RSTA, input CSA2, CSA1, CSA0, - output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + (* abc_flop_q *) output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, input DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, input ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, input CEB, OCEB, CLKB, WEB, RSTB, input CSB2, CSB1, CSB0, - output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 + (* abc_flop_q *) output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 ); parameter DATA_WIDTH_A = 18; parameter DATA_WIDTH_B = 18; diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index c6e12248e..b271500f1 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -82,6 +82,9 @@ struct SynthEcp5Pass : public ScriptPass log(" -abc2\n"); log(" run two passes of 'abc' for slightly improved logic density\n"); log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\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"); @@ -93,7 +96,7 @@ struct SynthEcp5Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool noccu2, nodffe, nobram, nodram, nomux, flatten, retime, abc2, vpr; + bool noccu2, nodffe, nobram, nodram, nomux, flatten, retime, abc2, abc9, vpr; void clear_flags() YS_OVERRIDE { @@ -110,6 +113,7 @@ struct SynthEcp5Pass : public ScriptPass retime = false; abc2 = false; vpr = false; + abc9 = false; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -184,6 +188,10 @@ struct SynthEcp5Pass : public ScriptPass vpr = true; continue; } + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } break; } extra_args(args, argidx, design); @@ -203,7 +211,7 @@ struct SynthEcp5Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v"); + run("read_verilog -D_ABC -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v"); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); } @@ -264,10 +272,15 @@ struct SynthEcp5Pass : public ScriptPass run("abc", " (only if -abc2)"); } run("techmap -map +/ecp5/latches_map.v"); - if (nomux) - run("abc -lut 4 -dress"); - else - run("abc -lut 4:7 -dress"); + if (abc9) { + run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200"); + } else { + if (nomux) + run("abc -lut 4 -dress"); + else + run("abc -lut 4:7 -dress"); + } + run("clean"); } diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index 723b59d6f..d258d5a5d 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -28,6 +28,12 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.lut)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.lut)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.lut)) $(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh)) $(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh)) diff --git a/techlibs/ice40/abc_hx.box b/techlibs/ice40/abc_hx.box new file mode 100644 index 000000000..a0655643d --- /dev/null +++ b/techlibs/ice40/abc_hx.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +126 259 231 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 1 4 1 +449 400 379 316 diff --git a/techlibs/ice40/abc_hx.lut b/techlibs/ice40/abc_hx.lut new file mode 100644 index 000000000..3b3bb11e2 --- /dev/null +++ b/techlibs/ice40/abc_hx.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt +# I3 I2 I1 I0 +1 1 316 +2 1 316 379 +3 1 316 379 400 +4 1 316 379 400 449 diff --git a/techlibs/ice40/abc_lp.box b/techlibs/ice40/abc_lp.box new file mode 100644 index 000000000..eb1cd0937 --- /dev/null +++ b/techlibs/ice40/abc_lp.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +186 675 609 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 1 4 1 +661 589 558 465 diff --git a/techlibs/ice40/abc_lp.lut b/techlibs/ice40/abc_lp.lut new file mode 100644 index 000000000..e72f760a2 --- /dev/null +++ b/techlibs/ice40/abc_lp.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt +# I3 I2 I1 I0 +1 1 465 +2 1 465 558 +3 1 465 558 589 +4 1 465 558 589 661 diff --git a/techlibs/ice40/abc_u.box b/techlibs/ice40/abc_u.box new file mode 100644 index 000000000..3b5834e40 --- /dev/null +++ b/techlibs/ice40/abc_u.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +278 675 609 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 1 4 1 +1285 1231 1205 874 diff --git a/techlibs/ice40/abc_u.lut b/techlibs/ice40/abc_u.lut new file mode 100644 index 000000000..1e4fcadb6 --- /dev/null +++ b/techlibs/ice40/abc_u.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt +# I3 I2 I1 I0 +1 1 874 +2 1 874 1205 +3 1 874 1205 1231 +4 1 874 1205 1231 1285 diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index d0ddfd02e..759549e30 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -37,20 +37,24 @@ module \$lut (A, Y); generate if (WIDTH == 1) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0)); + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(1'b0), .I2(1'b0), .I3(A[0])); end else if (WIDTH == 2) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0)); + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[1]}}, {4{LUT[2]}}, {4{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(1'b0), .I2(A[1]), .I3(A[0])); end else if (WIDTH == 3) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0)); + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[3]}}, {2{LUT[5]}}, {2{LUT[1]}}, {2{LUT[6]}}, {2{LUT[2]}}, {2{LUT[4]}}, {2{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(A[2]), .I2(A[1]), .I3(A[0])); end else if (WIDTH == 4) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + localparam [15:0] INIT = {LUT[15], LUT[7], LUT[11], LUT[3], LUT[13], LUT[5], LUT[9], LUT[1], LUT[14], LUT[6], LUT[10], LUT[2], LUT[12], LUT[4], LUT[8], LUT[0]}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[3]), .I1(A[2]), .I2(A[1]), .I3(A[0])); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f9945b2b5..55b4d98c9 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -127,6 +127,7 @@ endmodule // SiliconBlue Logic Cells +(* abc_box_id = 22, lib_whitebox *) module SB_LUT4 (output O, input I0, I1, I2, I3); parameter [15:0] LUT_INIT = 0; wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0]; @@ -135,24 +136,29 @@ module SB_LUT4 (output O, input I0, I1, I2, I3); assign O = I0 ? s1[1] : s1[0]; endmodule -module SB_CARRY (output CO, input I0, I1, CI); +(* abc_box_id = 21, abc_carry, lib_whitebox *) +module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI); assign CO = (I0 && I1) || ((I0 || I1) && CI); endmodule // Positive Edge SiliconBlue FF Cells -module SB_DFF (output `SB_DFF_REG, input C, D); +module SB_DFF ((* abc_flop_q *) output `SB_DFF_REG, input C, D); +`ifndef _ABC always @(posedge C) Q <= D; +`else + always @* Q <= D; +`endif endmodule -module SB_DFFE (output `SB_DFF_REG, input C, E, D); +module SB_DFFE ((* abc_flop_q *) output `SB_DFF_REG, input C, E, D); always @(posedge C) if (E) Q <= D; endmodule -module SB_DFFSR (output `SB_DFF_REG, input C, R, D); +module SB_DFFSR ((* abc_flop_q *) output `SB_DFF_REG, input C, R, D); always @(posedge C) if (R) Q <= 0; @@ -160,7 +166,7 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFR (output `SB_DFF_REG, input C, R, D); +module SB_DFFR ((* abc_flop_q *) output `SB_DFF_REG, input C, R, D); always @(posedge C, posedge R) if (R) Q <= 0; @@ -168,7 +174,7 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFSS (output `SB_DFF_REG, input C, S, D); +module SB_DFFSS ((* abc_flop_q *) output `SB_DFF_REG, input C, S, D); always @(posedge C) if (S) Q <= 1; @@ -176,7 +182,7 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFS (output `SB_DFF_REG, input C, S, D); +module SB_DFFS ((* abc_flop_q *) output `SB_DFF_REG, input C, S, D); always @(posedge C, posedge S) if (S) Q <= 1; @@ -184,7 +190,7 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFESR ((* abc_flop_q *) output `SB_DFF_REG, input C, E, R, D); always @(posedge C) if (E) begin if (R) @@ -194,7 +200,7 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D); end endmodule -module SB_DFFER (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFER ((* abc_flop_q *) output `SB_DFF_REG, input C, E, R, D); always @(posedge C, posedge R) if (R) Q <= 0; @@ -202,7 +208,7 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D); Q <= D; endmodule -module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFESS ((* abc_flop_q *) output `SB_DFF_REG, input C, E, S, D); always @(posedge C) if (E) begin if (S) @@ -212,7 +218,7 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D); end endmodule -module SB_DFFES (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFES ((* abc_flop_q *) output `SB_DFF_REG, input C, E, S, D); always @(posedge C, posedge S) if (S) Q <= 1; @@ -222,18 +228,18 @@ endmodule // Negative Edge SiliconBlue FF Cells -module SB_DFFN (output `SB_DFF_REG, input C, D); +module SB_DFFN ((* abc_flop_q *) output `SB_DFF_REG, input C, D); always @(negedge C) Q <= D; endmodule -module SB_DFFNE (output `SB_DFF_REG, input C, E, D); +module SB_DFFNE ((* abc_flop_q *) output `SB_DFF_REG, input C, E, D); always @(negedge C) if (E) Q <= D; endmodule -module SB_DFFNSR (output `SB_DFF_REG, input C, R, D); +module SB_DFFNSR ((* abc_flop_q *) output `SB_DFF_REG, input C, R, D); always @(negedge C) if (R) Q <= 0; @@ -241,7 +247,7 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFNR (output `SB_DFF_REG, input C, R, D); +module SB_DFFNR ((* abc_flop_q *) output `SB_DFF_REG, input C, R, D); always @(negedge C, posedge R) if (R) Q <= 0; @@ -249,7 +255,7 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D); Q <= D; endmodule -module SB_DFFNSS (output `SB_DFF_REG, input C, S, D); +module SB_DFFNSS ((* abc_flop_q *) output `SB_DFF_REG, input C, S, D); always @(negedge C) if (S) Q <= 1; @@ -257,7 +263,7 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFNS (output `SB_DFF_REG, input C, S, D); +module SB_DFFNS ((* abc_flop_q *) output `SB_DFF_REG, input C, S, D); always @(negedge C, posedge S) if (S) Q <= 1; @@ -265,7 +271,7 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D); Q <= D; endmodule -module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFNESR ((* abc_flop_q *) output `SB_DFF_REG, input C, E, R, D); always @(negedge C) if (E) begin if (R) @@ -275,7 +281,7 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D); end endmodule -module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D); +module SB_DFFNER ((* abc_flop_q *) output `SB_DFF_REG, input C, E, R, D); always @(negedge C, posedge R) if (R) Q <= 0; @@ -283,7 +289,7 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D); Q <= D; endmodule -module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFNESS ((* abc_flop_q *) output `SB_DFF_REG, input C, E, S, D); always @(negedge C) if (E) begin if (S) @@ -293,7 +299,7 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D); end endmodule -module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D); +module SB_DFFNES ((* abc_flop_q *) output `SB_DFF_REG, input C, E, S, D); always @(negedge C, posedge S) if (S) Q <= 1; @@ -304,7 +310,7 @@ endmodule // SiliconBlue RAM Cells module SB_RAM40_4K ( - output [15:0] RDATA, + (* abc_flop_q *) output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, input WCLK, WCLKE, WE, @@ -472,7 +478,7 @@ module SB_RAM40_4K ( endmodule module SB_RAM40_4KNR ( - output [15:0] RDATA, + (* abc_flop_q *) output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, input WCLK, WCLKE, WE, @@ -537,7 +543,7 @@ module SB_RAM40_4KNR ( endmodule module SB_RAM40_4KNW ( - output [15:0] RDATA, + (* abc_flop_q *) output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, input WCLKN, WCLKE, WE, @@ -602,7 +608,7 @@ module SB_RAM40_4KNW ( endmodule module SB_RAM40_4KNRNW ( - output [15:0] RDATA, + (* abc_flop_q *) output [15:0] RDATA, input RCLKN, RCLKE, RE, input [10:0] RADDR, input WCLKN, WCLKE, WE, @@ -890,12 +896,13 @@ module SB_WARMBOOT ( ); endmodule +(* nomem2reg *) module SB_SPRAM256KA ( input [13:0] ADDRESS, input [15:0] DATAIN, input [3:0] MASKWREN, input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF, - output reg [15:0] DATAOUT + (* abc_flop_q *) output reg [15:0] DATAOUT ); `ifndef BLACKBOX `ifndef EQUIV diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index bb96d66d1..a60829764 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -37,6 +37,10 @@ struct SynthIce40Pass : public ScriptPass log("\n"); log("This command runs synthesis for iCE40 FPGAs.\n"); log("\n"); + log(" -device < hx | lp | u >\n"); + log(" optimise the synthesis netlist for the specified device.\n"); + log(" HX is the default target if no device argument specified.\n"); + log("\n"); log(" -top <module>\n"); log(" use the specified module as top module\n"); log("\n"); @@ -92,13 +96,17 @@ struct SynthIce40Pass : public ScriptPass log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\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; + + string top_opt, blif_file, edif_file, json_file, abc, device_opt; bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr; int min_ce_use; @@ -119,6 +127,8 @@ struct SynthIce40Pass : public ScriptPass noabc = false; abc2 = false; vpr = false; + abc = "abc"; + device_opt = "hx"; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -201,12 +211,22 @@ struct SynthIce40Pass : public ScriptPass vpr = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } + if (args[argidx] == "-device" && argidx+1 < args.size()) { + device_opt = 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 (device_opt != "hx" && device_opt != "lp" && device_opt !="u") + log_cmd_error("Invalid or no device specified: '%s'\n", device_opt.c_str()); log_header(design, "Executing SYNTH_ICE40 pass.\n"); log_push(); @@ -220,7 +240,7 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib +/ice40/cells_sim.v"); + run("read_verilog -lib -D_ABC +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); run("proc"); } @@ -277,8 +297,8 @@ struct SynthIce40Pass : public ScriptPass run("techmap"); else run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); - if (retime || help_mode) - run("abc -dff", "(only if -retime)"); + if ((retime || help_mode) && abc != "abc9") + run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); } @@ -302,7 +322,7 @@ struct SynthIce40Pass : public ScriptPass if (check_label("map_luts")) { if (abc2 || help_mode) { - run("abc", " (only if -abc2)"); + run(abc, " (only if -abc2)"); run("ice40_opt", "(only if -abc2)"); } run("techmap -map +/ice40/latches_map.v"); @@ -311,7 +331,10 @@ struct SynthIce40Pass : public ScriptPass run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)"); } if (!noabc) { - run("abc -dress -lut 4", "(skip if -noabc)"); + if (abc == "abc9") + run(abc + stringf(" -dress -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); + else + run(abc + " -dress -lut 4", "(skip if -noabc)"); } run("clean"); if (relut || help_mode) { diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index d68f03bb4..296edace9 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -30,6 +30,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc.box)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc.lut)) $(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh)) $(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh)) diff --git a/techlibs/xilinx/abc.box b/techlibs/xilinx/abc.box new file mode 100644 index 000000000..a4182ed63 --- /dev/null +++ b/techlibs/xilinx/abc.box @@ -0,0 +1,62 @@ +# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf + +# F7BMUX slower than F7AMUX +# Inputs: I0 I1 S0 +# Outputs: O +F7BMUX 1 1 3 1 +217 223 296 + +# Inputs: I0 I1 S0 +# Outputs: O +MUXF8 2 1 3 1 +104 94 273 + +# CARRY4 + CARRY4_[ABCD]X +# Inputs: S0 S1 S2 S3 CYINIT DI0 DI1 DI2 DI3 CI +# Outputs: O0 O1 O2 O3 CO0 CO1 CO2 CO3 +# (NB: carry chain input/output must be last input/output, +# swapped with what normally would have been the last +# output, here: CI <-> S, CO <-> O +CARRY4 3 1 10 8 +223 - - - 482 - - - - 222 +400 205 - - 598 407 - - - 334 +523 558 226 - 584 556 537 - - 239 +582 618 330 227 642 615 596 438 - 313 +340 - - - 536 379 - - - 271 +433 469 - - 494 465 445 - - 157 +512 548 292 - 592 540 520 356 - 228 +508 528 378 380 580 526 507 398 385 114 + +# SLICEM/A6LUT +# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE +# Outputs: DPO SPO +RAM64X1D 4 0 15 2 +- - - - - - - 124 124 124 124 124 124 - - +124 124 124 124 124 124 - - - - - - 124 - - + +# SLICEM/A6LUT + F7[AB]MUX +# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE +# Outputs: DPO SPO +RAM128X1D 5 0 17 2 +- - - - - - - - 314 314 314 314 314 314 292 - - +347 347 347 347 347 347 296 - - - - - - - - - - + +# Inputs: C CE D R +# Outputs: Q +FDRE 6 0 4 1 +- - - - + +# Inputs: C CE D S +# Outputs: Q +FDSE 7 0 4 1 +- - - - + +# Inputs: C CE CLR D +# Outputs: Q +FDCE 8 0 4 1 +- - 404 - + +# Inputs: C CE D PRE +# Outputs: Q +FDPE 9 0 4 1 +- - - 404 diff --git a/techlibs/xilinx/abc.lut b/techlibs/xilinx/abc.lut new file mode 100644 index 000000000..3a7dc268d --- /dev/null +++ b/techlibs/xilinx/abc.lut @@ -0,0 +1,14 @@ +# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf + +# K area delay +1 1 124 +2 2 124 235 +3 3 124 235 399 +4 3 124 235 399 490 +5 3 124 235 399 490 620 +6 5 124 235 399 490 620 632 + # F7BMUX +7 10 296 420 531 695 756 916 928 + # F8MUX + # F8MUX+F7BMUX +8 20 273 569 693 804 968 1029 1189 1201 diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index 09a5f07e8..5c848d4e6 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -180,7 +180,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); // First one if (i == 0) begin - CARRY4 #(.IS_INITIALIZED(1'd1)) carry4_1st_part + CARRY4 carry4_1st_part ( .CYINIT(CI), .CI (1'd0), @@ -207,7 +207,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); // First one if (i == 0) begin - CARRY4 #(.IS_INITIALIZED(1'd1)) carry4_1st_full + CARRY4 carry4_1st_full ( .CYINIT(CI), .CI (1'd0), diff --git a/techlibs/xilinx/brams_bb.v b/techlibs/xilinx/brams_bb.v index a682ba4a7..f540d299d 100644 --- a/techlibs/xilinx/brams_bb.v +++ b/techlibs/xilinx/brams_bb.v @@ -19,10 +19,10 @@ module RAMB18E1 ( input [1:0] WEA, input [3:0] WEBWE, - output [15:0] DOADO, - output [15:0] DOBDO, - output [1:0] DOPADOP, - output [1:0] DOPBDOP + (* abc_flop_q *) output [15:0] DOADO, + (* abc_flop_q *) output [15:0] DOBDO, + (* abc_flop_q *) output [1:0] DOPADOP, + (* abc_flop_q *) output [1:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -143,10 +143,10 @@ module RAMB36E1 ( input [3:0] WEA, input [7:0] WEBWE, - output [31:0] DOADO, - output [31:0] DOBDO, - output [3:0] DOPADOP, - output [3:0] DOPBDOP + (* abc_flop_q *) output [31:0] DOADO, + (* abc_flop_q *) output [31:0] DOBDO, + (* abc_flop_q *) output [3:0] DOPADOP, + (* abc_flop_q *) output [3:0] DOPBDOP ); parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 40789ddbe..b5114758c 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -2,6 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * 2019 Eddie Hung <eddie@fpgeh.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,14 +20,16 @@ // Convert negative-polarity reset to positive-polarity (* techmap_celltype = "$_DFF_NN0_" *) -module _90_dff_nn0_to_np0 (input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +module _90_dff_nn0_to_np0(input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule (* techmap_celltype = "$_DFF_PN0_" *) -module _90_dff_pn0_to_pp0 (input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule +module _90_dff_pn0_to_pp0(input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule + (* techmap_celltype = "$_DFF_NN1_" *) module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule (* techmap_celltype = "$_DFF_PN1_" *) module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule + module \$__SHREG_ (input C, input D, input E, output Q); parameter DEPTH = 0; parameter [DEPTH-1:0] INIT = 0; @@ -88,7 +91,7 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o end else if (DEPTH > 65 && DEPTH <= 96) begin wire T0, T1, T2, T3, T4, T5, T6; - SRLC32E #(.INIT(INIT_R[32-1:0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); \$__XILINX_SHREG_ #(.DEPTH(DEPTH-64), .INIT(INIT[DEPTH-64-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_2 (.C(C), .D(T3), .L(L[4:0]), .E(E), .Q(T4)); if (&_TECHMAP_CONSTMSK_L_) @@ -101,7 +104,7 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o end else if (DEPTH > 97 && DEPTH < 128) begin wire T0, T1, T2, T3, T4, T5, T6, T7, T8; - SRLC32E #(.INIT(INIT_R[32-1:0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); SRLC32E #(.INIT(INIT_R[96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5)); \$__XILINX_SHREG_ #(.DEPTH(DEPTH-96), .INIT(INIT[DEPTH-96-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_3 (.C(C), .D(T5), .L(L[4:0]), .E(E), .Q(T6)); @@ -115,9 +118,9 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o end else if (DEPTH == 128) begin wire T0, T1, T2, T3, T4, T5, T6; - SRLC32E #(.INIT(INIT_R[32-1:0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(T0), .Q31(T1)); - SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); - SRLC32E #(.INIT(INIT_R[96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5)); + SRLC32E #(.INIT(INIT_R[ 32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[ 64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); + SRLC32E #(.INIT(INIT_R[ 96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5)); SRLC32E #(.INIT(INIT_R[128-1:96]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_3 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T5), .Q(T6), .Q31(SO)); if (&_TECHMAP_CONSTMSK_L_) assign Q = T6; @@ -151,6 +154,3 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o end endgenerate endmodule - -`ifndef SRL_ONLY -`endif diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3a4540b83..d9aa36666 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -159,10 +159,12 @@ module MUXCY(output O, input CI, DI, S); assign O = S ? CI : DI; endmodule +(* abc_box_id = 1, lib_whitebox *) module MUXF7(output O, input I0, I1, S); assign O = S ? I1 : I0; endmodule +(* abc_box_id = 2, lib_whitebox *) module MUXF8(output O, input I0, I1, S); assign O = S ? I1 : I0; endmodule @@ -171,7 +173,8 @@ module XORCY(output O, input CI, LI); assign O = CI ^ LI; endmodule -module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S); +(* abc_box_id = 3, abc_carry, lib_whitebox *) +module CARRY4((* abc_carry_out *) output [3:0] CO, output [3:0] O, (* abc_carry_in *) input CI, input CYINIT, input [3:0] DI, S); assign O = S ^ {CO[2:0], CI | CYINIT}; assign CO[0] = S[0] ? CI | CYINIT : DI[0]; assign CO[1] = S[1] ? CO[0] : DI[1]; @@ -202,7 +205,7 @@ endmodule `endif -module FDRE (output reg Q, input C, CE, D, R); +module FDRE ((* abc_flop_q *) output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -214,7 +217,7 @@ module FDRE (output reg Q, input C, CE, D, R); endcase endgenerate endmodule -module FDSE (output reg Q, input C, CE, D, S); +module FDSE ((* abc_flop_q *) output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -226,7 +229,7 @@ module FDSE (output reg Q, input C, CE, D, S); endcase endgenerate endmodule -module FDCE (output reg Q, input C, CE, D, CLR); +module FDCE ((* abc_flop_q *) output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -240,7 +243,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); endcase endgenerate endmodule -module FDPE (output reg Q, input C, CE, D, PRE); +module FDPE ((* abc_flop_q *) output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D_INVERTED = 1'b0; @@ -254,30 +257,31 @@ module FDPE (output reg Q, input C, CE, D, PRE); endcase endgenerate endmodule -module FDRE_1 (output reg Q, input C, CE, D, R); +module FDRE_1 ((* abc_flop_q *) output reg Q, input C, CE, D, R); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; endmodule -module FDSE_1 (output reg Q, input C, CE, D, S); +module FDSE_1 ((* abc_flop_q *) output reg Q, input C, CE, D, S); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; endmodule -module FDCE_1 (output reg Q, input C, CE, D, CLR); +module FDCE_1 ((* abc_flop_q *) output reg Q, input C, CE, D, CLR); parameter [0:0] INIT = 1'b0; initial Q <= INIT; always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; endmodule -module FDPE_1 (output reg Q, input C, CE, D, PRE); +module FDPE_1 ((* abc_flop_q *) output reg Q, input C, CE, D, PRE); parameter [0:0] INIT = 1'b1; initial Q <= INIT; always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule +//(* abc_box_id = 4 /*, lib_whitebox*/ *) module RAM64X1D ( output DPO, SPO, input D, WCLK, WE, @@ -295,6 +299,7 @@ module RAM64X1D ( always @(posedge clk) if (WE) mem[a] <= D; endmodule +//(* abc_box_id = 5 /*, lib_whitebox*/ *) module RAM128X1D ( output DPO, SPO, input D, WCLK, WE, @@ -310,7 +315,7 @@ module RAM128X1D ( endmodule module SRL16E ( - output Q, + (* abc_flop_q *) output Q, input A0, A1, A2, A3, CE, CLK, D ); parameter [15:0] INIT = 16'h0000; @@ -328,7 +333,7 @@ module SRL16E ( endmodule module SRLC32E ( - output Q, + (* abc_flop_q *) output Q, output Q31, input [4:0] A, input CE, CLK, D diff --git a/techlibs/xilinx/cells_xtra.sh b/techlibs/xilinx/cells_xtra.sh index 8e39b440d..2b384f405 100644 --- a/techlibs/xilinx/cells_xtra.sh +++ b/techlibs/xilinx/cells_xtra.sh @@ -116,7 +116,7 @@ function xtract_cell_decl() xtract_cell_decl PS7 "(* keep *)" xtract_cell_decl PULLDOWN xtract_cell_decl PULLUP - xtract_cell_decl RAM128X1D + #xtract_cell_decl RAM128X1D xtract_cell_decl RAM128X1S xtract_cell_decl RAM256X1S xtract_cell_decl RAM32M @@ -125,7 +125,7 @@ function xtract_cell_decl() xtract_cell_decl RAM32X1S_1 xtract_cell_decl RAM32X2S xtract_cell_decl RAM64M - xtract_cell_decl RAM64X1D + #xtract_cell_decl RAM64X1D xtract_cell_decl RAM64X1S xtract_cell_decl RAM64X1S_1 xtract_cell_decl RAM64X2S diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index fbcc74682..0ec3d0df0 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -3655,17 +3655,6 @@ module PULLUP (...); output O; endmodule -module RAM128X1D (...); - parameter [127:0] INIT = 128'h00000000000000000000000000000000; - parameter [0:0] IS_WCLK_INVERTED = 1'b0; - output DPO, SPO; - input [6:0] A; - input [6:0] DPRA; - input D; - input WCLK; - input WE; -endmodule - module RAM128X1S (...); parameter [127:0] INIT = 128'h00000000000000000000000000000000; parameter [0:0] IS_WCLK_INVERTED = 1'b0; @@ -3756,13 +3745,6 @@ module RAM64M (...); input WE; endmodule -module RAM64X1D (...); - parameter [63:0] INIT = 64'h0000000000000000; - parameter [0:0] IS_WCLK_INVERTED = 1'b0; - output DPO, SPO; - input A0, A1, A2, A3, A4, A5, D, DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5, WCLK, WE; -endmodule - module RAM64X1S (...); parameter [63:0] INIT = 64'h0000000000000000; parameter [0:0] IS_WCLK_INVERTED = 1'b0; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a293081f1..69a3d99c2 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -58,6 +58,9 @@ struct SynthXilinxPass : public ScriptPass log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); log("\n"); + log(" -nocarry\n"); + log(" disable inference of carry chains\n"); + log("\n"); log(" -nobram\n"); log(" disable inference of block rams\n"); log("\n"); @@ -78,23 +81,28 @@ struct SynthXilinxPass : public ScriptPass log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - std::string top_opt, edif_file, blif_file, arch; - bool flatten, retime, vpr, nobram, nodram, nosrl; + std::string top_opt, edif_file, blif_file, abc, arch; + bool flatten, retime, vpr, nocarry, nobram, nodram, nosrl; void clear_flags() YS_OVERRIDE { top_opt = "-auto-top"; edif_file.clear(); blif_file.clear(); + abc = "abc"; flatten = false; retime = false; vpr = false; + nocarry = false; nobram = false; nodram = false; nosrl = false; @@ -145,6 +153,10 @@ struct SynthXilinxPass : public ScriptPass vpr = true; continue; } + if (args[argidx] == "-nocarry") { + nocarry = true; + continue; + } if (args[argidx] == "-nobram") { nobram = true; continue; @@ -157,6 +169,10 @@ struct SynthXilinxPass : public ScriptPass nosrl = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } break; } extra_args(args, argidx, design); @@ -179,9 +195,9 @@ struct SynthXilinxPass : public ScriptPass { if (check_label("begin")) { if (vpr) - run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); + run("read_verilog -lib -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); else - run("read_verilog -lib +/xilinx/cells_sim.v"); + run("read_verilog -lib -D _ABC +/xilinx/cells_sim.v"); run("read_verilog -lib +/xilinx/cells_xtra.v"); @@ -200,6 +216,17 @@ struct SynthXilinxPass : public ScriptPass if (check_label("coarse")) { run("synth -run coarse"); + + // shregmap -tech xilinx can cope with $shiftx and $mux + // cells for identifying variable-length shift registers, + // so attempt to convert $pmux-es to the former + if (!nosrl || help_mode) + run("pmux2shiftx", "(skip if '-nosrl')"); + + // Run a number of peephole optimisations, including one + // that optimises $mul cells driving $shiftx's B input + // and that aids wide mux analysis + run("peepopt"); } if (check_label("bram", "(skip if '-nobram')")) { @@ -217,12 +244,6 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("fine")) { - // shregmap -tech xilinx can cope with $shiftx and $mux - // cells for identifiying variable-length shift registers, - // so attempt to convert $pmux-es to the former - if (!nosrl || help_mode) - run("pmux2shiftx", "(skip if '-nosrl')"); - run("opt -fast -full"); run("memory_map"); run("dffsr2dff"); @@ -237,11 +258,17 @@ struct SynthXilinxPass : public ScriptPass run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')"); } - if (!vpr || help_mode) - run("techmap -map +/techmap.v -map +/xilinx/arith_map.v"); - else - run("techmap -map +/techmap.v +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); - + std::string techmap_files = " -map +/techmap.v"; + if (help_mode) + techmap_files += " [-map +/xilinx/arith_map.v]"; + else if (!nocarry) { + techmap_files += " -map +/xilinx/arith_map.v"; + if (vpr) + techmap_files += " -D _EXPLICIT_CARRY"; + else if (abc == "abc9") + techmap_files += " -D _CLB_CARRY"; + } + run("techmap " + techmap_files); run("opt -fast"); } @@ -251,11 +278,14 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_luts")) { - if (help_mode) - run("abc -luts 2:2,3,6:5,10,20 [-dff]"); + if (abc == "abc9") + run(abc + " -lut +/xilinx/abc.lut -box +/xilinx/abc.box -W 160" + string(retime ? " -dff" : "")); + else if (help_mode) + run(abc + " -luts 2:2,3,6:5,10,20 [-dff]"); else - run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); run("clean"); + // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming if (!nosrl || help_mode) |