diff options
Diffstat (limited to 'techlibs')
| -rw-r--r-- | techlibs/xilinx/abc9_map.v | 356 | ||||
| -rw-r--r-- | techlibs/xilinx/abc9_model.v | 7 | ||||
| -rw-r--r-- | techlibs/xilinx/abc9_unmap.v | 8 | ||||
| -rw-r--r-- | techlibs/xilinx/abc9_xc7.box | 51 | ||||
| -rw-r--r-- | techlibs/xilinx/cells_sim.v | 82 | ||||
| -rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 20 | 
6 files changed, 476 insertions, 48 deletions
| diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 0eac08f3f..49000ea25 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -18,7 +18,361 @@   *   */ -// ============================================================================ +// The following techmapping rules are intended to be run (with -max_iter 1) +//   before invoking the `abc9` pass in order to transform the design into +//   a format that it understands. +// +// For example, (complex) flip-flops are expected to be described as an +//   combinatorial box (containing all control logic such as clock enable +//   or synchronous resets) followed by a basic D-Q flop. +// Yosys will automatically analyse the simulation model (described in +//   cells_sim.v) and detach any $_DFF_P_ or $_DFF_N_ cells present in +//   order to extract the combinatorial control logic left behind. +//   Specifically, a simulation model similar to the one below: +// +//                ++===================================++ +//                ||                        Sim model  || +//                ||      /\/\/\/\                     || +//            D -->>-----<        >     +------+       || +//            R -->>-----<  Comb. >     |$_DFF_|       || +//           CE -->>-----<  logic >-----| [NP]_|---+---->>-- Q +//                ||  +--<        >     +------+   |   || +//                ||  |   \/\/\/\/                 |   || +//                ||  |                            |   || +//                ||  +----------------------------+   || +//                ||                                   || +//                ++===================================++ +// +//   is transformed into: +// +//                ++==================++ +//                ||         Comb box || +//                ||                  || +//                ||      /\/\/\/\    || +//           D  -->>-----<        >   ||            +------+ +//           R  -->>-----<  Comb. >   ||            |$__ABC| +//          CE  -->>-----<  logic >--->>-- $nextQ --| _FF_ |--+-->> Q +// $abc9_currQ +-->>-----<        >   ||            +------+  | +//             |  ||      \/\/\/\/    ||                      | +//             |  ||                  ||                      | +//             |  ++==================++                      | +//             |                                              | +//             +----------------------------------------------+ +// +// The purpose of the following FD* rules are to wrap the flop with: +// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9 +//     the connectivity of its basic D-Q flop +// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to +//     capture asynchronous behaviour +// (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock +//     domain and polarity (used when partitioning the module so that `abc9' only +//     performs sequential synthesis (with reachability analysis) correctly on +//     one domain at a time) and also used to infer the optional delay target +//     from the (* abc9_clock_period = %d *) attribute attached to any wire +//     within +// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial +//     state +// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback +//     into the (combinatorial) FD* cell to facilitate clock-enable behaviour +// +// In order to perform sequential synthesis, `abc9' also requires that +// the initial value of all flops be zero. + +module FDRE (output 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 QQ, $nextQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDSE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_S_INVERTED(IS_R_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .S(R) +    ); +  end +  else begin +    assign Q = QQ; +    FDRE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_R_INVERTED(IS_R_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) +    ); +  end +  endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +endmodule +module FDRE_1 (output Q, input C, CE, D, R); +  parameter [0:0] INIT = 1'b0; +  wire QQ, $nextQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDSE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .S(R) +    ); +  end +  else begin +    assign Q = QQ; +    FDRE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R) +    ); +  end +  endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +endmodule + +module FDCE (output 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 QQ, $nextQ, $abc9_currQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDPE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_PRE_INVERTED(IS_CLR_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .PRE(CLR) +                                            // ^^^ Note that async +                                            //     control is not directly +                                            //     supported by abc9 but its +                                            //     behaviour is captured by +                                            //     $__ABC9_ASYNC below +    ); +  end +  else begin +    assign Q = QQ; +    FDCE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_CLR_INVERTED(IS_CLR_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) +                                           // ^^^ Note that async +                                           //     control is not directly +                                           //     supported by abc9 but its +                                           //     behaviour is captured by +                                           //     $__ABC9_ASYNC below +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); +  // Since this is an async flop, async behaviour is also dealt with +  //   using the $_ABC9_ASYNC box by abc9_map.v +  \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +endmodule +module FDCE_1 (output Q, input C, CE, D, CLR); +  parameter [0:0] INIT = 1'b0; +  wire QQ, $nextQ, $abc9_currQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDPE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .PRE(CLR) +                                            // ^^^ Note that async +                                            //     control is not directly +                                            //     supported by abc9 but its +                                            //     behaviour is captured by +                                            //     $__ABC9_ASYNC below +    ); +  end +  else begin +    assign Q = QQ; +    FDCE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR) +                                           // ^^^ Note that async +                                           //     control is not directly +                                           //     supported by abc9 but its +                                           //     behaviour is captured by +                                           //     $__ABC9_ASYNC below +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); +  \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +endmodule + +module FDPE (output Q, input C, CE, D, PRE); +  parameter [0:0] INIT = 1'b1; +  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 QQ, $nextQ, $abc9_currQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDCE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_CLR_INVERTED(IS_PRE_INVERTED), +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .CLR(PRE) +                                            // ^^^ Note that async +                                            //     control is not directly +                                            //     supported by abc9 but its +                                            //     behaviour is captured by +                                            //     $__ABC9_ASYNC below +    ); +  end +  else begin +    assign Q = QQ; +    FDPE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_PRE_INVERTED(IS_PRE_INVERTED), +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) +                                           // ^^^ Note that async +                                           //     control is not directly +                                           //     supported by abc9 but its +                                           //     behaviour is captured by +                                           //     $__ABC9_ASYNC below +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); +  \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +endmodule +module FDPE_1 (output Q, input C, CE, D, PRE); +  parameter [0:0] INIT = 1'b1; +  wire QQ, $nextQ, $abc9_currQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDCE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .CLR(PRE) +                                            // ^^^ Note that async +                                            //     control is not directly +                                            //     supported by abc9 but its +                                            //     behaviour is captured by +                                            //     $__ABC9_ASYNC below +    ); +  end +  else begin +    assign Q = QQ; +    FDPE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE) +                                           // ^^^ Note that async +                                           //     control is not directly +                                           //     supported by abc9 but its +                                           //     behaviour is captured by +                                           //     $__ABC9_ASYNC below +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ)); +  \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; +endmodule + +module FDSE (output Q, input C, CE, D, S); +  parameter [0:0] INIT = 1'b1; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_S_INVERTED = 1'b0; +  wire QQ, $nextQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDRE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_R_INVERTED(IS_S_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .R(S) +    ); +  end +  else begin +    assign Q = QQ; +    FDSE #( +      .INIT(1'b0), +      .IS_C_INVERTED(IS_C_INVERTED), +      .IS_D_INVERTED(IS_D_INVERTED), +      .IS_S_INVERTED(IS_S_INVERTED) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +endmodule +module FDSE_1 (output Q, input C, CE, D, S); +  parameter [0:0] INIT = 1'b1; +  wire QQ, $nextQ; +  generate if (INIT == 1'b1) begin +    assign Q = ~QQ; +    FDRE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(~D), .Q($nextQ), .C(C), .CE(CE), .R(S) +    ); +  end +  else begin +    assign Q = QQ; +    FDSE_1 #( +      .INIT(1'b0) +    ) _TECHMAP_REPLACE_ ( +      .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S) +    ); +  end endgenerate +  \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(QQ)); + +  // Special signals +  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; +  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; +endmodule  module RAM32X1D (    output DPO, SPO, diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index 8c8e1556c..cc0e5ec41 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -30,6 +30,13 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);                  : (S0 ? I1 : I0);  endmodule +module \$__ABC9_FF_ (input D, output Q); +endmodule + +(* abc_box_id = 1000 *) +module \$__ABC9_ASYNC (input A, S, output Y); +endmodule +  // Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}  //   Necessary since RAMD* and SRL* have both combinatorial (i.e.  //   same-cycle read operation) and sequential (write operation diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v index ad6469702..21fe78d08 100644 --- a/techlibs/xilinx/abc9_unmap.v +++ b/techlibs/xilinx/abc9_unmap.v @@ -20,6 +20,14 @@  // ============================================================================ +module \$__ABC9_ASYNC (input A, S, output Y); +  assign Y = A; +endmodule + +module \$__ABC9_FF_ (input D, output Q); +  assign Q = D; +endmodule +  module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);    assign Y = A;  endmodule diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 774388d49..24b1898a4 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -41,6 +41,57 @@ CARRY4 4 1 10 8  592 540 520 356 -   512 548 292 -   228  580 526 507 398 385 508 528 378 380 114 +# Box to emulate async behaviour of FD[CP]* +# Inputs: A S +# Outputs: Y +$__ABC9_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 \$currQ +# Outputs: Q +FDRE 1001 1 5 1 +0 151 0 446 0 + +# Inputs: C CE D R \$currQ +# Outputs: Q +FDRE_1 1002 1 5 1 +0 151 0 446 0 + +# Inputs: C CE CLR D \$currQ +# Outputs: Q +FDCE 1003 1 5 1 +0 151 806 0 0 + +# Inputs: C CE CLR D \$currQ +# Outputs: Q +FDCE_1 1004 1 5 1 +0 151 806 0 0 + +# Inputs: C CE D PRE \$currQ +# Outputs: Q +FDPE 1005 1 5 1 +0 151 0 806 0 + +# Inputs: C CE D PRE \$currQ +# Outputs: Q +FDPE_1 1006 1 5 1 +0 151 0 806 0 + +# Inputs: C CE D S \$currQ +# Outputs: Q +FDSE 1007 1 5 1 +0 151 0 446 0 + +# Inputs: C CE D S \$currQ +# Outputs: Q +FDSE_1 1008 1 5 1 +0 151 0 446 0 +  # SLICEM/A6LUT  # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}  #   Necessary since RAMD* and SRL* have both combinatorial (i.e. diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 3ed0759db..ef963793c 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -283,6 +283,7 @@ endmodule  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250 +(* abc9_box_id=1001, lib_whitebox, abc9_flop *)  module FDRE (    (* abc9_arrival=303 *)    output reg Q, @@ -306,29 +307,20 @@ module FDRE (    endcase endgenerate  endmodule -module FDSE ( +(* abc9_box_id=1002, lib_whitebox, abc9_flop *) +module FDRE_1 (    (* abc9_arrival=303 *)    output reg Q,    (* clkbuf_sink *) -  (* invertible_pin = "IS_C_INVERTED" *)    input C, -  input CE, -  (* invertible_pin = "IS_D_INVERTED" *) -  input D, -  (* invertible_pin = "IS_S_INVERTED" *) -  input S +  input CE, D, R  ); -  parameter [0:0] INIT = 1'b1; -  parameter [0:0] IS_C_INVERTED = 1'b0; -  parameter [0:0] IS_D_INVERTED = 1'b0; -  parameter [0:0] IS_S_INVERTED = 1'b0; +  parameter [0:0] INIT = 1'b0;    initial Q <= INIT; -  generate case (|IS_C_INVERTED) -    1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; -    1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; -  endcase endgenerate +  always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D;  endmodule +(* abc9_box_id=1003, lib_whitebox, abc9_flop *)  module FDCE (    (* abc9_arrival=303 *)    output reg Q, @@ -354,6 +346,20 @@ module FDCE (    endcase endgenerate  endmodule +(* abc9_box_id=1004, lib_whitebox, abc9_flop *) +module FDCE_1 ( +  (* abc9_arrival=303 *) +  output reg Q, +  (* clkbuf_sink *) +  input C, +  input CE, D, CLR +); +  parameter [0:0] INIT = 1'b0; +  initial Q <= INIT; +  always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; +endmodule + +(* abc9_box_id=1005, lib_whitebox, abc9_flop *)  module FDPE (    (* abc9_arrival=303 *)    output reg Q, @@ -379,52 +385,54 @@ module FDPE (    endcase endgenerate  endmodule -module FDRE_1 ( -  (* abc9_arrival=303 *) -  output reg Q, -  (* clkbuf_sink *) -  input C, -  input CE, D, R -); -  parameter [0:0] INIT = 1'b0; -  initial Q <= INIT; -  always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; -endmodule - -module FDSE_1 ( +(* abc9_box_id=1006, lib_whitebox, abc9_flop *) +module FDPE_1 (    (* abc9_arrival=303 *)    output reg Q,    (* clkbuf_sink *)    input C, -  input CE, D, S +  input CE, D, PRE  );    parameter [0:0] INIT = 1'b1;    initial Q <= INIT; -  always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; +  always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;  endmodule -module FDCE_1 ( +(* abc9_box_id=1007, lib_whitebox, abc9_flop *) +module FDSE (    (* abc9_arrival=303 *)    output reg Q,    (* clkbuf_sink *) +  (* invertible_pin = "IS_C_INVERTED" *)    input C, -  input CE, D, CLR +  input CE, +  (* invertible_pin = "IS_D_INVERTED" *) +  input D, +  (* invertible_pin = "IS_S_INVERTED" *) +  input S  ); -  parameter [0:0] INIT = 1'b0; +  parameter [0:0] INIT = 1'b1; +  parameter [0:0] IS_C_INVERTED = 1'b0; +  parameter [0:0] IS_D_INVERTED = 1'b0; +  parameter [0:0] IS_S_INVERTED = 1'b0;    initial Q <= INIT; -  always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; +  generate case (|IS_C_INVERTED) +    1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; +    1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; +  endcase endgenerate  endmodule -module FDPE_1 ( +(* abc9_box_id=1008, lib_whitebox, abc9_flop *) +module FDSE_1 (    (* abc9_arrival=303 *)    output reg Q,    (* clkbuf_sink *)    input C, -  input CE, D, PRE +  input CE, D, S  );    parameter [0:0] INIT = 1'b1;    initial Q <= INIT; -  always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; +  always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D;  endmodule  module LDCE ( diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 2c5686a35..de262c8ad 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -292,10 +292,11 @@ struct SynthXilinxPass : public ScriptPass  			ff_map_file = "+/xilinx/xc7_ff_map.v";  		if (check_label("begin")) { +			std::string read_args;  			if (vpr) -				run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); -			else -				run("read_verilog -lib +/xilinx/cells_sim.v"); +				read_args += " -D_EXPLICIT_CARRY"; +			read_args += " -lib +/xilinx/cells_sim.v"; +			run("read_verilog" + read_args);  			run("read_verilog -lib +/xilinx/cells_xtra.v"); @@ -542,6 +543,7 @@ struct SynthXilinxPass : public ScriptPass  				else  					abc9_opts += " -lut +/xilinx/abc9_xc7.lut";  				run("abc9" + abc9_opts); +				run("techmap -map +/xilinx/abc9_unmap.v");  			}  			else {  				if (nowidelut) @@ -557,13 +559,10 @@ struct SynthXilinxPass : public ScriptPass  				run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");  			std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";  			if (help_mode) -				techmap_args += " [-map " + ff_map_file + "]"; -			else if (abc9) -				techmap_args += " -map +/xilinx/abc9_unmap.v"; -			else -				techmap_args += " -map " + ff_map_file; -			run("techmap " + techmap_args); -			run("clean"); +				techmap_args += stringf("[-map %s]", ff_map_file.c_str()); +			else if (!abc9) +				techmap_args += stringf(" -map %s", ff_map_file.c_str()); +			run("techmap " + techmap_args, "(option without '-abc9')");  		}  		if (check_label("finalize")) { @@ -571,6 +570,7 @@ struct SynthXilinxPass : public ScriptPass  				run("clkbufmap -buf BUFG O:I ", "(skip if '-noclkbuf')");  			if (help_mode || ise)  				run("extractinv -inv INV O:I", "(only if '-ise')"); +			run("clean");  		}  		if (check_label("check")) { | 
