MAC89_DSP48E1
DSP48E1ユニットを4つ使って、49bit*35bit=84bitの積を求め、89bitアキュムレータで和を求めるユニット。
初めからいろいろつけると途中で挫折しそうだったので最小限の構成。
マジックナンバーもとりあえず直書きで、繰り返しもベタに展開した。
基本アイディアは桁ごとに積和を求め、最後に最終結果算出(ファイナライズ)命令を発行して初めて結果としてまとめるということ。
これにより、アキュムレータ用に別途DPS48E1を2つ使わなくてよい。
ただし、DSP48E1を別に使えば96bitのアキュムレータになるので、悪くはない。
レイテンシ6のパイプラインで、通常演算も位ごとに1サイクルずつずらし和と最終結果算出で取り合うPレジスタのハザードをなくしたので、スループットは1。
可能な限りDSP48E1ユニット内のレジスタと配線リソースを使うようにしたが、一部のレジスタはスライス上に実装する必要がある。
クロックゲーティングも一応入れた。
命令内容を見てマスクすればもっとスイッチングを減らせそうだが、記述量の割には効果が?だったのでとりあえずなし。
NOP命令はクロックゲーティングで代用できるのでいらなかったかも。
シミュレーションでA*Bに乱数を与えてVerilogの*演算子で計算した結果と一致させるテストをしばらく走らせていたが、結果はずっと合ってるのでとりあえずは大丈夫か?
他の積和とかも順次検証する。
後は一応つけてあるけど動いていないオーバーフロー/アンダーフロー検出とか。
module MAC89_DSP48E1 ( //Clock & Reset input wire i_clk, input wire i_rst, //Control input wire i_ce, output wire o_ce, output wire o_valid, //0:non finalized data //1:finalized data //Status output wire o_overflow, //Overflow any P reg output wire o_underflow, //Underflow any P reg //Command input wire [2:0] i_cmd, //refer:C_* localparam //Data input wire [48:0] i_a, input wire [34:0] i_b, input wire [88:0] i_c, output wire [88:0] o_p ); //Command localparam [2:0] C_NOP = 3'b000; //NOP(P<=P) localparam [2:0] C_AB = 3'b001; //P<=A*B localparam [2:0] C_AB_P = 3'b010; //P<=A*B+P localparam [2:0] C_AB_C = 3'b011; //P<=A*B+C localparam [2:0] C_C = 3'b100; //P<=C localparam [2:0] C_C_P = 3'b101; //P<=P+C localparam [2:0] C_ZERO = 3'b110; //P<=0 localparam [2:0] C_FINAL = 3'b111; //Finalize(must 3cycle assert) //XY MUX OPMODE[3:0] (X&Y not indipendent, unison) localparam [3:0] XY_ZERO = 4'b0000; //0 localparam [3:0] XY_MUL = 4'b0101; //M localparam [3:0] XY_P = 4'b0010; //P localparam [3:0] XY_C = 4'b1100; //C //Z MUX OPMODE[6:4] localparam [6:4] Z_ZERO = 3'b000; //0 localparam [6:4] Z_PCIN = 3'b001; //PCIN localparam [6:4] Z_P = 3'b010; //P localparam [6:4] Z_C = 3'b011; //C localparam [6:4] Z_PCIN_17S = 3'b101; //PCIN(17bit shift) localparam [6:4] Z_P_17S = 3'b110; //P(17bit shift) //Control wire wire [3:0] ALUMODE_ALBL; wire [3:0] ALUMODE_ALBH; wire [3:0] ALUMODE_AHBL; wire [3:0] ALUMODE_AHBH; wire [2:0] CARRYINSEL_ALBL; wire [2:0] CARRYINSEL_ALBH; wire [2:0] CARRYINSEL_AHBL; wire [2:0] CARRYINSEL_AHBH; wire [4:0] INMODE_ALBL; wire [4:0] INMODE_ALBH; wire [4:0] INMODE_AHBL; wire [4:0] INMODE_AHBH; wire [6:0] OPMODE_ALBL; wire [6:0] OPMODE_ALBH; wire [6:0] OPMODE_AHBL; wire [6:0] OPMODE_AHBH; wire OVERFLOW_ALBL; wire OVERFLOW_ALBH; wire OVERFLOW_AHBL; wire OVERFLOW_AHBH; wire UNDERFLOW_ALBL; wire UNDERFLOW_ALBH; wire UNDERFLOW_AHBL; wire UNDERFLOW_AHBH; //Control Reg reg r_ce [1:6]; reg [2:0] r_cmd [1:6]; //Data wire wire [29:0] AL; wire [29:0] AH; wire [17:0] BL; wire [17:0] BH; wire [47:0] C_ALBL; wire [47:0] C_AHBH; wire [29:0] ACOUT_ALBL; wire [29:0] ACOUT_AHBL; wire [47:0] PCOUT_ALBL; wire [47:0] PCOUT_AHBL; wire [47:0] P_ALBH_TO_C_AHBL; wire [47:0] P_ALBL; wire [47:0] P_ALBH; wire [47:0] P_AHBL; wire [47:0] P_AHBH; //Data Reg reg [29:0] r_AH [1:1]; reg [17:0] r_BL [1:1]; reg [17:0] r_BH [1:2]; reg [47:0] r_C_ALBL [1:1]; reg [47:0] r_C_AHBH [1:4]; reg [16:0] r_low_ALBH; reg [23:0] r_low_AHBL; reg [40:0] r_low_AHBH; //Clock Enable FF always @(posedge i_clk) begin if(i_rst) begin r_ce[1] <= 1'b0; r_ce[2] <= 1'b0; r_ce[3] <= 1'b0; r_ce[4] <= 1'b0; r_ce[5] <= 1'b0; r_ce[6] <= 1'b0; end else begin r_ce[1] <= i_ce; r_ce[2] <= r_ce[1]; r_ce[3] <= r_ce[2]; r_ce[4] <= r_ce[3]; r_ce[5] <= r_ce[4]; r_ce[6] <= r_ce[5]; end end assign o_ce = r_ce[6]; //Command FF always @(posedge i_clk) begin if(i_rst) begin r_cmd[1] <= 3'b0; r_cmd[2] <= 3'b0; r_cmd[3] <= 3'b0; r_cmd[4] <= 3'b0; r_cmd[5] <= 3'b0; r_cmd[6] <= 3'b0; end else begin if(i_ce) r_cmd[1] <= i_cmd; if(r_ce[1]) r_cmd[2] <= r_cmd[1]; if(r_ce[2]) r_cmd[3] <= r_cmd[2]; if(r_ce[3]) r_cmd[4] <= r_cmd[3]; if(r_ce[4]) r_cmd[5] <= r_cmd[4]; if(r_ce[5]) r_cmd[6] <= r_cmd[5]; end end assign o_valid = (r_cmd[6] == C_FINAL) ? 1'b1 : 1'b0; //overflow underflow assign o_overflow = OVERFLOW_ALBL | OVERFLOW_ALBH | OVERFLOW_AHBL | OVERFLOW_AHBH ; assign o_underflow = UNDERFLOW_ALBL | UNDERFLOW_ALBH | UNDERFLOW_AHBL | UNDERFLOW_AHBH ; //INMODE assign INMODE_ALBL[0] = 1'b0; //A2 assign INMODE_ALBL[1] = 1'b0; //Pass A Value assign INMODE_ALBL[2] = 1'b0; //Default assign INMODE_ALBL[3] = 1'b0; //Default assign INMODE_ALBL[4] = 1'b0; //B2 assign INMODE_ALBH = INMODE_ALBL; assign INMODE_AHBL = INMODE_ALBL; assign INMODE_AHBH = INMODE_ALBL; //CARRYINSEL assign CARRYINSEL_ALBL = 3'b000; //Use User carry(Fixed zero) assign CARRYINSEL_ALBH = 3'b000; assign CARRYINSEL_AHBL = 3'b000; assign CARRYINSEL_AHBH = 3'b000; //OPMODE assign OPMODE_ALBL = ((r_cmd[2] != C_FINAL) && //Last Executed Command (r_cmd[1] == C_FINAL)) ? {Z_ZERO, XY_P } : //Finalize (r_cmd[1] == C_NOP ) ? {Z_ZERO, XY_P } : //NOP(P<=P) (r_cmd[1] == C_AB ) ? {Z_ZERO, XY_MUL } : //P<=A*B (r_cmd[1] == C_AB_P ) ? {Z_P, XY_MUL } : //P<=A*B+P (r_cmd[1] == C_AB_C ) ? {Z_C, XY_MUL } : //P<=A*B+C (r_cmd[1] == C_C ) ? {Z_ZERO, XY_C } : //P<=C (r_cmd[1] == C_C_P ) ? {Z_P, XY_C } : //P<=P+C (r_cmd[1] == C_ZERO ) ? {Z_ZERO, XY_ZERO } : //P<=0 {Z_ZERO, XY_P } ; //Default assign OPMODE_ALBH = ((r_cmd[3] != C_FINAL) && //Last Executed Command (r_cmd[2] == C_FINAL)) ? {Z_PCIN_17S, XY_P } : //Finalize (r_cmd[2] == C_NOP ) ? {Z_ZERO, XY_P } : //NOP(P<=P) (r_cmd[2] == C_AB ) ? {Z_ZERO, XY_MUL } : //P<=A*B (r_cmd[2] == C_AB_P ) ? {Z_P, XY_MUL } : //P<=A*B+P (r_cmd[2] == C_AB_C ) ? {Z_ZERO, XY_MUL } : //P<=A*B+C (r_cmd[2] == C_C ) ? {Z_ZERO, XY_ZERO } : //P<=C (r_cmd[2] == C_C_P ) ? {Z_P, XY_ZERO } : //P<=P+C (r_cmd[2] == C_ZERO ) ? {Z_ZERO, XY_ZERO } : //P<=0 {Z_ZERO, XY_P } ; //Default assign OPMODE_AHBL = ((r_cmd[4] != C_FINAL) && //Last Executed Command (r_cmd[3] == C_FINAL)) ? {Z_C, XY_P } : //Finalize (r_cmd[3] == C_NOP ) ? {Z_ZERO, XY_P } : //NOP(P<=P) (r_cmd[3] == C_AB ) ? {Z_ZERO, XY_MUL } : //P<=A*B (r_cmd[3] == C_AB_P ) ? {Z_P, XY_MUL } : //P<=A*B+P (r_cmd[3] == C_AB_C ) ? {Z_ZERO, XY_MUL } : //P<=A*B+C (r_cmd[3] == C_C ) ? {Z_ZERO, XY_ZERO } : //P<=C (r_cmd[3] == C_C_P ) ? {Z_P, XY_ZERO } : //P<=P+C (r_cmd[3] == C_ZERO ) ? {Z_ZERO, XY_ZERO } : //P<=0 {Z_ZERO, XY_P } ; //Default assign OPMODE_AHBH = ((r_cmd[5] != C_FINAL) && //Last Executed Command (r_cmd[4] == C_FINAL)) ? {Z_PCIN_17S, XY_P } : //Finalize (r_cmd[4] == C_NOP ) ? {Z_ZERO, XY_P } : //NOP(P<=P) (r_cmd[4] == C_AB ) ? {Z_ZERO, XY_MUL } : //P<=A*B (r_cmd[4] == C_AB_P ) ? {Z_P, XY_MUL } : //P<=A*B+P (r_cmd[4] == C_AB_C ) ? {Z_C, XY_MUL } : //P<=A*B+C (r_cmd[4] == C_C ) ? {Z_ZERO, XY_C } : //P<=C (r_cmd[4] == C_C_P ) ? {Z_P, XY_C } : //P<=P+C (r_cmd[4] == C_ZERO ) ? {Z_ZERO, XY_ZERO } : //P<=0 {Z_ZERO, XY_P } ; //Default //ALUMODE assign ALUMODE_ALBL = 4'b0000; //Z+X+Y+CIN assign ALUMODE_ALBH = 4'b0000; assign ALUMODE_AHBL = 4'b0000; assign ALUMODE_AHBH = 4'b0000; //Input Data Packing assign AL = {6'b0, i_a[23: 0]}; assign AH = {5'b0, i_a[48:24]}; assign BL = {1'b0, i_b[16: 0]}; assign BH = i_b[34:17] ; assign C_ALBL = {7'b0, i_c[40: 0]}; assign C_AHBH = i_c[88:41] ; assign P_ALBH_TO_C_AHBL = {{7{P_ALBH[47]}}, P_ALBH[47:7]}; //Input Data Pipeline Reg always @(posedge i_clk) begin if(i_rst) begin r_AH[1] <= 0; r_BL[1] <= 0; r_BH[1] <= 0; r_BH[2] <= 0; r_C_ALBL[1] <= 0; r_C_AHBH[1] <= 0; r_C_AHBH[2] <= 0; r_C_AHBH[3] <= 0; r_C_AHBH[4] <= 0; end else begin if(i_ce) r_AH[1] <= AH; if(i_ce) r_BL[1] <= BL; if(i_ce) r_BH[1] <= BH; if(r_ce[1]) r_BH[2] <= r_BH[1]; if(i_ce) r_C_ALBL[1] <= C_ALBL; if(i_ce) r_C_AHBH[1] <= C_AHBH; if(r_ce[1]) r_C_AHBH[2] <= r_C_AHBH[1]; if(r_ce[2]) r_C_AHBH[3] <= r_C_AHBH[2]; if(r_ce[3]) r_C_AHBH[4] <= r_C_AHBH[3]; end end //P Pipeline Reg always @(posedge i_clk) begin if(i_rst) begin r_low_ALBH <= 0; r_low_AHBL <= 0; r_low_AHBH <= 0; end else begin if(r_ce[3]) r_low_ALBH <= P_ALBL[16:0]; if(r_ce[4]) r_low_AHBL <= {P_ALBH[6:0], r_low_ALBH}; if(r_ce[5]) r_low_AHBH <= {P_AHBL[16:0], r_low_AHBL}; end end //Output Data Pcaking assign o_p = {P_AHBH, r_low_AHBH}; //DSP Cores DSP48E1 #( // Feature Control Attributes: Data Path Selection .A_INPUT ( "DIRECT" ), // Selects A input source, "DIRECT" (A port) or "CASCADE" (ACIN port) .B_INPUT ( "DIRECT" ), // Selects B input source, "DIRECT" (B port) or "CASCADE" (BCIN port) .USE_DPORT ( "FALSE" ), // Select D port usage (TRUE or FALSE) .USE_MULT ( "MULTIPLY" ), // Select multiplier usage ("MULTIPLY", "DYNAMIC", or "NONE") .USE_SIMD ( "ONE48" ), // SIMD selection ("ONE48", "TWO24", "FOUR12") // Pattern Detector Attributes: Pattern Detection Configuration .AUTORESET_PATDET ( "NO_RESET" ), // "NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH" .MASK ( 48'h3fffffffffff ), // 48-bit mask value for pattern detect (1=ignore) .PATTERN ( 48'h000000000000 ), // 48-bit pattern match for pattern detect .SEL_MASK ( "MASK" ), // "C", "MASK", "ROUNDING_MODE1", "ROUNDING_MODE2" .SEL_PATTERN ( "PATTERN" ), // Select pattern value ("PATTERN" or "C") .USE_PATTERN_DETECT ( "NO_PATDET" ), // Enable pattern detect ("PATDET" or "NO_PATDET") // Register Control Attributes: Pipeline Register Configuration .ACASCREG ( 1 ), // Number of pipeline stages between A/ACIN and ACOUT (0, 1 or 2) .ADREG ( 1 ), // Number of pipeline stages for pre-adder (0 or 1) .ALUMODEREG ( 1 ), // Number of pipeline stages for ALUMODE (0 or 1) .AREG ( 1 ), // Number of pipeline stages for A (0, 1 or 2) .BCASCREG ( 1 ), // Number of pipeline stages between B/BCIN and BCOUT (0, 1 or 2) .BREG ( 1 ), // Number of pipeline stages for B (0, 1 or 2) .CARRYINREG ( 1 ), // Number of pipeline stages for CARRYIN (0 or 1) .CARRYINSELREG ( 1 ), // Number of pipeline stages for CARRYINSEL (0 or 1) .CREG ( 1 ), // Number of pipeline stages for C (0 or 1) .DREG ( 1 ), // Number of pipeline stages for D (0 or 1) .INMODEREG ( 1 ), // Number of pipeline stages for INMODE (0 or 1) .MREG ( 1 ), // Number of multiplier pipeline stages (0 or 1) .OPMODEREG ( 1 ), // Number of pipeline stages for OPMODE (0 or 1) .PREG ( 1 ) // Number of pipeline stages for P (0 or 1) ) DSP48E1_ALBL ( // Cascade: 30-bit (each) output: Cascade Ports .ACOUT ( ACOUT_ALBL ), // 30-bit output: A port cascade output .BCOUT ( ), // 18-bit output: B port cascade output .CARRYCASCOUT ( ), // 1-bit output: Cascade carry output .MULTSIGNOUT ( ), // 1-bit output: Multiplier sign cascade output .PCOUT ( PCOUT_ALBL ), // 48-bit output: Cascade output // Control: 1-bit (each) output: Control Inputs/Status Bits .OVERFLOW ( OVERFLOW_ALBL ), // 1-bit output: Overflow in add/acc output .PATTERNBDETECT ( ), // 1-bit output: Pattern bar detect output .PATTERNDETECT ( ), // 1-bit output: Pattern detect output .UNDERFLOW ( UNDERFLOW_ALBL ), // 1-bit output: Underflow in add/acc output // Data: 4-bit (each) output: Data Ports .CARRYOUT ( ), // 4-bit output: Carry output .P ( P_ALBL ), // 48-bit output: Primary data output // Cascade: 30-bit (each) input: Cascade Ports .ACIN ( 30'b0 ), // 30-bit input: A cascade data input .BCIN ( 18'b0 ), // 18-bit input: B cascade input .CARRYCASCIN ( 1'b0 ), // 1-bit input: Cascade carry input .MULTSIGNIN ( 1'b0 ), // 1-bit input: Multiplier sign input .PCIN ( 48'b0 ), // 48-bit input: P cascade input // Control: 4-bit (each) input: Control Inputs/Status Bits .ALUMODE ( ALUMODE_ALBL ), // 4-bit input: ALU control input .CARRYINSEL ( CARRYINSEL_ALBL ), // 3-bit input: Carry select input .CLK ( i_clk ), // 1-bit input: Clock input .INMODE ( INMODE_ALBL ), // 5-bit input: INMODE control input .OPMODE ( OPMODE_ALBL ), // 7-bit input: Operation mode input // Data: 30-bit (each) input: Data Ports .A ( AL ), // 30-bit input: A data input .B ( BL ), // 18-bit input: B data input .C ( r_C_ALBL[1] ), // 48-bit input: C data input .CARRYIN ( 1'b0 ), // 1-bit input: Carry input signal .D ( 25'b0 ), // 25-bit input: D data input // Reset/Clock Enable: 1-bit (each) input: Reset/Clock Enable Inputs .CED ( 1'b0 ), // 1-bit input: Clock enable input for DREG .CEAD ( 1'b0 ), // 1-bit input: Clock enable input for ADREG .CEA1 ( 1'b0 ), // 1-bit input: Clock enable input for 1st stage AREG .CEB1 ( 1'b0 ), // 1-bit input: Clock enable input for 1st stage BREG .CEA2 ( i_ce ), // 1-bit input: Clock enable input for 2nd stage AREG .CEB2 ( i_ce ), // 1-bit input: Clock enable input for 2nd stage BREG .CEINMODE ( i_ce ), // 1-bit input: Clock enable input for INMODEREG .CEM ( r_ce[1] ), // 1-bit input: Clock enable input for MREG .CEC ( r_ce[1] ), // 1-bit input: Clock enable input for CREG .CECARRYIN ( r_ce[1] ), // 1-bit input: Clock enable input for CARRYINREG .CECTRL ( r_ce[1] ), // 1-bit input: Clock enable input for OPMODEREG and CARRYINSELREG .CEALUMODE ( r_ce[1] ), // 1-bit input: Clock enable input for ALUMODE .CEP ( r_ce[2] ), // 1-bit input: Clock enable input for PREG .RSTA ( i_rst ), // 1-bit input: Reset input for AREG .RSTALLCARRYIN ( i_rst ), // 1-bit input: Reset input for CARRYINREG .RSTALUMODE ( i_rst ), // 1-bit input: Reset input for ALUMODEREG .RSTB ( i_rst ), // 1-bit input: Reset input for BREG .RSTC ( i_rst ), // 1-bit input: Reset input for CREG .RSTCTRL ( i_rst ), // 1-bit input: Reset input for OPMODEREG and CARRYINSELREG .RSTD ( i_rst ), // 1-bit input: Reset input for DREG and ADREG .RSTINMODE ( i_rst ), // 1-bit input: Reset input for INMODEREG .RSTM ( i_rst ), // 1-bit input: Reset input for MREG .RSTP ( i_rst ) // 1-bit input: Reset input for PREG ); DSP48E1 #( // Feature Control Attributes: Data Path Selection .A_INPUT ( "CASCADE" ), // Selects A input source, "DIRECT" (A port) or "CASCADE" (ACIN port) .B_INPUT ( "DIRECT" ), // Selects B input source, "DIRECT" (B port) or "CASCADE" (BCIN port) .USE_DPORT ( "FALSE" ), // Select D port usage (TRUE or FALSE) .USE_MULT ( "MULTIPLY" ), // Select multiplier usage ("MULTIPLY", "DYNAMIC", or "NONE") .USE_SIMD ( "ONE48" ), // SIMD selection ("ONE48", "TWO24", "FOUR12") // Pattern Detector Attributes: Pattern Detection Configuration .AUTORESET_PATDET ( "NO_RESET" ), // "NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH" .MASK ( 48'h3fffffffffff ), // 48-bit mask value for pattern detect (1=ignore) .PATTERN ( 48'h000000000000 ), // 48-bit pattern match for pattern detect .SEL_MASK ( "MASK" ), // "C", "MASK", "ROUNDING_MODE1", "ROUNDING_MODE2" .SEL_PATTERN ( "PATTERN" ), // Select pattern value ("PATTERN" or "C") .USE_PATTERN_DETECT ( "NO_PATDET" ), // Enable pattern detect ("PATDET" or "NO_PATDET") // Register Control Attributes: Pipeline Register Configuration .ACASCREG ( 1 ), // Number of pipeline stages between A/ACIN and ACOUT (0, 1 or 2) .ADREG ( 1 ), // Number of pipeline stages for pre-adder (0 or 1) .ALUMODEREG ( 1 ), // Number of pipeline stages for ALUMODE (0 or 1) .AREG ( 1 ), // Number of pipeline stages for A (0, 1 or 2) .BCASCREG ( 1 ), // Number of pipeline stages between B/BCIN and BCOUT (0, 1 or 2) .BREG ( 2 ), // Number of pipeline stages for B (0, 1 or 2) .CARRYINREG ( 1 ), // Number of pipeline stages for CARRYIN (0 or 1) .CARRYINSELREG ( 1 ), // Number of pipeline stages for CARRYINSEL (0 or 1) .CREG ( 1 ), // Number of pipeline stages for C (0 or 1) .DREG ( 1 ), // Number of pipeline stages for D (0 or 1) .INMODEREG ( 1 ), // Number of pipeline stages for INMODE (0 or 1) .MREG ( 1 ), // Number of multiplier pipeline stages (0 or 1) .OPMODEREG ( 1 ), // Number of pipeline stages for OPMODE (0 or 1) .PREG ( 1 ) // Number of pipeline stages for P (0 or 1) ) DSP48E1_ALBH ( // Cascade: 30-bit (each) output: Cascade Ports .ACOUT ( ), // 30-bit output: A port cascade output .BCOUT ( ), // 18-bit output: B port cascade output .CARRYCASCOUT ( ), // 1-bit output: Cascade carry output .MULTSIGNOUT ( ), // 1-bit output: Multiplier sign cascade output .PCOUT ( ), // 48-bit output: Cascade output // Control: 1-bit (each) output: Control Inputs/Status Bits .OVERFLOW ( OVERFLOW_ALBH ), // 1-bit output: Overflow in add/acc output .PATTERNBDETECT ( ), // 1-bit output: Pattern bar detect output .PATTERNDETECT ( ), // 1-bit output: Pattern detect output .UNDERFLOW ( UNDERFLOW_ALBH ), // 1-bit output: Underflow in add/acc output // Data: 4-bit (each) output: Data Ports .CARRYOUT ( ), // 4-bit output: Carry output .P ( P_ALBH ), // 48-bit output: Primary data output // Cascade: 30-bit (each) input: Cascade Ports .ACIN ( ACOUT_ALBL ), // 30-bit input: A cascade data input .BCIN ( 18'b0 ), // 18-bit input: B cascade input .CARRYCASCIN ( 1'b0 ), // 1-bit input: Cascade carry input .MULTSIGNIN ( 1'b0 ), // 1-bit input: Multiplier sign input .PCIN ( PCOUT_ALBL ), // 48-bit input: P cascade input // Control: 4-bit (each) input: Control Inputs/Status Bits .ALUMODE ( ALUMODE_ALBH ), // 4-bit input: ALU control input .CARRYINSEL ( CARRYINSEL_ALBH ), // 3-bit input: Carry select input .CLK ( i_clk ), // 1-bit input: Clock input .INMODE ( INMODE_ALBH ), // 5-bit input: INMODE control input .OPMODE ( OPMODE_ALBH ), // 7-bit input: Operation mode input // Data: 30-bit (each) input: Data Ports .A ( 30'b0 ), // 30-bit input: A data input .B ( BH ), // 18-bit input: B data input .C ( 48'b0 ), // 48-bit input: C data input .CARRYIN ( 1'b0 ), // 1-bit input: Carry input signal .D ( 25'b0 ), // 25-bit input: D data input // Reset/Clock Enable: 1-bit (each) input: Reset/Clock Enable Inputs .CEA1 ( 1'b0 ), // 1-bit input: Clock enable input for 1st stage AREG .CED ( 1'b0 ), // 1-bit input: Clock enable input for DREG .CEAD ( 1'b0 ), // 1-bit input: Clock enable input for ADREG .CEB1 ( i_ce ), // 1-bit input: Clock enable input for 1st stage BREG .CEA2 ( r_ce[1] ), // 1-bit input: Clock enable input for 2nd stage AREG .CEB2 ( r_ce[1] ), // 1-bit input: Clock enable input for 2nd stage BREG .CEINMODE ( r_ce[1] ), // 1-bit input: Clock enable input for INMODEREG .CEM ( r_ce[2] ), // 1-bit input: Clock enable input for MREG .CEC ( r_ce[2] ), // 1-bit input: Clock enable input for CREG .CECARRYIN ( r_ce[2] ), // 1-bit input: Clock enable input for CARRYINREG .CECTRL ( r_ce[2] ), // 1-bit input: Clock enable input for OPMODEREG and CARRYINSELREG .CEALUMODE ( r_ce[2] ), // 1-bit input: Clock enable input for ALUMODE .CEP ( r_ce[3] ), // 1-bit input: Clock enable input for PREG .RSTA ( i_rst ), // 1-bit input: Reset input for AREG .RSTALLCARRYIN ( i_rst ), // 1-bit input: Reset input for CARRYINREG .RSTALUMODE ( i_rst ), // 1-bit input: Reset input for ALUMODEREG .RSTB ( i_rst ), // 1-bit input: Reset input for BREG .RSTC ( i_rst ), // 1-bit input: Reset input for CREG .RSTCTRL ( i_rst ), // 1-bit input: Reset input for OPMODEREG and CARRYINSELREG .RSTD ( i_rst ), // 1-bit input: Reset input for DREG and ADREG .RSTINMODE ( i_rst ), // 1-bit input: Reset input for INMODEREG .RSTM ( i_rst ), // 1-bit input: Reset input for MREG .RSTP ( i_rst ) // 1-bit input: Reset input for PREG ); DSP48E1 #( // Feature Control Attributes: Data Path Selection .A_INPUT ( "DIRECT" ), // Selects A input source, "DIRECT" (A port) or "CASCADE" (ACIN port) .B_INPUT ( "DIRECT" ), // Selects B input source, "DIRECT" (B port) or "CASCADE" (BCIN port) .USE_DPORT ( "FALSE" ), // Select D port usage (TRUE or FALSE) .USE_MULT ( "MULTIPLY" ), // Select multiplier usage ("MULTIPLY", "DYNAMIC", or "NONE") .USE_SIMD ( "ONE48" ), // SIMD selection ("ONE48", "TWO24", "FOUR12") // Pattern Detector Attributes: Pattern Detection Configuration .AUTORESET_PATDET ( "NO_RESET" ), // "NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH" .MASK ( 48'h3fffffffffff ), // 48-bit mask value for pattern detect (1=ignore) .PATTERN ( 48'h000000000000 ), // 48-bit pattern match for pattern detect .SEL_MASK ( "MASK" ), // "C", "MASK", "ROUNDING_MODE1", "ROUNDING_MODE2" .SEL_PATTERN ( "PATTERN" ), // Select pattern value ("PATTERN" or "C") .USE_PATTERN_DETECT ( "NO_PATDET" ), // Enable pattern detect ("PATDET" or "NO_PATDET") // Register Control Attributes: Pipeline Register Configuration .ACASCREG ( 2 ), // Number of pipeline stages between A/ACIN and ACOUT (0, 1 or 2) .ADREG ( 1 ), // Number of pipeline stages for pre-adder (0 or 1) .ALUMODEREG ( 1 ), // Number of pipeline stages for ALUMODE (0 or 1) .AREG ( 2 ), // Number of pipeline stages for A (0, 1 or 2) .BCASCREG ( 1 ), // Number of pipeline stages between B/BCIN and BCOUT (0, 1 or 2) .BREG ( 2 ), // Number of pipeline stages for B (0, 1 or 2) .CARRYINREG ( 1 ), // Number of pipeline stages for CARRYIN (0 or 1) .CARRYINSELREG ( 1 ), // Number of pipeline stages for CARRYINSEL (0 or 1) .CREG ( 0 ), // Number of pipeline stages for C (0 or 1) .DREG ( 1 ), // Number of pipeline stages for D (0 or 1) .INMODEREG ( 1 ), // Number of pipeline stages for INMODE (0 or 1) .MREG ( 1 ), // Number of multiplier pipeline stages (0 or 1) .OPMODEREG ( 1 ), // Number of pipeline stages for OPMODE (0 or 1) .PREG ( 1 ) // Number of pipeline stages for P (0 or 1) ) DSP48E1_AHBL ( // Cascade: 30-bit (each) output: Cascade Ports .ACOUT ( ACOUT_AHBL ), // 30-bit output: A port cascade output .BCOUT ( ), // 18-bit output: B port cascade output .CARRYCASCOUT ( ), // 1-bit output: Cascade carry output .MULTSIGNOUT ( ), // 1-bit output: Multiplier sign cascade output .PCOUT ( PCOUT_AHBL ), // 48-bit output: Cascade output // Control: 1-bit (each) output: Control Inputs/Status Bits .OVERFLOW ( OVERFLOW_AHBL ), // 1-bit output: Overflow in add/acc output .PATTERNBDETECT ( ), // 1-bit output: Pattern bar detect output .PATTERNDETECT ( ), // 1-bit output: Pattern detect output .UNDERFLOW ( UNDERFLOW_AHBL ), // 1-bit output: Underflow in add/acc output // Data: 4-bit (each) output: Data Ports .CARRYOUT ( ), // 4-bit output: Carry output .P ( P_AHBL ), // 48-bit output: Primary data output // Cascade: 30-bit (each) input: Cascade Ports .ACIN ( 30'b0 ), // 30-bit input: A cascade data input .BCIN ( 18'b0 ), // 18-bit input: B cascade input .CARRYCASCIN ( 1'b0 ), // 1-bit input: Cascade carry input .MULTSIGNIN ( 1'b0 ), // 1-bit input: Multiplier sign input .PCIN ( 48'b0 ), // 48-bit input: P cascade input // Control: 4-bit (each) input: Control Inputs/Status Bits .ALUMODE ( ALUMODE_AHBL ), // 4-bit input: ALU control input .CARRYINSEL ( CARRYINSEL_AHBL ), // 3-bit input: Carry select input .CLK ( i_clk ), // 1-bit input: Clock input .INMODE ( INMODE_AHBL ), // 5-bit input: INMODE control input .OPMODE ( OPMODE_AHBL ), // 7-bit input: Operation mode input // Data: 30-bit (each) input: Data Ports .A ( r_AH[1] ), // 30-bit input: A data input .B ( r_BL[1] ), // 18-bit input: B data input .C ( P_ALBH_TO_C_AHBL ), // 48-bit input: C data input .CARRYIN ( 1'b0 ), // 1-bit input: Carry input signal .D ( 25'b0 ), // 25-bit input: D data input // Reset/Clock Enable: 1-bit (each) input: Reset/Clock Enable Inputs .CED ( 1'b0 ), // 1-bit input: Clock enable input for DREG .CEAD ( 1'b0 ), // 1-bit input: Clock enable input for ADREG .CEC ( 1'b0 ), // 1-bit input: Clock enable input for CREG .CEA1 ( r_ce[1] ), // 1-bit input: Clock enable input for 1st stage AREG .CEB1 ( r_ce[1] ), // 1-bit input: Clock enable input for 1st stage BREG .CEA2 ( r_ce[2] ), // 1-bit input: Clock enable input for 2nd stage AREG .CEB2 ( r_ce[2] ), // 1-bit input: Clock enable input for 2nd stage BREG .CEINMODE ( r_ce[2] ), // 1-bit input: Clock enable input for INMODEREG .CEM ( r_ce[3] ), // 1-bit input: Clock enable input for MREG .CECARRYIN ( r_ce[3] ), // 1-bit input: Clock enable input for CARRYINREG .CECTRL ( r_ce[3] ), // 1-bit input: Clock enable input for OPMODEREG and CARRYINSELREG .CEALUMODE ( r_ce[3] ), // 1-bit input: Clock enable input for ALUMODE .CEP ( r_ce[4] ), // 1-bit input: Clock enable input for PREG .RSTA ( i_rst ), // 1-bit input: Reset input for AREG .RSTALLCARRYIN ( i_rst ), // 1-bit input: Reset input for CARRYINREG .RSTALUMODE ( i_rst ), // 1-bit input: Reset input for ALUMODEREG .RSTB ( i_rst ), // 1-bit input: Reset input for BREG .RSTC ( i_rst ), // 1-bit input: Reset input for CREG .RSTCTRL ( i_rst ), // 1-bit input: Reset input for OPMODEREG and CARRYINSELREG .RSTD ( i_rst ), // 1-bit input: Reset input for DREG and ADREG .RSTINMODE ( i_rst ), // 1-bit input: Reset input for INMODEREG .RSTM ( i_rst ), // 1-bit input: Reset input for MREG .RSTP ( i_rst ) // 1-bit input: Reset input for PREG ); DSP48E1 #( // Feature Control Attributes: Data Path Selection .A_INPUT ( "CASCADE" ), // Selects A input source, "DIRECT" (A port) or "CASCADE" (ACIN port) .B_INPUT ( "DIRECT" ), // Selects B input source, "DIRECT" (B port) or "CASCADE" (BCIN port) .USE_DPORT ( "FALSE" ), // Select D port usage (TRUE or FALSE) .USE_MULT ( "MULTIPLY" ), // Select multiplier usage ("MULTIPLY", "DYNAMIC", or "NONE") .USE_SIMD ( "ONE48" ), // SIMD selection ("ONE48", "TWO24", "FOUR12") // Pattern Detector Attributes: Pattern Detection Configuration .AUTORESET_PATDET ( "NO_RESET" ), // "NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH" .MASK ( 48'h3fffffffffff ), // 48-bit mask value for pattern detect (1=ignore) .PATTERN ( 48'h000000000000 ), // 48-bit pattern match for pattern detect .SEL_MASK ( "MASK" ), // "C", "MASK", "ROUNDING_MODE1", "ROUNDING_MODE2" .SEL_PATTERN ( "PATTERN" ), // Select pattern value ("PATTERN" or "C") .USE_PATTERN_DETECT ( "NO_PATDET" ), // Enable pattern detect ("PATDET" or "NO_PATDET") // Register Control Attributes: Pipeline Register Configuration .ACASCREG ( 1 ), // Number of pipeline stages between A/ACIN and ACOUT (0, 1 or 2) .ADREG ( 1 ), // Number of pipeline stages for pre-adder (0 or 1) .ALUMODEREG ( 1 ), // Number of pipeline stages for ALUMODE (0 or 1) .AREG ( 1 ), // Number of pipeline stages for A (0, 1 or 2) .BCASCREG ( 1 ), // Number of pipeline stages between B/BCIN and BCOUT (0, 1 or 2) .BREG ( 2 ), // Number of pipeline stages for B (0, 1 or 2) .CARRYINREG ( 1 ), // Number of pipeline stages for CARRYIN (0 or 1) .CARRYINSELREG ( 1 ), // Number of pipeline stages for CARRYINSEL (0 or 1) .CREG ( 1 ), // Number of pipeline stages for C (0 or 1) .DREG ( 1 ), // Number of pipeline stages for D (0 or 1) .INMODEREG ( 1 ), // Number of pipeline stages for INMODE (0 or 1) .MREG ( 1 ), // Number of multiplier pipeline stages (0 or 1) .OPMODEREG ( 1 ), // Number of pipeline stages for OPMODE (0 or 1) .PREG ( 1 ) // Number of pipeline stages for P (0 or 1) ) DSP48E1_AHBH ( // Cascade: 30-bit (each) output: Cascade Ports .ACOUT ( ), // 30-bit output: A port cascade output .BCOUT ( ), // 18-bit output: B port cascade output .CARRYCASCOUT ( ), // 1-bit output: Cascade carry output .MULTSIGNOUT ( ), // 1-bit output: Multiplier sign cascade output .PCOUT ( ), // 48-bit output: Cascade output // Control: 1-bit (each) output: Control Inputs/Status Bits .OVERFLOW ( OVERFLOW_AHBH ), // 1-bit output: Overflow in add/acc output .PATTERNBDETECT ( ), // 1-bit output: Pattern bar detect output .PATTERNDETECT ( ), // 1-bit output: Pattern detect output .UNDERFLOW ( UNDERFLOW_AHBH ), // 1-bit output: Underflow in add/acc output // Data: 4-bit (each) output: Data Ports .CARRYOUT ( ), // 4-bit output: Carry output .P ( P_AHBH ), // 48-bit output: Primary data output // Cascade: 30-bit (each) input: Cascade Ports .ACIN ( ACOUT_AHBL ), // 30-bit input: A cascade data input .BCIN ( 18'b0 ), // 18-bit input: B cascade input .CARRYCASCIN ( 1'b0 ), // 1-bit input: Cascade carry input .MULTSIGNIN ( 1'b0 ), // 1-bit input: Multiplier sign input .PCIN ( PCOUT_AHBL ), // 48-bit input: P cascade input // Control: 4-bit (each) input: Control Inputs/Status Bits .ALUMODE ( ALUMODE_AHBH ), // 4-bit input: ALU control input .CARRYINSEL ( CARRYINSEL_AHBH ), // 3-bit input: Carry select input .CLK ( i_clk ), // 1-bit input: Clock input .INMODE ( INMODE_AHBH ), // 5-bit input: INMODE control input .OPMODE ( OPMODE_AHBH ), // 7-bit input: Operation mode input // Data: 30-bit (each) input: Data Ports .A ( 30'b0 ), // 30-bit input: A data input .B ( r_BH[2] ), // 18-bit input: B data input .C ( C_AHBH[4] ), // 48-bit input: C data input .CARRYIN ( 1'b0 ), // 1-bit input: Carry input signal .D ( 25'b0 ), // 25-bit input: D data input // Reset/Clock Enable: 1-bit (each) input: Reset/Clock Enable Inputs .CEA1 ( 1'b0 ), // 1-bit input: Clock enable input for 1st stage AREG .CED ( 1'b0 ), // 1-bit input: Clock enable input for DREG .CEAD ( 1'b0 ), // 1-bit input: Clock enable input for ADREG .CEB1 ( r_ce[2] ), // 1-bit input: Clock enable input for 1st stage BREG .CEA2 ( r_ce[3] ), // 1-bit input: Clock enable input for 2nd stage AREG .CEB2 ( r_ce[3] ), // 1-bit input: Clock enable input for 2nd stage BREG .CEINMODE ( r_ce[3] ), // 1-bit input: Clock enable input for INMODEREG .CEM ( r_ce[4] ), // 1-bit input: Clock enable input for MREG .CEC ( r_ce[4] ), // 1-bit input: Clock enable input for CREG .CECARRYIN ( r_ce[4] ), // 1-bit input: Clock enable input for CARRYINREG .CECTRL ( r_ce[4] ), // 1-bit input: Clock enable input for OPMODEREG and CARRYINSELREG .CEALUMODE ( r_ce[4] ), // 1-bit input: Clock enable input for ALUMODE .CEP ( r_ce[5] ), // 1-bit input: Clock enable input for PREG .RSTA ( i_rst ), // 1-bit input: Reset input for AREG .RSTALLCARRYIN ( i_rst ), // 1-bit input: Reset input for CARRYINREG .RSTALUMODE ( i_rst ), // 1-bit input: Reset input for ALUMODEREG .RSTB ( i_rst ), // 1-bit input: Reset input for BREG .RSTC ( i_rst ), // 1-bit input: Reset input for CREG .RSTCTRL ( i_rst ), // 1-bit input: Reset input for OPMODEREG and CARRYINSELREG .RSTD ( i_rst ), // 1-bit input: Reset input for DREG and ADREG .RSTINMODE ( i_rst ), // 1-bit input: Reset input for INMODEREG .RSTM ( i_rst ), // 1-bit input: Reset input for MREG .RSTP ( i_rst ) // 1-bit input: Reset input for PREG ); endmodule