xilinx: Improve flip-flop handling.

This adds support for infering more kinds of flip-flops:

- FFs with async set/reset and clock enable
- FFs with sync set/reset
- FFs with sync set/reset and clock enable

Some passes have been moved (and some added) in order for dff2dffs to
work correctly.

This gives us complete coverage of Virtex 6+ and Spartan 6 flip-flop
capabilities (though not latch capabilities).  Older FPGAs also support
having both a set and a reset input, which will be handled at a later
data.
diff --git a/CHANGELOG b/CHANGELOG
index a49c27b..cb2b7bf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -50,6 +50,8 @@
     - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental)
     - "synth_ice40 -dsp" to infer DSP blocks
     - Added latch support to synth_xilinx
+    - Added support for flip-flops with synchronous reset to synth_xilinx
+    - Added support for flip-flops with reset and enable to synth_xilinx
     - Added "check -mapped"
     - Added checking of SystemVerilog always block types (always_comb,
       always_latch and always_ff)
diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v
index a15884e..f7fc0af 100644
--- a/techlibs/xilinx/cells_map.v
+++ b/techlibs/xilinx/cells_map.v
@@ -28,6 +28,33 @@
 (* 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
 
+(* techmap_celltype = "$__DFFE_NN0" *)
+module _90_dffe_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFE_NP0  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFE_PN0" *)
+module _90_dffe_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFE_PP0  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFE_NN1" *)
+module _90_dffe_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFE_NP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFE_PN1" *)
+module _90_dffe_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFE_PP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+
+(* techmap_celltype = "$__DFFS_NN0_" *)
+module _90_dffs_nn0_to_np0 (input D, C, R, output Q); \$__DFFS_NP0_  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
+(* techmap_celltype = "$__DFFS_PN0_" *)
+module _90_dffs_pn0_to_pp0 (input D, C, R, output Q); \$__DFFS_PP0_  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
+(* techmap_celltype = "$__DFFS_NN1_" *)
+module _90_dffs_nn1_to_np1 (input D, C, R, output Q); \$__DFFS_NP1_   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
+(* techmap_celltype = "$__DFFS_PN1_" *)
+module _90_dffs_pn1_to_pp1 (input D, C, R, output Q); \$__DFFS_PP1_   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
+
+(* techmap_celltype = "$__DFFSE_NN0" *)
+module _90_dffse_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFSE_NP0  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFSE_PN0" *)
+module _90_dffse_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFSE_PP0  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFSE_NN1" *)
+module _90_dffse_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFSE_NP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule
+(* techmap_celltype = "$__DFFSE_PN1" *)
+module _90_dffse_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFSE_PP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); 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/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 3d4a65c..2f68b8e 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -441,6 +441,16 @@
 		}
 
 		if (check_label("map_ffram")) {
+			// Required for dffsr2dff to work.
+			run("simplemap t:$dff t:$adff t:$mux");
+			// Needs to be done before opt -mux_bool happens.
+			run("dffsr2dff");
+			if (help_mode)
+				run("dff2dffs [-match-init]", "(-match-init for xc6s only)");
+			else if (family == "xc6s")
+				run("dff2dffs -match-init");
+			else
+				run("dff2dffs");
 			if (widemux > 0)
 				run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
 									    // performs less efficiently
@@ -450,14 +460,11 @@
 		}
 
 		if (check_label("fine")) {
-			run("dffsr2dff");
-			run("dff2dffe");
+			run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
 			if (help_mode) {
-				run("simplemap t:$mux", "         ('-widemux' only)");
 				run("muxcover <internal options>, ('-widemux' only)");
 			}
 			else if (widemux > 0) {
-				run("simplemap t:$mux");
 				constexpr int cost_mux2 = 100;
 				std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
 				switch (widemux) {
diff --git a/techlibs/xilinx/xc6s_ff_map.v b/techlibs/xilinx/xc6s_ff_map.v
index bf35b09..c40f446 100644
--- a/techlibs/xilinx/xc6s_ff_map.v
+++ b/techlibs/xilinx/xc6s_ff_map.v
@@ -27,6 +27,8 @@
 
 `ifndef _NO_FFS
 
+// No reset.
+
 module  \$_DFF_N_   (input D, C, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
@@ -46,6 +48,8 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
+// No reset, enable.
+
 module  \$_DFFE_NP_ (input D, C, E, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
@@ -65,15 +69,8 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
-module  \$_DFF_NN0_ (input D, C, R, output Q);
-  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
-  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
-    $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
-  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
+// Async reset.
+
 module  \$_DFF_NP0_ (input D, C, R, output Q);
   parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
@@ -83,15 +80,6 @@
   endgenerate
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
-module  \$_DFF_PN0_ (input D, C, R, output Q);
-  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
-  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
-    $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
-  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;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
@@ -102,15 +90,6 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
-module  \$_DFF_NN1_ (input D, C, R, output Q);
-  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
-  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
-    $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
-  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;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
@@ -120,15 +99,6 @@
   endgenerate
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
-module  \$_DFF_PN1_ (input D, C, R, output Q);
-  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
-  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
-    $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
-  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;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
@@ -139,6 +109,128 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
+// Async reset, enable.
+
+module  \$__DFFE_NP0 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
+  else
+    FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFE_PP0 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
+  else
+    FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFE_NP1 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
+  else
+    FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFE_PP1 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
+  else
+    FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Sync reset.
+
+module  \$__DFFS_NP0_ (input D, C, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with reset initialized to 1");
+  else
+    FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFS_PP0_ (input D, C, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with reset initialized to 1");
+  else
+    FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFS_NP1_ (input D, C, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with set initialized to 0");
+  else
+    FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFS_PP1_ (input D, C, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with set initialized to 0");
+  else
+    FDSE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Sync reset, enable.
+
+module  \$__DFFSE_NP0 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with reset initialized to 1");
+  else
+    FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFSE_PP0 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
+    $error("Spartan 6 doesn't support FFs with reset initialized to 1");
+  else
+    FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFSE_NP1 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with set initialized to 0");
+  else
+    FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFSE_PP1 (input D, C, E, R, output Q);
+  parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
+  generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
+    $error("Spartan 6 doesn't support FFs with set initialized to 0");
+  else
+    FDSE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
+  endgenerate
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Latches (no reset).
+
 module  \$_DLATCH_N_ (input E, D, output Q);
   parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
   generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
@@ -158,5 +250,7 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
+// Latches with reset (TODO).
+
 `endif
 
diff --git a/techlibs/xilinx/xc7_ff_map.v b/techlibs/xilinx/xc7_ff_map.v
index 32ca9f5..2bd8744 100644
--- a/techlibs/xilinx/xc7_ff_map.v
+++ b/techlibs/xilinx/xc7_ff_map.v
@@ -37,6 +37,8 @@
 
 `ifndef _NO_FFS
 
+// No reset.
+
 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));
@@ -48,6 +50,8 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
+// No reset, enable.
+
 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));
@@ -59,48 +63,104 @@
   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
+// Async reset.
+
 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
 
+// Async reset, enable.
+
+module  \$__DFFE_NP0 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFE_PP0 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDCE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFE_NP1 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFE_PP1 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDPE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Sync reset.
+
+module  \$__DFFS_NP0_ (input D, C, R, 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( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFS_PP0_ (input D, C, R, 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( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFS_NP1_ (input D, C, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFS_PP1_ (input D, C, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDSE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Sync reset, enable.
+
+module  \$__DFFSE_NP0 (input D, C, E, R, 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( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFSE_PP0 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDRE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+module  \$__DFFSE_NP1 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+module  \$__DFFSE_PP1 (input D, C, E, R, output Q);
+  parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+  FDSE   #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R));
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+endmodule
+
+// Latches (no reset).
+
 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));
@@ -112,5 +172,7 @@
   wire _TECHMAP_REMOVEINIT_Q_ = 1;
 endmodule
 
+// Latches with reset (TODO).
+
 `endif
 
diff --git a/tests/arch/xilinx/adffs.ys b/tests/arch/xilinx/adffs.ys
index e73bfe0..c0ff6a2 100644
--- a/tests/arch/xilinx/adffs.ys
+++ b/tests/arch/xilinx/adffs.ys
@@ -32,10 +32,9 @@
 design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
 cd dffs # Constrain all select calls below inside the top module
 select -assert-count 1 t:BUFG
-select -assert-count 1 t:FDRE
-select -assert-count 1 t:LUT2
+select -assert-count 1 t:FDSE
 
-select -assert-none t:BUFG t:FDRE t:LUT2 %% t:* %D
+select -assert-none t:BUFG t:FDSE %% t:* %D
 
 
 design -load read
@@ -46,6 +45,6 @@
 cd ndffnr # Constrain all select calls below inside the top module
 select -assert-count 1 t:BUFG
 select -assert-count 1 t:FDRE_1
-select -assert-count 1 t:LUT2
+select -assert-count 1 t:INV
 
-select -assert-none t:BUFG t:FDRE_1 t:LUT2 %% t:* %D
+select -assert-none t:BUFG t:FDRE_1 t:INV %% t:* %D
diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys
index 2a72c34..4545cf6 100644
--- a/tests/arch/xilinx/fsm.ys
+++ b/tests/arch/xilinx/fsm.ys
@@ -11,8 +11,9 @@
 cd fsm # Constrain all select calls below inside the top module
 
 select -assert-count 1 t:BUFG
-select -assert-count 5 t:FDRE
-select -assert-count 1 t:LUT3
-select -assert-count 2 t:LUT4
-select -assert-count 4 t:LUT6
-select -assert-none t:BUFG t:FDRE t:LUT3 t:LUT4 t:LUT6 %% t:* %D
+select -assert-count 4 t:FDRE
+select -assert-count 1 t:FDSE
+select -assert-count 1 t:LUT2
+select -assert-count 2 t:LUT3
+select -assert-count 4 t:LUT5
+select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT3 t:LUT5 %% t:* %D
diff --git a/tests/arch/xilinx/macc.ys b/tests/arch/xilinx/macc.ys
index 6e884b3..11e9599 100644
--- a/tests/arch/xilinx/macc.ys
+++ b/tests/arch/xilinx/macc.ys
@@ -23,9 +23,10 @@
 sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter
 design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
 cd macc2 # Constrain all select calls below inside the top module
+
 select -assert-count 1 t:BUFG
 select -assert-count 1 t:DSP48E1
 select -assert-count 1 t:FDRE
 select -assert-count 1 t:LUT2
-select -assert-count 41 t:LUT3
+select -assert-count 40 t:LUT3
 select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D