synth_xilinx: Support latches, remove used-up FF init values.
authorMarcin Kościelnicki <marcin@symbioticeda.com>
Mon, 23 Sep 2019 10:41:42 +0000 (12:41 +0200)
committerMarcin Kościelnicki <koriakin@0x04.net>
Mon, 30 Sep 2019 10:52:43 +0000 (12:52 +0200)
Fixes #1387.

CHANGELOG
techlibs/xilinx/xc6s_ff_map.v
techlibs/xilinx/xc7_ff_map.v

index 481f33a6c4c76479d87d2278f5dff2ef28cdeec2..c1ffaa44a18030ad9630a65c2904531d6644d50f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -49,6 +49,7 @@ Yosys 0.9 .. Yosys 0.9-dev
     - "synth_xilinx" to now infer DSP blocks (-nodsp to disable)
     - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental)
     - "synth_ice40 -dsp" to infer DSP blocks
+    - Added latch support to synth_xilinx
 
 Yosys 0.8 .. Yosys 0.9
 ----------------------
index 520a67579ec1130019596f27d947ea5ab1b53896..bf35b09e5df8d8d6181dabec1b71aea5c77109ca 100644 (file)
  */
 
 // ============================================================================
-// FF mapping
+// FF mapping for Spartan 6.  The primitives used are the same as Series 7,
+// but with one major difference: the initial value is implied by the
+// primitive type used (FFs with reset pin must have INIT set to 0 or x, FFs
+// with set pin must have INIT set to 1 or x).  For Yosys primitives without
+// set/reset, this means we have to pick the primitive type based on the INIT
+// value.
 
 `ifndef _NO_FFS
 
@@ -29,6 +34,7 @@ module  \$_DFF_N_   (input D, C, output Q);
   else
     FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_P_   (input D, C, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -37,6 +43,7 @@ module  \$_DFF_P_   (input D, C, output Q);
   else
     FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFFE_NP_ (input D, C, E, output Q);
@@ -46,6 +53,7 @@ module  \$_DFFE_NP_ (input D, C, E, output Q);
   else
     FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFFE_PP_ (input D, C, E, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -54,6 +62,7 @@ module  \$_DFFE_PP_ (input D, C, E, output Q);
   else
     FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFF_NN0_ (input D, C, R, output Q);
@@ -63,6 +72,7 @@ module  \$_DFF_NN0_ (input D, C, R, output Q);
   else
     FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_NP0_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -71,6 +81,7 @@ module  \$_DFF_NP0_ (input D, C, R, output Q);
   else
     FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PN0_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -79,6 +90,7 @@ module  \$_DFF_PN0_ (input D, C, R, output Q);
   else
     FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PP0_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -87,6 +99,7 @@ module  \$_DFF_PP0_ (input D, C, R, output Q);
   else
     FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFF_NN1_ (input D, C, R, output Q);
@@ -96,6 +109,7 @@ module  \$_DFF_NN1_ (input D, C, R, output Q);
   else
     FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_NP1_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -104,6 +118,7 @@ module  \$_DFF_NP1_ (input D, C, R, output Q);
   else
     FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PN1_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -112,6 +127,7 @@ module  \$_DFF_PN1_ (input D, C, R, output Q);
   else
     FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PP1_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
@@ -120,6 +136,26 @@ module  \$_DFF_PP1_ (input D, C, R, output Q);
   else
     FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
   endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$_DLATCH_N_ (input E, D, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
+  else
+    LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$_DLATCH_P_ (input E, D, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
+  else
+    LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 `endif
index f6197b78b3a53ab40afdad94ec3a7fb35af512e2..32ca9f560e4b4ca4e2d9b14b99068b81d63945a3 100644 (file)
  */
 
 // ============================================================================
-// FF mapping
+// FF mapping for Virtex 6, Series 7 and Ultrascale.  These families support
+// the following features:
+//
+// - a CLB flip-flop can be used as a latch or as a flip-flop
+// - a CLB flip-flop has the following pins:
+//
+//   - data input
+//   - clock (or gate for latches) (with optional inversion)
+//   - clock enable (or gate enable, which is just ANDed with gate — unused by
+//     synthesis)
+//   - either a set or a reset input, which (for FFs) can be either
+//     synchronous or asynchronous (with optional inversion)
+//   - data output
+//
+// - a flip-flop also has an initial value, which is set at device
+//   initialization (or whenever GSR is asserted)
 
 `ifndef _NO_FFS
 
 module  \$_DFF_N_   (input D, C, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_P_   (input D, C, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFFE_NP_ (input D, C, E, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFFE_PP_ (input D, C, E, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFF_NN0_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_NP0_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PN0_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PP0_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 module  \$_DFF_NN1_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_NP1_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PN1_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 module  \$_DFF_PP1_ (input D, C, R, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$_DLATCH_N_ (input E, D, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$_DLATCH_P_ (input E, D, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  LDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
 `endif