blob: e498d4e8733d4d8e085bee61ed077d9efb899f72 [file] [log] [blame]
// 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"