问题遇到的现象和发生背景
quartus prime 21综合时只将部分子模块中的乘法器用DSP实现
操作环境、软件版本等信息
软件版本:Quartus Prime 21.4
在full_mul_level4中例化了多个mul,每个mul中有多个乘法器,但只有u0_mul中的乘法器在综合时用到了DSP,并且综合结果很不正常,full_mul_level4为1024bit的karatsuba大整数乘法器,不应该这么小。可能是什么原因呢。真心请教
代码如下:
(*multstyle="dsp"*)module full_mul_level4( //384x384 or similar bits
clk,
rstn,
i_a,
i_b,
en0,
en1,
en2,
en3,
en4,
en5,
en6,
o_res
);
parameter A_WIDTH = 1024;
parameter B_WIDTH = 1024;
parameter R_WIDTH = 2048;
parameter DATA_IN_WIDTH = 64;
parameter DATA_OUT_WIDTH = 64;
input clk;
input rstn;
input [DATA_IN_WIDTH-1:0] i_a;
input [DATA_IN_WIDTH-1:0] i_b;
input en0;
input en1;
input en2;
input en3;
input en4;
input en5;
input en6;
output [DATA_OUT_WIDTH-1:0] o_res;
localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
localparam WIDTH_ODD = WIDTH % 2;
localparam WIDTH_HALF = (WIDTH - WIDTH_ODD) / 2;
localparam H_WIDTH = WIDTH_HALF + WIDTH_ODD;
localparam L_WIDTH = WIDTH_HALF;
localparam F_WIDTH = H_WIDTH + 1;
wire [A_WIDTH-1:0] a;
wire [B_WIDTH-1:0] b;
assign a = {16{i_a}};
assign b = {16{i_b}};
wire [L_WIDTH-1:0] a0;
wire [H_WIDTH-1:0] a1;
wire [L_WIDTH-1:0] b0;
wire [H_WIDTH-1:0] b1;
// a1 a0
//x b1 b0
//-------------------------
// a1b1 a1b0+a0b1 a0b0
// a1b0 + a0b1 = (a0+a1)(b0+b1) - a1b1 - a0b0
assign {a1, a0} = a;
assign {b1, b0} = b;
wire [L_WIDTH*2-1:0] a0b0_r5;
wire [H_WIDTH*2-1:0] a1b1_r5;
full_mul_level3 #(L_WIDTH, L_WIDTH) u0_mul (
.clk (clk),
.rstn (rstn),
.en0 (en0),
.en1 (en1),
.en2 (en2),
.en3 (en3),
.en4 (en4),
.a (a0),
.b (b0),
.res (a0b0_r5));
full_mul_level3 #(H_WIDTH, H_WIDTH) u1_mul (
.clk (clk),
.rstn (rstn),
.en0 (en0),
.en1 (en1),
.en2 (en2),
.en3 (en3),
.en4 (en4),
.a (a1),
.b (b1),
.res (a1b1_r5));
wire [F_WIDTH-1:0] a_fold = a0 + a1;
wire [F_WIDTH-1:0] b_fold = b0 + b1;
wire [F_WIDTH*2-1:0] temp0_r5;
full_mul_level3 #(F_WIDTH, F_WIDTH) u2_mul (
.clk (clk),
.rstn (rstn),
.en0 (en0),
.en1 (en1),
.en2 (en2),
.en3 (en3),
.en4 (en4),
.a (a_fold),
.b (b_fold),
.res (temp0_r5));
reg [L_WIDTH*2-1:0] a0b0_r6;
reg [H_WIDTH*2-1:0] a1b1_r6;
reg [F_WIDTH*2-1:0] temp0_r6;
always @(posedge clk)
if(en5) begin
a0b0_r6 <= a0b0_r5;
a1b1_r6 <= a1b1_r5;
temp0_r6 <= temp0_r5;
end
reg [L_WIDTH*2-1:0] a0b0_r7;
reg [H_WIDTH*2-1:0] a1b1_r7;
reg [F_WIDTH*2-1:0] tmp_r7;
always @(posedge clk) begin
if (en6) begin
tmp_r7 <= temp0_r6-a0b0_r6-a1b1_r6;
a0b0_r7 <= a0b0_r6;
a1b1_r7 <= a1b1_r6;
end
end
wire [WIDTH*2-1:0] r;
assign r = {{a1b1_r7, {(L_WIDTH){1'b0}}} + tmp_r7, {(L_WIDTH){1'b0}}} + a0b0_r7;
reg [R_WIDTH-1:0] res;
always @(posedge clk)
if(en6)
res <= r[R_WIDTH-1:0];
assign o_res = res[DATA_OUT_WIDTH-1:0];
endmodule
编译流程从上到下