/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf * 2019 Eddie Hung * * 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. * */ // ============================================================================ // 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 (* abc_box_id = 3, lib_whitebox *) module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); assign O = S1 ? (S0 ? I3 : I2) : (S0 ? I1 : I0); endmodule // 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. (* abc_box_id=2000 *) module \$__ABC_LUT6 (input A, input [5:0] S, output Y); endmodule // Box to emulate comb/seq behaviour of RAMD128 (* abc_box_id=2001 *) module \$__ABC_LUT7 (input A, input [6:0] S, output Y); endmodule // Modules used to model the comb/seq behaviour of DSP48E1 // With abc_map.v responsible for splicing the below modules // between the combinatorial DSP48E1 box (e.g. disconnecting // A when AREG, MREG or PREG is enabled and splicing in the // "$__ABC_DSP48E1_REG" blackbox as "REG" in the diagram below) // 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. // Note: Since these "$__ABC_DSP48E1_REG" modules are of a // 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. // In contrast to "REG", the "$__ABC_DSP48E1_*_MUX" modules are // 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. // // 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: // // +-----+ // +------>> REG >>----+ // | +-----+ | // | | // | +---------+ | __ // A >>-+X X-| | +--| \ // | DSP48E1 |P | M |--->> P // | AREG=1 |-------|__/ // B >>------| | // +---------+ // `define ABC_DSP48E1_MUX(__NAME__) """ module __NAME__ (input Aq, ADq, Bq, Cq, Dq, input [47:0] I, input Mq, input [47:0] P, input Pq, output [47:0] O); endmodule """ (* abc_box_id=2100 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_MULT_P_MUX ) (* abc_box_id=2101 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_MULT_PCOUT_MUX ) (* abc_box_id=2102 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_MULT_DPORT_P_MUX ) (* abc_box_id=2103 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_MULT_DPORT_PCOUT_MUX ) (* abc_box_id=2104 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_P_MUX ) (* abc_box_id=2105 *) `ABC_DSP48E1_MUX(\$__ABC_DSP48E1_PCOUT_MUX ) `define ABC_DSP48E1(__NAME__) """ module \$__ABC_DSP48E1_MULT ( 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; endmodule """ (* abc_box_id=3000 *) `ABC_DSP48E1(\$__ABC_DSP48E1_MULT ) (* abc_box_id=3001 *) `ABC_DSP48E1(\$__ABC_DSP48E1_MULT_DPORT ) (* abc_box_id=3002 *) `ABC_DSP48E1(\$__ABC_DSP48E1 )