2019-06-16 00:41:29 -05:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-09-30 17:39:24 -05:00
|
|
|
// 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.
|
2020-01-01 10:34:43 -06:00
|
|
|
|
|
|
|
`ifdef DFF_MODE
|
2019-09-30 17:39:24 -05:00
|
|
|
// 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.
|
2019-10-07 14:54:45 -05:00
|
|
|
// 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:
|
|
|
|
//
|
2019-10-07 17:31:43 -05:00
|
|
|
// ++===================================++
|
|
|
|
// || Sim model ||
|
|
|
|
// || /\/\/\/\ ||
|
|
|
|
// D -->>-----< > +------+ ||
|
|
|
|
// R -->>-----< Comb. > |$_DFF_| ||
|
|
|
|
// CE -->>-----< logic >-----| [NP]_|---+---->>-- Q
|
|
|
|
// || +--< > +------+ | ||
|
|
|
|
// || | \/\/\/\/ | ||
|
|
|
|
// || | | ||
|
|
|
|
// || +----------------------------+ ||
|
|
|
|
// || ||
|
|
|
|
// ++===================================++
|
2019-10-07 14:54:45 -05:00
|
|
|
//
|
|
|
|
// is transformed into:
|
|
|
|
//
|
2019-10-07 17:31:43 -05:00
|
|
|
// ++==================++
|
|
|
|
// || Comb box ||
|
|
|
|
// || ||
|
|
|
|
// || /\/\/\/\ ||
|
2019-12-30 16:19:29 -06:00
|
|
|
// D -->>-----< > ||
|
2020-01-02 14:36:54 -06:00
|
|
|
// R -->>-----< Comb. > || +-----------+
|
|
|
|
// CE -->>-----< logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q
|
|
|
|
// abc9_ff.Q +-->>-----< > || +-----------+ |
|
|
|
|
// | || \/\/\/\/ || |
|
|
|
|
// | || || |
|
|
|
|
// | ++==================++ |
|
|
|
|
// | |
|
|
|
|
// +-----------------------------------------------+
|
2019-10-07 14:54:45 -05:00
|
|
|
//
|
|
|
|
// The purpose of the following FD* rules are to wrap the flop with:
|
2019-10-04 19:21:14 -05:00
|
|
|
// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
|
2019-10-03 12:11:25 -05:00
|
|
|
// the connectivity of its basic D-Q flop
|
2019-12-06 01:18:27 -06:00
|
|
|
// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
|
|
|
|
// capture asynchronous behaviour
|
2020-01-02 14:39:52 -06:00
|
|
|
// (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)
|
2020-02-12 17:33:02 -06:00
|
|
|
// (d) an (* abc9_init *) attribute on the $__ABC9_FF_ cell capturing its
|
|
|
|
// initial state
|
|
|
|
// NOTE: in order to perform sequential synthesis, `abc9' requires that
|
|
|
|
// the initial value of all flops be zero
|
2020-01-02 14:36:54 -06:00
|
|
|
// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
|
2019-09-30 18:33:40 -05:00
|
|
|
// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
|
2019-12-04 23:36:41 -06:00
|
|
|
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
|
2019-08-20 20:17:14 -05:00
|
|
|
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;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire QQ, $Q;
|
2019-12-04 23:36:41 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .R(R)
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
|
|
|
end
|
2019-12-04 18:11:02 -06:00
|
|
|
endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
|
2019-08-20 20:17:14 -05:00
|
|
|
parameter [0:0] INIT = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire QQ, $Q;
|
2019-12-04 23:36:41 -06:00
|
|
|
generate if (INIT == 1'b1) begin
|
|
|
|
assign Q = ~QQ;
|
|
|
|
FDSE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign Q = QQ;
|
|
|
|
FDRE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .R(R)
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
|
|
|
end
|
2019-12-04 18:11:02 -06:00
|
|
|
endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
|
|
|
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
|
2019-12-31 20:47:38 -06:00
|
|
|
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
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
2019-12-31 20:47:38 -06:00
|
|
|
|
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
2019-12-31 20:47:38 -06:00
|
|
|
endmodule
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
|
2019-12-31 20:47:38 -06:00
|
|
|
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
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
2019-12-31 20:47:38 -06:00
|
|
|
|
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
2019-12-31 20:47:38 -06:00
|
|
|
endmodule
|
|
|
|
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
|
2019-08-20 20:17:14 -05:00
|
|
|
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;
|
2020-01-02 14:36:54 -06:00
|
|
|
wire QQ, $Q, $QQ;
|
2019-12-04 23:36:41 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC1 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2019-12-19 13:23:41 -06:00
|
|
|
// Since this is an async flop, async behaviour is dealt with here
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC0 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2019-12-19 13:23:41 -06:00
|
|
|
// Since this is an async flop, async behaviour is dealt with here
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
|
2019-08-20 20:17:14 -05:00
|
|
|
parameter [0:0] INIT = 1'b0;
|
2020-01-02 14:36:54 -06:00
|
|
|
wire QQ, $Q, $QQ;
|
2019-12-04 23:36:41 -06:00
|
|
|
generate if (INIT == 1'b1) begin
|
|
|
|
assign Q = ~QQ;
|
|
|
|
FDPE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC1 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign Q = QQ;
|
|
|
|
FDCE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC0 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
|
|
|
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
|
2019-12-04 18:11:02 -06:00
|
|
|
parameter [0:0] INIT = 1'b1;
|
2019-08-20 20:17:14 -05:00
|
|
|
parameter [0:0] IS_C_INVERTED = 1'b0;
|
|
|
|
parameter [0:0] IS_D_INVERTED = 1'b0;
|
|
|
|
parameter [0:0] IS_PRE_INVERTED = 1'b0;
|
2020-01-02 14:36:54 -06:00
|
|
|
wire QQ, $Q, $QQ;
|
2019-12-04 23:36:41 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC0 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC1 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
2020-01-14 14:22:21 -06:00
|
|
|
module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
|
2019-12-04 18:11:02 -06:00
|
|
|
parameter [0:0] INIT = 1'b1;
|
2020-01-02 14:36:54 -06:00
|
|
|
wire QQ, $Q, $QQ;
|
2019-12-04 23:36:41 -06:00
|
|
|
generate if (INIT == 1'b1) begin
|
|
|
|
assign Q = ~QQ;
|
|
|
|
FDCE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC0 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign Q = QQ;
|
|
|
|
FDPE_1 #(
|
|
|
|
.INIT(1'b0)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
|
2020-02-10 12:17:23 -06:00
|
|
|
// ^^^ Note that async
|
|
|
|
// control is not directly
|
|
|
|
// supported by abc9 but its
|
|
|
|
// behaviour is captured by
|
|
|
|
// $__ABC9_ASYNC1 below
|
2019-12-04 23:36:41 -06:00
|
|
|
);
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
|
2019-12-04 23:36:41 -06:00
|
|
|
end endgenerate
|
2020-02-12 17:33:02 -06:00
|
|
|
(* abc9_init = 1'b0 *)
|
2020-01-02 14:36:54 -06:00
|
|
|
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
2019-10-06 00:55:18 -05:00
|
|
|
|
2019-10-07 14:54:45 -05:00
|
|
|
// Special signals
|
2020-01-02 14:36:54 -06:00
|
|
|
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
|
|
|
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
2020-01-01 10:34:43 -06:00
|
|
|
`endif
|
2019-08-20 20:17:14 -05:00
|
|
|
|
2019-12-31 20:29:44 -06:00
|
|
|
// Attach a (combinatorial) black-box onto the output
|
|
|
|
// of thes LUTRAM primitives to capture their
|
|
|
|
// asynchronous read behaviour
|
2019-08-20 16:49:11 -05:00
|
|
|
module RAM32X1D (
|
|
|
|
output DPO, SPO,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* 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
|
2019-08-20 16:49:11 -05:00
|
|
|
);
|
|
|
|
parameter INIT = 32'h0;
|
|
|
|
parameter IS_WCLK_INVERTED = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $DPO, $SPO;
|
2019-08-20 21:47:11 -05:00
|
|
|
RAM32X1D #(
|
2019-08-20 16:49:11 -05:00
|
|
|
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.DPO($DPO), .SPO($SPO),
|
2019-08-20 16:49:11 -05:00
|
|
|
.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)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__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));
|
2019-08-20 16:49:11 -05:00
|
|
|
endmodule
|
|
|
|
|
|
|
|
module RAM64X1D (
|
|
|
|
output DPO, SPO,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* 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
|
2019-08-20 16:49:11 -05:00
|
|
|
);
|
|
|
|
parameter INIT = 64'h0;
|
|
|
|
parameter IS_WCLK_INVERTED = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $DPO, $SPO;
|
2019-08-20 21:47:11 -05:00
|
|
|
RAM64X1D #(
|
2019-08-20 16:49:11 -05:00
|
|
|
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.DPO($DPO), .SPO($SPO),
|
2019-08-20 16:49:11 -05:00
|
|
|
.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)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__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));
|
2019-08-20 16:49:11 -05:00
|
|
|
endmodule
|
|
|
|
|
2019-08-20 19:51:50 -05:00
|
|
|
module RAM128X1D (
|
2019-08-20 16:49:11 -05:00
|
|
|
output DPO, SPO,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* techmap_autopurge *) input D,
|
|
|
|
(* techmap_autopurge *) input WCLK,
|
|
|
|
(* techmap_autopurge *) input WE,
|
|
|
|
(* techmap_autopurge *) input [6:0] A, DPRA
|
2019-08-20 16:49:11 -05:00
|
|
|
);
|
|
|
|
parameter INIT = 128'h0;
|
|
|
|
parameter IS_WCLK_INVERTED = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $DPO, $SPO;
|
2019-08-20 21:47:11 -05:00
|
|
|
RAM128X1D #(
|
2019-08-20 16:49:11 -05:00
|
|
|
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.DPO($DPO), .SPO($SPO),
|
2019-08-20 16:49:11 -05:00
|
|
|
.D(D), .WCLK(WCLK), .WE(WE),
|
|
|
|
.A(A),
|
|
|
|
.DPRA(DPRA)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__ABC9_LUT7 spo (.A($SPO), .S(A), .Y(SPO));
|
|
|
|
$__ABC9_LUT7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
|
2019-08-20 17:09:38 -05:00
|
|
|
endmodule
|
2019-08-20 16:49:11 -05:00
|
|
|
|
2019-12-19 13:24:39 -06:00
|
|
|
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;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire [1:0] $DOA, $DOB, $DOC, $DOD;
|
2019-12-19 13:24:39 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
|
2019-12-19 13:24:39 -06:00
|
|
|
.WCLK(WCLK), .WE(WE),
|
|
|
|
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
|
|
|
|
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__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]));
|
2019-12-19 13:24:39 -06:00
|
|
|
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;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $DOA, $DOB, $DOC, $DOD;
|
2019-12-19 13:24:39 -06:00
|
|
|
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_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
|
2019-12-19 13:24:39 -06:00
|
|
|
.WCLK(WCLK), .WE(WE),
|
|
|
|
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
|
|
|
|
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__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));
|
2019-12-19 13:24:39 -06:00
|
|
|
endmodule
|
|
|
|
|
2019-08-20 17:09:38 -05:00
|
|
|
module SRL16E (
|
|
|
|
output Q,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
|
2019-08-20 17:09:38 -05:00
|
|
|
);
|
|
|
|
parameter [15:0] INIT = 16'h0000;
|
|
|
|
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $Q;
|
2019-08-20 21:47:11 -05:00
|
|
|
SRL16E #(
|
2019-08-20 17:09:38 -05:00
|
|
|
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.Q($Q),
|
2019-08-20 17:09:38 -05:00
|
|
|
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__ABC9_LUT6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
|
2019-08-20 17:09:38 -05:00
|
|
|
endmodule
|
|
|
|
|
|
|
|
module SRLC32E (
|
2019-08-20 19:52:27 -05:00
|
|
|
output Q,
|
|
|
|
output Q31,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* techmap_autopurge *) input [4:0] A,
|
|
|
|
(* techmap_autopurge *) input CE, CLK, D
|
2019-08-20 17:09:38 -05:00
|
|
|
);
|
|
|
|
parameter [31:0] INIT = 32'h00000000;
|
|
|
|
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
2019-12-30 16:19:29 -06:00
|
|
|
wire $Q;
|
2019-08-20 21:47:11 -05:00
|
|
|
SRLC32E #(
|
2019-08-20 17:09:38 -05:00
|
|
|
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
|
|
|
|
) _TECHMAP_REPLACE_ (
|
2019-12-30 16:19:29 -06:00
|
|
|
.Q($Q), .Q31(Q31),
|
2019-08-20 17:09:38 -05:00
|
|
|
.A(A), .CE(CE), .CLK(CLK), .D(D)
|
|
|
|
);
|
2019-12-30 16:19:29 -06:00
|
|
|
$__ABC9_LUT6 q (.A($Q), .S({1'b1, A}), .Y(Q));
|
2019-08-20 16:49:11 -05:00
|
|
|
endmodule
|
2019-09-12 19:11:01 -05:00
|
|
|
|
|
|
|
module DSP48E1 (
|
2019-09-23 23:56:28 -05:00
|
|
|
(* 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,
|
2019-09-19 17:58:01 -05:00
|
|
|
(* 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
|
2019-09-12 19:11:01 -05:00
|
|
|
);
|
|
|
|
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;
|
|
|
|
|
2020-01-01 19:30:26 -06:00
|
|
|
wire [47:0] $P, $PCOUT;
|
2019-09-12 19:11:01 -05:00
|
|
|
|
2020-01-01 19:30:26 -06:00
|
|
|
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)
|
|
|
|
);
|
2019-09-13 14:05:14 -05:00
|
|
|
|
2019-09-19 20:59:28 -05:00
|
|
|
generate
|
2020-01-01 19:30:26 -06:00
|
|
|
wire [29:0] $A;
|
|
|
|
wire [17:0] $B;
|
|
|
|
wire [47:0] $C;
|
|
|
|
wire [24:0] $D;
|
2019-09-13 14:05:14 -05:00
|
|
|
|
2019-09-19 22:04:52 -05:00
|
|
|
if (PREG == 0) begin
|
2020-01-02 15:28:37 -06:00
|
|
|
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;
|
2019-09-13 14:05:14 -05:00
|
|
|
|
2020-01-02 15:28:37 -06:00
|
|
|
if (CREG == 0) assign $C = C;
|
|
|
|
else assign $C = 48'bx;
|
2019-09-19 22:04:52 -05:00
|
|
|
end
|
2020-01-02 15:28:37 -06:00
|
|
|
else begin
|
|
|
|
assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx;
|
2019-09-19 22:04:52 -05:00
|
|
|
end
|
2019-09-13 13:45:55 -05:00
|
|
|
|
2020-01-02 15:28:37 -06:00
|
|
|
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));
|
2019-09-13 14:05:14 -05:00
|
|
|
else
|
2020-01-02 15:28:37 -06:00
|
|
|
$error("Invalid DSP48E1 configuration");
|
2019-09-19 22:04:52 -05:00
|
|
|
endgenerate
|
2019-09-12 19:11:01 -05:00
|
|
|
endmodule
|