乘以 15 的改进方法是什么?
What is the improve way to multiplying by 15?
我正在尝试按以下方式实现乘以 15。
module mul15(
output [10:0] result,
input [3:0] a
);
assign result = a*15;
endmodule
但是有什么改进的方法可以将 a 乘以 15 吗?
我认为有两种方法是这样的
1.result = a<<4 -1;
2.result = {a,3'b1111_1111};
Ans 我认为最好的方法是 2。
但我也不确定综合方面。
更新:
如果我在 {a,3'b1111_1111} 处乘以 0 会怎样?这是 255 而不是 0。
有谁知道最好的方法吗?
更新
这样怎么样?
案例一
结果 = {a,8'b0}+ {a,7'b0}+ {a,6'b0}+ {a,5'b0}+ {a,4'b0}+ {a, 7'b0}+ {a,3'b0}+ {a,2'b0}+ {a,1'b0}+ a;
但它看起来使用了 8 个加法器。
案例2
结果=a<<8 -1
我不确定还有什么是最好的方法。
最干净的 RTL 版本如您在问题中所述:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
result = a * 4'd15;
end
endmodule
二进制的被乘数15是4'b1111;即 8 + 4 + 2 + 1.
它可以分解为 2 的这些幂的总和,而不是乘数。2 的幂只是桶式移位。这就是移位和加法乘数的工作方式。
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
// 8 4 2 1 =>15
result = (a<<3) + (a<<2) + (a<<1) + a;
end
endmodule
为了尽量减少所需的加法器数量,可以使用 CSD。从 16-1 中获得 15:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
// 16 - 1 =>15
result = (a<<4) - a;
end
endmodule
使用现代综合工具,这些都应该产生相同的结果。因此,拥有更具可读性的代码,可以向工具明确说明您的意图,使其可以根据需要自由优化。
总有a*16 - a
。 2 的幂的静态乘法在硬件中基本上是免费的;它只是 LSB 的硬编码 0。所以你只需要一个11位的全减器,就是一个全加器和一些反相器。
其他形式:
result = a<<4 - a;
result = {a,4'b0} - a; // unsigned full-subtractor
result = {a,4'b0} + ~a + 1'b1; // unsigned full-adder w/ carry in, 2's complement
result = {{3{a[3]}},a,4'b0} + ~{ {7{a[3]}}, a} + 1'b1; // signed full-adder w/ carry in, 2's complement
我正在尝试按以下方式实现乘以 15。
module mul15(
output [10:0] result,
input [3:0] a
);
assign result = a*15;
endmodule
但是有什么改进的方法可以将 a 乘以 15 吗?
我认为有两种方法是这样的
1.result = a<<4 -1;
2.result = {a,3'b1111_1111};
Ans 我认为最好的方法是 2。 但我也不确定综合方面。
更新:
如果我在 {a,3'b1111_1111} 处乘以 0 会怎样?这是 255 而不是 0。
有谁知道最好的方法吗?
更新 这样怎么样?
案例一
结果 = {a,8'b0}+ {a,7'b0}+ {a,6'b0}+ {a,5'b0}+ {a,4'b0}+ {a, 7'b0}+ {a,3'b0}+ {a,2'b0}+ {a,1'b0}+ a; 但它看起来使用了 8 个加法器。
案例2
结果=a<<8 -1
我不确定还有什么是最好的方法。
最干净的 RTL 版本如您在问题中所述:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
result = a * 4'd15;
end
endmodule
二进制的被乘数15是4'b1111;即 8 + 4 + 2 + 1.
它可以分解为 2 的这些幂的总和,而不是乘数。2 的幂只是桶式移位。这就是移位和加法乘数的工作方式。
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
// 8 4 2 1 =>15
result = (a<<3) + (a<<2) + (a<<1) + a;
end
endmodule
为了尽量减少所需的加法器数量,可以使用 CSD。从 16-1 中获得 15:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always @* begin
// 16 - 1 =>15
result = (a<<4) - a;
end
endmodule
使用现代综合工具,这些都应该产生相同的结果。因此,拥有更具可读性的代码,可以向工具明确说明您的意图,使其可以根据需要自由优化。
总有a*16 - a
。 2 的幂的静态乘法在硬件中基本上是免费的;它只是 LSB 的硬编码 0。所以你只需要一个11位的全减器,就是一个全加器和一些反相器。
其他形式:
result = a<<4 - a;
result = {a,4'b0} - a; // unsigned full-subtractor
result = {a,4'b0} + ~a + 1'b1; // unsigned full-adder w/ carry in, 2's complement
result = {{3{a[3]}},a,4'b0} + ~{ {7{a[3]}}, a} + 1'b1; // signed full-adder w/ carry in, 2's complement