aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs')
-rw-r--r--techlibs/common/synth.cc18
-rw-r--r--techlibs/ice40/synth_ice40.cc17
-rw-r--r--techlibs/xilinx/Makefile.inc3
-rw-r--r--techlibs/xilinx/cells.box19
-rw-r--r--techlibs/xilinx/cells.lut12
-rw-r--r--techlibs/xilinx/cells_box.v19
-rw-r--r--techlibs/xilinx/cells_map.v79
-rw-r--r--techlibs/xilinx/synth_xilinx.cc16
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"))