mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Rework abc9's DSP48E1 model
This commit is contained in:
		
							parent
							
								
									9e5ff30d05
								
							
						
					
					
						commit
						db04161eca
					
				
					 5 changed files with 508 additions and 1658 deletions
				
			
		|  | @ -282,11 +282,9 @@ module DSP48E1 ( | |||
|     parameter [4:0] IS_INMODE_INVERTED = 5'b0; | ||||
|     parameter [6:0] IS_OPMODE_INVERTED = 7'b0; | ||||
| 
 | ||||
|     parameter _TECHMAP_CELLTYPE_ = ""; | ||||
|     localparam techmap_guard = (_TECHMAP_CELLTYPE_ != ""); | ||||
|     wire [47:0] $P, $PCOUT; | ||||
| 
 | ||||
| `define DSP48E1_INST(__CELL__) """ | ||||
| __CELL__ #( | ||||
|     DSP48E1 #( | ||||
|         .ACASCREG(ACASCREG), | ||||
|         .ADREG(ADREG), | ||||
|         .ALUMODEREG(ALUMODEREG), | ||||
|  | @ -324,17 +322,17 @@ __CELL__ #( | |||
|         .CARRYOUT(CARRYOUT), | ||||
|         .MULTSIGNOUT(MULTSIGNOUT), | ||||
|         .OVERFLOW(OVERFLOW), | ||||
|             .P(oP), | ||||
|         .P($P), | ||||
|         .PATTERNBDETECT(PATTERNBDETECT), | ||||
|         .PATTERNDETECT(PATTERNDETECT), | ||||
|             .PCOUT(oPCOUT), | ||||
|         .PCOUT($PCOUT), | ||||
|         .UNDERFLOW(UNDERFLOW), | ||||
|             .A(iA), | ||||
|         .A(A), | ||||
|         .ACIN(ACIN), | ||||
|         .ALUMODE(ALUMODE), | ||||
|             .B(iB), | ||||
|         .B(B), | ||||
|         .BCIN(BCIN), | ||||
|             .C(iC), | ||||
|         .C(C), | ||||
|         .CARRYCASCIN(CARRYCASCIN), | ||||
|         .CARRYIN(CARRYIN), | ||||
|         .CARRYINSEL(CARRYINSEL), | ||||
|  | @ -352,7 +350,7 @@ __CELL__ #( | |||
|         .CEM(CEM), | ||||
|         .CEP(CEP), | ||||
|         .CLK(CLK), | ||||
|             .D(iD), | ||||
|         .D(D), | ||||
|         .INMODE(INMODE), | ||||
|         .MULTSIGNIN(MULTSIGNIN), | ||||
|         .OPMODE(OPMODE), | ||||
|  | @ -368,158 +366,29 @@ __CELL__ #( | |||
|         .RSTM(RSTM), | ||||
|         .RSTP(RSTP) | ||||
|     ); | ||||
| """ | ||||
| 
 | ||||
|     wire [29:0] iA; | ||||
|     wire [17:0] iB; | ||||
|     wire [47:0] iC; | ||||
|     wire [24:0] iD; | ||||
| 
 | ||||
|     wire pA, pB, pC, pD, pAD, pM, pP; | ||||
|     wire [47:0] oP, mP; | ||||
|     wire [47:0] oPCOUT, mPCOUT; | ||||
| 
 | ||||
|     generate | ||||
|     if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin | ||||
|         // Disconnect the A-input if MREG is enabled, since | ||||
|         //   combinatorial path is broken | ||||
|         if (AREG == 0 && MREG == 0 && PREG == 0) | ||||
|             assign iA = A, pA = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA)); | ||||
|         if (BREG == 0 && MREG == 0 && PREG == 0) | ||||
|             assign iB = B, pB = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB)); | ||||
|         if (CREG == 0 && PREG == 0) | ||||
|             assign iC = C, pC = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC)); | ||||
|         if (DREG == 0) | ||||
|             assign iD = D; | ||||
|         else if (techmap_guard) | ||||
|         $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\""); | ||||
|         assign pD = 1'bx; | ||||
|         if (ADREG == 1 && techmap_guard) | ||||
|             $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\""); | ||||
|         assign pAD = 1'bx; | ||||
|     if (PREG == 0) begin | ||||
|         if (MREG == 1) | ||||
|         \$__ABC9_REG rM (.Q(pM)); | ||||
|         else | ||||
|         assign pM = 1'bx; | ||||
|         assign pP = 1'bx; | ||||
|     end else begin | ||||
|             assign pM = 1'bx; | ||||
|             \$__ABC9_REG rP (.Q(pP)); | ||||
|         end | ||||
|         wire [29:0] $A; | ||||
|         wire [17:0] $B; | ||||
|         wire [47:0] $C; | ||||
|         wire [24:0] $D; | ||||
| 
 | ||||
|         if (MREG == 0 && PREG == 0) | ||||
|             assign mP = oP, mPCOUT = oPCOUT; | ||||
|         else | ||||
|             assign mP = 1'bx, mPCOUT = 1'bx; | ||||
|         \$__ABC9_DSP48E1_MULT_P_MUX muxP ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P) | ||||
|         ); | ||||
|         \$__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT) | ||||
|         ); | ||||
|         if (PREG != 0) | ||||
|             assign P = $P, PCOUT = $PCOUT; | ||||
|         else begin | ||||
|             if (AREG == 0) assign $A = A; | ||||
|             if (BREG == 0) assign $B = B; | ||||
|             if (CREG == 0) assign $C = C; | ||||
|             if (DREG == 0) assign $D = D; | ||||
| 
 | ||||
|         `DSP48E1_INST(\$__ABC9_DSP48E1_MULT ) | ||||
|     end | ||||
|     else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin | ||||
|         // Disconnect the A-input if MREG is enabled, since | ||||
|         //   combinatorial path is broken | ||||
|         if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0) | ||||
|             assign iA = A, pA = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA)); | ||||
|         if (BREG == 0 && MREG == 0 && PREG == 0) | ||||
|             assign iB = B, pB = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB)); | ||||
|         if (CREG == 0 && PREG == 0) | ||||
|             assign iC = C, pC = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC)); | ||||
|         if (DREG == 0 && ADREG == 0) | ||||
|             assign iD = D, pD = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD)); | ||||
|         if (PREG == 0) begin | ||||
|             if (MREG == 1) begin | ||||
|                 assign pAD = 1'bx; | ||||
|         \$__ABC9_REG rM (.Q(pM)); | ||||
|             end else begin | ||||
|                 if (ADREG == 1) | ||||
|                     \$__ABC9_REG rAD (.Q(pAD)); | ||||
|                 else | ||||
|                     assign pAD = 1'bx; | ||||
|         assign pM = 1'bx; | ||||
|         end | ||||
|         assign pP = 1'bx; | ||||
|     end else begin | ||||
|             assign pAD = 1'bx, pM = 1'bx; | ||||
|             \$__ABC9_REG rP (.Q(pP)); | ||||
|         end | ||||
| 
 | ||||
|         if (MREG == 0 && PREG == 0) | ||||
|             assign mP = oP, mPCOUT = oPCOUT; | ||||
|         else | ||||
|             assign mP = 1'bx, mPCOUT = 1'bx; | ||||
|         \$__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P) | ||||
|         ); | ||||
|         \$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT) | ||||
|         ); | ||||
| 
 | ||||
|         `DSP48E1_INST(\$__ABC9_DSP48E1_MULT_DPORT ) | ||||
|     end | ||||
|     else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin | ||||
|         // Disconnect the A-input if MREG is enabled, since | ||||
|         //   combinatorial path is broken | ||||
|         if (AREG == 0 && PREG == 0) | ||||
|             assign iA = A, pA = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA)); | ||||
|         if (BREG == 0 && PREG == 0) | ||||
|             assign iB = B, pB = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB)); | ||||
|         if (CREG == 0 && PREG == 0) | ||||
|             assign iC = C, pC = 1'bx; | ||||
|         else | ||||
|             \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC)); | ||||
|         if (DREG == 1 && techmap_guard) | ||||
|             $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\""); | ||||
|         assign pD = 1'bx; | ||||
|         if (ADREG == 1 && techmap_guard) | ||||
|             $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\""); | ||||
|         assign pAD = 1'bx; | ||||
|         if (MREG == 1 && techmap_guard) | ||||
|             $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\""); | ||||
|         assign pM = 1'bx; | ||||
|         if (PREG == 1) | ||||
|             \$__ABC9_REG rP (.Q(pP)); | ||||
|         else | ||||
|             assign pP = 1'bx; | ||||
| 
 | ||||
|         if (MREG == 0 && PREG == 0) | ||||
|             assign mP = oP, mPCOUT = oPCOUT; | ||||
|         else | ||||
|             assign mP = 1'bx, mPCOUT = 1'bx; | ||||
|         \$__ABC9_DSP48E1_P_MUX muxP ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P) | ||||
|         ); | ||||
|         \$__ABC9_DSP48E1_PCOUT_MUX muxPCOUT ( | ||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT) | ||||
|         ); | ||||
| 
 | ||||
|         `DSP48E1_INST(\$__ABC9_DSP48E1 ) | ||||
|     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"); | ||||
|         end | ||||
|     endgenerate | ||||
|     `undef DSP48E1_INST | ||||
| endmodule | ||||
|  |  | |||
|  | @ -44,147 +44,22 @@ endmodule | |||
| module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); | ||||
| endmodule | ||||
| 
 | ||||
| 
 | ||||
| // Modules used to model the comb/seq behaviour of DSP48E1 | ||||
| //   With abc9_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 | ||||
| //   "$__ABC9_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 "$__ABC9_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 "$__ABC9_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 ABC9_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 | ||||
| """ | ||||
| (* 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 ) | ||||
| 
 | ||||
| // Boxes used to represent the comb behaviour of various modes | ||||
| //   of DSP48E1 | ||||
| `define ABC9_DSP48E1(__NAME__) """ | ||||
| module __NAME__ ( | ||||
|     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; | ||||
|     input [29:0] $A, | ||||
|     input [17:0] $B, | ||||
|     input [47:0] $C, | ||||
|     input [24:0] $D, | ||||
|     input [47:0] $P, | ||||
|     input [47:0] $PCIN, | ||||
|     input [47:0] $PCOUT, | ||||
|     output [47:0] P, | ||||
|     output [47:0] PCOUT); | ||||
| endmodule | ||||
| """ | ||||
| (* 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 ) | ||||
| (* 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) | ||||
| `undef ABC9_DSP48E1 | ||||
|  |  | |||
|  | @ -20,192 +20,24 @@ | |||
| 
 | ||||
| // ============================================================================ | ||||
| 
 | ||||
| module \$__ABC9_LUT6 (input A, input [5:0] S, output Y); | ||||
| module $__ABC9_LUT6(input A, input [5:0] S, output Y); | ||||
|   assign Y = A; | ||||
| endmodule | ||||
| module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); | ||||
| module $__ABC9_LUT7(input A, input [6:0] S, output Y); | ||||
|   assign Y = A; | ||||
| endmodule | ||||
| 
 | ||||
| module \$__ABC9_REG (input [WIDTH-1:0] I, output [WIDTH-1:0] O, output Q); | ||||
|   parameter WIDTH = 1; | ||||
|   assign O = I; | ||||
| endmodule | ||||
| (* techmap_celltype = "$__ABC9_DSP48E1_MULT_P_MUX $__ABC9_DSP48E1_MULT_PCOUT_MUX $__ABC9_DSP48E1_MULT_DPORT_P_MUX $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX $__ABC9_DSP48E1_P_MUX $__ABC9_DSP48E1_PCOUT_MUX" *) | ||||
| module \$__ABC9_DSP48E1_MUX ( | ||||
|   input Aq, Bq, Cq, Dq, ADq, | ||||
|   input [47:0] I, | ||||
|   input Mq, | ||||
|   input [47:0] P,  | ||||
|   input Pq,  | ||||
|   output [47:0] O | ||||
| ); | ||||
|   assign O = I; | ||||
| endmodule | ||||
| 
 | ||||
| (* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *) | ||||
| module \$__ABC9_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; | ||||
| 
 | ||||
|     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) | ||||
| module $ABC9_DSP48E1( | ||||
|     input [29:0] $A, | ||||
|     input [17:0] $B, | ||||
|     input [47:0] $C, | ||||
|     input [24:0] $D, | ||||
|     input [47:0] $P, | ||||
|     input [47:0] $PCIN, | ||||
|     input [47:0] $PCOUT, | ||||
|     output [47:0] P, | ||||
|     output [47:0] PCOUT | ||||
| ); | ||||
|     assign P = $P, PCOUT = $PCOUT; | ||||
| endmodule | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -2160,9 +2160,15 @@ module DSP48E1 ( | |||
|     output reg [3:0] CARRYOUT, | ||||
|     output reg MULTSIGNOUT, | ||||
|     output OVERFLOW, | ||||
| `ifndef __ICARUS__ | ||||
|     (* abc9_arrival = \DSP48E1.P_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) | ||||
| `endif | ||||
|     output reg signed [47:0] P, | ||||
|     output reg PATTERNBDETECT, | ||||
|     output reg PATTERNDETECT, | ||||
| `ifndef __ICARUS__ | ||||
|     (* abc9_arrival = \DSP48E1.PCOUT_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *) | ||||
| `endif | ||||
|     output [47:0] PCOUT, | ||||
|     output UNDERFLOW, | ||||
|     input signed [29:0] A, | ||||
|  | @ -2235,6 +2241,79 @@ module DSP48E1 ( | |||
|     parameter [4:0] IS_INMODE_INVERTED = 5'b0; | ||||
|     parameter [6:0] IS_OPMODE_INVERTED = 7'b0; | ||||
| 
 | ||||
|     function \DSP48E1.P_arrival ; | ||||
|         input USE_MULT, USE_DPORT; | ||||
|         input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; | ||||
|     begin | ||||
|         \DSP48E1.P_arrival = 0; | ||||
|         if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin | ||||
|             if (PREG != 0)      \DSP48E1.P_arrival =  329; | ||||
|             // Worse-case from CREG and MREG | ||||
|             else if (CREG != 0) \DSP48E1.P_arrival = 1687; | ||||
|             else if (MREG != 0) \DSP48E1.P_arrival = 1671; | ||||
|             // Worse-case from AREG and BREG | ||||
|             else if (AREG != 0) \DSP48E1.P_arrival = 2952; | ||||
|             else if (BREG != 0) \DSP48E1.P_arrival = 2813; | ||||
|         end | ||||
|         else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin | ||||
|             if (PREG != 0)      \DSP48E1.P_arrival =  329; | ||||
|             // Worse-case from CREG and MREG | ||||
|             else if (CREG != 0) \DSP48E1.P_arrival = 1687; | ||||
|             else if (MREG != 0) \DSP48E1.P_arrival = 1671; | ||||
|             // Worse-case from AREG, ADREG, BREG, DREG | ||||
|             else if (AREG != 0)  \DSP48E1.P_arrival = 3935; | ||||
|             else if (DREG != 0)  \DSP48E1.P_arrival = 3908; | ||||
|             else if (ADREG != 0) \DSP48E1.P_arrival = 2958; | ||||
|             else if (BREG != 0)  \DSP48E1.P_arrival = 2813; | ||||
|         end | ||||
|         else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin | ||||
|             if (PREG != 0)      \DSP48E1.P_arrival =  329; | ||||
|             // Worse-case from AREG, BREG, CREG | ||||
|             else if (CREG != 0) \DSP48E1.P_arrival = 1687; | ||||
|             else if (AREG != 0) \DSP48E1.P_arrival = 1632; | ||||
|             else if (BREG != 0) \DSP48E1.P_arrival = 1616; | ||||
|         end | ||||
|         //else | ||||
|         //    $error("Invalid DSP48E1 configuration"); | ||||
|     end | ||||
|     endfunction | ||||
|     function \DSP48E1.PCOUT_arrival ; | ||||
|         input USE_MULT, USE_DPORT; | ||||
|         input AREG, ADREG, BREG, CREG, DREG, MREG, PREG; | ||||
|     begin | ||||
|         \DSP48E1.PCOUT_arrival = 0; | ||||
|         if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin | ||||
|             if (PREG != 0)      \DSP48E1.PCOUT_arrival =  435; | ||||
|             // Worse-case from CREG and MREG | ||||
|             else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; | ||||
|             else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; | ||||
|             // Worse-case from AREG and BREG | ||||
|             else if (AREG != 0) \DSP48E1.PCOUT_arrival = 3098; | ||||
|             else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960; | ||||
|         end | ||||
|         else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin | ||||
|             if (PREG != 0)      \DSP48E1.PCOUT_arrival =  435; | ||||
|             // Worse-case from CREG and MREG | ||||
|             else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; | ||||
|             else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819; | ||||
|             // Worse-case from AREG, ADREG, BREG, DREG | ||||
|             else if (AREG != 0)  \DSP48E1.PCOUT_arrival = 4083; | ||||
|             else if (DREG != 0)  \DSP48E1.PCOUT_arrival = 4056; | ||||
|             else if (BREG != 0)  \DSP48E1.PCOUT_arrival = 2960; | ||||
|             else if (ADREG != 0) \DSP48E1.PCOUT_arrival = 2859; | ||||
|         end | ||||
|         else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin | ||||
|             if (PREG != 0)      \DSP48E1.PCOUT_arrival =  435; | ||||
|             // Worse-case from AREG, BREG, CREG | ||||
|             else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835; | ||||
|             else if (AREG != 0) \DSP48E1.PCOUT_arrival = 1780; | ||||
|             else if (BREG != 0) \DSP48E1.PCOUT_arrival = 1765; | ||||
|         end | ||||
|         //else | ||||
|         //    $error("Invalid DSP48E1 configuration"); | ||||
|     end | ||||
|     endfunction | ||||
| 
 | ||||
|     initial begin | ||||
| `ifdef __ICARUS__ | ||||
|         if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue