aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/intel_alm/common
diff options
context:
space:
mode:
authorDan Ravensloft <dan.ravensloft@gmail.com>2019-11-19 10:19:00 +0000
committerMarcelina Koƛcielnicka <mwk@0x04.net>2020-04-15 11:40:41 +0200
commit2e37e62e6b926ca1712b1636ef720748e382dc97 (patch)
tree25936d690dff24f0cddcc5dbbfe68aea74500994 /techlibs/intel_alm/common
parent4c52691a58a469a525401bbc83c65f262b2a5504 (diff)
downloadyosys-2e37e62e6b926ca1712b1636ef720748e382dc97.tar.gz
yosys-2e37e62e6b926ca1712b1636ef720748e382dc97.tar.bz2
yosys-2e37e62e6b926ca1712b1636ef720748e382dc97.zip
synth_intel_alm: alternative synthesis for Intel FPGAs
By operating at a layer of abstraction over the rather clumsy Intel primitives, we can avoid special hacks like `dffinit -highlow` in favour of simple techmapping. This also makes the primitives much easier to manipulate, and more descriptive (no more cyclonev_lcell_comb to mean anything from a LUT2 to a LUT6).
Diffstat (limited to 'techlibs/intel_alm/common')
-rw-r--r--techlibs/intel_alm/common/alm_map.v56
-rw-r--r--techlibs/intel_alm/common/alm_sim.v482
-rw-r--r--techlibs/intel_alm/common/arith_alm_map.v64
-rw-r--r--techlibs/intel_alm/common/bram_m10k.txt33
-rw-r--r--techlibs/intel_alm/common/bram_m10k_map.v31
-rw-r--r--techlibs/intel_alm/common/bram_m20k.txt33
-rw-r--r--techlibs/intel_alm/common/bram_m20k_map.v31
-rw-r--r--techlibs/intel_alm/common/dff_map.v124
-rw-r--r--techlibs/intel_alm/common/dff_sim.v48
-rw-r--r--techlibs/intel_alm/common/lutram_mlab.txt20
-rw-r--r--techlibs/intel_alm/common/lutram_mlab_map.v29
-rw-r--r--techlibs/intel_alm/common/megafunction_bb.v108
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v23
13 files changed, 1082 insertions, 0 deletions
diff --git a/techlibs/intel_alm/common/alm_map.v b/techlibs/intel_alm/common/alm_map.v
new file mode 100644
index 000000000..fe646c5d6
--- /dev/null
+++ b/techlibs/intel_alm/common/alm_map.v
@@ -0,0 +1,56 @@
+module \$lut (A, Y);
+
+parameter WIDTH = 1;
+parameter LUT = 0;
+
+input [WIDTH-1:0] A;
+output Y;
+
+generate
+ if (WIDTH == 1) begin
+ generate
+ if (LUT == 2'b00) begin
+ assign Y = 1'b0;
+ end
+ else if (LUT == 2'b01) begin
+ MISTRAL_NOT _TECHMAP_REPLACE_(
+ .A(A[0]), .Q(Y)
+ );
+ end
+ else if (LUT == 2'b10) begin
+ assign Y = A;
+ end
+ else if (LUT == 2'b11) begin
+ assign Y = 1'b1;
+ end
+ endgenerate
+ end else
+ if (WIDTH == 2) begin
+ MISTRAL_ALUT2 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 3) begin
+ MISTRAL_ALUT3 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .C(A[2]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 4) begin
+ MISTRAL_ALUT4 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 5) begin
+ MISTRAL_ALUT5 #(.LUT(LUT)) _TECHMAP_REPLACE_ (
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .E(A[4]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 6) begin
+ MISTRAL_ALUT6 #(.LUT(LUT)) _TECHMAP_REPLACE_ (
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .E(A[4]), .F(A[5]), .Q(Y)
+ );
+ end else begin
+ wire _TECHMAP_FAIL_ = 1'b1;
+ end
+endgenerate
+endmodule
diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v
new file mode 100644
index 000000000..69768d9f7
--- /dev/null
+++ b/techlibs/intel_alm/common/alm_sim.v
@@ -0,0 +1,482 @@
+`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
+*/
diff --git a/techlibs/intel_alm/common/arith_alm_map.v b/techlibs/intel_alm/common/arith_alm_map.v
new file mode 100644
index 000000000..ddf81d9d0
--- /dev/null
+++ b/techlibs/intel_alm/common/arith_alm_map.v
@@ -0,0 +1,64 @@
+`default_nettype none
+
+module \$alu (A, B, CI, BI, X, Y, CO);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+parameter _TECHMAP_CONSTMSK_CI_ = 0;
+parameter _TECHMAP_CONSTVAL_CI_ = 0;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+input CI, BI;
+output [Y_WIDTH-1:0] X, Y, CO;
+
+wire [Y_WIDTH-1:0] A_buf, B_buf;
+\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+wire [Y_WIDTH-1:0] AA = A_buf;
+wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+wire [Y_WIDTH-1:0] BX = B_buf;
+wire [Y_WIDTH:0] ALM_CARRY;
+
+// Start of carry chain
+generate
+ if (_TECHMAP_CONSTMSK_CI_ == 1) begin
+ assign ALM_CARRY[0] = _TECHMAP_CONSTVAL_CI_;
+ end else begin
+ MISTRAL_ALUT_ARITH #(
+ .LUT0(16'b1010_1010_1010_1010), // Q = A
+ .LUT1(16'b0000_0000_0000_0000), // Q = 0 (LUT1's input to the adder is inverted)
+ ) alm_start (
+ .A(CI), .B(1'b1), .C(1'b1), .D0(1'b1), .D1(1'b1),
+ .CI(1'b0),
+ .CO(ALM_CARRY[0])
+ );
+ end
+endgenerate
+
+// Carry chain
+genvar i;
+generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
+ // TODO: mwk suggests that a pass could merge pre-adder logic into this.
+ MISTRAL_ALUT_ARITH #(
+ .LUT0(16'b1010_1010_1010_1010), // Q = A
+ .LUT1(16'b1100_0011_1100_0011), // Q = C ? B : ~B (LUT1's input to the adder is inverted)
+ ) alm_i (
+ .A(AA[i]), .B(BX[i]), .C(BI), .D0(1'b1), .D1(1'b1),
+ .CI(ALM_CARRY[i]),
+ .SO(Y[i]),
+ .CO(ALM_CARRY[i+1])
+ );
+
+ // ALM carry chain is not directly accessible, so calculate the carry through soft logic if really needed.
+ assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i]));
+end endgenerate
+
+assign X = AA ^ BB;
+
+endmodule
diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt
new file mode 100644
index 000000000..837e3a330
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m10k.txt
@@ -0,0 +1,33 @@
+bram __MISTRAL_M10K_SDP
+ init 0 # TODO: Re-enable when I figure out how BRAM init works
+ abits 13 @D8192x1
+ dbits 1 @D8192x1
+ abits 12 @D4096x2
+ dbits 2 @D4096x2
+ abits 11 @D2048x4 @D2048x5
+ dbits 4 @D2048x4
+ dbits 5 @D2048x5
+ abits 10 @D1024x8 @D1024x10
+ dbits 8 @D1024x8
+ dbits 10 @D1024x10
+ abits 9 @D512x16 @D512x20
+ dbits 16 @D512x16
+ dbits 20 @D512x20
+ abits 8 @D256x32 @D256x40
+ dbits 32 @D256x32
+ dbits 40 @D256x40
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable; write enable + byte enables (only for multiples of 8)
+ enable 1 1
+ transp 0 0
+ clocks 1 1
+ clkpol 1 1
+endbram
+
+
+match __MISTRAL_M10K_SDP
+ min efficiency 5
+ make_transp
+endmatch
diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v
new file mode 100644
index 000000000..e5566010d
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m10k_map.v
@@ -0,0 +1,31 @@
+module __MISTRAL_M10K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+parameter CFG_ABITS = 10;
+parameter CFG_DBITS = 10;
+parameter CFG_ENABLE_A = 1;
+parameter CFG_ENABLE_B = 1;
+
+input CLK1;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+output [CFG_DBITS-1:0] B1DATA;
+input [CFG_ENABLE_A-1:0] A1EN, B1EN;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("m10k"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1)
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/bram_m20k.txt b/techlibs/intel_alm/common/bram_m20k.txt
new file mode 100644
index 000000000..b4c5a5372
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m20k.txt
@@ -0,0 +1,33 @@
+bram __MISTRAL_M20K_SDP
+ init 1 # TODO: Re-enable when I figure out how BRAM init works
+ abits 14 @D16384x1
+ dbits 1 @D16384x1
+ abits 13 @D8192x2
+ dbits 2 @D8192x2
+ abits 12 @D4096x4 @D4096x5
+ dbits 4 @D4096x4
+ dbits 5 @D4096x5
+ abits 11 @D2048x8 @D2048x10
+ dbits 8 @D2048x8
+ dbits 10 @D2048x10
+ abits 10 @D1024x16 @D1024x20
+ dbits 16 @D1024x16
+ dbits 20 @D1024x20
+ abits 9 @D512x32 @D512x40
+ dbits 32 @D512x32
+ dbits 40 @D512x40
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable; write enable + byte enables (only for multiples of 8)
+ enable 1 1
+ transp 0 0
+ clocks 1 1
+ clkpol 1 1
+endbram
+
+
+match __MISTRAL_M20K_SDP
+ min efficiency 5
+ make_transp
+endmatch
diff --git a/techlibs/intel_alm/common/bram_m20k_map.v b/techlibs/intel_alm/common/bram_m20k_map.v
new file mode 100644
index 000000000..92f41310f
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m20k_map.v
@@ -0,0 +1,31 @@
+module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+parameter CFG_ABITS = 10;
+parameter CFG_DBITS = 20;
+parameter CFG_ENABLE_A = 1;
+parameter CFG_ENABLE_B = 1;
+
+input CLK1;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+output [CFG_DBITS-1:0] B1DATA;
+input [CFG_ENABLE_A-1:0] A1EN, B1EN;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("m20k"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1)
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/dff_map.v b/techlibs/intel_alm/common/dff_map.v
new file mode 100644
index 000000000..f7f2fe3c3
--- /dev/null
+++ b/techlibs/intel_alm/common/dff_map.v
@@ -0,0 +1,124 @@
+`default_nettype none
+
+// D flip-flops
+module \$_DFF_P_ (input D, C, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_P_ with INIT=1");
+endmodule
+
+module \$_DFF_N_ (input D, C, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_N_ with INIT=1");
+endmodule
+
+// D flip-flops with reset
+module \$_DFF_PP0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_PP0_ with INIT=1");
+endmodule
+
+module \$_DFF_PN0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_PN0_ with INIT=1");
+endmodule
+
+module \$_DFF_NP0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_NP0_ with INIT=1");
+endmodule
+
+module \$_DFF_NN0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_NN0_ with INIT=1");
+endmodule
+
+// D flip-flops with set
+module \$_DFF_PP1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_PP1_ with INIT=0");
+endmodule
+
+module \$_DFF_PN1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+end else $error("Unsupported flop: $_DFF_PN1_ with INIT=0");
+endmodule
+
+module \$_DFF_NP1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_NP1_ with INIT=0");
+endmodule
+
+module \$_DFF_NN1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_NN1_ with INIT=0");
+endmodule
+
+// D flip-flops with clock enable
+module \$_DFFE_PP_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_PP_ with INIT=1");
+endmodule
+
+module \$_DFFE_PN_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_PN_ with INIT=1");
+endmodule
+
+module \$_DFFE_NP_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_NP_ with INIT=1");
+endmodule
+
+module \$_DFFE_NN_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_NN_ with INIT=1");
+endmodule
diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v
new file mode 100644
index 000000000..07865905f
--- /dev/null
+++ b/techlibs/intel_alm/common/dff_sim.v
@@ -0,0 +1,48 @@
+// DATAIN: synchronous data input
+// CLK: clock input (positive edge)
+// ACLR: asynchronous clear (negative-true)
+// ENA: clock-enable
+// SCLR: synchronous clear
+// SLOAD: synchronous load
+// SDATA: synchronous load data
+//
+// Q: data output
+//
+// Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements.
+module MISTRAL_FF(
+ input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
+ output reg Q
+);
+
+`ifdef cyclonev
+specify
+ (posedge CLK => (Q : DATAIN)) = 262;
+ $setup(DATAIN, posedge CLK, 522);
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (posedge CLK => (Q : DATAIN)) = 219;
+ $setup(DATAIN, posedge CLK, 268);
+endspecify
+`endif
+
+initial begin
+ // Altera flops initialise to zero.
+ Q = 0;
+end
+
+always @(posedge CLK, negedge ACLR) begin
+ // Asynchronous clear
+ if (!ACLR) Q <= 0;
+ // Clock-enable
+ else if (ENA) begin
+ // Synchronous clear
+ if (SCLR) Q <= 0;
+ // Synchronous load
+ else if (SLOAD) Q <= SDATA;
+ else Q <= DATAIN;
+ end
+end
+
+endmodule
diff --git a/techlibs/intel_alm/common/lutram_mlab.txt b/techlibs/intel_alm/common/lutram_mlab.txt
new file mode 100644
index 000000000..1d6174d85
--- /dev/null
+++ b/techlibs/intel_alm/common/lutram_mlab.txt
@@ -0,0 +1,20 @@
+bram __MISTRAL_MLAB
+ init 0 # TODO: Re-enable when I figure out how LUTRAM init works
+ abits 5
+ dbits 16 @D32x16
+ dbits 18 @D32x18
+ dbits 20 @D32x20
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable
+ enable 1 0
+ transp 1 0
+ clocks 1 2
+ clkpol 1 1
+endbram
+
+match __MISTRAL_MLAB
+ min efficiency 5
+ make_outreg
+endmatch
diff --git a/techlibs/intel_alm/common/lutram_mlab_map.v b/techlibs/intel_alm/common/lutram_mlab_map.v
new file mode 100644
index 000000000..3a9c8590e
--- /dev/null
+++ b/techlibs/intel_alm/common/lutram_mlab_map.v
@@ -0,0 +1,29 @@
+module __MISTRAL_MLAB(CLK1, CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA);
+
+parameter CFG_ABITS = 5;
+parameter CFG_DBITS = 20;
+
+input CLK1, CLK2;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+input A1EN;
+output [CFG_DBITS-1:0] B1DATA;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("mlab"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1),
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v
new file mode 100644
index 000000000..21ba73a09
--- /dev/null
+++ b/techlibs/intel_alm/common/megafunction_bb.v
@@ -0,0 +1,108 @@
+// Intel megafunction declarations, to avoid Yosys complaining.
+`default_nettype none
+
+(* blackbox *)
+module altera_std_synchronizer(clk, din, dout, reset_n);
+
+parameter depth = 2;
+
+input clk;
+input reset_n;
+input din;
+output dout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_in(datain, dataout);
+
+parameter enable_bus_hold = "FALSE";
+parameter use_differential_mode = "FALSE";
+parameter number_of_channels = 1;
+
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_out(datain, dataout);
+
+parameter enable_bus_hold = "FALSE";
+parameter use_differential_mode = "FALSE";
+parameter use_oe = "FALSE";
+parameter number_of_channels = 1;
+
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_bidir(dataio, oe, datain, dataout);
+
+parameter number_of_channels = 1;
+parameter enable_bus_hold = "OFF";
+
+inout [number_of_channels-1:0] dataio;
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+input [number_of_channels-1:0] oe;
+
+endmodule
+
+(* blackbox *)
+module altsyncram(clock0, clock1, address_a, data_a, rden_a, wren_a, byteena_a, q_a, addressstall_a, address_b, data_b, rden_b, wren_b, byteena_b, q_b, addressstall_b, clocken0, clocken1, clocken2, clocken3, aclr0, aclr1, eccstatus);
+
+parameter lpm_type = "altsyncram";
+parameter operation_mode = "dual_port";
+parameter ram_block_type = "auto";
+parameter intended_device_family = "auto";
+parameter power_up_uninitialized = "false";
+parameter read_during_write_mode_mixed_ports = "dontcare";
+parameter byte_size = 8;
+parameter widthad_a = 1;
+parameter width_a = 1;
+parameter width_byteena_a = 1;
+parameter numwords_a = 1;
+parameter clock_enable_input_a = "clocken0";
+parameter widthad_b = 1;
+parameter width_b = 1;
+parameter numwords_b = 1;
+parameter address_aclr_b = "aclr0";
+parameter address_reg_b = "";
+parameter outdata_aclr_b = "aclr0";
+parameter outdata_reg_b = "";
+parameter clock_enable_input_b = "clocken0";
+parameter clock_enable_output_b = "clocken0";
+
+input clock0, clock1;
+input [widthad_a-1:0] address_a;
+input [width_a-1:0] data_a;
+input rden_a;
+input wren_a;
+input [(width_a/8)-1:0] byteena_a;
+input addressstall_a;
+
+output [width_a-1:0] q_a;
+
+input wren_b;
+input rden_b;
+input [widthad_b-1:0] address_b;
+input [width_b-1:0] data_b;
+input [(width_b/8)-1:0] byteena_b;
+input addressstall_b;
+
+output [width_b-1:0] q_b;
+
+input clocken0;
+input clocken1;
+input clocken2;
+input clocken3;
+
+input aclr0;
+input aclr1;
+
+output eccstatus;
+
+endmodule
diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v
new file mode 100644
index 000000000..e69eefeb7
--- /dev/null
+++ b/techlibs/intel_alm/common/quartus_rename.v
@@ -0,0 +1,23 @@
+module __MISTRAL_VCC(output Q);
+
+MISTRAL_ALUT2 #(.LUT(4'b1111)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
+
+endmodule
+
+
+module __MISTRAL_GND(output Q);
+
+MISTRAL_ALUT2 #(.LUT(4'b0000)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
+
+endmodule
+
+
+module MISTRAL_FF(input D, CLK, ACn, ALD, AD, EN, output reg Q);
+
+parameter INIT = 1'b0;
+
+localparam [1023:0] INIT_STR = (INIT !== 1'b1) ? "low" : "high";
+
+dffeas #(.power_up(INIT_STR), .is_wysiwyg("true")) _TECHMAP_REPLACE_ (.d(D), .clk(CLK), .clrn(ACn), .aload(ALD), .asdata(AD), .ena(EN), .q(Q));
+
+endmodule