quicklogic: PolarPro 3 support
authorLofty <dan.ravensloft@gmail.com>
Wed, 17 Mar 2021 02:34:30 +0000 (02:34 +0000)
committerMarcelina Kościelnicka <mwk@0x04.net>
Thu, 18 Mar 2021 12:28:16 +0000 (13:28 +0100)
Co-authored-by: Grzegorz Latosiński <glatosinski@antmicro.com>
Co-authored-by: Maciej Kurc <mkurc@antmicro.com>
Co-authored-by: Tarachand Pagarani <tpagarani@quicklogic.com>
Co-authored-by: Lalit Sharma <lsharma@quicklogic.com>
Co-authored-by: kkumar23 <kkumar@quicklogic.com>
20 files changed:
Makefile
techlibs/quicklogic/Makefile.inc [new file with mode: 0644]
techlibs/quicklogic/cells_sim.v [new file with mode: 0644]
techlibs/quicklogic/lut_sim.v [new file with mode: 0644]
techlibs/quicklogic/pp3_cells_map.v [new file with mode: 0644]
techlibs/quicklogic/pp3_cells_sim.v [new file with mode: 0644]
techlibs/quicklogic/pp3_ffs_map.v [new file with mode: 0644]
techlibs/quicklogic/pp3_latches_map.v [new file with mode: 0644]
techlibs/quicklogic/pp3_lut_map.v [new file with mode: 0644]
techlibs/quicklogic/synth_quicklogic.cc [new file with mode: 0644]
tests/arch/quicklogic/add_sub.ys [new file with mode: 0644]
tests/arch/quicklogic/adffs.ys [new file with mode: 0644]
tests/arch/quicklogic/counter.ys [new file with mode: 0644]
tests/arch/quicklogic/dffs.ys [new file with mode: 0644]
tests/arch/quicklogic/fsm.ys [new file with mode: 0644]
tests/arch/quicklogic/latches.ys [new file with mode: 0644]
tests/arch/quicklogic/logic.ys [new file with mode: 0644]
tests/arch/quicklogic/mux.ys [new file with mode: 0644]
tests/arch/quicklogic/run-test.sh [new file with mode: 0755]
tests/arch/quicklogic/tribuf.ys [new file with mode: 0644]

index e6a27de07d9d5c7ff7bf3936df282805b51290e9..763871523d2e8805fc1b696d6debaba24cc6a2e6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -816,6 +816,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
        +cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
        +cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT)
        +cd tests/arch/nexus && bash run-test.sh $(SEEDOPT)
+       +cd tests/arch/quicklogic && bash run-test.sh $(SEEDOPT)
        +cd tests/rpc && bash run-test.sh
        +cd tests/memfile && bash run-test.sh
        +cd tests/verilog && bash run-test.sh
diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc
new file mode 100644 (file)
index 0000000..9a07c2e
--- /dev/null
@@ -0,0 +1,9 @@
+OBJS += techlibs/quicklogic/synth_quicklogic.o
+
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_ffs_map.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_lut_map.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_latches_map.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_map.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/lut_sim.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_sim.v))
diff --git a/techlibs/quicklogic/cells_sim.v b/techlibs/quicklogic/cells_sim.v
new file mode 100644 (file)
index 0000000..f24782e
--- /dev/null
@@ -0,0 +1,36 @@
+module inv (
+  output Q,
+  input A
+);
+  assign Q = A ? 0 : 1;
+endmodule
+
+module buff (
+  output Q,
+  input A
+);
+  assign Q = A;
+endmodule
+
+module logic_0 (
+  output A
+);
+  assign A = 0;
+endmodule
+
+module logic_1 (
+  output A
+);
+  assign A = 1;
+endmodule
+
+module gclkbuff (
+  input A,
+  output Z
+);
+  specify
+    (A => Z) = 0;
+  endspecify
+
+  assign Z = A;
+endmodule
diff --git a/techlibs/quicklogic/lut_sim.v b/techlibs/quicklogic/lut_sim.v
new file mode 100644 (file)
index 0000000..851ce4d
--- /dev/null
@@ -0,0 +1,76 @@
+(* abc9_lut=1, lib_whitebox *)
+module LUT1 (
+  output O,
+  input I0
+);
+  parameter [1:0] INIT = 0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 698; // FS -> FZ
+  endspecify
+
+  assign O = I0 ? INIT[1] : INIT[0];
+endmodule
+
+//               TZ        TSL TAB
+(* abc9_lut=2, lib_whitebox *)
+module LUT2 (
+  output O,
+  input I0, I1
+);
+  parameter [3:0] INIT = 4'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 1251; // TAB -> TZ
+    (I1 => O) = 1406; // TSL -> TZ
+  endspecify
+
+  wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
+
+(* abc9_lut=2, lib_whitebox *)
+module LUT3 (
+  output O,
+  input I0, I1, I2
+);
+  parameter [7:0] INIT = 8'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 1251; // TAB -> TZ
+    (I1 => O) = 1406; // TSL -> TZ
+    (I2 => O) = 1699; // ('TA1', 'TA2', 'TB1', 'TB2') -> TZ
+  endspecify
+
+  wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0];
+  wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
+
+(* abc9_lut=4, lib_whitebox *)
+module LUT4 (
+  output O,
+  input I0, I1, I2, I3
+);
+  parameter [15:0] INIT = 16'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 995;  // TBS -> CZ
+    (I1 => O) = 1437; // ('TAB', 'BAB') -> CZ
+    (I2 => O) = 1593; // ('TSL', 'BSL') -> CZ
+    (I3 => O) = 1887; // ('TA1', 'TA2', 'TB1', 'TB2', 'BA1', 'BA2', 'BB1', 'BB2') -> CZ
+  endspecify
+
+  wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0];
+  wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0];
+  wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
diff --git a/techlibs/quicklogic/pp3_cells_map.v b/techlibs/quicklogic/pp3_cells_map.v
new file mode 100644 (file)
index 0000000..10e270d
--- /dev/null
@@ -0,0 +1,36 @@
+module \$_MUX8_ (
+  A, B, C, D, E, F, G, H, S, T, U, Y
+);
+  input A, B, C, D, E, F, G, H, S, T, U;
+  output Y;
+  mux8x0 _TECHMAP_REPLACE_ (
+    .A(A),
+    .B(B),
+    .C(C),
+    .D(D),
+    .E(E),
+    .F(F),
+    .G(G),
+    .H(H),
+    .S0(S),
+    .S1(T),
+    .S2(U),
+    .Q(Y)
+  );
+endmodule
+
+module \$_MUX4_ (
+  A, B, C, D, S, T, U, Y
+);
+  input A, B, C, D, S, T, U;
+  output Y;
+  mux4x0 _TECHMAP_REPLACE_ (
+    .A(A),
+    .B(B),
+    .C(C),
+    .D(D),
+    .S0(S),
+    .S1(T),
+    .Q(Y)
+  );
+endmodule
diff --git a/techlibs/quicklogic/pp3_cells_sim.v b/techlibs/quicklogic/pp3_cells_sim.v
new file mode 100644 (file)
index 0000000..61d1ee3
--- /dev/null
@@ -0,0 +1,330 @@
+module inpad (
+  output Q,
+  (* iopad_external_pin *)
+  input P
+);
+  specify
+    (P => Q) = 0;
+  endspecify
+  assign Q = P;
+endmodule
+
+module outpad (
+  (* iopad_external_pin *)
+  output P,
+  input A
+);
+  specify
+    (A => P) = 0;
+  endspecify
+  assign P = A;
+endmodule
+
+module ckpad (
+  output Q,
+  (* iopad_external_pin *)
+  input P
+);
+  specify
+    (P => Q) = 0;
+  endspecify
+  assign Q = P;
+endmodule
+
+module bipad (
+  input A,
+  input EN,
+  output Q,
+  (* iopad_external_pin *)
+  inout P
+);
+  assign Q = P;
+  assign P = EN ? A : 1'bz;
+endmodule
+
+module dff (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+  always @(posedge CLK) Q <= D;
+endmodule
+
+module dffc (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  (* clkbuf_sink *)
+  input CLR
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR)
+    if (CLR) Q <= 1'b0;
+    else Q <= D;
+endmodule
+
+module dffp (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  (* clkbuf_sink *)
+  input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge PRE)
+    if (PRE) Q <= 1'b1;
+    else Q <= D;
+endmodule
+
+module dffpc (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  (* clkbuf_sink *)
+  input CLR,
+  (* clkbuf_sink *)
+  input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR or posedge PRE)
+    if (CLR) Q <= 1'b0;
+    else if (PRE) Q <= 1'b1;
+    else Q <= D;
+endmodule
+
+module dffe (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  input EN
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+  always @(posedge CLK) if (EN) Q <= D;
+endmodule
+
+module dffec (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  input EN,
+  (* clkbuf_sink *)
+  input CLR
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR)
+    if (CLR) Q <= 1'b0;
+    else if (EN) Q <= D;
+endmodule
+
+(* lib_whitebox *)
+module dffepc (
+  output reg Q,
+  input D,
+  (* clkbuf_sink *)
+  input CLK,
+  input EN,
+  (* clkbuf_sink *)
+  input CLR,
+  (* clkbuf_sink *)
+  input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+
+  // The CLR => Q and PRE => Q paths are commented out due to YosysHQ/yosys#2530.
+  specify
+    if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ
+    // if (CLR) (CLR => Q) = 967; // QRT -> QZ
+    // if (PRE) (PRE => Q) = 1252; // QST -> QZ
+    $setup(D, posedge CLK, 216); // QCK -> QDS
+    $setup(EN, posedge CLK, 590); // QCK -> QEN
+  endspecify
+
+  initial Q = INIT;
+  always @(posedge CLK or posedge CLR or posedge PRE)
+    if (CLR) Q <= 1'b0;
+    else if (PRE) Q <= 1'b1;
+    else if (EN) Q <= D;
+endmodule
+
+//                  FZ       FS F2 (F1 TO 0)
+(* abc9_box, lib_whitebox *)
+module AND2I0 (
+  output Q,
+  input A, B
+);
+  specify
+    (A => Q) = 698; // FS -> FZ
+    (B => Q) = 639; // F2 -> FZ
+  endspecify
+
+  assign Q = A ? B : 0;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux2x0 (
+  output Q,
+  input S, A, B
+);
+  specify
+    (S => Q) = 698; // FS -> FZ
+    (A => Q) = 639; // F1 -> FZ
+    (B => Q) = 639; // F2 -> FZ
+  endspecify
+
+  assign Q = S ? B : A;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux2x1 (
+  output Q,
+  input S, A, B
+);
+  specify
+    (S => Q) = 698; // FS -> FZ
+    (A => Q) = 639; // F1 -> FZ
+    (B => Q) = 639; // F2 -> FZ
+  endspecify
+
+  assign Q = S ? B : A;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux4x0 (
+  output Q,
+  input S0, S1, A, B, C, D
+);
+  specify
+    (S0 => Q) = 1251; // TAB -> TZ
+    (S1 => Q) = 1406; // TSL -> TZ
+    (A => Q) = 1699;  // TA1 -> TZ
+    (B => Q) = 1687;  // TA2 -> TZ
+    (C => Q) = 1669;  // TB1 -> TZ
+    (D => Q) = 1679;  // TB2 -> TZ
+  endspecify
+
+  assign Q = S1 ? (S0 ? D : C) : (S0 ? B : A);
+endmodule
+
+// S0 BSL TSL
+// S1 BAB TAB
+// S2 TBS
+// A TA1
+// B TA2
+// C TB1
+// D TB2
+// E BA1
+// F BA2
+// G BB1
+// H BB2
+// Q CZ
+(* abc9_box, lib_whitebox *)
+module mux8x0 (
+  output Q,
+  input S0, S1, S2, A, B, C, D, E, F, G, H
+);
+  specify
+    (S0 => Q) = 1593; // ('TSL', 'BSL') -> CZ
+    (S1 => Q) = 1437; // ('TAB', 'BAB') -> CZ
+    (S2 => Q) = 995; // TBS -> CZ
+    (A => Q) = 1887; // TA1 -> CZ
+    (B => Q) = 1873; // TA2 -> CZ
+    (C => Q) = 1856; // TB1 -> CZ
+    (D => Q) = 1860; // TB2 -> CZ
+    (E => Q) = 1714; // BA1 -> CZ
+    (F => Q) = 1773; // BA2 -> CZ
+    (G => Q) = 1749; // BB1 -> CZ
+    (H => Q) = 1723; // BB2 -> CZ
+  endspecify
+
+  assign Q = S2 ? (S1 ? (S0 ? H : G) : (S0 ? F : E)) : (S1 ? (S0 ? D : C) : (S0 ? B : A));
+endmodule
+
+(* blackbox *)
+(* keep *)
+module qlal4s3b_cell_macro (
+  input WB_CLK,
+  input WBs_ACK,
+  input [31:0] WBs_RD_DAT,
+  output [3:0] WBs_BYTE_STB,
+  output WBs_CYC,
+  output WBs_WE,
+  output WBs_RD,
+  output WBs_STB,
+  output [16:0] WBs_ADR,
+  input [3:0] SDMA_Req,
+  input [3:0] SDMA_Sreq,
+  output [3:0] SDMA_Done,
+  output [3:0] SDMA_Active,
+  input [3:0] FB_msg_out,
+  input [7:0] FB_Int_Clr,
+  output FB_Start,
+  input FB_Busy,
+  output WB_RST,
+  output Sys_PKfb_Rst,
+  output Clk16,
+  output Clk16_Rst,
+  output Clk21,
+  output Clk21_Rst,
+  output Sys_Pclk,
+  output Sys_Pclk_Rst,
+  input Sys_PKfb_Clk,
+  input [31:0] FB_PKfbData,
+  output [31:0] WBs_WR_DAT,
+  input [3:0] FB_PKfbPush,
+  input FB_PKfbSOF,
+  input FB_PKfbEOF,
+  output [7:0] Sensor_Int,
+  output FB_PKfbOverflow,
+  output [23:0] TimeStamp,
+  input Sys_PSel,
+  input [15:0] SPIm_Paddr,
+  input SPIm_PEnable,
+  input SPIm_PWrite,
+  input [31:0] SPIm_PWdata,
+  output SPIm_PReady,
+  output SPIm_PSlvErr,
+  output [31:0] SPIm_Prdata,
+  input [15:0] Device_ID,
+  input [13:0] FBIO_In_En,
+  input [13:0] FBIO_Out,
+  input [13:0] FBIO_Out_En,
+  output [13:0] FBIO_In,
+  inout [13:0] SFBIO,
+  input Device_ID_6S,
+  input Device_ID_4S,
+  input SPIm_PWdata_26S,
+  input SPIm_PWdata_24S,
+  input SPIm_PWdata_14S,
+  input SPIm_PWdata_11S,
+  input SPIm_PWdata_0S,
+  input SPIm_Paddr_8S,
+  input SPIm_Paddr_6S,
+  input FB_PKfbPush_1S,
+  input FB_PKfbData_31S,
+  input FB_PKfbData_21S,
+  input FB_PKfbData_19S,
+  input FB_PKfbData_9S,
+  input FB_PKfbData_6S,
+  input Sys_PKfb_ClkS,
+  input FB_BusyS,
+  input WB_CLKS
+);
+
+endmodule
diff --git a/techlibs/quicklogic/pp3_ffs_map.v b/techlibs/quicklogic/pp3_ffs_map.v
new file mode 100644 (file)
index 0000000..73ba6c9
--- /dev/null
@@ -0,0 +1,4 @@
+module \$_DFFSRE_PPPP_ (input C, S, R, E, D, output Q);
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+  dffepc #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.CLK(C), .PRE(S), .CLR(R), .EN(E), .D(D), .Q(Q));
+endmodule
diff --git a/techlibs/quicklogic/pp3_latches_map.v b/techlibs/quicklogic/pp3_latches_map.v
new file mode 100644 (file)
index 0000000..240a3fb
--- /dev/null
@@ -0,0 +1,11 @@
+module \$_DLATCH_P_ (E, D, Q);
+  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
+  input E, D;
+  output Q = E ? D : Q;
+endmodule
+
+module \$_DLATCH_N_ (E, D, Q);
+  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
+  input E, D;
+  output Q = !E ? D : Q;
+endmodule
diff --git a/techlibs/quicklogic/pp3_lut_map.v b/techlibs/quicklogic/pp3_lut_map.v
new file mode 100644 (file)
index 0000000..4c375c9
--- /dev/null
@@ -0,0 +1,53 @@
+module \$lut (
+  A, Y
+);
+  parameter WIDTH = 0;
+  parameter LUT = 0;
+
+  input [WIDTH-1:0] A;
+  output Y;
+
+  generate
+    if (WIDTH == 1) begin
+      LUT1 #(
+        .EQN(""),
+        .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+        .O(Y),
+        .I0(A[0])
+      );
+    end else if (WIDTH == 2) begin
+      LUT2 #(
+        .EQN(""),
+        .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+        .O(Y),
+        .I0(A[0]),
+        .I1(A[1])
+      );
+    end else if (WIDTH == 3) begin
+      LUT3 #(
+        .EQN(""),
+        .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+        .O(Y),
+        .I0(A[0]),
+        .I1(A[1]),
+        .I2(A[2])
+      );
+    end else if (WIDTH == 4) begin
+      LUT4 #(
+        .EQN(""),
+        .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+        .O(Y),
+        .I0(A[0]),
+        .I1(A[1]),
+        .I2(A[2]),
+        .I3(A[3])
+      );
+    end else begin
+      wire _TECHMAP_FAIL_ = 1;
+    end
+  endgenerate
+endmodule
diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc
new file mode 100644 (file)
index 0000000..90eb0f7
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2021 QuickLogic Corp.
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+#include "kernel/celltypes.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct SynthQuickLogicPass : public ScriptPass {
+
+       SynthQuickLogicPass() : ScriptPass("synth_quicklogic", "Synthesis for QuickLogic FPGAs") {}
+
+       void help() override
+       {
+               log("\n");
+               log("   synth_quicklogic [options]\n");
+               log("This command runs synthesis for QuickLogic FPGAs\n");
+               log("\n");
+               log("    -top <module>\n");
+               log("         use the specified module as top module\n");
+               log("\n");
+               log("    -family <family>\n");
+               log("        run synthesis for the specified QuickLogic architecture\n");
+               log("        generate the synthesis netlist for the specified family.\n");
+               log("        supported values:\n");
+               log("        - pp3: PolarPro 3 \n");
+               log("\n");
+               log("    -blif <file>\n");
+               log("        write the design to the specified BLIF file. writing of an output file\n");
+               log("        is omitted if this parameter is not specified.\n");
+               log("\n");
+               log("    -verilog <file>\n");
+               log("        write the design to the specified verilog file. writing of an output file\n");
+               log("        is omitted if this parameter is not specified.\n");
+               log("\n");
+               log("The following commands are executed by this synthesis command:\n");
+               help_script();
+               log("\n");
+       }
+
+       string top_opt, blif_file, family, currmodule, verilog_file;
+
+       void clear_flags() override
+       {
+               top_opt = "-auto-top";
+               blif_file = "";
+               verilog_file = "";
+               currmodule = "";
+               family = "pp3";
+       }
+
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               string run_from, run_to;
+               clear_flags();
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       if (args[argidx] == "-top" && argidx+1 < args.size()) {
+                               top_opt = "-top " + args[++argidx];
+                               continue;
+                       }
+                       if (args[argidx] == "-family" && argidx+1 < args.size()) {
+                               family = args[++argidx];
+                               continue;
+                       }
+                       if (args[argidx] == "-blif" && argidx+1 < args.size()) {
+                               blif_file = args[++argidx];
+                               continue;
+                       }
+                       if (args[argidx] == "-verilog" && argidx+1 < args.size()) {
+                               verilog_file = args[++argidx];
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               if (!design->full_selection())
+                       log_cmd_error("This command only operates on fully selected designs!\n");
+
+               if (family != "pp3")
+                       log_cmd_error("Invalid family specified: '%s'\n", family.c_str());
+
+               log_header(design, "Executing SYNTH_QUICKLOGIC pass.\n");
+               log_push();
+
+               run_script(design, run_from, run_to);
+
+               log_pop();
+       }
+
+       void script() override
+       {
+               if (check_label("begin")) {
+                       run(stringf("read_verilog -lib -specify +/quicklogic/cells_sim.v +/quicklogic/%s_cells_sim.v", family.c_str()));
+                       run("read_verilog -lib -specify +/quicklogic/lut_sim.v");
+                       run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+               }
+
+               if (check_label("coarse")) {
+                       run("proc");
+                       run("flatten");
+                       run("tribuf -logic");
+                       run("deminout");
+                       run("opt_expr");
+                       run("opt_clean");
+                       run("check");
+                       run("opt -nodffe -nosdff");
+                       run("fsm");
+                       run("opt");
+                       run("wreduce");
+                       run("peepopt");
+                       run("opt_clean");
+                       run("share");
+                       run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+                       run("opt_expr");
+                       run("opt_clean");
+                       run("alumacc");
+                       run("pmuxtree");
+                       run("opt");
+                       run("memory -nomap");
+                       run("opt_clean");
+               }
+
+               if (check_label("map_ffram")) {
+                       run("opt -fast -mux_undef -undriven -fine");
+                       run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
+                               "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
+                               "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+                       run("opt -undriven -fine");
+               }
+
+               if (check_label("map_gates")) {
+                       run("techmap");
+                       run("opt -fast");
+                       run("muxcover -mux8 -mux4");
+               }
+
+               if (check_label("map_ffs")) {
+                       run("opt_expr");
+                       run("dfflegalize -cell $_DFFSRE_PPPP_ 0 -cell $_DLATCH_?_ x");
+
+                       run(stringf("techmap -map +/quicklogic/%s_cells_map.v -map +/quicklogic/%s_ffs_map.v", family.c_str(), family.c_str()));
+
+                       run("opt_expr -mux_undef");
+               }
+
+               if (check_label("map_luts")) {
+                       run(stringf("techmap -map +/quicklogic/%s_latches_map.v", family.c_str()));
+                       run("abc -luts 1,2,2,4 -dress");
+
+                       run("clean");
+               }
+
+               if (check_label("map_cells")) {
+                       run(stringf("techmap -map +/quicklogic/%s_lut_map.v", family.c_str()));
+                       run("clean");
+               }
+
+               if (check_label("check")) {
+                       run("autoname");
+                       run("hierarchy -check");
+                       run("stat");
+                       run("check -noinit");
+               }
+
+               if (check_label("iomap")) {
+                       run("clkbufmap -inpad ckpad Q:P");
+                       run("iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top");
+               }
+
+               if (check_label("finalize")) {
+                       run("setundef -zero -params -undriven");
+                       run("hilomap -hicell logic_1 A -locell logic_0 A -singleton A:top");
+                       run("opt_clean -purge");
+                       run("check");
+                       run("blackbox =A:whitebox");
+               }
+
+               if (check_label("blif")) {
+                       if (!blif_file.empty() || help_mode) {
+                               run(stringf("write_blif -attr -param %s %s", top_opt.c_str(), blif_file.c_str()));
+                       }
+               }
+
+               if (check_label("verilog")) {
+                       if (!verilog_file.empty()) {
+                               run("write_verilog -noattr -nohex " + verilog_file);
+                       }
+               }
+       }
+
+} SynthQuicklogicPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/tests/arch/quicklogic/add_sub.ys b/tests/arch/quicklogic/add_sub.ys
new file mode 100644 (file)
index 0000000..168b3f8
--- /dev/null
@@ -0,0 +1,11 @@
+read_verilog ../common/add_sub.v
+hierarchy -top top
+equiv_opt -assert -map +/quicklogic/lut_sim.v -map +/quicklogic/pp3_cells_sim.v synth_quicklogic -family pp3 # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+select -assert-count 3 t:LUT2
+select -assert-count 4 t:LUT3
+select -assert-count 4 t:LUT4
+select -assert-count 8 t:inpad
+select -assert-count 8 t:outpad
+select -assert-none t:LUT2 t:LUT3 t:LUT4 t:inpad t:outpad %% t:* %D
diff --git a/tests/arch/quicklogic/adffs.ys b/tests/arch/quicklogic/adffs.ys
new file mode 100644 (file)
index 0000000..41a1758
--- /dev/null
@@ -0,0 +1,67 @@
+read_verilog ../common/adffs.v
+design -save read
+
+hierarchy -top adff
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adff # Constrain all select calls below inside the top module
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 1 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 2 t:ckpad
+
+select -assert-none t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+
+design -load read
+hierarchy -top adffn
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adffn # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT1
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT1 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+
+design -load read
+hierarchy -top dffs
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+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:LUT2
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+
+design -load read
+hierarchy -top ndffnr
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd ndffnr # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT1
+select -assert-count 1 t:LUT2
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 4 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT1 t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad %% t:* %D
diff --git a/tests/arch/quicklogic/counter.ys b/tests/arch/quicklogic/counter.ys
new file mode 100644 (file)
index 0000000..0c04b57
--- /dev/null
@@ -0,0 +1,18 @@
+read_verilog ../common/counter.v
+hierarchy -top top
+proc
+flatten
+equiv_opt -assert -multiclock -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT1
+select -assert-count 5 t:LUT2
+select -assert-count 2 t:LUT3
+select -assert-count 3 t:LUT4
+select -assert-count 8 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 8 t:outpad
+select -assert-count 2 t:ckpad
+
+select -assert-none t:LUT1 t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:outpad t:ckpad %% t:* %D
diff --git a/tests/arch/quicklogic/dffs.ys b/tests/arch/quicklogic/dffs.ys
new file mode 100644 (file)
index 0000000..2e0a345
--- /dev/null
@@ -0,0 +1,20 @@
+read_verilog ../common/dffs.v
+rename dff my_dff # Work around conflicting module names between test and vendor cells
+rename dffe my_dffe
+design -save read
+
+hierarchy -top my_dff
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd dff # Constrain all select calls below inside the top module
+select -assert-none t:*
+
+design -load read
+hierarchy -top my_dffe
+proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd dffe # Constrain all select calls below inside the top module
+
+select -assert-none t:*
\ No newline at end of file
diff --git a/tests/arch/quicklogic/fsm.ys b/tests/arch/quicklogic/fsm.ys
new file mode 100644 (file)
index 0000000..7ed36b9
--- /dev/null
@@ -0,0 +1,24 @@
+read_verilog ../common/fsm.v
+hierarchy -top fsm
+proc
+flatten
+
+equiv_opt -run :prove -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic
+async2sync
+miter -equiv -make_assert -flatten gold gate miter
+sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
+
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd fsm # Constrain all select calls below inside the top module
+
+select -assert-count 3 t:LUT2
+select -assert-count 6 t:LUT3
+select -assert-count 7 t:LUT4
+select -assert-count 6 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 3 t:inpad
+select -assert-count 2 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
diff --git a/tests/arch/quicklogic/latches.ys b/tests/arch/quicklogic/latches.ys
new file mode 100644 (file)
index 0000000..d7652f7
--- /dev/null
@@ -0,0 +1,39 @@
+read_verilog ../common/latches.v
+design -save read
+
+hierarchy -top latchp
+proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic
+cd latchp # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+
+design -load read
+hierarchy -top latchn
+proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic
+cd latchn # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+
+design -load read
+hierarchy -top latchsr
+proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic
+cd latchsr # Constrain all select calls below inside the top module
+select -assert-count 2 t:LUT3
+select -assert-count 5 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
diff --git a/tests/arch/quicklogic/logic.ys b/tests/arch/quicklogic/logic.ys
new file mode 100644 (file)
index 0000000..65f48a4
--- /dev/null
@@ -0,0 +1,14 @@
+read_verilog ../common/logic.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+
+select -assert-count 1 t:LUT1
+select -assert-count 6 t:LUT2
+select -assert-count 2 t:LUT4
+select -assert-count 8 t:inpad
+select -assert-count 10 t:outpad
+
+select -assert-none t:LUT1 t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D
diff --git a/tests/arch/quicklogic/mux.ys b/tests/arch/quicklogic/mux.ys
new file mode 100644 (file)
index 0000000..632d146
--- /dev/null
@@ -0,0 +1,52 @@
+read_verilog ../common/mux.v
+design -save read
+
+hierarchy -top mux2
+proc
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux2 # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux4
+proc
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux4 # Constrain all select calls below inside the top module
+select -assert-count 3 t:LUT3
+select -assert-count 6 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux8
+proc
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux8 # Constrain all select calls below inside the top module
+select -assert-count 4 t:LUT2
+select -assert-count 1 t:LUT3
+select -assert-count 2 t:mux4x0
+select -assert-count 11 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT2 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux16
+proc
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux16 # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT3
+select -assert-count 2 t:mux8x0
+select -assert-count 20 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:mux8x0 t:inpad t:outpad %% t:* %D
diff --git a/tests/arch/quicklogic/run-test.sh b/tests/arch/quicklogic/run-test.sh
new file mode 100755 (executable)
index 0000000..4be4b70
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+set -eu
+source ../../gen-tests-makefile.sh
+run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'"
diff --git a/tests/arch/quicklogic/tribuf.ys b/tests/arch/quicklogic/tribuf.ys
new file mode 100644 (file)
index 0000000..de76300
--- /dev/null
@@ -0,0 +1,13 @@
+read_verilog ../common/tribuf.v
+hierarchy -top tristate
+proc
+tribuf
+flatten
+synth
+equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/simcells.v synth_quicklogic # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd tristate # Constrain all select calls below inside the top module
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:$_TBUF_
+select -assert-none t:inpad t:outpad t:$_TBUF_ %% t:* %D