symbiflow-arch-defs
symbiflow-arch-defs

dsp48e1

Component Diagram

// DSP48E1 - 7 Series DSP48E1 User Guide UG479 (v1.9) September 27, 2016 `ifndef PB_TYPE `include "alu/alu.sim.v" `include "alumode_mux/alumode_mux.sim.v" `include "carryinsel_logic/carryinsel_logic.sim.v" `include "carryinsel_mux/carryinsel_mux.sim.v" `include "creg_mux/creg_mux.sim.v" `include "dual_ad_preadder/dual_ad_preadder.sim.v" `include "dual_b_reg/dual_b_reg.sim.v" `include "inmode_mux/inmode_mux.sim.v" `include "mult25x18/mult25x18.sim.v" `include "mult_mux/mult_mux.sim.v" `include "nreg/nreg.sim.v" `include "opmode_mux/opmode_mux.sim.v" `include "xmux/dsp48_xmux.sim.v" `include "ymux/dsp48_ymux.sim.v" `include "zmux/dsp48_zmux.sim.v" `endif // Figure 2-1: 7 Series FPGA DSP48E1 Slice module DSP48E1( A, B, C, D, OPMODE,ALUMODE, CARRYIN, CARRYINSEL, INMODE, CEA1, CEA2, CEB1, CEB2, CEC, CED, CEM, CEP, CEAD, CEALUMODE, CECTRL, CECARRYIN, CEINMODE, RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCTRL, RSTALLCARRYIN, RSTALUMODE, RSTINMODE, CLK, ACIN, BCIN, PCIN, CARRYCASCIN, MULTSIGNIN, ACOUT, BCOUT, PCOUT, P, CARRYOUT, CARRYCASCOUT, MULTSIGNOUT, PATTERNDETECT, PATTERNBDETECT, OVERFLOW, UNDERFLOW ); // Main inputs input wire [29:0] A; input wire [17:0] B; input wire [47:0] C; input wire [24:0] D; input wire [6:0] OPMODE; input wire [3:0] ALUMODE; input wire CARRYIN; input wire [2:0] CARRYINSEL; input wire [4:0] INMODE; // Clock enable for registers input wire CEA1; input wire CEA2; input wire CEB1; input wire CEB2; input wire CEC; input wire CED; input wire CEM; input wire CEP; input wire CEAD; input wire CEALUMODE; input wire CECTRL; input wire CECARRYIN; input wire CEINMODE; // Reset for registers input wire RSTA; input wire RSTB; input wire RSTC; input wire RSTD; input wire RSTM; input wire RSTP; input wire RSTCTRL; input wire RSTALLCARRYIN; input wire RSTALUMODE; input wire RSTINMODE; // clock for all registers and flip-flops input wire CLK; // Interslice connections input wire [29:0] ACIN; input wire [17:0] BCIN; input wire [47:0] PCIN; input wire CARRYCASCIN; input wire MULTSIGNIN; output wire [29:0] ACOUT; output wire [17:0] BCOUT; output wire [47:0] PCOUT; output wire [47:0] P; // main outputs output wire [3:0] CARRYOUT; output wire CARRYCASCOUT; output wire MULTSIGNOUT; output wire PATTERNDETECT; output wire PATTERNBDETECT; output wire OVERFLOW; output wire UNDERFLOW; // wires for concatenating A and B registers to XMUX input wire [47:0] XMUX_CAT; wire [29:0] XMUX_A_CAT; wire [17:0] XMUX_B_CAT; // wires for multiplier inputs wire [24:0] AMULT; wire [17:0] BMULT; `ifndef PB_TYPE parameter ACASCREG = 1; parameter ADREG = 1; parameter ALUMODEREG = 1; parameter AREG = 1; parameter BCASCREG = 1; parameter BREG = 1; parameter CARRYINREG = 1; parameter CARRYINSELREG = 1; parameter CREG = 1; parameter DREG = 1; parameter INMODEREG = 1; parameter MREG = 1; parameter OPMODEREG = 1; parameter PREG = 1; parameter A_INPUT = "DIRECT"; parameter B_INPUT = "DIRECT"; parameter USE_DPORT = "FALSE"; parameter USE_MULT = "MULTIPLY"; parameter USE_SIMD = "ONE48"; parameter AUTORESET_PATDET = "NO_RESET"; parameter MASK = 001111111111111111111111111111111111111111111111; parameter PATTERN = 000000000000000000000000000000000000000000000000; parameter SEL_MASK = "MASK"; parameter SEL_PATTERN = "PATTERN"; parameter USE_PATTERN_DETECT = "NO_PATDET"; // Figure 2-10 OPMODE, ALUMODE, CARRYINSEL wire [6:0] OPMODE_REG; wire [6:0] OPMODE_MUX_OUT; NREG #(.NBITS(7)) opmode_reg (.D(OPMODE), .Q(OPMODE_REG), .CE(CECTRL), .CLK(CLK), .RESET(RSTCTRL)); OPMODE_MUX #(.S(OPMODEREG)) opmode_mux (.BYPASS(OPMODE), .REG(OPMODE_REG), .O(OPMODE_MUX_OUT)); // ALUMODE register wire [3:0] ALUMODE_REG; wire [3:0] ALUMODE_MUX_OUT; NREG #(.NBITS(4)) alu_reg (.D(ALUMODE), .Q(ALUMODE_REG), .CE(CEALUMODE), .CLK(CLK), .RESET(RSTALUMODE)); ALUMODE_MUX #(.S(ALUMODEREG)) alumode_mux (.BYPASS(ALUMODE), .REG(ALUMODE_REG), .O(ALUMODE_MUX_OUT)); wire [2:0] CARRYINSEL_REG; wire [2:0] CARRYINSEL_MUX_OUT; NREG #(.NBITS(3)) carryinsel_reg (.D(CARRYINSEL), .Q(CARRYINSEL_REG), .CE(CECTRL), .CLK(CLK), .RESET(RSTCTRL)); CARRYINSEL_MUX #(.S(CARRYINSELREG)) carryseling_mux (.BYPASS(CARRYSELIN), .REG(CARRYINSEL_REG), .O(CARRYINSEL_MUX_OUT)); wire CIN; CARRYINSEL_LOGIC #(.MREG(MREG), .CARRYINREG(CARRYINREG)) carryinsel_logic (.CARRYIN(CARRYIN), .CARRYCASCIN(CARRYCASCIN), .CARRYCASCOUT(CARRYCASCOUT), .A(A), .B(B), .P(P), .PCIN(PCIN), .CARRYINSEL(CARRYINSEL), .CIN(CIN), .RSTALLCARRYIN(RSTALLCARRYIN), .CECARRYIN(CECARRYIN), .CEM(CEM), .CLK(CLK)); // INMODE register and bypass mux wire [4:0] INMODE_REG; wire [4:0] INMODE_MUX_OUT; NREG #(.NBITS(5)) inmode_reg (.D(INMODE), .Q(INMODE_REG), .CE(CEINMODE), .CLK(CLK), .RESET(RSTINMODE)); INMODE_MUX #(.S(INMODEREG)) inmode_mux(.BYPASS(INMODE), .REG(INMODE_REG), .O(INMODE_MUX_OUT)); // input register blocks for A, B, D DUAL_AD_PREADDER dual_ad_preadder (.A(A), .ACIN(ACIN), .D(D), .INMODE(INMODE_MUX_OUT), .ACOUT(ACOUT), .XMUX(XMUX_A_CAT), .AMULT(AMULT), .CEA1(CEA1), .CEA2(CEA2), .RSTA(RSTA), .CED(CED), .CEAD(CEAD), .RSTD(RSTD), .CLK(CLK)); DUAL_B_REG dualb_reg (.B(B), .BCIN(BCIN), .INMODE(INMODE_MUX_OUT), .BCOUT(BCOUT), .XMUX(XMUX_B_CAT), .BMULT(BMULT), .CEB1(CEB1), .CEB2(CEB2), .RSTB(RSTB), .CLK(CLK)); // concatenate for XMUX assign XMUX_CAT = {XMUX_A_CAT, XMUX_B_CAT}; // Multiplier output wire [85:0] MULT_OUT; wire [85:0] MULT_REG; wire [85:0] MULT_MUX_OUT; // 25bit by 18bit multiplier MULT25X18 mult25x18 (.A(AMULT), .B(BMULT), .OUT(MULT_OUT)); NREG #(.NBITS(86)) mult_reg (.D(MULT_OUT), .Q(MULT_REG), .CLK(CLK), .CE(CEM), .RESET(RSTM)); MULT_MUX #(.S(MREG)) mult_mux (.BYPASS(MULT_OUT), .REG(MULT_REG), .O(MULT_MUX_OUT)); // Figure 2-9 wire [47:0] C_REG; wire [47:0] CMUX_OUT; NREG #(.NBITS(48)) creg (.D(C), .Q(C_REG), .CLK(CLK), .CE(CEC), .RESET(RSTC)); CREG_MUX #(.S(CREG)) creg_mux (.BYPASS(C), .REG(C_REG), .O(CMUX_OUT)); // signals from muxes to ALU unit wire [47:0] X; wire [47:0] Y; wire [47:0] Z; // TODO(elmsfu): take in full OPMODE to check for undefined behaviors // See table 2-7 for X mux selection DSP48_XMUX dsp48_xmux (.ZEROS(48'h000000000000), .M({5'b00000, MULT_MUX_OUT[85:43]}), .P(P), .AB_CAT(XMUX_CAT), .S(OPMODE_MUX_OUT[1:0]), .O(X)); // See table 2-8 for Y mux selection DSP48_YMUX dsp48_ymux (.ZEROS(48'h000000000000), .M({5'b00000, MULT_MUX_OUT[42:0]}), .ONES(48'hFFFFFFFFFFFF), .C(CMUX_OUT), .S(OPMODE_MUX_OUT[3:2]), .O(Y)); // See table 2-9 for Z mux selection // Note: Z mux actually has 7 inputs but 2 and 4 are both P DSP48_ZMUX dsp48_zmux (.ZEROS(48'h000000000000), .PCIN(PCIN), .P(P), .C(CMUX_OUT), .P2(P), .PCIN_UPSHIFT({ {17{PCIN[47]}}, PCIN[47:17]}), .P_UPSHIFT({ {17{P[47]}}, P[47:17]}), .S(OPMODE_MUX_OUT[6:4]), .O(Z)); // See table 2-10 for 3 input behavior // See table 2-13 for 2 input behavior ALU alu (.X(X), .Y(Y), .Z(Z), .ALUMODE(ALUMODE_MUX_OUT), .CARRYIN(CIN), .MULTSIGNIN(MULTSIGNIN), .OUT(P), .CARRYOUT(CARRYOUT), .MULTSIGNOUT(MULTSIGNOUT)); assign PCOUT = P; `endif // `ifndef PB_TYPE endmodule // DSP48E1

Verilog File

// DSP48E1 - 7 Series DSP48E1 User Guide UG479 (v1.9) September 27, 2016

`ifndef PB_TYPE
`include "alu/alu.sim.v"
`include "alumode_mux/alumode_mux.sim.v"
`include "carryinsel_logic/carryinsel_logic.sim.v"
`include "carryinsel_mux/carryinsel_mux.sim.v"
`include "creg_mux/creg_mux.sim.v"
`include "dual_ad_preadder/dual_ad_preadder.sim.v"
`include "dual_b_reg/dual_b_reg.sim.v"
`include "inmode_mux/inmode_mux.sim.v"
`include "mult25x18/mult25x18.sim.v"
`include "mult_mux/mult_mux.sim.v"
`include "nreg/nreg.sim.v"
`include "opmode_mux/opmode_mux.sim.v"
`include "xmux/dsp48_xmux.sim.v"
`include "ymux/dsp48_ymux.sim.v"
`include "zmux/dsp48_zmux.sim.v"
`endif

// Figure 2-1: 7 Series FPGA DSP48E1 Slice
module DSP48E1(
       A, B, C, D,
       OPMODE,ALUMODE, CARRYIN, CARRYINSEL, INMODE,
       CEA1, CEA2, CEB1, CEB2, CEC, CED, CEM, CEP, CEAD,
       CEALUMODE, CECTRL, CECARRYIN, CEINMODE,
       RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCTRL, RSTALLCARRYIN, RSTALUMODE, RSTINMODE,
       CLK,
       ACIN, BCIN, PCIN, CARRYCASCIN, MULTSIGNIN,
       ACOUT, BCOUT, PCOUT, P, CARRYOUT, CARRYCASCOUT, MULTSIGNOUT, PATTERNDETECT, PATTERNBDETECT, OVERFLOW, UNDERFLOW
       );

   // Main inputs
   input wire [29:0] A;
   input wire [17:0] B;
   input wire [47:0] C;
   input wire [24:0] D;
   input wire [6:0]  OPMODE;
   input wire [3:0]  ALUMODE;
   input wire 	     CARRYIN;
   input wire [2:0]  CARRYINSEL;
   input wire [4:0]  INMODE;

   // Clock enable for registers
   input wire 	     CEA1;
   input wire 	     CEA2;
   input wire 	     CEB1;
   input wire 	     CEB2;
   input wire 	     CEC;
   input wire 	     CED;
   input wire 	     CEM;
   input wire 	     CEP;
   input wire 	     CEAD;
   input wire 	     CEALUMODE;
   input wire 	     CECTRL;
   input wire 	     CECARRYIN;
   input wire 	     CEINMODE;

   // Reset for registers
   input wire 	     RSTA;
   input wire 	     RSTB;
   input wire 	     RSTC;
   input wire 	     RSTD;
   input wire 	     RSTM;
   input wire 	     RSTP;
   input wire 	     RSTCTRL;
   input wire 	     RSTALLCARRYIN;
   input wire 	     RSTALUMODE;
   input wire 	     RSTINMODE;

   // clock for all registers and flip-flops
   input wire 	     CLK;

   // Interslice connections
   input wire [29:0] ACIN;
   input wire [17:0] BCIN;
   input wire [47:0] PCIN;
   input wire 	     CARRYCASCIN;
   input wire 	     MULTSIGNIN;

   output wire [29:0] ACOUT;
   output wire [17:0] BCOUT;
   output wire [47:0] PCOUT;
   output wire [47:0] P;

   // main outputs
   output wire [3:0]  CARRYOUT;
   output wire 	      CARRYCASCOUT;
   output wire 	      MULTSIGNOUT;
   output wire 	      PATTERNDETECT;
   output wire 	      PATTERNBDETECT;
   output wire 	      OVERFLOW;
   output wire 	      UNDERFLOW;

   // wires for concatenating A and B registers to XMUX input
   wire [47:0] 	      XMUX_CAT;
   wire [29:0] 	      XMUX_A_CAT;
   wire [17:0] 	      XMUX_B_CAT;

   // wires for multiplier inputs
   wire [24:0] 	      AMULT;
   wire [17:0] 	      BMULT;

`ifndef PB_TYPE

   parameter ACASCREG = 1;
   parameter ADREG = 1;
   parameter ALUMODEREG = 1;
   parameter AREG = 1;
   parameter BCASCREG = 1;
   parameter BREG = 1;
   parameter CARRYINREG = 1;
   parameter CARRYINSELREG = 1;
   parameter CREG = 1;
   parameter DREG = 1;
   parameter INMODEREG = 1;
   parameter MREG = 1;
   parameter OPMODEREG = 1;
   parameter PREG = 1;
   parameter A_INPUT = "DIRECT";
   parameter B_INPUT = "DIRECT";
   parameter USE_DPORT = "FALSE";
   parameter USE_MULT = "MULTIPLY";
   parameter USE_SIMD = "ONE48";
   parameter AUTORESET_PATDET = "NO_RESET";
   parameter MASK = 001111111111111111111111111111111111111111111111;
   parameter PATTERN = 000000000000000000000000000000000000000000000000;
   parameter SEL_MASK = "MASK";
   parameter SEL_PATTERN = "PATTERN";
   parameter USE_PATTERN_DETECT = "NO_PATDET";


   // Figure 2-10 OPMODE, ALUMODE, CARRYINSEL
   wire [6:0] 	      OPMODE_REG;
   wire [6:0] 	      OPMODE_MUX_OUT;

   NREG #(.NBITS(7)) opmode_reg (.D(OPMODE), .Q(OPMODE_REG), .CE(CECTRL), .CLK(CLK), .RESET(RSTCTRL));
   OPMODE_MUX #(.S(OPMODEREG)) opmode_mux (.BYPASS(OPMODE), .REG(OPMODE_REG), .O(OPMODE_MUX_OUT));

   // ALUMODE register
   wire [3:0]	      ALUMODE_REG;
   wire [3:0] 	      ALUMODE_MUX_OUT;

   NREG #(.NBITS(4)) alu_reg (.D(ALUMODE), .Q(ALUMODE_REG), .CE(CEALUMODE), .CLK(CLK), .RESET(RSTALUMODE));
   ALUMODE_MUX #(.S(ALUMODEREG)) alumode_mux (.BYPASS(ALUMODE), .REG(ALUMODE_REG), .O(ALUMODE_MUX_OUT));

   wire [2:0] 	      CARRYINSEL_REG;
   wire [2:0] 	      CARRYINSEL_MUX_OUT;

   NREG #(.NBITS(3)) carryinsel_reg (.D(CARRYINSEL), .Q(CARRYINSEL_REG), .CE(CECTRL), .CLK(CLK), .RESET(RSTCTRL));
   CARRYINSEL_MUX #(.S(CARRYINSELREG)) carryseling_mux (.BYPASS(CARRYSELIN), .REG(CARRYINSEL_REG), .O(CARRYINSEL_MUX_OUT));

   wire 	      CIN;
   CARRYINSEL_LOGIC #(.MREG(MREG), .CARRYINREG(CARRYINREG)) carryinsel_logic (.CARRYIN(CARRYIN), .CARRYCASCIN(CARRYCASCIN), .CARRYCASCOUT(CARRYCASCOUT), .A(A), .B(B), .P(P), .PCIN(PCIN), .CARRYINSEL(CARRYINSEL), .CIN(CIN),
									     .RSTALLCARRYIN(RSTALLCARRYIN), .CECARRYIN(CECARRYIN), .CEM(CEM), .CLK(CLK));

   // INMODE register and bypass mux
   wire [4:0] 	      INMODE_REG;
   wire [4:0] 	      INMODE_MUX_OUT;

   NREG #(.NBITS(5)) inmode_reg (.D(INMODE), .Q(INMODE_REG), .CE(CEINMODE), .CLK(CLK), .RESET(RSTINMODE));
   INMODE_MUX #(.S(INMODEREG)) inmode_mux(.BYPASS(INMODE), .REG(INMODE_REG), .O(INMODE_MUX_OUT));

   // input register blocks for A, B, D
   DUAL_AD_PREADDER dual_ad_preadder (.A(A), .ACIN(ACIN), .D(D), .INMODE(INMODE_MUX_OUT),
				      .ACOUT(ACOUT), .XMUX(XMUX_A_CAT), .AMULT(AMULT),
				      .CEA1(CEA1), .CEA2(CEA2), .RSTA(RSTA), .CED(CED), .CEAD(CEAD), .RSTD(RSTD), .CLK(CLK));
   DUAL_B_REG dualb_reg (.B(B), .BCIN(BCIN), .INMODE(INMODE_MUX_OUT),
			 .BCOUT(BCOUT), .XMUX(XMUX_B_CAT), .BMULT(BMULT),
			 .CEB1(CEB1), .CEB2(CEB2), .RSTB(RSTB), .CLK(CLK));

   // concatenate for XMUX
   assign XMUX_CAT = {XMUX_A_CAT, XMUX_B_CAT};

   // Multiplier output
   wire [85:0] 	      MULT_OUT;
   wire [85:0] 	      MULT_REG;
   wire [85:0] 	      MULT_MUX_OUT;

   // 25bit by 18bit multiplier
   MULT25X18 mult25x18 (.A(AMULT), .B(BMULT), .OUT(MULT_OUT));
   NREG #(.NBITS(86)) mult_reg (.D(MULT_OUT), .Q(MULT_REG), .CLK(CLK), .CE(CEM), .RESET(RSTM));
   MULT_MUX #(.S(MREG)) mult_mux (.BYPASS(MULT_OUT), .REG(MULT_REG), .O(MULT_MUX_OUT));

   // Figure 2-9
   wire [47:0] 	      C_REG;
   wire [47:0] 	      CMUX_OUT;

   NREG #(.NBITS(48)) creg (.D(C), .Q(C_REG), .CLK(CLK), .CE(CEC), .RESET(RSTC));
   CREG_MUX #(.S(CREG)) creg_mux (.BYPASS(C), .REG(C_REG), .O(CMUX_OUT));

   // signals from muxes to ALU unit
   wire [47:0] 	      X;
   wire [47:0] 	      Y;
   wire [47:0] 	      Z;

   // TODO(elmsfu): take in full OPMODE to check for undefined behaviors
   // See table 2-7 for X mux selection
   DSP48_XMUX dsp48_xmux (.ZEROS(48'h000000000000), .M({5'b00000, MULT_MUX_OUT[85:43]}), .P(P), .AB_CAT(XMUX_CAT), .S(OPMODE_MUX_OUT[1:0]), .O(X));

   // See table 2-8 for Y mux selection
   DSP48_YMUX dsp48_ymux (.ZEROS(48'h000000000000), .M({5'b00000, MULT_MUX_OUT[42:0]}), .ONES(48'hFFFFFFFFFFFF), .C(CMUX_OUT), .S(OPMODE_MUX_OUT[3:2]), .O(Y));

   // See table 2-9 for Z mux selection
   // Note: Z mux actually has 7 inputs but 2 and 4 are both P
   DSP48_ZMUX dsp48_zmux (.ZEROS(48'h000000000000), .PCIN(PCIN), .P(P), .C(CMUX_OUT), .P2(P), .PCIN_UPSHIFT({ {17{PCIN[47]}}, PCIN[47:17]}), .P_UPSHIFT({ {17{P[47]}}, P[47:17]}), .S(OPMODE_MUX_OUT[6:4]), .O(Z));

   // See table 2-10 for 3 input behavior
   // See table 2-13 for 2 input behavior
   ALU alu (.X(X), .Y(Y), .Z(Z), .ALUMODE(ALUMODE_MUX_OUT), .CARRYIN(CIN), .MULTSIGNIN(MULTSIGNIN), .OUT(P), .CARRYOUT(CARRYOUT), .MULTSIGNOUT(MULTSIGNOUT));

   assign PCOUT = P;

`endif //  `ifndef PB_TYPE

endmodule // DSP48E1