|  | // Copyright (C) 2020-2021  The SymbiFlow Authors. | 
|  | // | 
|  | // Use of this source code is governed by a ISC-style | 
|  | // license that can be found in the LICENSE file or at | 
|  | // https://opensource.org/licenses/ISC | 
|  | // | 
|  | // SPDX-License-Identifier:ISC | 
|  |  | 
|  | 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 | 
|  |  | 
|  | 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; | 
|  |  | 
|  | 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 | 
|  |  | 
|  | (* 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 | 
|  |  | 
|  | module logic_cell_macro ( | 
|  | input  BA1, | 
|  | input  BA2, | 
|  | input  BAB, | 
|  | input  BAS1, | 
|  | input  BAS2, | 
|  | input  BB1, | 
|  | input  BB2, | 
|  | input  BBS1, | 
|  | input  BBS2, | 
|  | input  BSL, | 
|  | input  F1, | 
|  | input  F2, | 
|  | input  FS, | 
|  | input  QCK, | 
|  | input  QCKS, | 
|  | input  QDI, | 
|  | input  QDS, | 
|  | input  QEN, | 
|  | input  QRT, | 
|  | input  QST, | 
|  | input  TA1, | 
|  | input  TA2, | 
|  | input  TAB, | 
|  | input  TAS1, | 
|  | input  TAS2, | 
|  | input  TB1, | 
|  | input  TB2, | 
|  | input  TBS, | 
|  | input  TBS1, | 
|  | input  TBS2, | 
|  | input  TSL, | 
|  | output CZ, | 
|  | output FZ, | 
|  | output QZ, | 
|  | output TZ | 
|  | ); | 
|  |  | 
|  | wire TAP1, TAP2, TBP1, TBP2, BAP1, BAP2, BBP1, BBP2, QCKP, TAI, TBI, BAI, BBI, TZI, BZI, CZI, QZI; | 
|  | reg QZ_r; | 
|  |  | 
|  | initial begin | 
|  | QZ_r = 1'b0; | 
|  | end | 
|  | assign QZ   = QZ_r; | 
|  | assign TAP1 = TAS1 ? ~TA1 : TA1; | 
|  | assign TAP2 = TAS2 ? ~TA2 : TA2; | 
|  | assign TBP1 = TBS1 ? ~TB1 : TB1; | 
|  | assign TBP2 = TBS2 ? ~TB2 : TB2; | 
|  | assign BAP1 = BAS1 ? ~BA1 : BA1; | 
|  | assign BAP2 = BAS2 ? ~BA2 : BA2; | 
|  | assign BBP1 = BBS1 ? ~BB1 : BB1; | 
|  | assign BBP2 = BBS2 ? ~BB2 : BB2; | 
|  |  | 
|  | assign TAI  = TSL ? TAP2 : TAP1; | 
|  | assign TBI  = TSL ? TBP2 : TBP1; | 
|  | assign BAI  = BSL ? BAP2 : BAP1; | 
|  | assign BBI  = BSL ? BBP2 : BBP1; | 
|  | assign TZI  = TAB ? TBI : TAI; | 
|  | assign BZI  = BAB ? BBI : BAI; | 
|  | assign CZI  = TBS ? BZI : TZI; | 
|  | assign QZI  = QDS ? QDI : CZI; | 
|  | assign FZ   = FS ? F2 : F1; | 
|  | assign TZ   = TZI; | 
|  | assign CZ   = CZI; | 
|  | assign QCKP = QCKS ? QCK : ~QCK; | 
|  |  | 
|  |  | 
|  | always @(posedge QCKP) if (~QRT && ~QST) if (QEN) QZ_r = QZI; | 
|  | always @(QRT or QST) | 
|  | if (QRT) QZ_r = 1'b0; | 
|  | else if (QST) QZ_r = 1'b1; | 
|  |  | 
|  | endmodule | 
|  |  | 
|  | // Include simulation models of QLAL4S3B eFPGA interface | 
|  | `include "qlal4s3b_sim.v" | 
|  | // Include simulation models for QLAL3 hard blocks | 
|  | `include "qlal3_sim.v" | 
|  | // Include BRAM and FIFO simulation models | 
|  | `include "brams_sim.v" | 
|  | // Include MULT simulation models | 
|  | `include "mult_sim.v" | 
|  |  |