向量乘法器设计

同样基于Wallace树乘法器,我们来构造向量乘法器。

在一些矩阵运算中经常用到向量的相乘运算,本例以4维向量为例子介绍向量乘法器的verilog HDL设计。

设向量a = (a1, a2, a3, a4), b = (b1, b2, b3, b4)。

a b的点乘为:a * b = a1 b1 + a2 b2 + a3 b3 + a4 b4,

即向量对应位置的值相乘,再相加。

原理十分简单,下面给出verilog HDL设计代码:

  1. //向量乘法器的设计  
  2. module vector(a1, a2, a3, a4, b1, b2, b3, b4, out);  
  3.     input [3:0] a1, a2, a3, a4;  
  4.     input [3:0] b1, b2, b3, b4;  
  5.     output [9:0] out; //a1b1+a2b2+a3b3+a4b4为10位  
  6.     wire [7:0] out1, out2, out3, out4;//乘积项a1b1为8位,a2b2,a3b3,a4b4同理为8位  
  7.     wire [8:0] out5, out6 ;//同理a3b3+a4b4为9位,a1b1+a2b2为9位  
  8.     wire [9:0] out; //a1b1+a2b2+a3b3+a4b4为10位  
  9.       
  10.     //wallace树乘法器例化部分,得到乘积项  
  11.     wallace m1(.x(a1), .y(b1), .out(out1)); //out1 == a1b1  
  12.     wallace m2(.x(a2), .y(b2), .out(out2)); //out2 == a2b2  
  13.     wallace m3(.x(a3), .y(b3), .out(out3)); //out3 == a3b3  
  14.     wallace m4(.x(a4), .y(b4), .out(out4)); //out4 == a4b4  
  15.       
  16.     assign out5 = out1 + out2; //a1b1+a2b2  
  17.     assign out6 = out3 + out4; //a3b3+a4b4  
  18.     assign out = out5 + out6; //a1b1+a2b2+a3b3+a4b4  
  19.       
  20. endmodule  
  21.   
  22. //wallace树乘法器模块  
  23. module wallace(x,y,out);  
  24.     parameter size = 4; //定义参数,乘法器的位数  
  25.     input [size - 1 : 0] x,y; //输入y是乘数,x是被乘数  
  26.     output [2*size - 1 : 0] out;  
  27.     wire [size*size - 1 : 0] a; //a为部分积  
  28.     wire [1 : 0] b0, b1; //第一级的输出,包含进位  
  29.     wire [1 : 0] c0, c1, c2, c3; //第二级的输出,包含进位  
  30.     wire [5 : 0] add_a, add_b; //第三极的输入  
  31.     wire [6 : 0] add_out; //第三极的输出  
  32.     wire [2*size - 1 : 0] out; //乘法器的输出(组合逻辑)  
  33.       
  34.     assign a = {x[3],x[2],x[3],x[1],x[2],x[3],x[0],x[1],  
  35.                 x[2],x[3],x[0],x[1],x[2],x[0],x[1],x[0]}  
  36.                 &{y[3],y[3],y[2],y[3],y[2],y[1],y[3],y[2]  
  37.                 ,y[1],y[0],y[2],y[1],y[0],y[1],y[0],y[0]}; //部分积  
  38.     hadd U1(.x(a[8]), .y(a[9]), .out(b0));  //2输入半加器(第一级)  
  39.     hadd U2(.x(a[11]), .y(a[12]), .out(b1));//第一级  
  40.     hadd U3(.x(a[4]), .y(a[5]), .out(c0)); //第二级  
  41.       
  42.     fadd U4(.x(a[6]), .y(a[7]), .z(b0[0]), .out(c1)); //3输入全加器(第二级)  
  43.     fadd U5(.x(b1[0]), .y(a[10]), .z(b0[1]), .out(c2));  
  44.     fadd U6(.x(a[13]), .y(a[14]), .z(b1[1]), .out(c3));  
  45.       
  46.       
  47.     assign add_a = {c3[1],c2[1],c1[1],c0[1],c0[0],a[2]}; //加法器(第三极)  
  48.     assign add_b = {a[15],c3[0],c2[0],c1[0],a[3],a[1]};  
  49.     assign add_out = add_a + add_b;  
  50.     assign out = {add_out,a[0]};  
  51.   
  52. endmodule  
  53.   
  54. //全加器模块  
  55. module fadd(x, y, z, out);  
  56.     input x, y, z;  
  57.     output [1 : 0] out;  
  58.     assign out = x + y + z;   
  59. endmodule  
  60.   
  61. //半加器模块  
  62. module hadd(x, y, out);  
  63.     input x, y;  
  64.     output [1 : 0] out;  
  65.     assign out = x + y;  
  66. endmodule  

其测试文件verilog HDL代码如下:

  1. //向量乘法器测试文件  
  2. `timescale 1ns/1ps  
  3. module vector_tb;  
  4.     reg [3:0] a1, a2, a3, a4;  
  5.     reg [3:0] b1, b2, b3, b4;  
  6.     wire [9:0] out;  
  7.     initial  
  8.     begin  
  9.         a1 = 2'b10; a2 = 2'b10; a3 = 2'b10; a4 = 2'b10;  
  10.         b1 = 2'b10; b2 = 2'b10; b3 = 2'b10; b4 = 2'b10;  
  11.     end  
  12.       
  13.     vector U1(.a1(a1), .a2(a2), .a3(a3), .a4(a4), .b1(b1),  
  14.                 .b2(b2), .b3(b3), .b4(b4), .out(out));  
  15.   
  16. endmodule  
在modelsim中仿真波形如下:


想深入了解Wallace乘法器,可以到我的其他博客里查看专题。

猜你喜欢

转载自blog.csdn.net/reborn_lee/article/details/80316609