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

来源:互联网 发布:mac os 制作u盘启动盘 编辑:程序博客网 时间:2024/05/21 09:28

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

//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;endfunctionalways @ (posedge Clk) beginif(Start == 1) begintemp0 <= 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) begintemp0 <= 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; endendassign 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;endalways @(posedge Clk)      begin        mycnt<=mycnt + 1;        if(mycnt==7) begin          DataInA <= DataInA + 100;          DataInB <= DataInB + 10;          mycnt<= 0;        end      endendmodule

原创粉丝点击