基础004_V7-DSP Slice
主要参考ug479.pdf。之前的文章:FIR调用DSP48E_05。本文主要记录基本用法。
一、DSP48核
A-参数说明
- instrctions,多个功能,通过sel选用
目前没发现C勾选与否,有何影响。
如上图所示,结果3拍后输出:
其他参数:
B-IP调用
生成IP核,参数设置完毕直接调用即可
1 2 3 4 5 6 7 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | `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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | // 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | `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 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步