aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2019-07-01 10:44:42 -0700
committerEddie Hung <eddie@fpgeh.com>2019-07-01 10:44:42 -0700
commit699d8e393953a3e5f0c35afec54464e6810f8f1d (patch)
tree4edf4b25dd3c9f8eaf1dad737baa49a04f78ec3f /techlibs/xilinx
parent75d92fb590b190e0da43e99853f839b7afb10f83 (diff)
parent0067dc44f3928833eede2b9bb40260be78e11a93 (diff)
downloadyosys-699d8e393953a3e5f0c35afec54464e6810f8f1d.tar.gz
yosys-699d8e393953a3e5f0c35afec54464e6810f8f1d.tar.bz2
yosys-699d8e393953a3e5f0c35afec54464e6810f8f1d.zip
Merge remote-tracking branch 'origin/master' into xaig_dff
Diffstat (limited to 'techlibs/xilinx')
-rw-r--r--techlibs/xilinx/Makefile.inc2
-rw-r--r--techlibs/xilinx/abc_xc7.box47
-rw-r--r--techlibs/xilinx/abc_xc7.lut2
-rw-r--r--techlibs/xilinx/abc_xc7_nowide.lut10
-rw-r--r--techlibs/xilinx/cells_map.v6
-rw-r--r--techlibs/xilinx/cells_sim.v26
-rw-r--r--techlibs/xilinx/cells_xtra.sh2
-rw-r--r--techlibs/xilinx/cells_xtra.v7
-rw-r--r--techlibs/xilinx/drams.txt20
-rw-r--r--techlibs/xilinx/drams_map.v34
-rw-r--r--techlibs/xilinx/lut_map.v97
-rw-r--r--techlibs/xilinx/synth_xilinx.cc73
12 files changed, 228 insertions, 98 deletions
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc
index 12ec20053..860fcd88c 100644
--- a/techlibs/xilinx/Makefile.inc
+++ b/techlibs/xilinx/Makefile.inc
@@ -30,9 +30,11 @@ $(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_ff.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7_nowide.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_xc7.box b/techlibs/xilinx/abc_xc7.box
index 4caf69320..bb9258e78 100644
--- a/techlibs/xilinx/abc_xc7.box
+++ b/techlibs/xilinx/abc_xc7.box
@@ -1,5 +1,8 @@
# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf
+# NB: Inputs/Outputs must be ordered alphabetically
+# (with exceptions for carry in/out)
+
# F7BMUX slower than F7AMUX
# Inputs: I0 I1 S0
# Outputs: O
@@ -12,34 +15,42 @@ MUXF8 2 1 3 1
104 94 273
# CARRY4 + CARRY4_[ABCD]X
-# Inputs: S0 S1 S2 S3 CYINIT DI0 DI1 DI2 DI3 CI
+# Inputs: CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 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
+# (NB: carry chain input/output must be last
+# input/output and the entire bus has been
+# moved there overriding the otherwise
+# alphabetical ordering)
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
+482 - - - - 223 - - - 222
+598 407 - - - 400 205 - - 334
+584 556 537 - - 523 558 226 - 239
+642 615 596 438 - 582 618 330 227 313
+536 379 - - - 340 - - - 271
+494 465 445 - - 433 469 - - 157
+592 540 520 356 - 512 548 292 - 228
+580 526 507 398 385 508 528 378 380 114
+
+# SLICEM/A6LUT
+# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE
+# Outputs: DPO SPO
+RAM32X1D 4 0 13 2
+- - - - - - 631 472 407 238 127 - -
+631 472 407 238 127 - - - - - - - -
# 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 - -
+RAM64X1D 5 0 15 2
+- - - - - - - 642 631 472 407 238 127 - -
+642 631 472 407 238 127 - - - - - - - - -
# 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 - - - - - - - - - -
+RAM128X1D 6 0 17 2
+- - - - - - - - 1009 998 839 774 605 494 450 - -
+1047 1036 877 812 643 532 478 - - - - - - - - - -
# Inputs: C CE D R \$pastQ
# Outputs: Q
diff --git a/techlibs/xilinx/abc_xc7.lut b/techlibs/xilinx/abc_xc7.lut
index f69a923d0..bcbdec127 100644
--- a/techlibs/xilinx/abc_xc7.lut
+++ b/techlibs/xilinx/abc_xc7.lut
@@ -8,7 +8,7 @@
4 3 127 238 407 472
5 3 127 238 407 472 631
6 5 127 238 407 472 631 642
- # F7AMUX.S+F7BMUX.S + AOUTMUX+COUTMUX / 2
+ # (F7[AB]MUX.S + [AC]OUTMUX) / 2
7 10 464 513 624 793 858 1017 1028
# F8MUX.S+BOUTMUX
# F8MUX.I0+F7MUX.S+BOUTMUX
diff --git a/techlibs/xilinx/abc_xc7_nowide.lut b/techlibs/xilinx/abc_xc7_nowide.lut
new file mode 100644
index 000000000..fab48c879
--- /dev/null
+++ b/techlibs/xilinx/abc_xc7_nowide.lut
@@ -0,0 +1,10 @@
+# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/timings/CLBLL_L.sdf
+# and https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/tile_type_CLBLL_L.json
+
+# K area delay
+1 1 127
+2 2 127 238
+3 3 127 238 407
+4 3 127 238 407 472
+5 3 127 238 407 472 631
+6 5 127 238 407 472 631 642
diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v
index b5114758c..9a316fc96 100644
--- a/techlibs/xilinx/cells_map.v
+++ b/techlibs/xilinx/cells_map.v
@@ -20,16 +20,14 @@
// 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;
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index bf7a0ed44..5a148be01 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -173,8 +173,8 @@ module XORCY(output O, input CI, LI);
assign O = CI ^ LI;
endmodule
-(* 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);
+(* abc_box_id = 3, abc_carry="CI,CO", lib_whitebox *)
+module CARRY4(output [3:0] CO, O, input CI, 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];
@@ -281,7 +281,25 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE);
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
endmodule
-//(* abc_box_id = 4 /*, lib_whitebox*/ *)
+(* abc_box_id = 4, abc_scc_break="D,WE" *)
+module RAM32X1D (
+ output DPO, SPO,
+ input D, WCLK, WE,
+ input A0, A1, A2, A3, A4,
+ input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
+);
+ parameter INIT = 32'h0;
+ parameter IS_WCLK_INVERTED = 1'b0;
+ wire [4:0] a = {A4, A3, A2, A1, A0};
+ wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
+ reg [31:0] mem = INIT;
+ assign SPO = mem[a];
+ assign DPO = mem[dpra];
+ wire clk = WCLK ^ IS_WCLK_INVERTED;
+ always @(posedge clk) if (WE) mem[a] <= D;
+endmodule
+
+(* abc_box_id = 5, abc_scc_break="D,WE" *)
module RAM64X1D (
output DPO, SPO,
input D, WCLK, WE,
@@ -299,7 +317,7 @@ module RAM64X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
-//(* abc_box_id = 5 /*, lib_whitebox*/ *)
+(* abc_box_id = 6, abc_scc_break="D,WE" *)
module RAM128X1D (
output DPO, SPO,
input D, WCLK, WE,
diff --git a/techlibs/xilinx/cells_xtra.sh b/techlibs/xilinx/cells_xtra.sh
index 2b384f405..53b528820 100644
--- a/techlibs/xilinx/cells_xtra.sh
+++ b/techlibs/xilinx/cells_xtra.sh
@@ -120,7 +120,7 @@ function xtract_cell_decl()
xtract_cell_decl RAM128X1S
xtract_cell_decl RAM256X1S
xtract_cell_decl RAM32M
- xtract_cell_decl RAM32X1D
+ #xtract_cell_decl RAM32X1D
xtract_cell_decl RAM32X1S
xtract_cell_decl RAM32X1S_1
xtract_cell_decl RAM32X2S
diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v
index 0ec3d0df0..15fa1b63a 100644
--- a/techlibs/xilinx/cells_xtra.v
+++ b/techlibs/xilinx/cells_xtra.v
@@ -3694,13 +3694,6 @@ module RAM32M (...);
input WE;
endmodule
-module RAM32X1D (...);
- parameter [31:0] INIT = 32'h00000000;
- parameter [0:0] IS_WCLK_INVERTED = 1'b0;
- output DPO, SPO;
- input A0, A1, A2, A3, A4, D, DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, WCLK, WE;
-endmodule
-
module RAM32X1S (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
diff --git a/techlibs/xilinx/drams.txt b/techlibs/xilinx/drams.txt
index 91632bcee..2613c206c 100644
--- a/techlibs/xilinx/drams.txt
+++ b/techlibs/xilinx/drams.txt
@@ -1,4 +1,17 @@
+bram $__XILINX_RAM32X1D
+ init 1
+ abits 5
+ dbits 1
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 0 1
+ transp 0 0
+ clocks 0 1
+ clkpol 0 2
+endbram
+
bram $__XILINX_RAM64X1D
init 1
abits 6
@@ -25,6 +38,13 @@ bram $__XILINX_RAM128X1D
clkpol 0 2
endbram
+match $__XILINX_RAM32X1D
+ min bits 3
+ min wports 1
+ make_outreg
+ or_next_if_better
+endmatch
+
match $__XILINX_RAM64X1D
min bits 5
min wports 1
diff --git a/techlibs/xilinx/drams_map.v b/techlibs/xilinx/drams_map.v
index 47476b592..77041ca86 100644
--- a/techlibs/xilinx/drams_map.v
+++ b/techlibs/xilinx/drams_map.v
@@ -1,4 +1,38 @@
+module \$__XILINX_RAM32X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
+ parameter [31:0] INIT = 32'bx;
+ parameter CLKPOL2 = 1;
+ input CLK1;
+
+ input [4:0] A1ADDR;
+ output A1DATA;
+
+ input [4:0] B1ADDR;
+ input B1DATA;
+ input B1EN;
+
+ RAM32X1D #(
+ .INIT(INIT),
+ .IS_WCLK_INVERTED(!CLKPOL2)
+ ) _TECHMAP_REPLACE_ (
+ .DPRA0(A1ADDR[0]),
+ .DPRA1(A1ADDR[1]),
+ .DPRA2(A1ADDR[2]),
+ .DPRA3(A1ADDR[3]),
+ .DPRA4(A1ADDR[4]),
+ .DPO(A1DATA),
+
+ .A0(B1ADDR[0]),
+ .A1(B1ADDR[1]),
+ .A2(B1ADDR[2]),
+ .A3(B1ADDR[3]),
+ .A4(B1ADDR[4]),
+ .D(B1DATA),
+ .WCLK(CLK1),
+ .WE(B1EN)
+ );
+endmodule
+
module \$__XILINX_RAM64X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
parameter [63:0] INIT = 64'bx;
parameter CLKPOL2 = 1;
diff --git a/techlibs/xilinx/lut_map.v b/techlibs/xilinx/lut_map.v
index d07c59dee..13d3c3268 100644
--- a/techlibs/xilinx/lut_map.v
+++ b/techlibs/xilinx/lut_map.v
@@ -29,61 +29,86 @@ module \$lut (A, Y);
input [WIDTH-1:0] A;
output Y;
+ // Need to swap input ordering, and fix init accordingly,
+ // to match ABC's expectation of LUT inputs in non-decreasing
+ // delay order
+ function [WIDTH-1:0] permute_index;
+ input [WIDTH-1:0] i;
+ integer j;
+ begin
+ permute_index = 0;
+ for (j = 0; j < WIDTH; j = j + 1)
+ permute_index[WIDTH-1 - j] = i[j];
+ end
+ endfunction
+
+ function [2**WIDTH-1:0] permute_init;
+ input [2**WIDTH-1:0] orig;
+ integer i;
+ begin
+ permute_init = 0;
+ for (i = 0; i < 2**WIDTH; i = i + 1)
+ permute_init[i] = orig[permute_index(i)];
+ end
+ endfunction
+
+ parameter [2**WIDTH-1:0] P_LUT = permute_init(LUT);
+
generate
if (WIDTH == 1) begin
- LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ LUT1 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]));
end else
if (WIDTH == 2) begin
- LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
- .I0(A[0]), .I1(A[1]));
+ LUT2 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ .I0(A[1]), .I1(A[0]));
end else
if (WIDTH == 3) begin
- LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
- .I0(A[0]), .I1(A[1]), .I2(A[2]));
+ LUT3 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ .I0(A[2]), .I1(A[1]), .I2(A[0]));
end else
if (WIDTH == 4) begin
- LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]));
+ LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ .I0(A[3]), .I1(A[2]), .I2(A[1]),
+ .I3(A[0]));
end else
if (WIDTH == 5) begin
- LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]));
+ LUT5 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ .I0(A[4]), .I1(A[3]), .I2(A[2]),
+ .I3(A[1]), .I4(A[0]));
end else
if (WIDTH == 6) begin
- LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
+ LUT6 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
+ .I0(A[5]), .I1(A[4]), .I2(A[3]),
+ .I3(A[2]), .I4(A[1]), .I5(A[0]));
end else
if (WIDTH == 7) begin
wire T0, T1;
- LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[6]));
+ LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0),
+ .I0(A[6]), .I1(A[5]), .I2(A[4]),
+ .I3(A[3]), .I4(A[2]), .I5(A[1]));
+ LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1),
+ .I0(A[6]), .I1(A[5]), .I2(A[4]),
+ .I3(A[3]), .I4(A[2]), .I5(A[1]));
+ MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[0]));
end else
if (WIDTH == 8) begin
wire T0, T1, T2, T3, T4, T5;
- LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[191:128])) fpga_lut_2 (.O(T2),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[255:192])) fpga_lut_3 (.O(T3),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[6]));
- MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[6]));
- MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[7]));
+ LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0),
+ .I0(A[7]), .I1(A[6]), .I2(A[5]),
+ .I3(A[4]), .I4(A[3]), .I5(A[2]));
+ LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1),
+ .I0(A[7]), .I1(A[6]), .I2(A[5]),
+ .I3(A[4]), .I4(A[3]), .I5(A[2]));
+ LUT6 #(.INIT(P_LUT[191:128])) fpga_lut_2 (.O(T2),
+ .I0(A[7]), .I1(A[6]), .I2(A[5]),
+ .I3(A[4]), .I4(A[3]), .I5(A[2]));
+ LUT6 #(.INIT(P_LUT[255:192])) fpga_lut_3 (.O(T3),
+ .I0(A[7]), .I1(A[6]), .I2(A[5]),
+ .I3(A[4]), .I4(A[3]), .I5(A[2]));
+ MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[1]));
+ MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[1]));
+ MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[0]));
end else begin
wire _TECHMAP_FAIL_ = 1;
end
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index d3f096220..cdc64db1d 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -45,8 +45,9 @@ struct SynthXilinxPass : public ScriptPass
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
- log(" -arch {xcup|xcu|xc7|xc6s}\n");
+ log(" -family {xcup|xcu|xc7|xc6s}\n");
log(" run synthesis for the specified Xilinx architecture\n");
+ log(" generate the synthesis netlist for the specified family.\n");
log(" default: xc7\n");
log("\n");
log(" -edif <file>\n");
@@ -61,9 +62,6 @@ 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");
@@ -73,6 +71,12 @@ struct SynthXilinxPass : public ScriptPass
log(" -nosrl\n");
log(" disable inference of shift registers\n");
log("\n");
+ log(" -nocarry\n");
+ log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
+ log("\n");
+ log(" -nowidelut\n");
+ log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
+ log("\n");
log(" -run <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
log(" from label is synonymous to 'begin', and empty to label is\n");
@@ -93,15 +97,15 @@ struct SynthXilinxPass : public ScriptPass
log("\n");
}
- std::string top_opt, edif_file, blif_file, abc, arch;
- bool flatten, retime, vpr, nocarry, nobram, nodram, nosrl;
+ std::string top_opt, edif_file, blif_file, family;
+ bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
void clear_flags() YS_OVERRIDE
{
top_opt = "-auto-top";
edif_file.clear();
blif_file.clear();
- abc = "abc";
+ family = "xc7";
flatten = false;
retime = false;
vpr = false;
@@ -109,7 +113,9 @@ struct SynthXilinxPass : public ScriptPass
nobram = false;
nodram = false;
nosrl = false;
- arch = "xc7";
+ nocarry = false;
+ nowidelut = false;
+ abc9 = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -124,8 +130,8 @@ struct SynthXilinxPass : public ScriptPass
top_opt = "-top " + args[++argidx];
continue;
}
- if (args[argidx] == "-arch" && argidx+1 < args.size()) {
- arch = args[++argidx];
+ if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
+ family = args[++argidx];
continue;
}
if (args[argidx] == "-edif" && argidx+1 < args.size()) {
@@ -152,6 +158,14 @@ struct SynthXilinxPass : public ScriptPass
retime = true;
continue;
}
+ if (args[argidx] == "-nocarry") {
+ nocarry = true;
+ continue;
+ }
+ if (args[argidx] == "-nowidelut") {
+ nowidelut = true;
+ continue;
+ }
if (args[argidx] == "-vpr") {
vpr = true;
continue;
@@ -173,15 +187,15 @@ struct SynthXilinxPass : public ScriptPass
continue;
}
if (args[argidx] == "-abc9") {
- abc = "abc9";
+ abc9 = true;
continue;
}
break;
}
extra_args(args, argidx, design);
- if (arch != "xcup" && arch != "xcu" && arch != "xc7" && arch != "xc6s")
- log_cmd_error("Invalid Xilinx -arch setting: %s\n", arch.c_str());
+ if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s")
+ 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");
@@ -225,11 +239,6 @@ struct SynthXilinxPass : public ScriptPass
// 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')")) {
@@ -268,7 +277,7 @@ struct SynthXilinxPass : public ScriptPass
techmap_files += " -map +/xilinx/arith_map.v";
if (vpr)
techmap_files += " -D _EXPLICIT_CARRY";
- else if (abc == "abc9")
+ else if (abc9)
techmap_files += " -D _CLB_CARRY";
}
run("techmap " + techmap_files);
@@ -276,7 +285,7 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("map_cells")) {
- if (abc == "abc9")
+ if (abc9)
run("techmap -map +/techmap.v -map +/xilinx/cells_map.v -D _ABC -map +/xilinx/ff_map.v");
else
run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
@@ -284,21 +293,31 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("map_luts")) {
- if (abc == "abc9") {
+ 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')");
+ else if (abc9) {
+ if (family != "xc7")
+ log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
run("read_verilog -icells -lib +/xilinx/abc_ff.v");
- run(abc + " -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + XC7_WIRE_DELAY + string(retime ? " -retime" : ""));
+ if (nowidelut)
+ run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
+ else
+ run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
+ }
+ else {
+ if (nowidelut)
+ run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
+ else
+ run("abc -luts 2:2,3,6:5,10,20" + 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("clean");
// This shregmap call infers fixed length shift registers after abc
// has performed any necessary retiming
if (!nosrl || help_mode)
run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')");
- if (abc == "abc9")
+ if (abc9)
run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v");
else
run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/ff_map.v");