基础004_V7-DSP Slice

主要参考ug479.pdf。之前的文章:FIR调用DSP48E_05。本文主要记录基本用法。

一、DSP48核

  A-参数说明

  •  instrctions,多个功能,通过sel选用

目前没发现C勾选与否,有何影响。

如上图所示,结果3拍后输出:

其他参数:

  B-IP调用

 生成IP核,参数设置完毕直接调用即可

dsp48_ex dsp_inst(
.CLK(clk),
.A(a),
.B(b),
.C(c),
.P(p)
);

  

二、原语示例

主要参考pg148-dsp48 macro.pdf用到再细化补充。

  Ex1

// m = b * (a + d)
// p = c+m or p+m

`timescale 1ns / 1ps
 
// m = b * (a + d)
// p = c+m or p+m
module dsp48_wrap_f
  (
   input          clock,
   input          ce1,
   input          ce2,
   input          cem,
   input          cep,
   input signed [24:0]    a,
   input signed [17:0]    b,
   input signed [47:0]    c,
   input signed [24:0]    d, // this has two fewer pipe stages
   // X+Y is usually the multiplier output (M)
   // Z is either P, PCIN or C
   // bit 1:0: 0: Z+X+Y 3:Z-(X+Y) 1: -Z + (X+Y) 2: -1*(Z+X+Y+1)
   // bits 3:2, 0: Z=0, 1: Z=PCIN, 2: Z=P, 3: Z = C
   // bit 4: sub in pre add
   input [4:0]        mode,
   input signed [47:0]    pcin,
   output signed [47:0]   pcout,
   output signed [47-S:0] p);
 
   parameter S = 0;
 
   parameter USE_DPORT = "FALSE"; // enabling adds 1 reg to A path
   parameter AREG = 1;
   parameter BREG = 1; // 0 - 2
 
   wire signed [47:0]      dsp_p;
   assign p = dsp_p[47:S];
 
   DSP48E1
     #(
       .A_INPUT("DIRECT"),   // "DIRECT" "CASCADE"
       .B_INPUT("DIRECT"),   // "DIRECT" "CASCADE"
       .USE_DPORT(USE_DPORT),
       .USE_MULT("MULTIPLY"),// "MULTIPLY" "DYNAMIC" "NONE"
       .USE_SIMD("ONE48"),   // "ONE48" "TWO24" "FOUR12"
       // pattern detector - not used
       .AUTORESET_PATDET("NO_RESET"), .MASK(48'h3fffffffffff),
       .PATTERN(48'h000000000000), .SEL_MASK("MASK"),
       .SEL_PATTERN("PATTERN"), .USE_PATTERN_DETECT("NO_PATDET"),
       // register enables
       .ACASCREG(1),   // pipeline stages between A/ACIN and ACOUT (0, 1 or 2)
       .ADREG(1),      // pipeline stages for pre-adder (0 or 1)
       .ALUMODEREG(1), // pipeline stages for ALUMODE (0 or 1)
       .AREG(AREG),       // pipeline stages for A (0, 1 or 2)
       .BCASCREG(1),   // pipeline stages between B/BCIN and BCOUT (0, 1 or 2)
       .BREG(BREG),    // pipeline stages for B (0, 1 or 2)
       .CARRYINREG(1), // this and below are 0 or 1
       .CARRYINSELREG(1),
       .CREG(1),
       .DREG(1),
       .INMODEREG(1),
       .MREG(1),
       .OPMODEREG(1),
       .PREG(1))
   dsp48_i
     (
      // status
      .OVERFLOW(),
      .PATTERNDETECT(), .PATTERNBDETECT(),
      .UNDERFLOW(),
      // outs
      .CARRYOUT(),
      .P(dsp_p),
      // control
      .ALUMODE({2'd0, mode[1:0]}),
      .CARRYINSEL(3'd0),
      .CLK(clock),
      .INMODE({1'b0,mode[4],3'b100}),
      .OPMODE({1'b0,mode[3:2],4'b0101}),
      // signal inputs
      .A({5'd0,a}), // 30
      .B(b), // 18
      .C(c), // 48
      .CARRYIN(1'b0),
      .D(d), // 25
      // cascade ports
      .ACOUT(),
      .BCOUT(),
      .CARRYCASCOUT(),
      .MULTSIGNOUT(),
      .PCOUT(pcout),
      .ACIN(30'h0),
      .BCIN(18'h0),
      .CARRYCASCIN(1'b0),
      .MULTSIGNIN(1'b0),
      .PCIN(pcin),
      // clock enables
      .CEA1(ce1), .CEA2(ce2),
      .CEAD(1'b1),
      .CEALUMODE(1'b1),
      .CEB1(ce1), .CEB2(ce2),
      .CEC(1'b1),
      .CECARRYIN(1'b1),
      .CECTRL(1'b1), // opmode
      .CED(1'b1),
      .CEINMODE(1'b1),
      .CEM(cem), .CEP(cep),
      .RSTA(1'b0),
      .RSTALLCARRYIN(1'b0),
      .RSTALUMODE(1'b0),
      .RSTB(1'b0),
      .RSTC(1'b0),
      .RSTCTRL(1'b0),
      .RSTD(1'b0),
      .RSTINMODE(1'b0),
      .RSTM(1'b0),
      .RSTP(1'b0)
      );
 
endmodule // dsp48_wrap_f

  Ex2

/ /p = c + b * a 3 cycles if r else p = p + b * a

// p = c + b * a 3 cycles if r else p = p + b * a
module macc
  (
   input          clock,
   input [2:0]    ce, // bit 0 = a, 1 = b , 2 = c
   input          r, // reset accumulator to c + a*b
   input signed [24:0]    a,
   input signed [17:0]    b,
   input signed [47:0]    c,
   output signed [47-S:0] p;
 
   parameter S = 0;
   parameter AREG = 1; // 0 - 2
   parameter BREG = 1; // 0 - 2
 
   wire signed [47:0]      dsp_p;
   assign p = dsp_p[47:S];
 
   // X+Y is usually the multiplier output (M)
   // Z is either P, PCIN or C
   // bit 1:0: 0: Z+X+Y 3:Z-(X+Y) 1: -Z + (X+Y) 2: -1*(Z+X+Y+1)
   // bits 3:2, 0: Z=0, 1: Z=PCIN, 2: Z=P, 3: Z = C
   // bit 4: sub in pre add
   wire [4:0]  mode = {1'b0, r ? 2'b11 : 2'b10, 2'b00};
 
   DSP48E1
     #(
       .A_INPUT("DIRECT"),   // "DIRECT" "CASCADE"
       .B_INPUT("DIRECT"),   // "DIRECT" "CASCADE"
       .USE_DPORT("FALSE"),
       .USE_MULT("MULTIPLY"),// "MULTIPLY" "DYNAMIC" "NONE"
       .USE_SIMD("ONE48"),   // "ONE48" "TWO24" "FOUR12"
       // pattern detector - not used
       .AUTORESET_PATDET("NO_RESET"), .MASK(48'h3fffffffffff),
       .PATTERN(48'h000000000000), .SEL_MASK("MASK"),
       .SEL_PATTERN("PATTERN"), .USE_PATTERN_DETECT("NO_PATDET"),
       // register enables
       .ACASCREG(1),   // pipeline stages between A/ACIN and ACOUT (0, 1 or 2)
       .ADREG(1),      // pipeline stages for pre-adder (0 or 1)
       .ALUMODEREG(1), // pipeline stages for ALUMODE (0 or 1)
       .AREG(AREG),       // pipeline stages for A (0, 1 or 2)
       .BCASCREG(1),   // pipeline stages between B/BCIN and BCOUT (0, 1 or 2)
       .BREG(BREG),    // pipeline stages for B (0, 1 or 2)
       .CARRYINREG(1), // this and below are 0 or 1
       .CARRYINSELREG(1),
       .CREG(1),
       .DREG(1),
       .INMODEREG(1),
       .MREG(1),
       .OPMODEREG(1),
       .PREG(1))
   dsp48_i
     (
      // status
      .OVERFLOW(),
      .PATTERNDETECT(), .PATTERNBDETECT(),
      .UNDERFLOW(),
      // outs
      .CARRYOUT(),
      .P(dsp_p),
      // control
      .ALUMODE({2'd0, mode[1:0]}),
      .CARRYINSEL(3'd0),
      .CLK(clock),
      .INMODE({1'b0,mode[4],3'b100}),
      .OPMODE({1'b0,mode[3:2],4'b0101}),
      // signal inputs
      .A({5'd0,a}), // 30
      .B(b), // 18
      .C(c), // 48
      .CARRYIN(1'b0),
      .D(25'd0), // 25
      // cascade ports
      .ACOUT(),
      .BCOUT(),
      .CARRYCASCOUT(),
      .MULTSIGNOUT(),
      .PCOUT(),
      .ACIN(30'h0),
      .BCIN(18'h0),
      .CARRYCASCIN(1'b0),
      .MULTSIGNIN(1'b0),
      .PCIN(48'h0),
      // clock enables
      .CEA1(1'b1), .CEA2(ce[0]),
      .CEAD(1'b1),
      .CEALUMODE(1'b1),
      .CEB1(1'b1), .CEB2(ce[1]),
      .CEC(ce[2]),
      .CECARRYIN(1'b1),
      .CECTRL(1'b1), // opmode
      .CED(1'b1),
      .CEINMODE(1'b1),
      .CEM(1'b1), .CEP(1'b1),
      .RSTA(1'b0),
      .RSTALLCARRYIN(1'b0),
      .RSTALUMODE(1'b0),
      .RSTB(1'b0),
      .RSTC(1'b0),
      .RSTCTRL(1'b0),
      .RSTD(1'b0),
      .RSTINMODE(1'b0),
      .RSTM(1'b0),
      .RSTP(1'b0)
      );
 
endmodule

  Ex3:(35bit * 25bit,级联)

// wide multiply using 2x DSP48E1
// p = ((a * b) + c), 4 clock pipe delay

`timescale 1ns / 1ps

// wide multiply using 2x DSP48E1
// p = ((a * b) + c), 4 clock pipe delay
module mult_35x25
  (
   input 	        clock,
   input signed [24:0]  a,
   input signed [34:0]  b,
   input signed [47:0]  c,
   output signed [64:0] p);

   wire signed [29:0] low_acout;
   wire signed [47:0] low_pcout;
   wire [47:0] 	      p_low3;
   reg [16:0] 	      p_low4;

   DSP48E1 #(.A_INPUT("CASCADE"), .AREG(1), .BREG(2)) dsp48_high
     (
      // status
      .OVERFLOW(), .PATTERNDETECT(), .PATTERNBDETECT(), .UNDERFLOW(),
      // outs
      .P(p[64:17]), .CARRYOUT(),
      // control
      .ALUMODE(4'b0), .CARRYINSEL(3'd0),
      .CLK(clock),
      .INMODE(5'b00000),
      .OPMODE(7'b1010101), // a*b + pcin >> 17
      // signal inputs
      .A(30'b0), .B(b[34:17]), .C(48'b0), .CARRYIN(1'b0), .D(25'b0),
      // cascade ports
      .ACOUT(), .BCOUT(), .CARRYCASCOUT(), .MULTSIGNOUT(), .PCOUT(),
      .ACIN(low_acout), .BCIN(18'h0), .CARRYCASCIN(1'b0), .MULTSIGNIN(1'b0),
      .PCIN(low_pcout),
      // clock enables, resets
      .CEA1(1'b1), .CEA2(1'b1), .CEAD(1'b1), .CEALUMODE(1'b1),
      .CEB1(1'b1), .CEB2(1'b1), .CEC(1'b1), .CECARRYIN(1'b1),
      .CECTRL(1'b1), .CED(1'b1), .CEINMODE(1'b1), .CEM(1'b1), .CEP(1'b1),
      .RSTA(1'b0), .RSTALLCARRYIN(1'b0), .RSTALUMODE(1'b0),
      .RSTB(1'b0), .RSTC(1'b0), .RSTCTRL(1'b0), .RSTD(1'b0),
      .RSTINMODE(1'b0), .RSTM(1'b0), .RSTP(1'b0)
      );

   DSP48E1 #(.ACASCREG(1), .AREG(1), .BREG(1)) dsp48_low
     (
      // status
      .OVERFLOW(), .PATTERNDETECT(), .PATTERNBDETECT(), .UNDERFLOW(),
      // outs
      .P(p_low3), .CARRYOUT(),
      // control
      .ALUMODE(4'b0), .CARRYINSEL(3'd0),
      .CLK(clock),
      .INMODE(5'b00000), .OPMODE(7'b0110101),
      // signal inputs
      .A({{5{a[24]}},a}), .B({1'b0,b[16:0]}),
      .C(c),
      .CARRYIN(1'b0),
      .D(25'b0),
      // cascade ports
      .ACOUT(low_acout), .BCOUT(), .CARRYCASCOUT(), .MULTSIGNOUT(), .PCOUT(low_pcout),
      .ACIN(30'h0), .BCIN(18'h0), .CARRYCASCIN(1'b0), .MULTSIGNIN(1'b0), .PCIN(48'h0),
      // clock enables, resets
      .CEA1(1'b1), .CEA2(1'b1), .CEAD(1'b1), .CEALUMODE(1'b1),
      .CEB1(1'b1), .CEB2(1'b1), .CEC(1'b1), .CECARRYIN(1'b1),
      .CECTRL(1'b1), .CED(1'b1), .CEINMODE(1'b1), .CEM(1'b1), .CEP(1'b1),
      .RSTA(1'b0), .RSTALLCARRYIN(1'b0), .RSTALUMODE(1'b0),
      .RSTB(1'b0), .RSTC(1'b0), .RSTCTRL(1'b0), .RSTD(1'b0),
      .RSTINMODE(1'b0), .RSTM(1'b0), .RSTP(1'b0)
      );

   always @ (posedge clock)
     begin
	p_low4 <= p_low3[16:0];
     end

   assign p[16:0] = p_low4;

   initial
     begin
        $dumpfile("dump.vcd");
        $dumpvars(0);
     end


endmodule

  

posted @ 2018-02-12 09:38  LeeLIn。  阅读(1058)  评论(0编辑  收藏  举报