aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx/abc9_map.v
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/xilinx/abc9_map.v')
-rw-r--r--techlibs/xilinx/abc9_map.v758
1 files changed, 758 insertions, 0 deletions
diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v
new file mode 100644
index 000000000..7dc027176
--- /dev/null
+++ b/techlibs/xilinx/abc9_map.v
@@ -0,0 +1,758 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ * 2019 Eddie Hung <eddie@fpgeh.com>
+ *
+ * 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.
+ *
+ */
+
+// The following techmapping rules are intended to be run (with -max_iter 1)
+// before invoking the `abc9` pass in order to transform the design into
+// a format that it understands.
+
+`ifdef DFF_MODE
+// For example, (complex) flip-flops are expected to be described as an
+// combinatorial box (containing all control logic such as clock enable
+// or synchronous resets) followed by a basic D-Q flop.
+// Yosys will automatically analyse the simulation model (described in
+// cells_sim.v) and detach any $_DFF_P_ or $_DFF_N_ cells present in
+// order to extract the combinatorial control logic left behind.
+// Specifically, a simulation model similar to the one below:
+//
+// ++===================================++
+// || Sim model ||
+// || /\/\/\/\ ||
+// D -->>-----< > +------+ ||
+// R -->>-----< Comb. > |$_DFF_| ||
+// CE -->>-----< logic >-----| [NP]_|---+---->>-- Q
+// || +--< > +------+ | ||
+// || | \/\/\/\/ | ||
+// || | | ||
+// || +----------------------------+ ||
+// || ||
+// ++===================================++
+//
+// is transformed into:
+//
+// ++==================++
+// || Comb box ||
+// || ||
+// || /\/\/\/\ ||
+// D -->>-----< > ||
+// R -->>-----< Comb. > || +-----------+
+// CE -->>-----< logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q
+// abc9_ff.Q +-->>-----< > || +-----------+ |
+// | || \/\/\/\/ || |
+// | || || |
+// | ++==================++ |
+// | |
+// +-----------------------------------------------+
+//
+// The purpose of the following FD* rules are to wrap the flop with:
+// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
+// the connectivity of its basic D-Q flop
+// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
+// capture asynchronous behaviour
+// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
+// (indicated to `abc9' so that it only performs sequential synthesis
+// (with reachability analysis) correctly on one domain at a time)
+// (d) a special abc9_ff.init wire to encode the flop's initial state
+// NOTE: in order to perform sequential synthesis, `abc9' also requires
+// that the initial value of all flops be zero
+// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
+// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
+
+module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
+ parameter [0:0] INIT = 1'b0;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_D_INVERTED = 1'b0;
+ parameter [0:0] IS_R_INVERTED = 1'b0;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDSE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_S_INVERTED(IS_R_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDRE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_R_INVERTED(IS_R_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .R(R)
+ );
+ end
+ endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
+ parameter [0:0] INIT = 1'b0;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDSE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDRE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .R(R)
+ );
+ end
+ endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+
+module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
+ parameter [0:0] INIT = 1'b1;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_D_INVERTED = 1'b0;
+ parameter [0:0] IS_S_INVERTED = 1'b0;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDRE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_R_INVERTED(IS_S_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDSE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_S_INVERTED(IS_S_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
+ );
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
+ parameter [0:0] INIT = 1'b1;
+ wire QQ, $Q;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDRE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
+ );
+ end
+ else begin
+ assign Q = QQ;
+ FDSE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
+ );
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
+endmodule
+
+module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
+ parameter [0:0] INIT = 1'b0;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_D_INVERTED = 1'b0;
+ parameter [0:0] IS_CLR_INVERTED = 1'b0;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDPE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_PRE_INVERTED(IS_CLR_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ // Since this is an async flop, async behaviour is dealt with here
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDCE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_CLR_INVERTED(IS_CLR_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ // Since this is an async flop, async behaviour is dealt with here
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
+ parameter [0:0] INIT = 1'b0;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDPE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDCE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+
+module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
+ parameter [0:0] INIT = 1'b1;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_D_INVERTED = 1'b0;
+ parameter [0:0] IS_PRE_INVERTED = 1'b0;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDCE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_CLR_INVERTED(IS_PRE_INVERTED),
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDPE #(
+ .INIT(1'b0),
+ .IS_C_INVERTED(IS_C_INVERTED),
+ .IS_D_INVERTED(IS_D_INVERTED),
+ .IS_PRE_INVERTED(IS_PRE_INVERTED),
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
+ parameter [0:0] INIT = 1'b1;
+ wire QQ, $Q, $QQ;
+ generate if (INIT == 1'b1) begin
+ assign Q = ~QQ;
+ FDCE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
+ );
+ $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
+ end
+ else begin
+ assign Q = QQ;
+ FDPE_1 #(
+ .INIT(1'b0)
+ ) _TECHMAP_REPLACE_ (
+ .D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
+ );
+ $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
+ end endgenerate
+ $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
+
+ // Special signals
+ wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+ wire [0:0] abc9_ff.init = 1'b0;
+ wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
+endmodule
+`endif
+
+// Attach a (combinatorial) black-box onto the output
+// of thes LUTRAM primitives to capture their
+// asynchronous read behaviour
+module RAM32X1D (
+ output DPO, SPO,
+ (* techmap_autopurge *) input D,
+ (* techmap_autopurge *) input WCLK,
+ (* techmap_autopurge *) input WE,
+ (* techmap_autopurge *) input A0, A1, A2, A3, A4,
+ (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
+);
+ parameter INIT = 32'h0;
+ parameter IS_WCLK_INVERTED = 1'b0;
+ wire $DPO, $SPO;
+ RAM32X1D #(
+ .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .DPO($DPO), .SPO($SPO),
+ .D(D), .WCLK(WCLK), .WE(WE),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
+ .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
+ );
+ $__ABC9_LUT6 spo (.A($SPO), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_LUT6 dpo (.A($DPO), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+endmodule
+
+module RAM64X1D (
+ output DPO, SPO,
+ (* techmap_autopurge *) input D,
+ (* techmap_autopurge *) input WCLK,
+ (* techmap_autopurge *) input WE,
+ (* techmap_autopurge *) input A0, A1, A2, A3, A4, A5,
+ (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
+);
+ parameter INIT = 64'h0;
+ parameter IS_WCLK_INVERTED = 1'b0;
+ wire $DPO, $SPO;
+ RAM64X1D #(
+ .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .DPO($DPO), .SPO($SPO),
+ .D(D), .WCLK(WCLK), .WE(WE),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
+ .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
+ );
+ $__ABC9_LUT6 spo (.A($SPO), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_LUT6 dpo (.A($DPO), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+endmodule
+
+module RAM128X1D (
+ output DPO, SPO,
+ (* techmap_autopurge *) input D,
+ (* techmap_autopurge *) input WCLK,
+ (* techmap_autopurge *) input WE,
+ (* techmap_autopurge *) input [6:0] A, DPRA
+);
+ parameter INIT = 128'h0;
+ parameter IS_WCLK_INVERTED = 1'b0;
+ wire $DPO, $SPO;
+ RAM128X1D #(
+ .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .DPO($DPO), .SPO($SPO),
+ .D(D), .WCLK(WCLK), .WE(WE),
+ .A(A),
+ .DPRA(DPRA)
+ );
+ $__ABC9_LUT7 spo (.A($SPO), .S(A), .Y(SPO));
+ $__ABC9_LUT7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
+endmodule
+
+module RAM32M (
+ output [1:0] DOA,
+ output [1:0] DOB,
+ output [1:0] DOC,
+ output [1:0] DOD,
+ (* techmap_autopurge *) input [4:0] ADDRA,
+ (* techmap_autopurge *) input [4:0] ADDRB,
+ (* techmap_autopurge *) input [4:0] ADDRC,
+ (* techmap_autopurge *) input [4:0] ADDRD,
+ (* techmap_autopurge *) input [1:0] DIA,
+ (* techmap_autopurge *) input [1:0] DIB,
+ (* techmap_autopurge *) input [1:0] DIC,
+ (* techmap_autopurge *) input [1:0] DID,
+ (* techmap_autopurge *) input WCLK,
+ (* techmap_autopurge *) input WE
+);
+ parameter [63:0] INIT_A = 64'h0000000000000000;
+ parameter [63:0] INIT_B = 64'h0000000000000000;
+ parameter [63:0] INIT_C = 64'h0000000000000000;
+ parameter [63:0] INIT_D = 64'h0000000000000000;
+ parameter [0:0] IS_WCLK_INVERTED = 1'b0;
+ wire [1:0] $DOA, $DOB, $DOC, $DOD;
+ RAM32M #(
+ .INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
+ .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
+ .WCLK(WCLK), .WE(WE),
+ .ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
+ .DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
+ );
+ $__ABC9_LUT6 doa0 (.A($DOA[0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
+ $__ABC9_LUT6 doa1 (.A($DOA[1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
+ $__ABC9_LUT6 dob0 (.A($DOB[0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
+ $__ABC9_LUT6 dob1 (.A($DOB[1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
+ $__ABC9_LUT6 doc0 (.A($DOC[0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
+ $__ABC9_LUT6 doc1 (.A($DOC[1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
+ $__ABC9_LUT6 dod0 (.A($DOD[0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
+ $__ABC9_LUT6 dod1 (.A($DOD[1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
+endmodule
+
+module RAM64M (
+ output DOA,
+ output DOB,
+ output DOC,
+ output DOD,
+ (* techmap_autopurge *) input [5:0] ADDRA,
+ (* techmap_autopurge *) input [5:0] ADDRB,
+ (* techmap_autopurge *) input [5:0] ADDRC,
+ (* techmap_autopurge *) input [5:0] ADDRD,
+ (* techmap_autopurge *) input DIA,
+ (* techmap_autopurge *) input DIB,
+ (* techmap_autopurge *) input DIC,
+ (* techmap_autopurge *) input DID,
+ (* techmap_autopurge *) input WCLK,
+ (* techmap_autopurge *) input WE
+);
+ parameter [63:0] INIT_A = 64'h0000000000000000;
+ parameter [63:0] INIT_B = 64'h0000000000000000;
+ parameter [63:0] INIT_C = 64'h0000000000000000;
+ parameter [63:0] INIT_D = 64'h0000000000000000;
+ parameter [0:0] IS_WCLK_INVERTED = 1'b0;
+ wire $DOA, $DOB, $DOC, $DOD;
+ RAM64M #(
+ .INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
+ .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
+ .WCLK(WCLK), .WE(WE),
+ .ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
+ .DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
+ );
+ $__ABC9_LUT6 doa (.A($DOA), .S(ADDRA), .Y(DOA));
+ $__ABC9_LUT6 dob (.A($DOB), .S(ADDRB), .Y(DOB));
+ $__ABC9_LUT6 doc (.A($DOC), .S(ADDRC), .Y(DOC));
+ $__ABC9_LUT6 dod (.A($DOD), .S(ADDRD), .Y(DOD));
+endmodule
+
+module SRL16E (
+ output Q,
+ (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
+);
+ parameter [15:0] INIT = 16'h0000;
+ parameter [0:0] IS_CLK_INVERTED = 1'b0;
+ wire $Q;
+ SRL16E #(
+ .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .Q($Q),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
+ );
+ $__ABC9_LUT6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
+endmodule
+
+module SRLC32E (
+ output Q,
+ output Q31,
+ (* techmap_autopurge *) input [4:0] A,
+ (* techmap_autopurge *) input CE, CLK, D
+);
+ parameter [31:0] INIT = 32'h00000000;
+ parameter [0:0] IS_CLK_INVERTED = 1'b0;
+ wire $Q;
+ SRLC32E #(
+ .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .Q($Q), .Q31(Q31),
+ .A(A), .CE(CE), .CLK(CLK), .D(D)
+ );
+ $__ABC9_LUT6 q (.A($Q), .S({1'b1, A}), .Y(Q));
+endmodule
+
+module DSP48E1 (
+ (* techmap_autopurge *) output [29:0] ACOUT,
+ (* techmap_autopurge *) output [17:0] BCOUT,
+ (* techmap_autopurge *) output reg CARRYCASCOUT,
+ (* techmap_autopurge *) output reg [3:0] CARRYOUT,
+ (* techmap_autopurge *) output reg MULTSIGNOUT,
+ (* techmap_autopurge *) output OVERFLOW,
+ (* techmap_autopurge *) output reg signed [47:0] P,
+ (* techmap_autopurge *) output PATTERNBDETECT,
+ (* techmap_autopurge *) output PATTERNDETECT,
+ (* techmap_autopurge *) output [47:0] PCOUT,
+ (* techmap_autopurge *) output UNDERFLOW,
+ (* techmap_autopurge *) input signed [29:0] A,
+ (* techmap_autopurge *) input [29:0] ACIN,
+ (* techmap_autopurge *) input [3:0] ALUMODE,
+ (* techmap_autopurge *) input signed [17:0] B,
+ (* techmap_autopurge *) input [17:0] BCIN,
+ (* techmap_autopurge *) input [47:0] C,
+ (* techmap_autopurge *) input CARRYCASCIN,
+ (* techmap_autopurge *) input CARRYIN,
+ (* techmap_autopurge *) input [2:0] CARRYINSEL,
+ (* techmap_autopurge *) input CEA1,
+ (* techmap_autopurge *) input CEA2,
+ (* techmap_autopurge *) input CEAD,
+ (* techmap_autopurge *) input CEALUMODE,
+ (* techmap_autopurge *) input CEB1,
+ (* techmap_autopurge *) input CEB2,
+ (* techmap_autopurge *) input CEC,
+ (* techmap_autopurge *) input CECARRYIN,
+ (* techmap_autopurge *) input CECTRL,
+ (* techmap_autopurge *) input CED,
+ (* techmap_autopurge *) input CEINMODE,
+ (* techmap_autopurge *) input CEM,
+ (* techmap_autopurge *) input CEP,
+ (* techmap_autopurge *) input CLK,
+ (* techmap_autopurge *) input [24:0] D,
+ (* techmap_autopurge *) input [4:0] INMODE,
+ (* techmap_autopurge *) input MULTSIGNIN,
+ (* techmap_autopurge *) input [6:0] OPMODE,
+ (* techmap_autopurge *) input [47:0] PCIN,
+ (* techmap_autopurge *) input RSTA,
+ (* techmap_autopurge *) input RSTALLCARRYIN,
+ (* techmap_autopurge *) input RSTALUMODE,
+ (* techmap_autopurge *) input RSTB,
+ (* techmap_autopurge *) input RSTC,
+ (* techmap_autopurge *) input RSTCTRL,
+ (* techmap_autopurge *) input RSTD,
+ (* techmap_autopurge *) input RSTINMODE,
+ (* techmap_autopurge *) input RSTM,
+ (* techmap_autopurge *) input RSTP
+);
+ parameter integer ACASCREG = 1;
+ parameter integer ADREG = 1;
+ parameter integer ALUMODEREG = 1;
+ parameter integer AREG = 1;
+ parameter AUTORESET_PATDET = "NO_RESET";
+ parameter A_INPUT = "DIRECT";
+ parameter integer BCASCREG = 1;
+ parameter integer BREG = 1;
+ parameter B_INPUT = "DIRECT";
+ parameter integer CARRYINREG = 1;
+ parameter integer CARRYINSELREG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer INMODEREG = 1;
+ parameter integer MREG = 1;
+ parameter integer OPMODEREG = 1;
+ parameter integer PREG = 1;
+ parameter SEL_MASK = "MASK";
+ parameter SEL_PATTERN = "PATTERN";
+ parameter USE_DPORT = "FALSE";
+ parameter USE_MULT = "MULTIPLY";
+ parameter USE_PATTERN_DETECT = "NO_PATDET";
+ parameter USE_SIMD = "ONE48";
+ parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
+ parameter [47:0] PATTERN = 48'h000000000000;
+ parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
+ parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
+ parameter [0:0] IS_CLK_INVERTED = 1'b0;
+ parameter [4:0] IS_INMODE_INVERTED = 5'b0;
+ parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
+
+ wire [47:0] $P, $PCOUT;
+
+ DSP48E1 #(
+ .ACASCREG(ACASCREG),
+ .ADREG(ADREG),
+ .ALUMODEREG(ALUMODEREG),
+ .AREG(AREG),
+ .AUTORESET_PATDET(AUTORESET_PATDET),
+ .A_INPUT(A_INPUT),
+ .BCASCREG(BCASCREG),
+ .BREG(BREG),
+ .B_INPUT(B_INPUT),
+ .CARRYINREG(CARRYINREG),
+ .CARRYINSELREG(CARRYINSELREG),
+ .CREG(CREG),
+ .DREG(DREG),
+ .INMODEREG(INMODEREG),
+ .MREG(MREG),
+ .OPMODEREG(OPMODEREG),
+ .PREG(PREG),
+ .SEL_MASK(SEL_MASK),
+ .SEL_PATTERN(SEL_PATTERN),
+ .USE_DPORT(USE_DPORT),
+ .USE_MULT(USE_MULT),
+ .USE_PATTERN_DETECT(USE_PATTERN_DETECT),
+ .USE_SIMD(USE_SIMD),
+ .MASK(MASK),
+ .PATTERN(PATTERN),
+ .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
+ .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
+ .IS_CLK_INVERTED(IS_CLK_INVERTED),
+ .IS_INMODE_INVERTED(IS_INMODE_INVERTED),
+ .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .ACOUT(ACOUT),
+ .BCOUT(BCOUT),
+ .CARRYCASCOUT(CARRYCASCOUT),
+ .CARRYOUT(CARRYOUT),
+ .MULTSIGNOUT(MULTSIGNOUT),
+ .OVERFLOW(OVERFLOW),
+ .P($P),
+ .PATTERNBDETECT(PATTERNBDETECT),
+ .PATTERNDETECT(PATTERNDETECT),
+ .PCOUT($PCOUT),
+ .UNDERFLOW(UNDERFLOW),
+ .A(A),
+ .ACIN(ACIN),
+ .ALUMODE(ALUMODE),
+ .B(B),
+ .BCIN(BCIN),
+ .C(C),
+ .CARRYCASCIN(CARRYCASCIN),
+ .CARRYIN(CARRYIN),
+ .CARRYINSEL(CARRYINSEL),
+ .CEA1(CEA1),
+ .CEA2(CEA2),
+ .CEAD(CEAD),
+ .CEALUMODE(CEALUMODE),
+ .CEB1(CEB1),
+ .CEB2(CEB2),
+ .CEC(CEC),
+ .CECARRYIN(CECARRYIN),
+ .CECTRL(CECTRL),
+ .CED(CED),
+ .CEINMODE(CEINMODE),
+ .CEM(CEM),
+ .CEP(CEP),
+ .CLK(CLK),
+ .D(D),
+ .INMODE(INMODE),
+ .MULTSIGNIN(MULTSIGNIN),
+ .OPMODE(OPMODE),
+ .PCIN(PCIN),
+ .RSTA(RSTA),
+ .RSTALLCARRYIN(RSTALLCARRYIN),
+ .RSTALUMODE(RSTALUMODE),
+ .RSTB(RSTB),
+ .RSTC(RSTC),
+ .RSTCTRL(RSTCTRL),
+ .RSTD(RSTD),
+ .RSTINMODE(RSTINMODE),
+ .RSTM(RSTM),
+ .RSTP(RSTP)
+ );
+
+ generate
+ wire [29:0] $A;
+ wire [17:0] $B;
+ wire [47:0] $C;
+ wire [24:0] $D;
+
+ if (PREG == 0) begin
+ if (MREG == 0 && AREG == 0) assign $A = A;
+ else assign $A = 30'bx;
+ if (MREG == 0 && BREG == 0) assign $B = B;
+ else assign $B = 18'bx;
+ if (MREG == 0 && DREG == 0) assign $D = D;
+ else assign $D = 25'bx;
+
+ if (CREG == 0) assign $C = C;
+ else assign $C = 48'bx;
+ end
+ else begin
+ assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx;
+ end
+
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE")
+ $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE")
+ $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE")
+ $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
+ else
+ $error("Invalid DSP48E1 configuration");
+ endgenerate
+endmodule