16位乘法器单时钟加法树结构

以下为加法树结构示意图:

//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

你可能感兴趣的:(芯片与逻辑)