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 [4:0] IS_INMODE_INVERTED = 5'b0; | ||||||
|     parameter [6:0] IS_OPMODE_INVERTED = 7'b0; |     parameter [6:0] IS_OPMODE_INVERTED = 7'b0; | ||||||
| 
 | 
 | ||||||
|     parameter _TECHMAP_CELLTYPE_ = ""; |     wire [47:0] $P, $PCOUT; | ||||||
|     localparam techmap_guard = (_TECHMAP_CELLTYPE_ != ""); |  | ||||||
| 
 | 
 | ||||||
| `define DSP48E1_INST(__CELL__) """ |     DSP48E1 #( | ||||||
| __CELL__ #( |  | ||||||
|         .ACASCREG(ACASCREG), |         .ACASCREG(ACASCREG), | ||||||
|         .ADREG(ADREG), |         .ADREG(ADREG), | ||||||
|         .ALUMODEREG(ALUMODEREG), |         .ALUMODEREG(ALUMODEREG), | ||||||
|  | @ -324,17 +322,17 @@ __CELL__ #( | ||||||
|         .CARRYOUT(CARRYOUT), |         .CARRYOUT(CARRYOUT), | ||||||
|         .MULTSIGNOUT(MULTSIGNOUT), |         .MULTSIGNOUT(MULTSIGNOUT), | ||||||
|         .OVERFLOW(OVERFLOW), |         .OVERFLOW(OVERFLOW), | ||||||
|             .P(oP), |         .P($P), | ||||||
|         .PATTERNBDETECT(PATTERNBDETECT), |         .PATTERNBDETECT(PATTERNBDETECT), | ||||||
|         .PATTERNDETECT(PATTERNDETECT), |         .PATTERNDETECT(PATTERNDETECT), | ||||||
|             .PCOUT(oPCOUT), |         .PCOUT($PCOUT), | ||||||
|         .UNDERFLOW(UNDERFLOW), |         .UNDERFLOW(UNDERFLOW), | ||||||
|             .A(iA), |         .A(A), | ||||||
|         .ACIN(ACIN), |         .ACIN(ACIN), | ||||||
|         .ALUMODE(ALUMODE), |         .ALUMODE(ALUMODE), | ||||||
|             .B(iB), |         .B(B), | ||||||
|         .BCIN(BCIN), |         .BCIN(BCIN), | ||||||
|             .C(iC), |         .C(C), | ||||||
|         .CARRYCASCIN(CARRYCASCIN), |         .CARRYCASCIN(CARRYCASCIN), | ||||||
|         .CARRYIN(CARRYIN), |         .CARRYIN(CARRYIN), | ||||||
|         .CARRYINSEL(CARRYINSEL), |         .CARRYINSEL(CARRYINSEL), | ||||||
|  | @ -352,7 +350,7 @@ __CELL__ #( | ||||||
|         .CEM(CEM), |         .CEM(CEM), | ||||||
|         .CEP(CEP), |         .CEP(CEP), | ||||||
|         .CLK(CLK), |         .CLK(CLK), | ||||||
|             .D(iD), |         .D(D), | ||||||
|         .INMODE(INMODE), |         .INMODE(INMODE), | ||||||
|         .MULTSIGNIN(MULTSIGNIN), |         .MULTSIGNIN(MULTSIGNIN), | ||||||
|         .OPMODE(OPMODE), |         .OPMODE(OPMODE), | ||||||
|  | @ -368,158 +366,29 @@ __CELL__ #( | ||||||
|         .RSTM(RSTM), |         .RSTM(RSTM), | ||||||
|         .RSTP(RSTP) |         .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 |     generate | ||||||
|     if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin |         wire [29:0] $A; | ||||||
|         // Disconnect the A-input if MREG is enabled, since |         wire [17:0] $B; | ||||||
|         //   combinatorial path is broken |         wire [47:0] $C; | ||||||
|         if (AREG == 0 && MREG == 0 && PREG == 0) |         wire [24:0] $D; | ||||||
|             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 |  | ||||||
| 
 | 
 | ||||||
|         if (MREG == 0 && PREG == 0) |         if (PREG != 0) | ||||||
|             assign mP = oP, mPCOUT = oPCOUT; |             assign P = $P, PCOUT = $PCOUT; | ||||||
|         else |         else begin | ||||||
|             assign mP = 1'bx, mPCOUT = 1'bx; |             if (AREG == 0) assign $A = A; | ||||||
|         \$__ABC9_DSP48E1_MULT_P_MUX muxP ( |             if (BREG == 0) assign $B = B; | ||||||
|             .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P) |             if (CREG == 0) assign $C = C; | ||||||
|         ); |             if (DREG == 0) assign $D = D; | ||||||
|         \$__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) |  | ||||||
|         ); |  | ||||||
| 
 | 
 | ||||||
|         `DSP48E1_INST(\$__ABC9_DSP48E1_MULT ) |             if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") | ||||||
|     end |                 $__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") begin |             else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") | ||||||
|         // Disconnect the A-input if MREG is enabled, since |                 $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); | ||||||
|         //   combinatorial path is broken |             else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") | ||||||
|         if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0) |                 $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); | ||||||
|             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 |  | ||||||
|             else |             else | ||||||
|                 $error("Invalid DSP48E1 configuration"); |                 $error("Invalid DSP48E1 configuration"); | ||||||
|  |         end | ||||||
|     endgenerate |     endgenerate | ||||||
|     `undef DSP48E1_INST |  | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
|  | @ -44,147 +44,22 @@ endmodule | ||||||
| module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); | module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| 
 | // Boxes used to represent the comb behaviour of various modes | ||||||
| // Modules used to model the comb/seq behaviour of DSP48E1 | //   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 ) |  | ||||||
| 
 |  | ||||||
| `define ABC9_DSP48E1(__NAME__) """ | `define ABC9_DSP48E1(__NAME__) """ | ||||||
| module __NAME__ ( | module __NAME__ ( | ||||||
|     output [29:0] ACOUT, |     input [29:0] $A, | ||||||
|     output [17:0] BCOUT, |     input [17:0] $B, | ||||||
|     output reg CARRYCASCOUT, |     input [47:0] $C, | ||||||
|     output reg [3:0] CARRYOUT, |     input [24:0] $D, | ||||||
|     output reg MULTSIGNOUT, |     input [47:0] $P, | ||||||
|     output OVERFLOW, |     input [47:0] $PCIN, | ||||||
|     output reg signed [47:0] P, |     input [47:0] $PCOUT, | ||||||
|     output PATTERNBDETECT, |     output [47:0] P, | ||||||
|     output PATTERNDETECT, |     output [47:0] PCOUT); | ||||||
|     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 | endmodule | ||||||
| """ | """ | ||||||
| (* abc9_box_id=3000 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT ) | (* abc9_box_id=3000 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT) | ||||||
| (* abc9_box_id=3001 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT_DPORT ) | (* abc9_box_id=3001 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT_DPORT) | ||||||
| (* abc9_box_id=3002 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1 ) | (* 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; |   assign Y = A; | ||||||
| endmodule | 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; |   assign Y = A; | ||||||
| endmodule | 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" *) | (* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *) | ||||||
| module \$__ABC9_DSP48E1 ( | module $ABC9_DSP48E1( | ||||||
|     (* techmap_autopurge *) output [29:0] ACOUT, |     input [29:0] $A, | ||||||
|     (* techmap_autopurge *) output [17:0] BCOUT, |     input [17:0] $B, | ||||||
|     (* techmap_autopurge *) output reg CARRYCASCOUT, |     input [47:0] $C, | ||||||
|     (* techmap_autopurge *) output reg [3:0] CARRYOUT, |     input [24:0] $D, | ||||||
|     (* techmap_autopurge *) output reg MULTSIGNOUT, |     input [47:0] $P, | ||||||
|     (* techmap_autopurge *) output OVERFLOW, |     input [47:0] $PCIN, | ||||||
|     (* techmap_autopurge *) output reg signed [47:0] P, |     input [47:0] $PCOUT, | ||||||
|     (* techmap_autopurge *) output PATTERNBDETECT, |     output [47:0] P, | ||||||
|     (* techmap_autopurge *) output PATTERNDETECT, |     output [47:0] PCOUT | ||||||
|     (* 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; |     assign P = $P, PCOUT = $PCOUT; | ||||||
|     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) |  | ||||||
|     ); |  | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -2160,9 +2160,15 @@ module DSP48E1 ( | ||||||
|     output reg [3:0] CARRYOUT, |     output reg [3:0] CARRYOUT, | ||||||
|     output reg MULTSIGNOUT, |     output reg MULTSIGNOUT, | ||||||
|     output OVERFLOW, |     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 signed [47:0] P, | ||||||
|     output reg PATTERNBDETECT, |     output reg PATTERNBDETECT, | ||||||
|     output reg PATTERNDETECT, |     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 [47:0] PCOUT, | ||||||
|     output UNDERFLOW, |     output UNDERFLOW, | ||||||
|     input signed [29:0] A, |     input signed [29:0] A, | ||||||
|  | @ -2235,6 +2241,79 @@ module DSP48E1 ( | ||||||
|     parameter [4:0] IS_INMODE_INVERTED = 5'b0; |     parameter [4:0] IS_INMODE_INVERTED = 5'b0; | ||||||
|     parameter [6:0] IS_OPMODE_INVERTED = 7'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 |     initial begin | ||||||
| `ifdef __ICARUS__ | `ifdef __ICARUS__ | ||||||
|         if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value"); |         if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue