以下为加法树结构示意图:
//16位加法树乘法器
module add_tree16(
Clk,DataInA,DataInB,Start,DataOut,DataOk
);
input Clk;
input Start;
input [15:0]DataInA;
input [15:0]DataInB;
output DataOk;
output [31:0]DataOut;
reg [15:0]temp0;
reg [15:0]temp1;
reg [15:0]temp2;
reg [15:0]temp3;
reg [15:0]temp4;
reg [15:0]temp5;
reg [15:0]temp6;
reg [15:0]temp7;
reg [15:0]temp8;
reg [15:0]temp9;
reg [15:0]temp10;
reg [15:0]temp11;
reg [15:0]temp12;
reg [15:0]temp13;
reg [15:0]temp14;
reg [15:0]temp15;
reg [31:0]outReg;
reg DataOkReg;
reg [2:0]cnt;
wire [31:0]sum0_0,sum0_1,sum0_2,sum0_3,sum0_4,sum0_5,sum0_6,sum0_7; //第〇层加法结果
wire [31:0]sum1_0,sum1_1,sum1_2,sum1_3; //第一层加法结果
wire [31:0]sum2_0,sum2_1; //第二层加法结果
wire [31:0]sum3; //第三层加法结果
//16位数据选通控制器
function [15:0]mult16x1;
input [15:0]operand;
input sel;
mult16x1 = sel ? (operand) : 'b0;
endfunction
always @ (posedge Clk) begin
if(Start == 1) begin
temp0 <= 0;
temp1 <= 0 ;
temp2 <= 0 ;
temp3 <= 0 ;
temp4 <= 0 ;
temp5 <= 0 ;
temp6 <= 0 ;
temp7 <= 0 ;
temp8 <= 0 ;
temp9 <= 0 ;
temp10 <= 0 ;
temp11 <= 0 ;
temp12 <= 0 ;
temp13 <= 0 ;
temp14 <= 0 ;
temp15 <= 0 ;
cnt <= 1;
DataOkReg <= 0;
outReg <= 0;
end else if(cnt == 1) begin
temp0 <= mult16x1(DataInA,DataInB[0]);
temp1 <= mult16x1(DataInA,DataInB[1]);
temp2 <= mult16x1(DataInA,DataInB[2]);
temp3 <= mult16x1(DataInA,DataInB[3]);
temp4 <= mult16x1(DataInA,DataInB[4]);
temp5 <= mult16x1(DataInA,DataInB[5]);
temp6 <= mult16x1(DataInA,DataInB[6]);
temp7 <= mult16x1(DataInA,DataInB[7]);
temp8 <= mult16x1(DataInA,DataInB[8]);
temp9 <= mult16x1(DataInA,DataInB[9]);
temp10<= mult16x1(DataInA,DataInB[10]);
temp11<= mult16x1(DataInA,DataInB[11]);
temp12<= mult16x1(DataInA,DataInB[12]);
temp13<= mult16x1(DataInA,DataInB[13]);
temp14<= mult16x1(DataInA,DataInB[14]);
temp15<= mult16x1(DataInA,DataInB[15]);
cnt <= 2;
outReg<= 0;
DataOkReg <= 0;
end else if(cnt ==2) begin
outReg <= sum3 ;
cnt <=4;
DataOkReg <= 1;
end else if(cnt ==4) begin
DataOkReg <= 0;
cnt <= 0;
end else begin cnt <= 0; end
end
assign sum0_0 = {16'b0 , temp0 } + {15'b0 , temp1 , 1'b0};
assign sum0_1 = {14'b0 , temp2 , 2'b0} + {13'b0 , temp3 , 3'b0};
assign sum0_2 = {12'b0 , temp4 , 4'b0} + {11'b0 , temp5 , 5'b0};
assign sum0_3 = {10'b0 , temp6 , 6'b0} + { 9'b0 , temp7 , 7'b0};
assign sum0_4 = { 8'b0 , temp8 , 8'b0} + { 7'b0 , temp9 , 9'b0};
assign sum0_5 = { 6'b0 , temp10,10'b0} + { 5'b0 , temp11 ,11'b0};
assign sum0_6 = { 4'b0 , temp12,12'b0} + { 3'b0 , temp13 ,13'b0};
assign sum0_7 = { 2'b0 , temp14,14'b0} + { 1'b0 , temp15 ,15'b0};
assign sum1_0 = sum0_0 + sum0_1 ;
assign sum1_1 = sum0_2 + sum0_3 ;
assign sum1_2 = sum0_4 + sum0_5 ;
assign sum1_3 = sum0_6 + sum0_7 ;
assign sum2_0 = sum1_0 + sum1_1;
assign sum2_1 = sum1_2 + sum1_3;
assign sum3 = sum2_0 + sum2_1 ;
assign DataOut = outReg;
assign DataOk = DataOkReg;
endmodule
以下是testbench文件
module add_tree16_tb;
wire DataOk ;
wire [31:0]DataOut ;
reg [15:0]DataInA ;
reg [15:0]DataInB ;
reg Clk ;
reg Start ;
add_tree16 DUT(
.DataOk (DataOk ) ,
.DataOut (DataOut ) ,
.DataInA (DataInA ) ,
.DataInB (DataInB ) ,
.Clk (Clk ) ,
.Start (Start )
);
reg [2:0] mycnt;
initial begin
Clk = 1'b0;
forever #50 Clk = !Clk;
end
initial begin
Start = 1 ;
DataInA = 0;
DataInB = 0;
mycnt = 0;
forever #400 Start = !Start;
end
always @(posedge Clk)
begin
mycnt<=mycnt + 1;
if(mycnt==7) begin
DataInA <= DataInA + 100;
DataInB <= DataInB + 10;
mycnt<= 0;
end
end
endmodule