我知道如何设计一个4x4阵列乘法器,但如果我遵循相同的逻辑,编码就会变得乏味。
除了8个全加器和4个半加器外,64 x 64位还需要多少个全加器和半加器。如何减少部分产品的数量?有没有简单的方法来解决这个问题?
答案 0 :(得分:9)
每当繁琐地编写重复模式时,您应该使用生成语句:
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要求使用流水线版本 - 就在这里。这次在数组部分的always-region中使用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
请注意,对于许多综合工具,也可以在非流水线加法器之后添加(宽度)寄存器级,并让工具寄存器平衡传递进行流水线操作。
答案 1 :(得分:0)
[how to] reduce the number of partial products?
修改Booth编码的一种常见方法:
以更复杂的附加选择为代价,它的数量至少减少了近一半。
以最简单的形式,考虑其中一个操作数(例如 b )的三个相邻位的组(重叠1),然后选择 0,a,2a,-2a 或 -a 作为加号。
答案 2 :(得分:-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 multiplyied 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