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-12 19:11:01 -05:00
|
|
|
// Box containing MUXF7.[AB] + MUXF8,
|
|
|
|
// Necessary to make these an atomic unit so that
|
|
|
|
// ABC cannot optimise just one of the MUXF7 away
|
|
|
|
// and expect to save on its delay
|
2019-10-04 13:04:10 -05:00
|
|
|
(* abc9_box_id = 3, lib_whitebox *)
|
2019-08-20 14:39:11 -05:00
|
|
|
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
|
|
|
|
assign O = S1 ? (S0 ? I3 : I2)
|
|
|
|
: (S0 ? I1 : I0);
|
2019-07-10 19:06:05 -05:00
|
|
|
endmodule
|
|
|
|
|
2019-11-20 16:30:56 -06:00
|
|
|
module \$__ABC9_FF_ (input D, output Q);
|
|
|
|
endmodule
|
|
|
|
|
2019-08-20 20:17:14 -05:00
|
|
|
(* abc_box_id = 1000 *)
|
2019-10-06 00:55:18 -05:00
|
|
|
module \$__ABC9_ASYNC (input A, S, output Y);
|
2019-09-29 23:55:53 -05:00
|
|
|
endmodule
|
2019-09-29 21:39:12 -05:00
|
|
|
|
2019-09-12 19:11:01 -05:00
|
|
|
// Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}
|
|
|
|
// Necessary since RAMD* and SRL* have both combinatorial (i.e.
|
|
|
|
// same-cycle read operation) and sequential (write operation
|
|
|
|
// is only committed on the next clock edge).
|
|
|
|
// To model the combinatorial path, such cells have to be split
|
|
|
|
// into comb and seq parts, with this box modelling only the former.
|
2019-10-04 13:04:10 -05:00
|
|
|
(* abc9_box_id=2000 *)
|
|
|
|
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
|
2019-08-20 16:49:11 -05:00
|
|
|
endmodule
|
2019-09-12 19:11:01 -05:00
|
|
|
// Box to emulate comb/seq behaviour of RAMD128
|
2019-10-04 13:04:10 -05:00
|
|
|
(* abc9_box_id=2001 *)
|
|
|
|
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
|
2019-08-20 17:09:38 -05:00
|
|
|
endmodule
|
2019-09-12 19:11:01 -05:00
|
|
|
|
2019-09-19 20:59:28 -05:00
|
|
|
|
|
|
|
// Modules used to model the comb/seq behaviour of DSP48E1
|
2019-10-04 13:04:10 -05:00
|
|
|
// With abc9_map.v responsible for splicing the below modules
|
2019-09-20 16:24:31 -05:00
|
|
|
// between the combinatorial DSP48E1 box (e.g. disconnecting
|
2019-09-19 20:59:28 -05:00
|
|
|
// A when AREG, MREG or PREG is enabled and splicing in the
|
2019-10-04 13:04:10 -05:00
|
|
|
// "$__ABC9_DSP48E1_REG" blackbox as "REG" in the diagram below)
|
2019-09-19 20:59:28 -05:00
|
|
|
// this acts to first disables the combinatorial path (as there
|
|
|
|
// is no connectivity through REG), and secondly, since this is
|
|
|
|
// blackbox a new PI will be introduced with an arrival time of
|
|
|
|
// zero.
|
2019-10-04 13:04:10 -05:00
|
|
|
// Note: Since these "$__ABC9_DSP48E1_REG" modules are of a
|
2019-09-19 20:59:28 -05:00
|
|
|
// sequential nature, they are not passed as a box to ABC and
|
|
|
|
// (desirably) represented as PO/PIs.
|
|
|
|
//
|
|
|
|
// At the DSP output, we place a blackbox mux ("M" in the diagram
|
|
|
|
// below) to capture the fact that the critical-path could come
|
|
|
|
// from any one of its inputs.
|
2019-10-04 13:04:10 -05:00
|
|
|
// In contrast to "REG", the "$__ABC9_DSP48E1_*_MUX" modules are
|
2019-09-19 20:59:28 -05:00
|
|
|
// combinatorial blackboxes that do get passed to ABC.
|
|
|
|
// The propagation delay through this box (specified in the box
|
|
|
|
// file) captures the arrival time of the register (i.e.
|
|
|
|
// propagation from AREG to P after clock edge), or zero delay
|
|
|
|
// for the combinatorial path from the DSP.
|
|
|
|
//
|
2019-09-19 20:33:38 -05:00
|
|
|
// Doing so should means that ABC is able to analyse the
|
|
|
|
// worst-case delay through to P, regardless of if it was
|
|
|
|
// through any combinatorial paths (e.g. B, below) or an
|
|
|
|
// internal register (A2REG).
|
|
|
|
// However, the true value of being as complete as this is
|
|
|
|
// questionable since if AREG=1 and BREG=0 (as below)
|
|
|
|
// then the worse-case path would very likely be through B
|
|
|
|
// and very unlikely to be through AREG.Q...?
|
|
|
|
//
|
|
|
|
// In graphical form:
|
|
|
|
//
|
2019-09-19 20:59:28 -05:00
|
|
|
// +-----+
|
|
|
|
// +------>> REG >>----+
|
|
|
|
// | +-----+ |
|
|
|
|
// | |
|
|
|
|
// | +---------+ | __
|
|
|
|
// A >>-+X X-| | +--| \
|
|
|
|
// | DSP48E1 |P | M |--->> P
|
2019-09-19 20:33:38 -05:00
|
|
|
// | AREG=1 |-------|__/
|
|
|
|
// B >>------| |
|
|
|
|
// +---------+
|
|
|
|
//
|
2019-10-04 13:04:10 -05:00
|
|
|
`define ABC9_DSP48E1_MUX(__NAME__) """
|
2019-09-19 20:59:28 -05:00
|
|
|
module __NAME__ (input Aq, ADq, Bq, Cq, Dq, input [47:0] I, input Mq, input [47:0] P, input Pq, output [47:0] O);
|
2019-09-19 20:33:38 -05:00
|
|
|
endmodule
|
|
|
|
"""
|
2019-10-04 13:04:10 -05:00
|
|
|
(* abc9_box_id=2100 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_P_MUX )
|
|
|
|
(* abc9_box_id=2101 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_PCOUT_MUX )
|
|
|
|
(* abc9_box_id=2102 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_P_MUX )
|
|
|
|
(* abc9_box_id=2103 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX )
|
|
|
|
(* abc9_box_id=2104 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_P_MUX )
|
|
|
|
(* abc9_box_id=2105 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_PCOUT_MUX )
|
2019-09-19 20:33:38 -05:00
|
|
|
|
2019-10-04 13:04:10 -05:00
|
|
|
`define ABC9_DSP48E1(__NAME__) """
|
2019-09-25 12:33:16 -05:00
|
|
|
module __NAME__ (
|
2019-09-12 19:11:01 -05:00
|
|
|
output [29:0] ACOUT,
|
|
|
|
output [17:0] BCOUT,
|
|
|
|
output reg CARRYCASCOUT,
|
|
|
|
output reg [3:0] CARRYOUT,
|
|
|
|
output reg MULTSIGNOUT,
|
|
|
|
output OVERFLOW,
|
|
|
|
output reg signed [47:0] P,
|
|
|
|
output PATTERNBDETECT,
|
|
|
|
output PATTERNDETECT,
|
|
|
|
output [47:0] PCOUT,
|
|
|
|
output UNDERFLOW,
|
|
|
|
input signed [29:0] A,
|
|
|
|
input [29:0] ACIN,
|
|
|
|
input [3:0] ALUMODE,
|
|
|
|
input signed [17:0] B,
|
|
|
|
input [17:0] BCIN,
|
|
|
|
input [47:0] C,
|
|
|
|
input CARRYCASCIN,
|
|
|
|
input CARRYIN,
|
|
|
|
input [2:0] CARRYINSEL,
|
|
|
|
input CEA1,
|
|
|
|
input CEA2,
|
|
|
|
input CEAD,
|
|
|
|
input CEALUMODE,
|
|
|
|
input CEB1,
|
|
|
|
input CEB2,
|
|
|
|
input CEC,
|
|
|
|
input CECARRYIN,
|
|
|
|
input CECTRL,
|
|
|
|
input CED,
|
|
|
|
input CEINMODE,
|
|
|
|
input CEM,
|
|
|
|
input CEP,
|
|
|
|
input CLK,
|
|
|
|
input [24:0] D,
|
|
|
|
input [4:0] INMODE,
|
|
|
|
input MULTSIGNIN,
|
|
|
|
input [6:0] OPMODE,
|
|
|
|
input [47:0] PCIN,
|
|
|
|
input RSTA,
|
|
|
|
input RSTALLCARRYIN,
|
|
|
|
input RSTALUMODE,
|
|
|
|
input RSTB,
|
|
|
|
input RSTC,
|
|
|
|
input RSTCTRL,
|
|
|
|
input RSTD,
|
|
|
|
input RSTINMODE,
|
|
|
|
input RSTM,
|
|
|
|
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;
|
2019-08-20 20:17:14 -05:00
|
|
|
endmodule
|
2019-09-13 14:05:14 -05:00
|
|
|
"""
|
2019-10-04 13:04:10 -05:00
|
|
|
(* abc9_box_id=3000 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT )
|
|
|
|
(* abc9_box_id=3001 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT_DPORT )
|
|
|
|
(* abc9_box_id=3002 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1 )
|