主要参考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 addinput [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 pathparameter AREG = 1;parameter BREG = 1; // 0 - 2wire 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 = cinput r, // reset accumulator to c + a*binput 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 - 2parameter BREG = 1; // 0 - 2wire 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 addwire [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)beginp_low4 <= p_low3[16:0];endassign p[16:0] = p_low4;initialbegin$dumpfile("dump.vcd");$dumpvars(0);endendmodule