我试图按如下方式实现乘以15。
module mul15(
output [10:0] result,
input [3:0] a
);
assign result = a*15;
endmodule
但是有没有改进的方法乘以15?
我认为有两种方式可以这样
1.result = a<<< 4 -1;
2.result = {a,3' b1111_1111};
我认为最好的方法是2。 但我也不确定合成的方面。
有谁知道最好的方法?
更新 这样怎么样?
结果= {a,8' b0} + {a,7' b0} + {a,6' b0} + {a,5' b0} + {a,4&# 39; b0} + {a,7' b0} + {a,3' b0} + {a,2' b0} + {a,1' b0} + a; 但它看起来使用了8个加法器。
result = a<<< 8 -1
我不确定最好的方法是什么。
答案 0 :(得分:2)
最清晰的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
使用现代综合工具,这些都应该产生相同的结果。因此,具有更易读的代码可以为工具提供关于您的预期的明确指示,从而可以根据需要自由地进行优化。
答案 1 :(得分:2)
始终有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