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,