Merge pull request #114 from samycharas/add_ff_support

Add ff support to qlf_k6n10 device
diff --git a/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_cells_sim.v b/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_cells_sim.v
index cbce0fb..2d415b6 100644
--- a/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_cells_sim.v
+++ b/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_cells_sim.v
@@ -1,13 +1,13 @@
 (* abc9_box, lib_whitebox *)
 module adder(
-        output sumout,
-        output cout,
-        input a,
-        input b,
-        input cin
+    output sumout,
+    output cout,
+    input a,
+    input b,
+    input cin
 );
-        assign sumout = a ^ b ^ cin;
-        assign cout = (a & b) | ((a | b) & cin);
+    assign sumout = a ^ b ^ cin;
+    assign cout = (a & b) | ((a | b) & cin);
 
 endmodule
 
@@ -15,93 +15,288 @@
 
 (* abc9_lut=1, lib_whitebox *)
 module frac_lut6(
-        input [0:5] in,
-        output [0:3] lut4_out,
-        output [0:1] lut5_out,
-        output lut6_out
+    input [0:5] in,
+    output [0:3] lut4_out,
+    output [0:1] lut5_out,
+    output lut6_out
 );
-        parameter [0:63] LUT = 0;
-        // Effective LUT input
-        wire [0:5] li = in;
+    parameter [0:63] LUT = 0;
+    // Effective LUT input
+    wire [0:5] li = in;
 
-        // Output function
-        wire [0:31] s1 = li[0] ?
-           {LUT[0] , LUT[2] , LUT[4] , LUT[6] , LUT[8] , LUT[10], LUT[12], LUT[14], 
-            LUT[16], LUT[18], LUT[20], LUT[22], LUT[24], LUT[26], LUT[28], LUT[30],
-            LUT[32], LUT[34], LUT[36], LUT[38], LUT[40], LUT[42], LUT[44], LUT[46],
-            LUT[48], LUT[50], LUT[52], LUT[54], LUT[56], LUT[58], LUT[60], LUT[62]}:
-           {LUT[1] , LUT[3] , LUT[5] , LUT[7] , LUT[9] , LUT[11], LUT[13], LUT[15], 
-            LUT[17], LUT[19], LUT[21], LUT[23], LUT[25], LUT[27], LUT[29], LUT[31],
-            LUT[33], LUT[35], LUT[37], LUT[39], LUT[41], LUT[43], LUT[45], LUT[47],
-            LUT[49], LUT[51], LUT[53], LUT[55], LUT[57], LUT[59], LUT[61], LUT[63]};
+    // Output function
+    wire [0:31] s1 = li[0] ?
+    {LUT[0] , LUT[2] , LUT[4] , LUT[6] , LUT[8] , LUT[10], LUT[12], LUT[14], 
+     LUT[16], LUT[18], LUT[20], LUT[22], LUT[24], LUT[26], LUT[28], LUT[30],
+     LUT[32], LUT[34], LUT[36], LUT[38], LUT[40], LUT[42], LUT[44], LUT[46],
+     LUT[48], LUT[50], LUT[52], LUT[54], LUT[56], LUT[58], LUT[60], LUT[62]}:
+    {LUT[1] , LUT[3] , LUT[5] , LUT[7] , LUT[9] , LUT[11], LUT[13], LUT[15], 
+     LUT[17], LUT[19], LUT[21], LUT[23], LUT[25], LUT[27], LUT[29], LUT[31],
+     LUT[33], LUT[35], LUT[37], LUT[39], LUT[41], LUT[43], LUT[45], LUT[47],
+     LUT[49], LUT[51], LUT[53], LUT[55], LUT[57], LUT[59], LUT[61], LUT[63]};
 
-        wire [0:15] s2 = li[1] ?
-           {s1[0] , s1[2] , s1[4] , s1[6] , s1[8] , s1[10], s1[12], s1[14],
-            s1[16], s1[18], s1[20], s1[22], s1[24], s1[26], s1[28], s1[30]}:
-           {s1[1] , s1[3] , s1[5] , s1[7] , s1[9] , s1[11], s1[13], s1[15],
-            s1[17], s1[19], s1[21], s1[23], s1[25], s1[27], s1[29], s1[31]};
+    wire [0:15] s2 = li[1] ?
+    {s1[0] , s1[2] , s1[4] , s1[6] , s1[8] , s1[10], s1[12], s1[14],
+     s1[16], s1[18], s1[20], s1[22], s1[24], s1[26], s1[28], s1[30]}:
+    {s1[1] , s1[3] , s1[5] , s1[7] , s1[9] , s1[11], s1[13], s1[15],
+     s1[17], s1[19], s1[21], s1[23], s1[25], s1[27], s1[29], s1[31]};
 
-        wire [0:7] s3 = li[2] ?
-            {s2[0], s2[2], s2[4], s2[6], s2[8], s2[10], s2[12], s2[14]}:
-            {s2[1], s2[3], s2[5], s2[7], s2[9], s2[11], s2[13], s2[15]};
+    wire [0:7] s3 = li[2] ?
+    {s2[0], s2[2], s2[4], s2[6], s2[8], s2[10], s2[12], s2[14]}:
+    {s2[1], s2[3], s2[5], s2[7], s2[9], s2[11], s2[13], s2[15]};
 
-        wire [0:3] s4 = li[3] ? {s3[0], s3[2], s3[4], s3[6]}:
-                                {s3[1], s3[3], s3[5], s3[7]};
+    wire [0:3] s4 = li[3] ? {s3[0], s3[2], s3[4], s3[6]}:
+                            {s3[1], s3[3], s3[5], s3[7]};
 
-        wire [0:1] s5 = li[4] ? {s4[0], s4[2]} : {s4[1], s4[3]};
+    wire [0:1] s5 = li[4] ? {s4[0], s4[2]} : {s4[1], s4[3]};
 
-        assign lut4_out[0] = s4[0];
-        assign lut4_out[1] = s4[1];
-        assign lut4_out[2] = s4[2];
-        assign lut4_out[3] = s4[3];
+    assign lut4_out[0] = s4[0];
+    assign lut4_out[1] = s4[1];
+    assign lut4_out[2] = s4[2];
+    assign lut4_out[3] = s4[3];
 
-        assign lut5_out[0] = s0[0];
-        assign lut5_out[1] = s5[1];
+    assign lut5_out[0] = s0[0];
+    assign lut5_out[1] = s5[1];
 
-        assign lut6_out = li[5] ? s5[0] : s5[1];
+    assign lut6_out = li[5] ? s5[0] : s5[1];
 
 endmodule
 
 (* abc9_flop, lib_whitebox *)
 module dff(
-        output reg Q,
-        input D,
-        (* clkbuf_sink *)
-        input C
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
 );
-        parameter [0:0] INIT = 1'b0;
-        initial Q = INIT;
-
-        always @(posedge C)
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C)
                 Q <= D;
+          1'b1:
+            always @(negedge C)
+                Q <= D;
+    endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffr(
+    output reg Q,
+    input D,
+    input R,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge R)
+                if (R)
+                        Q <= 1'b0;
+                else
+                        Q <= D;
+          1'b1:
+            always @(negedge C or posedge R)
+                if (R)
+                        Q <= 1'b0;
+                else
+                        Q <= D;
+    endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffre(
+    output reg Q,
+    input D,
+    input R,
+    input E,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge R)
+              if (R)
+                Q <= 1'b0;
+              else if(E)
+                Q <= D;
+          1'b1:
+            always @(negedge C or posedge R)
+              if (R)
+                Q <= 1'b0;
+              else if(E)
+                Q <= D;
+        endcase
+endmodule
+
+module dffs(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else
+                Q <= D;
+        endcase
+endmodule
+
+module dffse(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input S,
+    input E,
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else if(E)
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else if(E)
+                Q <= D;
+        endcase
+endmodule
+
+module dffsr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S or negedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S or negedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else
+                Q <= D;
+        endcase
+endmodule
+
+module dffsre(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input E,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge S or posedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else if (E)
+                Q <= D;
+        endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module latchsre (
+    output reg Q,
+    input S,
+    input R,
+    input D,
+    input G,
+    input E
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    always @*
+            begin
+              if (R) Q <= 1'b0;
+              if (S) Q <= 1'b1;
+            else if (E && G) Q <= D;
+    end
 endmodule
 
 (* abc9_flop, lib_whitebox *)
 module scff(
-        output reg Q,
-        input D,
-        input clk
+    output reg Q,
+    input D,
+    input clk
 );
-        parameter [0:0] INIT = 1'b0;
-        initial Q = INIT;
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
 
-        always @(posedge clk)
-                Q <= D;
+    always @(posedge clk)
+            Q <= D;
 endmodule
 
-
 module DP_RAM16K (
-        input rclk, 
-        input wclk,
-        input wen,
-        input ren,
-        input[8:0] waddr,
-        input[8:0] raddr,
-        input[31:0] d_in,
-        input[31:0] wenb,
-        output[31:0] d_out );
+    input rclk, 
+    input wclk,
+    input wen,
+    input ren,
+    input[8:0] waddr,
+    input[8:0] raddr,
+    input[31:0] d_in,
+    input[31:0] wenb,
+    output[31:0] d_out );
 
-        _dual_port_sram memory_0 (
+    _dual_port_sram memory_0 (
                 .wclk           (wclk),
                 .wen            (wen),
                 .waddr          (waddr),
@@ -115,81 +310,80 @@
 endmodule
 
 module _dual_port_sram (
-        input wclk,
-        input wen,
-        input[8:0] waddr,
-        input[31:0] data_in,
-        input rclk,
-        input ren,
-        input[8:0] raddr,
-        input[31:0] wenb,
-        output[31:0] d_out );
+    input wclk,
+    input wen,
+    input[8:0] waddr,
+    input[31:0] data_in,
+    input rclk,
+    input ren,
+    input[8:0] raddr,
+    input[31:0] wenb,
+    output[31:0] d_out );
 
-        // MODE 0:  512 x 32
-        // MODE 1:  1024 x 16
-        // MODE 2: 1024 x 8
-        // MODE 3: 2048 x 4
+    // MODE 0:  512 x 32
+    // MODE 1: 1024 x 16
+    // MODE 2: 1024 x 8
+    // MODE 3: 2048 x 4
         
-        integer i;
-        reg[31:0] ram[512:0];
-        reg[31:0] internal;
-        // The memory is self initialised
+    integer i;
+    reg[31:0] ram[512:0];
+    reg[31:0] internal;
+    // The memory is self initialised
         
-        initial begin
-                for (i=0;i<=512;i=i+1)
-                begin
-                    ram[i] = 0;
-                end
-                internal = 31'b0; 
-        end
-        
-        
-        wire [31:0] WMASK;
+    initial begin
+            for (i=0;i<=512;i=i+1)
+            begin
+                ram[i] = 0;
+            end
+            internal = 31'b0; 
+    end
+    
+    wire [31:0] WMASK;
 
-        assign d_out = internal;
-        assign WMASK = wenb;
+    assign d_out = internal;
+    assign WMASK = wenb;
 
-        always @(posedge wclk) begin
-                if(!wen) begin
-                        if (WMASK[ 0]) ram[waddr][ 0] <= data_in[ 0];
-                        if (WMASK[ 1]) ram[waddr][ 1] <= data_in[ 1];
-                        if (WMASK[ 2]) ram[waddr][ 2] <= data_in[ 2];
-                        if (WMASK[ 3]) ram[waddr][ 3] <= data_in[ 3];
-                        if (WMASK[ 4]) ram[waddr][ 4] <= data_in[ 4];
-                        if (WMASK[ 5]) ram[waddr][ 5] <= data_in[ 5];
-                        if (WMASK[ 6]) ram[waddr][ 6] <= data_in[ 6];
-                        if (WMASK[ 7]) ram[waddr][ 7] <= data_in[ 7];
-                        if (WMASK[ 8]) ram[waddr][ 8] <= data_in[ 8];
-                        if (WMASK[ 9]) ram[waddr][ 9] <= data_in[ 9];
-                        if (WMASK[10]) ram[waddr][10] <= data_in[10];
-                        if (WMASK[11]) ram[waddr][11] <= data_in[11];
-                        if (WMASK[12]) ram[waddr][12] <= data_in[12];
-                        if (WMASK[13]) ram[waddr][13] <= data_in[13];
-                        if (WMASK[14]) ram[waddr][14] <= data_in[14];
-                        if (WMASK[15]) ram[waddr][15] <= data_in[15];
-                        if (WMASK[16]) ram[waddr][16] <= data_in[16];
-                        if (WMASK[17]) ram[waddr][17] <= data_in[17];
-                        if (WMASK[18]) ram[waddr][18] <= data_in[18];
-                        if (WMASK[19]) ram[waddr][19] <= data_in[19];
-                        if (WMASK[20]) ram[waddr][20] <= data_in[20];
-                        if (WMASK[21]) ram[waddr][21] <= data_in[21];
-                        if (WMASK[22]) ram[waddr][22] <= data_in[22];
-                        if (WMASK[23]) ram[waddr][23] <= data_in[23];
-                        if (WMASK[24]) ram[waddr][24] <= data_in[24];
-                        if (WMASK[25]) ram[waddr][25] <= data_in[25];
-                        if (WMASK[26]) ram[waddr][26] <= data_in[26];
-                        if (WMASK[27]) ram[waddr][27] <= data_in[27];
-                        if (WMASK[28]) ram[waddr][28] <= data_in[28];
-                        if (WMASK[29]) ram[waddr][29] <= data_in[29];
-                        if (WMASK[30]) ram[waddr][30] <= data_in[30];
-                        if (WMASK[31]) ram[waddr][31] <= data_in[31];
-                end
-        end
+    always @(posedge wclk) begin
+            if(!wen) begin
+              if (WMASK[ 0]) ram[waddr][ 0] <= data_in[ 0];
+              if (WMASK[ 1]) ram[waddr][ 1] <= data_in[ 1];
+              if (WMASK[ 2]) ram[waddr][ 2] <= data_in[ 2];
+              if (WMASK[ 3]) ram[waddr][ 3] <= data_in[ 3];
+              if (WMASK[ 4]) ram[waddr][ 4] <= data_in[ 4];
+              if (WMASK[ 5]) ram[waddr][ 5] <= data_in[ 5];
+              if (WMASK[ 6]) ram[waddr][ 6] <= data_in[ 6];
+              if (WMASK[ 7]) ram[waddr][ 7] <= data_in[ 7];
+              if (WMASK[ 8]) ram[waddr][ 8] <= data_in[ 8];
+              if (WMASK[ 9]) ram[waddr][ 9] <= data_in[ 9];
+              if (WMASK[10]) ram[waddr][10] <= data_in[10];
+              if (WMASK[11]) ram[waddr][11] <= data_in[11];
+              if (WMASK[12]) ram[waddr][12] <= data_in[12];
+              if (WMASK[13]) ram[waddr][13] <= data_in[13];
+              if (WMASK[14]) ram[waddr][14] <= data_in[14];
+              if (WMASK[15]) ram[waddr][15] <= data_in[15];
+              if (WMASK[16]) ram[waddr][16] <= data_in[16];
+              if (WMASK[17]) ram[waddr][17] <= data_in[17];
+              if (WMASK[18]) ram[waddr][18] <= data_in[18];
+              if (WMASK[19]) ram[waddr][19] <= data_in[19];
+              if (WMASK[20]) ram[waddr][20] <= data_in[20];
+              if (WMASK[21]) ram[waddr][21] <= data_in[21];
+              if (WMASK[22]) ram[waddr][22] <= data_in[22];
+              if (WMASK[23]) ram[waddr][23] <= data_in[23];
+              if (WMASK[24]) ram[waddr][24] <= data_in[24];
+              if (WMASK[25]) ram[waddr][25] <= data_in[25];
+              if (WMASK[26]) ram[waddr][26] <= data_in[26];
+              if (WMASK[27]) ram[waddr][27] <= data_in[27];
+              if (WMASK[28]) ram[waddr][28] <= data_in[28];
+              if (WMASK[29]) ram[waddr][29] <= data_in[29];
+              if (WMASK[30]) ram[waddr][30] <= data_in[30];
+              if (WMASK[31]) ram[waddr][31] <= data_in[31];
+            end
+    end
 
-        always @(posedge rclk) begin
-                if(!ren) begin
-                        internal <= ram[raddr];
-                end
-        end
-
+    always @(posedge rclk) begin
+            if(!ren) begin
+              internal <= ram[raddr];
+            end
+    end
 endmodule
+
diff --git a/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_ffs_map.v b/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_ffs_map.v
index add0462..7347215 100644
--- a/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_ffs_map.v
+++ b/ql-qlf-plugin/ql-qlf-k6n10/qlf_k6n10_ffs_map.v
@@ -1,6 +1,149 @@
-module \$_DFF_P_ (D, Q, C);
+// Basic DFF
+
+module \$_DFF_P_ (D, C, Q);
     input D;
     input C;
     output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
     dff _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
 endmodule
+
+// Async reset
+module \$_DFF_PP0_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
+endmodule
+
+// Async set
+module \$_DFF_PP1_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffs _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
+endmodule
+
+// Async reset, enable
+
+module  \$_DFFE_PP0P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffre  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
+endmodule
+
+// Async set, enable
+
+module  \$_DFFE_PP1P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffse  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(S));
+endmodule
+
+// Async set & reset
+
+module \$_DFFSR_PPP_ (D, C, R, S, Q);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+// Async set, reset & enable
+
+module \$_DFFSRE_PPPP_ (D, Q, C, E, R, S);
+    input D;
+    input C;
+    input E;
+    input R;
+    input S;
+    output Q;
+    dffsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
+
+// Latch with async set and reset
+module  \$_DLATCHSR_PPP_ (input E, S, R, D, output Q);
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    latchsre _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E),  .R(R), .S(S));
+endmodule
+
+// The following techmap operation are not performed right now
+// as Negative edge FF are not legalized in synth_quicklogic for qlf_k6n10
+// but in case we implement clock inversion in the future, the support is ready for it.
+
+module \$_DFF_N_ (D, C, Q);
+    input D;
+    input C;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dff #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
+endmodule
+
+module \$_DFF_NP0_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffr #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
+endmodule
+
+module \$_DFF_NP1_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffs #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
+endmodule
+
+module  \$_DFFE_NP0P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffre #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
+endmodule
+
+module  \$_DFFE_NP1P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffse #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(S));
+endmodule
+
+module \$_DFFSR_NPP_ (D, C, R, S, Q);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+module \$_DFFSRE_PPPP_ (D, C, E, R, S, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    input S;
+    output Q;
+    dffsre #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
diff --git a/ql-qlf-plugin/synth_quicklogic.cc b/ql-qlf-plugin/synth_quicklogic.cc
index 9d7bb77..ff66320 100644
--- a/ql-qlf-plugin/synth_quicklogic.cc
+++ b/ql-qlf-plugin/synth_quicklogic.cc
@@ -225,7 +225,11 @@
                 run("shregmap -minlen 8 -maxlen 8");
             }
             if (family == "qlf_k6n10") {
-                run("dfflegalize -cell $_DFF_P_ 0");
+                run("dfflegalize -cell $_DFF_P_ 0 -cell $_DFF_PP?_ 0 -cell $_DFFE_PP?P_ 0 -cell $_DFFSR_PPP_ 0 -cell $_DFFSRE_PPPP_ 0 -cell "
+                    "$_DLATCHSR_PPP_ 0");
+                //    In case we add clock inversion in the future.
+                //    run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_DFFSR_?PP_ 0 -cell $_DFFSRE_?PPP_ 0 -cell
+                //    $_DLATCH_PPP_ 0");
             } else {
                 run("dfflegalize -cell $_DFF_P_ 0 -cell $_DFF_P??_ 0 -cell $_DFF_N_ 0 -cell $_DFF_N??_ 0 -cell $_DFFSR_???_ 0");
             }
diff --git a/ql-qlf-plugin/tests/Makefile b/ql-qlf-plugin/tests/Makefile
index 5c554d6..b64701e 100644
--- a/ql-qlf-plugin/tests/Makefile
+++ b/ql-qlf-plugin/tests/Makefile
@@ -1,7 +1,7 @@
-# The latch test is disabled as latches are not supported in the qlf_k4n8/qlf_k6n10.
 # The bram test will be enable in a future PR after it's been fixed.
 
 TESTS = dffs \
+	latches \
 	shreg \
 	iob_no_flatten \
 	full_adder \
diff --git a/ql-qlf-plugin/tests/dffs/dffs.tcl b/ql-qlf-plugin/tests/dffs/dffs.tcl
index b1f76cc..737acc1 100644
--- a/ql-qlf-plugin/tests/dffs/dffs.tcl
+++ b/ql-qlf-plugin/tests/dffs/dffs.tcl
@@ -158,11 +158,247 @@
 
 # DFF on qlf_k6n10 device
 read_verilog $::env(DESIGN_TOP).v
+design -save read
+
 # DFF
 hierarchy -top my_dff
 yosys proc
-equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic -family qlf_k6n10 -top my_dff
+equiv_opt -assert -map +/quicklogic/qlf_k6n10_cells_sim.v synth_quicklogic -family qlf_k6n10 -top my_dff
 design -load postopt
 yosys cd my_dff
 stat
 select -assert-count 1 t:dff
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_p
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffr
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_p_2
+yosys cd my_dffr_p_2
+stat
+select -assert-count 2 t:dffr
+
+# DFFR (negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_n
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:dffr
+select -assert-count 1 t:\$lut
+
+#DFFRE (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffre_p
+yosys cd my_dffre_p
+stat
+select -assert-count 1 t:dffre
+
+#DFFRE (negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffre_n
+yosys cd my_dffre_n
+stat
+select -assert-count 1 t:dffre
+select -assert-count 1 t:\$lut
+
+# DFFS (posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffs_p
+yosys cd my_dffs_p
+stat
+select -assert-count 1 t:dffs
+
+# DFFS (negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffs_n
+yosys cd my_dffs_n
+stat
+select -assert-count 1 t:dffs
+select -assert-count 1 t:\$lut
+
+# DFFSE (posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffse_p
+yosys cd my_dffse_p
+stat
+select -assert-count 1 t:dffse
+
+# DFFSE (negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffse_n
+yosys cd my_dffse_n
+stat
+select -assert-count 1 t:dffse
+
+# DFFN
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffn
+yosys cd my_dffn
+stat
+select -assert-count 1 t:dff
+select -assert-count 1 t:\$lut
+
+# DFFNR (negedge CLK posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffnr_p
+yosys cd my_dffnr_p
+stat
+select -assert-count 1 t:dffr
+select -assert-count 1 t:\$lut
+
+# DFFNR (negedge CLK negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffnr_n
+yosys cd my_dffnr_n
+stat
+select -assert-count 1 t:dffr
+select -assert-count 2 t:\$lut
+
+# DFFNS (negedge CLK posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffns_p
+yosys cd my_dffns_p
+stat
+select -assert-count 1 t:dffs
+select -assert-count 1 t:\$lut
+
+# DFFS (negedge CLK negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffns_n
+yosys cd my_dffns_n
+stat
+select -assert-count 1 t:dffs
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_ppp
+yosys cd my_dffsr_ppp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (posedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_pnp
+yosys cd my_dffsr_pnp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (posedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_ppn
+yosys cd my_dffsr_ppn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_pnn
+yosys cd my_dffsr_pnn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_npp
+yosys cd my_dffsr_npp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_nnp
+yosys cd my_dffsr_nnp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_npn
+yosys cd my_dffsr_npn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 3 t:\$lut
+
+# DFFSR (negedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_nnn
+yosys cd my_dffsr_nnn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 3 t:\$lut
+
+# DFFSRE (posedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_ppp
+yosys cd my_dffsre_ppp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE (posedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_pnp
+yosys cd my_dffsre_pnp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE (posedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_ppn
+yosys cd my_dffsre_ppn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (posedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_pnn
+yosys cd my_dffsre_pnn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_npp
+yosys cd my_dffsre_npp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_nnp
+yosys cd my_dffsre_nnp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_npn
+yosys cd my_dffsre_npn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 3 t:\$lut
+
+# DFFSRE (negedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_nnn
+yosys cd my_dffsre_nnn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 3 t:\$lut
diff --git a/ql-qlf-plugin/tests/dffs/dffs.v b/ql-qlf-plugin/tests/dffs/dffs.v
index 5376990..293b1af 100644
--- a/ql-qlf-plugin/tests/dffs/dffs.v
+++ b/ql-qlf-plugin/tests/dffs/dffs.v
@@ -46,6 +46,30 @@
     else q <= d;
 endmodule
 
+module my_dffre_p (
+    input d,
+    clk,
+    clr,
+    en,
+    output reg q
+);
+  always @(posedge clk or posedge clr)
+    if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffre_n (
+    input d,
+    clk,
+    clr,
+    en,
+    output reg q
+);
+  always @(posedge clk or negedge clr)
+    if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
 module my_dffs_p (
     input d,
     clk,
@@ -68,6 +92,30 @@
     else q <= d;
 endmodule
 
+module my_dffse_p (
+    input d,
+    clk,
+    pre,
+    en,
+    output reg q
+);
+  always @(posedge clk or posedge pre)
+    if (pre) q <= 1'b1;
+    else if(en) q <= d;
+endmodule
+
+module my_dffse_n (
+    input d,
+    clk,
+    pre,
+    en,
+    output reg q
+);
+  always @(posedge clk or negedge pre)
+    if (!pre) q <= 1'b1;
+    else if(en) q <= d;
+endmodule
+
 module my_dffn (
     input d,
     clk,
@@ -237,3 +285,123 @@
     else if (!clr) q <= 1'b0;
     else q <= d;
 endmodule
+
+module my_dffsre_ppp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_pnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_ppn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_pnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_npp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_nnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_npn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_nnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
diff --git a/ql-qlf-plugin/tests/latches/latches.tcl b/ql-qlf-plugin/tests/latches/latches.tcl
index 6b9f1f4..d5821a6 100644
--- a/ql-qlf-plugin/tests/latches/latches.tcl
+++ b/ql-qlf-plugin/tests/latches/latches.tcl
@@ -2,27 +2,46 @@
 if { [info procs synth_quicklogic] == {} } { plugin -i ql-qlf }
 yosys -import  ;# ingest plugin commands
 
-#read_verilog $::env(DESIGN_TOP).v
-read_verilog latches.v
+read_verilog $::env(DESIGN_TOP).v
 design -save read
 
+# Tests for qlf_k6n10 family
 # LATCHP
-synth_quicklogic -family qlf_k4n8 -top latchp
+design -load read
+synth_quicklogic -family qlf_k6n10 -top latchp
 yosys cd latchp
 stat
-select -assert-count 1 t:\$_DLATCH_P_
+select -assert-count 1 t:latchsre
 
 # LATCHN
 design -load read
 synth_quicklogic -family qlf_k6n10 -top latchn
 yosys cd latchn
 stat
-select -assert-count 1 t:\$_DLATCH_N_
+select -assert-count 1 t:\$lut
+select -assert-count 1 t:latchsre
 
-# LATCHP test for qlf_k6n10 family
+# LATCHSRE
 design -load read
-synth_quicklogic -family qlf_k4n8 -top latchp_noinit
-yosys cd latchp_noinit
+synth_quicklogic -family qlf_k6n10 -top my_latchsre
+yosys cd my_latchsre
 stat
-select -assert-count 1 t:\$_DLATCH_P_
+select -assert-count 2 t:\$lut
+select -assert-count 1 t:latchsre
+
+## Tests for qlf_k4n8 family
+## Currently disabled cause latch aren't supported
+## in synth_quicklogic for that family
+## LATCHP
+#synth_quicklogic -family qlf_k4n8 -top latchp
+#yosys cd latchp
+#stat
+#select -assert-count 1 t:\$_DLATCH_P_
+#
+## LATCHP no init
+#design -load read
+#synth_quicklogic -family qlf_k4n8 -top latchp_noinit
+#yosys cd latchp_noinit
+#stat
+#select -assert-count 1 t:\$_DLATCH_P_
 
diff --git a/ql-qlf-plugin/tests/latches/latches.v b/ql-qlf-plugin/tests/latches/latches.v
index 8b35992..4cc26b0 100644
--- a/ql-qlf-plugin/tests/latches/latches.v
+++ b/ql-qlf-plugin/tests/latches/latches.v
@@ -17,7 +17,7 @@
   always @* if (!en) q <= d;
 endmodule
 
-module latchsr (
+module my_latchsre (
     input d,
     clk,
     en,