8

我知道如何设计一个 4x4 数组乘法器,但如果我遵循相同的逻辑,编码就会变得乏味。

  • 4 x 4 - 16 部分产品
  • 64 x 64 - 4096 部分产品。

除了 8 个全加器和 4 个半加器,对于 64 x 64 位,我需要多少个全加器和半加器。如何减少部分产品的数量?有什么简单的方法可以解决这个问题吗?

4

3 回答 3

10

每当对重复模式进行繁琐的编码时,您都应该使用 generate 语句:

module array_multiplier(a, b, y);

parameter width = 8;
input [width-1:0] a, b;
output [width-1:0] y;

wire [width*width-1:0] partials;

genvar i;
assign partials[width-1 : 0] = a[0] ? b : 0;
generate for (i = 1; i < width; i = i+1) begin:gen
    assign partials[width*(i+1)-1 : width*i] = (a[i] ? b << i : 0) +
                                   partials[width*i-1 : width*(i-1)];
end endgenerate

assign y = partials[width*width-1 : width*(width-1)];

endmodule

我已经使用以下测试台验证了这个模块:http: //svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v

编辑:

正如@Debian 要求的流水线版本 - 就是这样。这次在数组部分的始终区域中使用 for 循环。

module array_multiplier_pipeline(clk, a, b, y);

parameter width = 8;

input clk;
input [width-1:0] a, b;
output [width-1:0] y;

reg [width-1:0] a_pipeline [0:width-2];
reg [width-1:0] b_pipeline [0:width-2];
reg [width-1:0] partials [0:width-1];
integer i;

always @(posedge clk) begin
    a_pipeline[0] <= a;
    b_pipeline[0] <= b;
    for (i = 1; i < width-1; i = i+1) begin
        a_pipeline[i] <= a_pipeline[i-1];
        b_pipeline[i] <= b_pipeline[i-1];
    end

    partials[0] <= a[0] ? b : 0;
    for (i = 1; i < width; i = i+1)
        partials[i] <= (a_pipeline[i-1][i] ? b_pipeline[i-1] << i : 0) +
                partials[i-1];
end

assign y = partials[width-1];

endmodule

请注意,对于许多综合工具,也可以在非流水线加法器之后添加(宽度)寄存器阶段,并让工具寄存器平衡通过进行流水线操作。

于 2013-05-24T11:20:58.500 回答
0

[how to] reduce the number of partial products?
一种比较常用的方法是修改 Booth encoding
以更复杂的加数选择为代价,它至少几乎将它们的数量减半。
在其最简单的形式中,考虑来自操作数之一的三个相邻位(重叠一个)的组,例如b,并选择0、a、2a、-2a 或 <em>-a 作为加数。

于 2019-02-21T13:46:14.263 回答
-1

下面的代码仅生成预期输出的一半。

module arr_multi(a, b, y);      
parameter w = 8;       
input [w-1:0] a, b;                // w-width       
output [(2*w)-1:0] y;              // p-partials       
wire [(2*w*w)-1:0] p;        //assign width as input bits multiplied by 
 output bits
 genvar i;        
 assign p[(2*w)-1 : 0] = a[0] ? b : 0;  //first output size bits          
  generate            
      for (i = 1; i < w; i = i+1)       
         begin        
             assign p[(w*(4+(2*(i-1))))-1 : (w*2)*i] = (a[i]?b<<i :0) + p[(w*(4+(2* 
                (i-2))))-1 :(w*2)*(i-1)];       
         end     
   endgenerate          
  assign y=p[(2*w*w)-1:(2*w)*(w-1)];     //taking last output size bits            
   endmodule       
于 2019-08-04T06:40:06.013 回答