diff options
Diffstat (limited to 'techlibs/xilinx')
-rw-r--r-- | techlibs/xilinx/Makefile.inc | 2 | ||||
-rw-r--r-- | techlibs/xilinx/cells.box | 13 | ||||
-rw-r--r-- | techlibs/xilinx/cells.lut | 12 | ||||
-rw-r--r-- | techlibs/xilinx/cells_map.v | 64 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 28 |
5 files changed, 110 insertions, 9 deletions
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index d68f03bb4..432bb0770 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/cells.box)) +$(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..c8092db6e --- /dev/null +++ b/techlibs/xilinx/cells.box @@ -0,0 +1,13 @@ +# 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 0 3 1 +217 223 296 + +# Inputs: 0 1 S0 +# Outputs: OUT +MUXF8 2 0 3 1 +104 94 273 diff --git a/techlibs/xilinx/cells.lut b/techlibs/xilinx/cells.lut new file mode 100644 index 000000000..a1d9b9c42 --- /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_map.v b/techlibs/xilinx/cells_map.v index d5801c0fc..ff33cf8ff 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -17,4 +17,66 @@ * */ -// Empty for now +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; + + generate + genvar i; + if (B_WIDTH < 3) begin + reg _TECHMAP_FAIL_; + assign _TECHMAP_FAIL_ = 1; + end + else if (B_WIDTH == 3) begin + localparam a_width0 = Y_WIDTH * (2 ** (B_WIDTH-1)); + localparam a_widthN = A_WIDTH - a_width0; + wire [Y_WIDTH-1:0] T0, T1; + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) fpga_shiftx (.A(A[a_width0-1:0]), .B(B[B_WIDTH-2: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[Y_WIDTH-1:0] (.I0(T0), .I1(T1), .S(B[B_WIDTH-1]), .O(Y)); + for (i = 0; i < Y_WIDTH; i++) + MUXF7 fpga_mux (.I0(T0[i]), .I1(T1[i]), .S(B[B_WIDTH-1]), .O(Y[i])); + end + else if (B_WIDTH == 4) begin + localparam a_width0 = Y_WIDTH * (2 ** (B_WIDTH-2)); + localparam num_mux8 = A_WIDTH / a_width0; + localparam a_widthN = A_WIDTH - num_mux8*a_width0; + wire [Y_WIDTH*B_WIDTH-1:0] T; + wire [Y_WIDTH-1:0] T0, T1; + for (i = 0; i < B_WIDTH; i++) + if (i < num_mux8) + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(a_width0), .B_WIDTH(B_WIDTH-2), .Y_WIDTH(Y_WIDTH)) fpga_shiftx (.A(A[(i+1)*a_width0-1:i*a_width0]), .B(B[B_WIDTH-3:0]), .Y(T[(i+1)*Y_WIDTH-1:i*Y_WIDTH])); + 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+1)*Y_WIDTH-1:i*Y_WIDTH])); + else + assign T[(i+1)*Y_WIDTH-1:i*Y_WIDTH] = {Y_WIDTH{1'bx}}; + for (i = 0; i < Y_WIDTH; i++) begin + MUXF7 fpga_mux_0 (.I0(T[i*B_WIDTH+0]), .I1(T[i*B_WIDTH+1]), .S(B[B_WIDTH-2]), .O(T0[i])); + MUXF7 fpga_mux_1 (.I0(T[i*B_WIDTH+2]), .I1(T[i*B_WIDTH+3]), .S(B[B_WIDTH-2]), .O(T1[i])); + MUXF8 fpga_mux_2 (.I0(T0[i]), .I1(T1[i]), .S(B[B_WIDTH-1]), .O(Y[i])); + end + end + else begin + localparam a_width0 = Y_WIDTH * (2 ** 4); + localparam num_mux16 = A_WIDTH / a_width0; + localparam a_widthN = A_WIDTH - num_mux16*a_width0; + wire [Y_WIDTH*(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+1)*a_width0-1:i*a_width0]), .B(B[4-1:0]), .Y(T[(i+1)*Y_WIDTH-1:i*Y_WIDTH])); + 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+1)*Y_WIDTH-1:i*Y_WIDTH])); + end + else + assign T[(i+1)*Y_WIDTH-1:i*Y_WIDTH] = {Y_WIDTH{1'bx}}; + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(Y_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 805ae8e6e..9178182fb 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -80,6 +80,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"); @@ -142,6 +145,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; @@ -191,6 +195,10 @@ struct SynthXilinxPass : public Pass nodram = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } break; } extra_args(args, argidx, design); @@ -256,28 +264,32 @@ struct SynthXilinxPass : public Pass Pass::call(design, "opt -full"); if (vpr) { - Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/arith_map.v -map +/xilinx/ff_map.v -D _EXPLICIT_CARRY"); + Pass::call(design, "techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); } else { - Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/arith_map.v -map +/xilinx/ff_map.v"); + Pass::call(design, "techmap -map +/xilinx/arith_map.v"); } Pass::call(design, "hierarchy -check"); Pass::call(design, "opt -fast"); } - if (check_label(active, run_from, run_to, "map_luts")) + if (check_label(active, run_from, run_to, "map_cells")) { - Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + Pass::call(design, "techmap -map +/xilinx/cells_map.v"); Pass::call(design, "clean"); - Pass::call(design, "techmap -map +/xilinx/lut_map.v"); } - if (check_label(active, run_from, run_to, "map_cells")) + if (check_label(active, run_from, run_to, "map_luts")) { - Pass::call(design, "techmap -map +/xilinx/cells_map.v"); + Pass::call(design, "techmap -map +/techmap.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"); + Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_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")) |