diff options
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/common/synth.cc | 18 | ||||
-rw-r--r-- | techlibs/ice40/synth_ice40.cc | 17 | ||||
-rw-r--r-- | techlibs/xilinx/Makefile.inc | 3 | ||||
-rw-r--r-- | techlibs/xilinx/cells.box | 19 | ||||
-rw-r--r-- | techlibs/xilinx/cells.lut | 12 | ||||
-rw-r--r-- | techlibs/xilinx/cells_box.v | 19 | ||||
-rw-r--r-- | techlibs/xilinx/cells_map.v | 79 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 16 |
8 files changed, 169 insertions, 14 deletions
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index ccfa76e02..349605f8c 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 abc9 instead of abc\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); @@ -239,15 +247,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/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 8899bfcc4..6c77e5482 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -92,13 +92,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 abc9 instead of abc\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; bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr; int min_ce_use; @@ -119,6 +123,7 @@ struct SynthIce40Pass : public ScriptPass noabc = false; abc2 = false; vpr = false; + abc = "abc"; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -201,6 +206,10 @@ struct SynthIce40Pass : public ScriptPass vpr = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } break; } extra_args(args, argidx, design); @@ -274,7 +283,7 @@ struct SynthIce40Pass : public ScriptPass else run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); if (retime || help_mode) - run("abc -dff", "(only if -retime)"); + run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); } @@ -298,7 +307,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"); @@ -307,7 +316,7 @@ 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)"); + 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..43be55d51 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -30,6 +30,9 @@ $(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/cells.box)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_box.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells.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/cells.box b/techlibs/xilinx/cells.box new file mode 100644 index 000000000..5ad284f47 --- /dev/null +++ b/techlibs/xilinx/cells.box @@ -0,0 +1,19 @@ +# Max delays from https://pastebin.com/v2hrcksd +# from https://github.com/SymbiFlow/prjxray/pull/706#issuecomment-479380321 + +# F7BMUX slower than F7AMUX +# Inputs: 0 1 S0 +# Outputs: OUT +F7BMUX 1 1 3 1 +217 223 296 + +# Inputs: 0 1 S0 +# Outputs: OUT +MUXF8 2 1 3 1 +104 94 273 + +MUXCY 3 1 3 1 +1 1 1 + +XORCY 4 1 2 1 +1 1 diff --git a/techlibs/xilinx/cells.lut b/techlibs/xilinx/cells.lut new file mode 100644 index 000000000..c6bc7b1f7 --- /dev/null +++ b/techlibs/xilinx/cells.lut @@ -0,0 +1,12 @@ +# Max delays from https://pastebin.com/v2hrcksd +# from https://github.com/SymbiFlow/prjxray/pull/706#issuecomment-479380321 + +# K area delay +1 11 624 +2 12 624 +3 13 624 +4 14 624 +5 15 624 +6 20 724 +7 40 1020 +8 80 1293 diff --git a/techlibs/xilinx/cells_box.v b/techlibs/xilinx/cells_box.v new file mode 100644 index 000000000..ef6f81d27 --- /dev/null +++ b/techlibs/xilinx/cells_box.v @@ -0,0 +1,19 @@ +(* abc_box_id = 1 *) +module MUXF7(output O, input I0, I1, S); + assign O = S ? I1 : I0; +endmodule + +(* abc_box_id = 2 *) +module MUXF8(output O, input I0, I1, S); + assign O = S ? I1 : I0; +endmodule + +(* abc_box_id = 3 *) +module MUXCY(output O, input CI, DI, S); + assign O = S ? CI : DI; +endmodule + +(* abc_box_id = 4 *) +module XORCY(output O, input CI, LI); + assign O = CI ^ LI; +endmodule diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 704ab21b1..3c4d8f4cd 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -142,5 +142,80 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o endgenerate endmodule -`ifndef SRL_ONLY -`endif +module \$shiftx (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0; + parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0; + + generate + genvar i, j; + if (B_SIGNED) begin + if (_TECHMAP_CONSTMSK_B_[B_WIDTH-1] && _TECHMAP_CONSTVAL_B_[B_WIDTH-1] == 1'b0) + // Optimisation to remove B_SIGNED if sign bit of B is constant-0 + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(0), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B[B_WIDTH-2:0]), .Y(Y)); + else + wire _TECHMAP_FAIL_ = 1; + end + else if (Y_WIDTH > 1) begin + wire [$clog2(A_WIDTH/Y_WIDTH)-1:0] B_bitty = B/Y_WIDTH; + for (i = 0; i < Y_WIDTH; i++) begin + wire [A_WIDTH/Y_WIDTH-1:0] A_i; + for (j = 0; j < A_WIDTH/Y_WIDTH; j++) + assign A_i[j] = A[j*Y_WIDTH+i]; + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH/Y_WIDTH), .B_WIDTH($clog2(A_WIDTH/Y_WIDTH)), .Y_WIDTH(1)) bitblast (.A(A_i), .B(B_bitty), .Y(Y[i])); + end + end + else if (B_WIDTH < 3) begin + wire _TECHMAP_FAIL_ = 1; + end + else if (B_WIDTH == 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_shiftx (.A(A[a_width0-1:0]), .B(B[2-1:0]), .Y(T0)); + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_shiftx_last (.A(A[A_WIDTH-1:a_width0]), .B(B[$clog2(a_widthN)-1:0]), .Y(T1)); + MUXF7 fpga_mux (.I0(T0), .I1(T1), .S(B[B_WIDTH-1]), .O(Y)); + end + else if (B_WIDTH == 4) begin + localparam a_width0 = 2 ** 2; + localparam num_mux8 = A_WIDTH / a_width0; + localparam a_widthN = A_WIDTH - num_mux8*a_width0; + wire [4-1:0] T; + wire T0, T1; + for (i = 0; i < 4; 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_shiftx (.A(A[i*a_width0+:a_width0]), .B(B[2-1:0]), .Y(T[i])); + else if (i == num_mux8 && a_widthN > 0) + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_shiftx_last (.A(A[A_WIDTH-1:i*a_width0]), .B(B[$clog2(a_widthN)-1:0]), .Y(T[i])); + else + assign T[i] = 1'bx; + MUXF7 fpga_mux_0 (.I0(T[0]), .I1(T[1]), .S(B[2]), .O(T0)); + MUXF7 fpga_mux_1 (.I0(T[2]), .I1(T[3]), .S(B[2]), .O(T1)); + MUXF8 fpga_mux_2 (.I0(T0), .I1(T1), .S(B[3]), .O(Y)); + end + else begin + localparam a_width0 = 2 ** 4; + localparam num_mux16 = A_WIDTH / a_width0; + localparam a_widthN = A_WIDTH - num_mux16*a_width0; + wire [(2**(B_WIDTH-4))-1:0] T; + for (i = 0; i < 2 ** (B_WIDTH-4); i++) + if (i < num_mux16) + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(4), .Y_WIDTH(Y_WIDTH)) fpga_shiftx (.A(A[i*a_width0+:a_width0]), .B(B[4-1:0]), .Y(T[i])); + else if (i == num_mux16 && a_widthN > 0) begin + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_widthN), .B_WIDTH($clog2(a_widthN)), .Y_WIDTH(Y_WIDTH)) fpga_shiftx_last (.A(A[A_WIDTH-1:i*a_width0]), .B(B[$clog2(a_widthN)-1:0]), .Y(T[i])); + end + else + assign T[i] = 1'bx; + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(2**(B_WIDTH-4)), .B_WIDTH(B_WIDTH-4), .Y_WIDTH(Y_WIDTH)) fpga_shiftx (.A(T), .B(B[B_WIDTH-1:4]), .Y(Y)); + end + endgenerate +endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 53eee7962..fa87a3ad6 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -83,6 +83,9 @@ struct SynthXilinxPass : public Pass log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); + log(" -abc9\n"); + log(" use abc9 instead of abc\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); log("\n"); @@ -132,7 +135,6 @@ struct SynthXilinxPass : public Pass log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT \\\n"); log(" -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n"); - log(" clean\n"); log("\n"); log(" check:\n"); log(" hierarchy -check\n"); @@ -152,6 +154,7 @@ struct SynthXilinxPass : public Pass std::string edif_file; std::string blif_file; std::string run_from, run_to; + std::string abc = "abc"; bool flatten = false; bool retime = false; bool vpr = false; @@ -204,6 +207,10 @@ struct SynthXilinxPass : public Pass } if (args[argidx] == "-nosrl") { nosrl = true; + continue; + } + if (args[argidx] == "-abc9") { + abc = "abc9"; continue; } break; @@ -304,7 +311,11 @@ struct SynthXilinxPass : public Pass { Pass::call(design, "opt -full"); Pass::call(design, "techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v"); - Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + Pass::call(design, "read_verilog +/xilinx/cells_box.v"); + if (abc == "abc9") + Pass::call(design, abc + " -lut +/xilinx/cells.lut -box +/xilinx/cells.box" + string(retime ? " -dff" : "")); + else + Pass::call(design, abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); Pass::call(design, "clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming @@ -313,7 +324,6 @@ struct SynthXilinxPass : public Pass Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); - Pass::call(design, "clean"); } if (check_label(active, run_from, run_to, "check")) |