基本算法
与分时复用的移位相加类似,取消分时复用,使用面积换时间,使用流水线设计,流水线填满后可以一个时钟周期计算出一个结果
- 分别计算乘数的移位结果,并与被乘数对应位相与
- 使用加法树将结果相加
RTL代码
移位部分
固定移位单元代码如下,当被乘数第n位为1时,输出乘数移位向左移位n位的结果
module shift_unit #(
parameter WIDTH = 4,
parameter SHIFT_NUM = 0
)(
input clk, // Clock
input rst_n, // Asynchronous reset active low
input shift_valid,
input shift_mask,
input [WIDTH - 1:0]shift_din,
output reg [2 * WIDTH - 1:0]shift_dout
);
wire [2 * WIDTH - 1:0]shift_din_ext;
assign shift_din_ext = {(WIDTH)'(0),shift_din};
always @ (posedge clk or negedge rst_n) begin
if(~rst_n) begin
shift_dout <= 'b0;
end else if((shift_valid == 1'b1) && (shift_mask == 1'b1)) begin
shift_dout <= shift_din_ext << SHIFT_NUM;
end else begin
shift_dout <= 'b0;
end
end
endmodule
移位器代码如下,使用生成语句生成位宽个移位器
module parallel_shifter #(
parameter WIDTH = 4
)(
input clk, // Clock
input rst_n, // Asynchronous reset active low
input mult_valid,
input [WIDTH - 1:0]mult1,mult2,
output [(WIDTH ** 2) * 2 - 1:0]shift_dout
);
genvar a;
generate
for (a = 0; a < WIDTH; a = a + 1) begin:shifter_layer