diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-07-01 10:44:42 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-07-01 10:44:42 -0700 |
commit | 699d8e393953a3e5f0c35afec54464e6810f8f1d (patch) | |
tree | 4edf4b25dd3c9f8eaf1dad737baa49a04f78ec3f /techlibs/xilinx | |
parent | 75d92fb590b190e0da43e99853f839b7afb10f83 (diff) | |
parent | 0067dc44f3928833eede2b9bb40260be78e11a93 (diff) | |
download | yosys-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.inc | 2 | ||||
-rw-r--r-- | techlibs/xilinx/abc_xc7.box | 47 | ||||
-rw-r--r-- | techlibs/xilinx/abc_xc7.lut | 2 | ||||
-rw-r--r-- | techlibs/xilinx/abc_xc7_nowide.lut | 10 | ||||
-rw-r--r-- | techlibs/xilinx/cells_map.v | 6 | ||||
-rw-r--r-- | techlibs/xilinx/cells_sim.v | 26 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.sh | 2 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.v | 7 | ||||
-rw-r--r-- | techlibs/xilinx/drams.txt | 20 | ||||
-rw-r--r-- | techlibs/xilinx/drams_map.v | 34 | ||||
-rw-r--r-- | techlibs/xilinx/lut_map.v | 97 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 73 |
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"); |