diff options
Diffstat (limited to 'techlibs/xilinx')
| -rw-r--r-- | techlibs/xilinx/Makefile.inc | 1 | ||||
| -rw-r--r-- | techlibs/xilinx/abc_ff.v | 186 | ||||
| -rw-r--r-- | techlibs/xilinx/abc_xc7.box | 43 | ||||
| -rw-r--r-- | techlibs/xilinx/cells_sim.v | 36 | ||||
| -rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 8 | ||||
| -rw-r--r-- | techlibs/xilinx/xc7_brams_bb.v | 18 | 
6 files changed, 272 insertions, 20 deletions
| diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index 2c6e7432e..a9e0c5c7b 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -39,6 +39,7 @@ $(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/mux_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)) diff --git a/techlibs/xilinx/abc_ff.v b/techlibs/xilinx/abc_ff.v new file mode 100644 index 000000000..36e1a08e4 --- /dev/null +++ b/techlibs/xilinx/abc_ff.v @@ -0,0 +1,186 @@ +/* + *  yosys -- Yosys Open SYnthesis Suite + * + *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> + *                2019  Eddie Hung    <eddie@fpgeh.com> + * + *  Permission to use, copy, modify, and/or distribute this software for any + *  purpose with or without fee is hereby granted, provided that the above + *  copyright notice and this permission notice appear in all copies. + * + *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// ============================================================================ + +// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 + +module FDRE (output reg Q, input C, CE, D, R); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_R_INVERTED = 1'b0; +  wire \$nextQ ; +  \$__ABC_FDRE #( +    .INIT(INIT), +    .IS_C_INVERTED(IS_C_INVERTED), +    .IS_D_INVERTED(IS_D_INVERTED), +    .IS_R_INVERTED(IS_R_INVERTED) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule +module FDRE_1 (output reg Q, input C, CE, D, R); +  parameter [0:0] INIT = 1'b0; +  wire \$nextQ ; +  \$__ABC_FDRE_1 #(.INIT(|0) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); +endmodule + +module FDCE (output reg Q, input C, CE, D, CLR); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_CLR_INVERTED = 1'b0; +  wire \$nextQ , \$currQ ; +  \$__ABC_FDCE #( +    .INIT(INIT), +    .IS_C_INVERTED(IS_C_INVERTED), +    .IS_D_INVERTED(IS_D_INVERTED), +    .IS_CLR_INVERTED(IS_CLR_INVERTED) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); +  \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); +endmodule +module FDCE_1 (output reg Q, input C, CE, D, CLR); +  parameter [0:0] INIT = 1'b0; +  wire \$nextQ , \$currQ ; +  \$__ABC_FDCE_1 #( +    .INIT(INIT) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); +  \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); +endmodule + +module FDPE (output reg Q, input C, CE, D, PRE); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_PRE_INVERTED = 1'b0; +  wire \$nextQ , \$currQ ; +  \$__ABC_FDPE #( +    .INIT(INIT), +    .IS_C_INVERTED(IS_C_INVERTED), +    .IS_D_INVERTED(IS_D_INVERTED), +    .IS_PRE_INVERTED(IS_PRE_INVERTED) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); +  \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); +endmodule +module FDPE_1 (output reg Q, input C, CE, D, PRE); +  parameter [0:0] INIT = 1'b0; +  wire \$nextQ , \$currQ ; +  \$__ABC_FDPE_1 #( +    .INIT(INIT) +  ) _TECHMAP_REPLACE_ ( +    .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) +  ); +  \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); +  \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); +endmodule + +`ifndef _ABC +module \$__ABC_FF_ (input C, D, output Q); +endmodule + +(* abc_box_id = 1000 *) +module \$__ABC_ASYNC (input A, S, output Y); +endmodule + +(* abc_box_id=1001, lib_whitebox, abc_flop="FDRE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, +                     (* abc_flop_clk *) input C, +                     (* abc_flop_en *)  input CE, +                     (* abc_flop_d *)   input D, +                     input R, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_R_INVERTED = 1'b0; +  assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); +endmodule + +(* abc_box_id = 1002, lib_whitebox, abc_flop = "FDRE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +module \$__ABC_FDRE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, +                       (* abc_flop_clk *) input C, +                       (* abc_flop_en *)  input CE, +                       (* abc_flop_d *)   input D, +                       input R, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); +endmodule + +(* abc_box_id = 1003, lib_whitebox, abc_flop = "FDCE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, +                     (* abc_flop_clk *) input C, +                     (* abc_flop_en *)  input CE, +                     (* abc_flop_d *)   input D, +                     input CLR, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_CLR_INVERTED = 1'b0; +  assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id = 1004, lib_whitebox, abc_flop = "FDCE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +module \$__ABC_FDCE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, +                       (* abc_flop_clk *) input C, +                       (* abc_flop_en *)  input CE, +                       (* abc_flop_d *)   input D, +                       input CLR, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  assign Q = (CE && !CLR) ? D : \$pastQ ; +endmodule + +(* abc_box_id=1005, lib_whitebox, abc_flop="FDPE", abc_flop_clk_pol="!IS_C_INVERTED", abc_flop_en_pol=1 *) +module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, +                     (* abc_flop_clk *) input C, +                     (* abc_flop_en *)  input CE, +                     (* abc_flop_d *)   input D, +                     input PRE, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_PRE_INVERTED = 1'b0; +  assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; +endmodule + +(* abc_box_id=1006, lib_whitebox, abc_flop="FDPE_1", abc_flop_clk_pol=1, abc_flop_en_pol=1 *) +module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, +                       (* abc_flop_clk *) input C, +                       (* abc_flop_en *)  input CE, +                       (* abc_flop_d *)   input D, +                       input PRE, \$pastQ ); +  parameter [0:0] INIT = 1'b0; +  assign Q = (CE && !PRE) ? D : \$pastQ ; +endmodule + +`endif diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box index 3789ff350..16040662c 100644 --- a/techlibs/xilinx/abc_xc7.box +++ b/techlibs/xilinx/abc_xc7.box @@ -1,4 +1,5 @@  # Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf +#                 https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf  # NB: Inputs/Outputs must be ordered alphabetically  #     (with exceptions for carry in/out) @@ -14,6 +15,7 @@ F7MUX 1 1 3 1  MUXF8 2 1 3 1  104 94 273 +# Box containing MUXF7.[AB] + MUXF8  # Inputs: I0 I1 I2 I3 S0 S1  # Outputs: O  $__MUXF78 3 1 6 1 @@ -56,3 +58,44 @@ RAM64X1D 6 0 15 2  RAM128X1D 7 0 17 2  -    -    -   -   -   -   -   - 1009 998 839 774 605 494 450 - -  1047 1036 877 812 643 532 478 - -    -   -   -   -   -   -   - - + +# Box to emulate async behaviour of FD[CP]* +# Inputs: A S +# Outputs: Y +$__ABC_ASYNC 1000 0 2 1 +0 764 + +# The following FD*.{CE,R,CLR,PRE) are offset by 46ps to +# reflect the -46ps Tsu +# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 +# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 + +# Inputs: C CE D R \$pastQ +# Outputs: Q +FDRE 1001 1 5 1 +0 151 0 446 0 + +# Inputs: C CE D R \$pastQ +# Outputs: Q +FDRE_1 1002 1 5 1 +0 151 0 446 0 + +# Inputs: C CE CLR D \$pastQ +# Outputs: Q +FDCE 1003 1 5 1 +0 151 806 0 0 + +# Inputs: C CE CLR D \$pastQ +# Outputs: Q +FDCE_1 1004 1 5 1 +0 151 806 0 0 + +# Inputs: C CE D PRE \$pastQ +# Outputs: Q +FDPE 1005 1 5 1 +0 151 0 806 0 + +# Inputs: C CE D PRE \$pastQ +# Outputs: Q +FDPE_1 1006 1 5 1 +0 151 0 806 0 diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 05e46b4e7..e5d9f480b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -181,8 +181,14 @@ module XORCY(output O, input CI, LI);    assign O = CI ^ LI;  endmodule -(* abc_box_id = 4, abc_carry="CI,CO", lib_whitebox *) -module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S); +(* abc_box_id = 4, 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 +);    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]; @@ -289,10 +295,12 @@ 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 = 5, abc_scc_break="D,WE" *) +(* abc_box_id = 5 *)  module RAM32X1D (    output DPO, SPO, -  input  D, WCLK, WE, +  (* abc_scc_break *) input D, +  input  WCLK, +  (* abc_scc_break *) input WE,    input  A0, A1, A2, A3, A4,    input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4  ); @@ -307,10 +315,12 @@ module RAM32X1D (    always @(posedge clk) if (WE) mem[a] <= D;  endmodule -(* abc_box_id = 6, abc_scc_break="D,WE" *) +(* abc_box_id = 6 *)  module RAM64X1D (    output DPO, SPO, -  input  D, WCLK, WE, +  (* abc_scc_break *) input D, +  input  WCLK, +  (* abc_scc_break *) input WE,    input  A0, A1, A2, A3, A4, A5,    input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5  ); @@ -325,10 +335,12 @@ module RAM64X1D (    always @(posedge clk) if (WE) mem[a] <= D;  endmodule -(* abc_box_id = 7, abc_scc_break="D,WE" *) +(* abc_box_id = 7 *)  module RAM128X1D (    output       DPO, SPO, -  input        D, WCLK, WE, +  (* abc_scc_break *) input D, +  input        WCLK, +  (* abc_scc_break *) input WE,    input  [6:0] A, DPRA  );    parameter INIT = 128'h0; @@ -341,7 +353,8 @@ module RAM128X1D (  endmodule  module SRL16E ( -  output Q, +  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 +  (* abc_arrival=1472 *) output Q,    input A0, A1, A2, A3, CE, CLK, D  );    parameter [15:0] INIT = 16'h0000; @@ -359,8 +372,9 @@ module SRL16E (  endmodule  module SRLC32E ( -  output Q, -  output Q31, +  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 +  (* abc_arrival=1472 *) output Q, +  (* abc_arrival=1114 *) output Q31,    input [4:0] A,    input CE, CLK, D  ); diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index d143c6823..6456dbdf4 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -376,6 +376,8 @@ struct SynthXilinxPass : public ScriptPass  			std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v";  			if (widemux > 0)  				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); +			if (abc9) +				techmap_args += " -map +/xilinx/ff_map.v -D _ABC -map +/xilinx/abc_ff.v";  			run("techmap " + techmap_args);  			run("clean");  		} @@ -387,6 +389,7 @@ struct SynthXilinxPass : public ScriptPass  			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");  				if (nowidelut)  					run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));  				else @@ -404,7 +407,10 @@ struct SynthXilinxPass : public ScriptPass  			//   has performed any necessary retiming  			if (!nosrl || help_mode)  				run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); -			run("techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); +			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");  			run("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");  			run("clean"); diff --git a/techlibs/xilinx/xc7_brams_bb.v b/techlibs/xilinx/xc7_brams_bb.v index a682ba4a7..0e8cb406c 100644 --- a/techlibs/xilinx/xc7_brams_bb.v +++ b/techlibs/xilinx/xc7_brams_bb.v @@ -1,3 +1,5 @@ +// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147 +  module RAMB18E1 (  	input CLKARDCLK,  	input CLKBWRCLK, @@ -19,10 +21,10 @@ module RAMB18E1 (  	input [1:0] WEA,  	input [3:0] WEBWE, -	output [15:0] DOADO, -	output [15:0] DOBDO, -	output [1:0] DOPADOP, -	output [1:0] DOPBDOP +	(* abc_arrival=2454 *) output [15:0] DOADO, +	(* abc_arrival=2454 *) output [15:0] DOBDO, +	(* abc_arrival=2454 *) output [1:0] DOPADOP, +	(* abc_arrival=2454 *) output [1:0] DOPBDOP  );  	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;  	parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -143,10 +145,10 @@ module RAMB36E1 (  	input [3:0] WEA,  	input [7:0] WEBWE, -	output [31:0] DOADO, -	output [31:0] DOBDO, -	output [3:0] DOPADOP, -	output [3:0] DOPBDOP +	(* abc_arrival=2454 *) output [31:0] DOADO, +	(* abc_arrival=2454 *) output [31:0] DOBDO, +	(* abc_arrival=2454 *) output [3:0] DOPADOP, +	(* abc_arrival=2454 *) output [3:0] DOPBDOP  );  	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;  	parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | 
