aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/intel_alm/common/alm_sim.v
blob: 979c511320fb96f16216081288af515856bdaa30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

INCLUDES = """
#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
/* The next define should really be in the OpenSSL header, but it is missing.
   Failing to include this on Windows causes compilation failures. */
#if defined(OPENSSL_SYS_WINDOWS)
#include <windows.h>
#endif
#include <openssl/cms.h>
#endif
"""

TYPES = """
static const long Cryptography_HAS_CMS;
static const long Cryptography_HAS_CMS_BIO_FUNCTIONS;

typedef ... CMS_ContentInfo;
typedef ... CMS_SignerInfo;
typedef ... CMS_CertificateChoices;
typedef ... CMS_RevocationInfoChoice;
typedef ... CMS_RecipientInfo;
typedef ... CMS_ReceiptRequest;
typedef ... CMS_Receipt;

static const int CMS_TEXT;
static const int CMS_NOCERTS;
static const int CMS_NO_CONTENT_VERIFY;
static const int CMS_NO_ATTR_VERIFY;
static const int CMS_NOSIGS;
static const int CMS_NOINTERN;
static const int CMS_NO_SIGNER_CERT_VERIFY;
static const int CMS_NOVERIFY;
static const int CMS_DETACHED;
static const int CMS_BINARY;
static const int CMS_NOATTR;
static const int CMS_NOSMIMECAP;
static const int CMS_NOOLDMIMETYPE;
static const int CMS_CRLFEOL;
static const int CMS_STREAM;
static const int CMS_NOCRL;
static const int CMS_PARTIAL;
static const int CMS_REUSE_DIGEST;
static const int CMS_USE_KEYID;
static const int CMS_DEBUG_DECRYPT;
"""

FUNCTIONS = """
"""

MACROS = """
BIO *BIO_new_CMS(BIO *, CMS_ContentInfo *);
int i2d_CMS_bio_stream(BIO *, CMS_ContentInfo *, BIO *, int);
int PEM_write_bio_CMS_stream(BIO *, CMS_ContentInfo *, BIO *, int);
int CMS_final(CMS_ContentInfo *, BIO *, BIO *, unsigned int);
CMS_ContentInfo *CMS_sign(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
                          BIO *, unsigned int);
int CMS_verify(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *, X509_STORE *,
               BIO *, BIO *, unsigned int);
CMS_ContentInfo *CMS_encrypt(Cryptography_STACK_OF_X509 *, BIO *,
                             const EVP_CIPHER *, unsigned int);
int CMS_decrypt(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
                unsigned int);
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *, X509 *, EVP_PKEY *,
                                const EVP_MD *, unsigned int);
"""

CUSTOMIZATIONS = """
#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
static const long Cryptography_HAS_CMS = 1;
#if OPENSSL_VERSION_NUMBER < 0x10000000L
static const long Cryptography_HAS_CMS_BIO_FUNCTIONS = 0;
/* These functions were added in 1.0.0 */
BIO *(*BIO_new_CMS)(BIO *, CMS_ContentInfo *) = NULL;
int (*i2d_CMS_bio_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
int (*PEM_write_bio_CMS_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
#else
static const long Cryptography_HAS_CMS_BIO_FUNCTIONS = 1;
#endif
#else
static const long Cryptography_HAS_CMS = 0;
static const long Cryptography_HAS_CMS_BIO_FUNCTIONS = 0;
typedef void CMS_ContentInfo;
typedef void CMS_SignerInfo;
typedef void CMS_CertificateChoices;
typedef void CMS_RevocationInfoChoice;
typedef void CMS_RecipientInfo;
typedef void CMS_ReceiptRequest;
typedef void CMS_Receipt;
const long CMS_TEXT = 0;
const long CMS_NOCERTS = 0;
const long CMS_NO_CONTENT_VERIFY = 0;
const long CMS_NO_ATTR_VERIFY = 0;
const long CMS_NOSIGS = 0;
const long CMS_NOINTERN = 0;
const long CMS_NO_SIGNER_CERT_VERIFY = 0;
const long CMS_NOVERIFY = 0;
const long CMS_DETACHED = 0;
const long CMS_BINARY = 0;
const long CMS_NOATTR = 0;
const long CMS_NOSMIMECAP = 0;
const long CMS_NOOLDMIMETYPE = 0;
const long CMS_CRLFEOL = 0;
const long CMS_STREAM = 0;
const long CMS_NOCRL = 0;
const long CMS_PARTIAL = 0;
const long CMS_REUSE_DIGEST = 0;
const long CMS_USE_KEYID = 0;
const long CMS_DEBUG_DECRYPT = 0;
BIO *(*BIO_new_CMS)(BIO *, CMS_ContentInfo *) = NULL;
int (*i2d_CMS_bio_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
int (*PEM_write_bio_CMS_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
int (*CMS_final)(CMS_ContentInfo *, BIO *, BIO *, unsigned int) = NULL;
CMS_ContentInfo *(*CMS_sign)(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
                             BIO *, unsigned int) = NULL;
int (*CMS_verify)(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *,
                  X509_STORE *, BIO *, BIO *, unsigned int) = NULL;
CMS_ContentInfo *(*CMS_encrypt)(Cryptography_STACK_OF_X509 *, BIO *,
                                const EVP_CIPHER *, unsigned int) = NULL;
int (*CMS_decrypt)(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
                   unsigned int) = NULL;
CMS_SignerInfo *(*CMS_add1_signer)(CMS_ContentInfo *, X509 *, EVP_PKEY *,
                                   const EVP_MD *, unsigned int) = NULL;
#endif
"""
ef='#n545'>545 546 547 548 549 550 551
// The core logic primitive of the Cyclone V/10GX is the Adaptive Logic Module
// (ALM). Each ALM is made up of an 8-input, 2-output look-up table, covered 
// in this file, connected to combinational outputs, a carry chain, and four
// D flip-flops (which are covered as MISTRAL_FF in dff_sim.v).
//
// The ALM is vertically symmetric, so I find it helps to think in terms of
// half-ALMs, as that's predominantly the unit that synth_intel_alm uses.
//
// ALMs are quite flexible, having multiple modes.
//
// Normal (combinational) mode
// ---------------------------
// The ALM can implement:
// - a single 6-input function (with the other inputs usable for flip-flop access)
// - two 5-input functions that share two inputs
// - a 5-input and a 4-input function that share one input
// - a 5-input and a 3-or-less-input function that share no inputs
// - two 4-or-less-input functions that share no inputs
//
// Normal-mode functions are represented as MISTRAL_ALUTN cells with N inputs.
// It would be possible to represent a normal mode function as a single cell -
// the vendor cyclone{v,10gx}_lcell_comb cell does exactly that - but I felt
// it was more user-friendly to print out the specific function sizes
// separately.
//
// With the exception of MISTRAL_ALUT6, you can think of two normal-mode cells
// fitting inside a single ALM.
//
// Extended (7-input) mode
// -----------------------
// The ALM can also fit a 7-input function made of two 5-input functions that
// share four inputs, multiplexed by another input.
//
// Because this can't accept arbitrary 7-input functions, Yosys can't handle
// it, so it doesn't have a cell, but I would likely call it MISTRAL_ALUT7(E?)
// if it did, and it would take up a full ALM.
//
// It might be possible to add an extraction pass to examine all ALUT5 cells
// that feed into ALUT3 cells to see if they can be combined into an extended
// ALM, but I don't think it will be worth it.
//
// Arithmetic mode
// ---------------
// In arithmetic mode, each half-ALM uses its carry chain to perform fast addition
// of two four-input functions that share three inputs. Oddly, the result of
// one of the functions is inverted before being added (you can see this as
// the dot on a full-adder input of Figure 1-8 in the Handbook).
//
// The cell for an arithmetic-mode half-ALM is MISTRAL_ALM_ARITH. One idea
// I've had (or rather was suggested by mwk) is that functions that feed into
// arithmetic-mode cells could be packed directly into the arithmetic-mode
// cell as a function, which reduces the number of ALMs needed.
//
// Shared arithmetic mode
// ----------------------
// Shared arithmetic mode looks a lot like arithmetic mode, but here the
// output of every other four-input function goes to the input of the adder
// the next bit along. What this means is that adding three bits together can
// be done in an ALM, because functions can be used to implement addition that
// then feeds into the carry chain. This means that three bits can be added per
// ALM, as opposed to two in the arithmetic mode.
//
// Shared arithmetic mode doesn't currently have a cell, but I intend to add
// it as MISTRAL_ALM_SHARED, and have it occupy a full ALM. Because it adds
// three bits per cell, it makes addition shorter and use less ALMs, but
// I don't know enough to tell whether it's more efficient to use shared
// arithmetic mode to shorten the carry chain, or plain arithmetic mode with
// the functions packed in.

`default_nettype none

(* abc9_lut=2, lib_whitebox *)
module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);

parameter [63:0] LUT = 64'h0000_0000_0000_0000;

`ifdef cyclonev
specify
    (A => Q) = 602;
    (B => Q) = 584;
    (C => Q) = 510;
    (D => Q) = 510;
    (E => Q) = 339;
    (F => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 275;
    (B => Q) = 272;
    (C => Q) = 175;
    (D => Q) = 165;
    (E => Q) = 162;
    (F => Q) = 53;
endspecify
`endif

assign Q = LUT >> {F, E, D, C, B, A};

endmodule


(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT5(input A, B, C, D, E, output Q);

parameter [31:0] LUT = 32'h0000_0000;

`ifdef cyclonev
specify
    (A => Q) = 584;
    (B => Q) = 510;
    (C => Q) = 510;
    (D => Q) = 339;
    (E => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 272;
    (B => Q) = 175;
    (C => Q) = 165;
    (D => Q) = 162;
    (E => Q) = 53;
endspecify
`endif

assign Q = LUT >> {E, D, C, B, A};

endmodule


(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT4(input A, B, C, D, output Q);

parameter [15:0] LUT = 16'h0000;

`ifdef cyclonev
specify
    (A => Q) = 510;
    (B => Q) = 510;
    (C => Q) = 339;
    (D => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 175;
    (B => Q) = 165;
    (C => Q) = 162;
    (D => Q) = 53;
endspecify
`endif

assign Q = LUT >> {D, C, B, A};

endmodule


(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT3(input A, B, C, output Q);

parameter [7:0] LUT = 8'h00;

`ifdef cyclonev
specify
    (A => Q) = 510;
    (B => Q) = 339;
    (C => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 165;
    (B => Q) = 162;
    (C => Q) = 53;
endspecify
`endif

assign Q = LUT >> {C, B, A};

endmodule


(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT2(input A, B, output Q);

parameter [3:0] LUT = 4'h0;

`ifdef cyclonev
specify
    (A => Q) = 339;
    (B => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 162;
    (B => Q) = 53;
endspecify
`endif

assign Q = LUT >> {B, A};

endmodule


(* abc9_lut=1, lib_whitebox *)
module MISTRAL_NOT(input A, output Q);

`ifdef cyclonev
specify
    (A => Q) = 94;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 53;
endspecify
`endif

assign Q = ~A;

endmodule

(* abc9_box, lib_whitebox *)
module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO);

parameter LUT0 = 16'h0000;
parameter LUT1 = 16'h0000;

`ifdef cyclonev
specify
    (A => SO) = 1283;
    (B => SO) = 1167;
    (C => SO) = 866;
    (D0 => SO) = 756;
    (D1 => SO) = 756;
    (CI => SO) = 355;
    (A => CO) = 950;
    (B => CO) = 1039;
    (C => CO) = 820;
    (D0 => CO) = 1006;
    (D1 => CO) = 1006;
    (CI => CO) = 23;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => SO) = 644;
    (B => SO) = 477;
    (C => SO) = 416;
    (D0 => SO) = 380;
    (D1 => SO) = 431;
    (CI => SO) = 276;
    (A => CO) = 525;
    (B => CO) = 433;
    (C => CO) = 712;
    (D0 => CO) = 653;
    (D1 => CO) = 593;
    (CI => CO) = 16;
endspecify
`endif

wire q0, q1;

assign q0 = LUT0 >> {D0, C, B, A};
assign q1 = LUT1 >> {D1, C, B, A};

assign {CO, SO} = q0 + !q1 + CI;

endmodule


/*
// A, B, C0, C1, E0, E1, F0, F1: data inputs
// CARRYIN: carry input
// SHAREIN: shared-arithmetic input
// CLK0, CLK1, CLK2: clock inputs
//
// COMB0, COMB1: combinational outputs
// FF0, FF1, FF2, FF3: DFF outputs
// SUM0, SUM1: adder outputs
// CARRYOUT: carry output
// SHAREOUT: shared-arithmetic output
module MISTRAL_ALM(
    input A, B, C0, C1, E0, E1, F0, F1, CARRYIN, SHAREIN, // LUT path
    input CLK0, CLK1, CLK2, AC0, AC1,                     // FF path
    output COMB0, COMB1, SUM0, SUM1, CARRYOUT, SHAREOUT,
    output FF0, FF1, FF2, FF3
);

parameter LUT0 = 16'b0000;
parameter LUT1 = 16'b0000;
parameter LUT2 = 16'b0000;
parameter LUT3 = 16'b0000;

parameter INIT0 = 1'b0;
parameter INIT1 = 1'b0;
parameter INIT2 = 1'b0;
parameter INIT3 = 1'b0;

parameter C0_MUX = "C0";
parameter C1_MUX = "C1";

parameter F0_MUX = "VCC";
parameter F1_MUX = "GND";

parameter FEEDBACK0 = "FF0";
parameter FEEDBACK1 = "FF2";

parameter ADD_MUX = "LUT";

parameter DFF01_DATA_MUX = "COMB";
parameter DFF23_DATA_MUX = "COMB";

parameter DFF0_CLK = "CLK0";
parameter DFF1_CLK = "CLK0";
parameter DFF2_CLK = "CLK0";
parameter DFF3_CLK = "CLK0";

parameter DFF0_AC  = "AC0";
parameter DFF1_AC  = "AC0";
parameter DFF2_AC  = "AC0";
parameter DFF3_AC  = "AC0";

// Feedback muxes from the flip-flop outputs.
wire ff_feedback_mux0, ff_feedback_mux1;

// C-input muxes which can be set to also use the F-input.
wire c0_input_mux, c1_input_mux;

// F-input muxes which can be set to a constant to allow LUT5 use.
wire f0_input_mux, f1_input_mux;

// Adder input muxes to select between shared-arithmetic mode and arithmetic mode.
wire add0_input_mux, add1_input_mux;

// Combinational-output muxes for LUT #1 and LUT #3
wire lut1_comb_mux, lut3_comb_mux;

// Sum-output muxes for LUT #1 and LUT #3
wire lut1_sum_mux, lut3_sum_mux;

// DFF data-input muxes
wire dff01_data_mux, dff23_data_mux;

// DFF clock selectors
wire dff0_clk, dff1_clk, dff2_clk, dff3_clk;

// DFF asynchronous-clear selectors
wire dff0_ac, dff1_ac, dff2_ac, dff3_ac;

// LUT, DFF and adder output wires for routing.
wire lut0_out, lut1a_out, lut1b_out, lut2_out, lut3a_out, lut3b_out;
wire dff0_out, dff1_out, dff2_out, dff3_out;
wire add0_sum, add1_sum, add0_carry, add1_carry;

generate
    if (FEEDBACK0 === "FF0")
        assign ff_feedback_mux0 = dff0_out;
    else if (FEEDBACK0 === "FF1")
        assign ff_feedback_mux0 = dff1_out;
    else
        $error("Invalid FEEDBACK0 setting!");

    if (FEEDBACK1 == "FF2")
        assign ff_feedback_mux1 = dff2_out;
    else if (FEEDBACK1 == "FF3")
        assign ff_feedback_mux1 = dff3_out;
    else
        $error("Invalid FEEDBACK1 setting!");

    if (C0_MUX === "C0")
        assign c0_input_mux = C0;
    else if (C0_MUX === "F1")
        assign c0_input_mux = F1;
    else if (C0_MUX === "FEEDBACK1")
        assign c0_input_mux = ff_feedback_mux1;
    else
        $error("Invalid C0_MUX setting!");

    if (C1_MUX === "C1")
        assign c1_input_mux = C1;
    else if (C1_MUX === "F0")
        assign c1_input_mux = F0;
    else if (C1_MUX === "FEEDBACK0")
        assign c1_input_mux = ff_feedback_mux0;
    else
        $error("Invalid C1_MUX setting!");

    // F0 == VCC is LUT5
    // F0 == F0 is LUT6
    // F0 == FEEDBACK is unknown
    if (F0_MUX === "VCC")
        assign f0_input_mux = 1'b1;
    else if (F0_MUX === "F0")
        assign f0_input_mux = F0;
    else if (F0_MUX === "FEEDBACK0")
        assign f0_input_mux = ff_feedback_mux0;
    else
        $error("Invalid F0_MUX setting!");

    // F1 == GND is LUT5
    // F1 == F1 is LUT6
    // F1 == FEEDBACK is unknown
    if (F1_MUX === "GND")
        assign f1_input_mux = 1'b0;
    else if (F1_MUX === "F1")
        assign f1_input_mux = F1;
    else if (F1_MUX === "FEEDBACK1")
        assign f1_input_mux = ff_feedback_mux1;
    else
        $error("Invalid F1_MUX setting!");

    if (ADD_MUX === "LUT") begin
        assign add0_input_mux = ~lut1_sum_mux;
        assign add1_input_mux = ~lut3_sum_mux;
    end else if (ADD_MUX === "SHARE") begin
        assign add0_input_mux = SHAREIN;
        assign add1_input_mux = lut1_comb_mux;
    end else
        $error("Invalid ADD_MUX setting!");

    if (DFF01_DATA_MUX === "COMB")
        assign dff01_data_mux = COMB0;
    else if (DFF01_DATA_MUX === "SUM")
        assign dff01_data_mux = SUM0;
    else
        $error("Invalid DFF01_DATA_MUX setting!");

    if (DFF23_DATA_MUX === "COMB")
        assign dff23_data_mux = COMB0;
    else if (DFF23_DATA_MUX === "SUM")
        assign dff23_data_mux = SUM0;
    else
        $error("Invalid DFF23_DATA_MUX setting!");

    if (DFF0_CLK === "CLK0")
        assign dff0_clk = CLK0;
    else if (DFF0_CLK === "CLK1")
        assign dff0_clk = CLK1;
    else if (DFF0_CLK === "CLK2")
        assign dff0_clk = CLK2;
    else
        $error("Invalid DFF0_CLK setting!");

    if (DFF1_CLK === "CLK0")
        assign dff1_clk = CLK0;
    else if (DFF1_CLK === "CLK1")
        assign dff1_clk = CLK1;
    else if (DFF1_CLK === "CLK2")
        assign dff1_clk = CLK2;
    else
        $error("Invalid DFF1_CLK setting!");

    if (DFF2_CLK === "CLK0")
        assign dff2_clk = CLK0;
    else if (DFF2_CLK === "CLK1")
        assign dff2_clk = CLK1;
    else if (DFF2_CLK === "CLK2")
        assign dff2_clk = CLK2;
    else
        $error("Invalid DFF2_CLK setting!");

    if (DFF3_CLK === "CLK0")
        assign dff3_clk = CLK0;
    else if (DFF3_CLK === "CLK1")
        assign dff3_clk = CLK1;
    else if (DFF3_CLK === "CLK2")
        assign dff3_clk = CLK2;
    else
        $error("Invalid DFF3_CLK setting!");

    if (DFF0_AC === "AC0")
        assign dff0_ac = AC0;
    else if (DFF0_AC === "AC1")
        assign dff0_ac = AC1;
    else
        $error("Invalid DFF0_AC setting!");

    if (DFF1_AC === "AC0")
        assign dff1_ac = AC0;
    else if (DFF1_AC === "AC1")
        assign dff1_ac = AC1;
    else
        $error("Invalid DFF1_AC setting!");

    if (DFF2_AC === "AC0")
        assign dff2_ac = AC0;
    else if (DFF2_AC === "AC1")
        assign dff2_ac = AC1;
    else
        $error("Invalid DFF2_AC setting!");

    if (DFF3_AC === "AC0")
        assign dff3_ac = AC0;
    else if (DFF3_AC === "AC1")
        assign dff3_ac = AC1;
    else
        $error("Invalid DFF3_AC setting!");

endgenerate

// F0 on the Quartus diagram
MISTRAL_ALUT4 #(.LUT(LUT0)) lut0 (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut0_out));

// F2 on the Quartus diagram
MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_comb (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut1_comb_mux));
MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_sum  (.A(A), .B(B), .C(C0), .D(E0), .Q(lut1_sum_mux));

// F1 on the Quartus diagram
MISTRAL_ALUT4 #(.LUT(LUT2)) lut2 (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut2_out));

// F3 on the Quartus diagram
MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_comb (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut3_comb_mux));
MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_sum  (.A(A), .B(B), .C(C1), .D(E1), .Q(lut3_sum_mux));

MISTRAL_FF #(.INIT(INIT0)) dff0 (.D(dff01_data_mux), .CLK(dff0_clk), .ACn(dff0_ac), .Q(dff0_out));
MISTRAL_FF #(.INIT(INIT1)) dff1 (.D(dff01_data_mux), .CLK(dff1_clk), .ACn(dff1_ac), .Q(dff1_out));
MISTRAL_FF #(.INIT(INIT2)) dff2 (.D(dff23_data_mux), .CLK(dff2_clk), .ACn(dff2_ac), .Q(dff2_out));
MISTRAL_FF #(.INIT(INIT3)) dff3 (.D(dff23_data_mux), .CLK(dff3_clk), .ACn(dff3_ac), .Q(dff3_out));

// Adders
assign {add0_carry, add0_sum} = CARRYIN + lut0_out + lut1_sum_mux;
assign {add1_carry, add1_sum} = add0_carry + lut2_out + lut3_sum_mux;

// COMBOUT outputs on the Quartus diagram
assign COMB0 = E0 ? (f0_input_mux ? lut3_comb_mux : lut1_comb_mux)
                    : (f0_input_mux ? lut2_out : lut0_out);

assign COMB1 = E1 ? (f1_input_mux ? lut3_comb_mux : lut1_comb_mux)
                    : (f1_input_mux ? lut2_out : lut0_out);

// SUMOUT output on the Quartus diagram
assign SUM0 = add0_sum;
assign SUM1 = add1_sum;

// COUT output on the Quartus diagram
assign CARRYOUT = add1_carry;

// SHAREOUT output on the Quartus diagram
assign SHAREOUT = lut3_comb_mux;

// REGOUT outputs on the Quartus diagram
assign FF0 = dff0_out;
assign FF1 = dff1_out;
assign FF2 = dff2_out;
assign FF3 = dff3_out;

endmodule
*/