Merge remote-tracking branch 'origin/master' into xc7dsp
[yosys.git] / techlibs / xilinx / abc_model.v
index 655b993f6838c56d1888a2a7f82ff4a25b239ef0..0a8d531d756dddc999bd8c8e68acdc2ebb53862d 100644 (file)
 
 // ============================================================================
 
+// 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 )