# 全并行流水线移位相加乘法器

## 基本算法

• 分别计算乘数的移位结果，并与被乘数对应位相与
• 使用加法树将结果相加

## RTL代码

### 移位部分

```module shift_unit #(
parameter WIDTH = 4,
parameter SHIFT_NUM = 0
)(
input clk,    // Clock
input rst_n,  // Asynchronous reset active low
input shift_valid,
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
shift_unit #(
.WIDTH(WIDTH),
.SHIFT_NUM(a)
) u_shift_unit (
.clk(clk),    // Clock
.rst_n(rst_n),  // Asynchronous reset active low
.shift_valid(mult_valid),
.shift_din(mult1),

.shift_dout(shift_dout[a * 2 * WIDTH +: 2 * WIDTH])
);
end
endgenerate

endmodule```

### 加法部分

```module adder_layer #(
)(
input clk,    // Clock
input rst_n,  // Asynchronous reset active low

);

genvar i;
generate
always @ (posedge clk or negedge rst_n) begin
if(~rst_n) begin
sum_reg <= 'b0;
end else begin
sum_reg <= sum;
end
end
end
endgenerate

endmodule```

```module adder_tree #(
parameter LAYER_NUM = 4,
)(
input clk,    // Clock
input rst_n,  // Asynchronous reset active low

);

genvar i;
generate
for(i = LAYER_NUM;i > 0;i = i - 1)begin:adder_layer_def
wire [(2 ** i) * (MIN_ADDER_WIDTH + LAYER_NUM - i) - 1:0]layer_din;
wire [2 ** (i - 1) * (MIN_ADDER_WIDTH + LAYER_NUM - i + 1) - 1:0]layer_dout;
if(i == LAYER_NUM) begin
end else begin
assign layer_din = adder_layer_def[i + 1].layer_dout;
end
.clk(clk),    // Clock
.rst_n(rst_n),  // Asynchronous reset active low
);
end
endgenerate

endmodule```

### 顶层

```module shift_adder #(
parameter LOG2_WIDTH = 2
)(
input clk,    // Clock
input rst_n,  // Asynchronous reset active low

input [2 ** LOG2_WIDTH - 1:0]mult1,mult2,
input din_valid,

output [(2 ** LOG2_WIDTH) * 2 - 1:0]dout
);

parameter WIDTH = 2 ** LOG2_WIDTH;

wire [(WIDTH ** 2) * 2 - 1:0]shift_dout;
parallel_shifter #(
.WIDTH(WIDTH)
) u_parallel_shifter (
.clk(clk),    // Clock
.rst_n(rst_n),  // Asynchronous reset active low

.mult_valid(din_valid),
.mult1(mult1),
.mult2(mult2),

.shift_dout(shift_dout)
);

wire [LOG2_WIDTH + 2 * WIDTH:0]adder_dout;
.LAYER_NUM(LOG2_WIDTH),
.clk(clk),    // Clock
.rst_n(rst_n),  // Asynchronous reset active low

);
assign dout = adder_dout[WIDTH * 2 - 1:0];

endmodule```

## 测试

```module mult_tb (
);

parameter LOG2_WIDTH = 2;
parameter WIDTH = 2 ** LOG2_WIDTH;

logic clk,rst_n;
logic multiplier_valid;
logic [WIDTH - 1:0]multiplier1;
logic [WIDTH - 1:0]multiplier2;

logic [2 * WIDTH - 1:0]product;

.LOG2_WIDTH(LOG2_WIDTH)
) dut (
.clk(clk),    // Clock
.rst_n(rst_n),  // Asynchronous reset active low

.mult1(multiplier1),
.mult2(multiplier2),
.din_valid(multiplier_valid),

.dout(product)
);

initial begin
clk = 1'b0;
forever begin
#50 clk = ~clk;
end
end

initial begin
rst_n = 1'b1;
#5 rst_n = 1'b0;
#10 rst_n = 1'b1;
end

initial begin
{multiplier_valid,multiplier1,multiplier2} = 'b0;
repeat(100) begin
@(negedge clk);
multiplier1 = (WIDTH)'(\$urandom_range(0,2 ** WIDTH));
multiplier2 = (WIDTH)'(\$urandom_range(0,2 ** WIDTH));
multiplier_valid = 1'b1;
end
\$stop();
end

reg [WIDTH - 1:0]mult11,mult12,mult13;
reg [WIDTH - 1:0]mult21,mult22,mult23;
reg [2 * WIDTH - 1:0]exp;

always @ (posedge clk or negedge rst_n) begin
if(~rst_n) begin
{mult11,mult12,mult13,mult21,mult22,mult23} <= 'b0;
end else begin
mult13 <= mult12;
mult12 <= mult11;
mult11 <= multiplier1;

mult23 <= mult22;
mult22 <= mult21;
mult21 <= multiplier2;
end
end

initial begin
exp = 'b0;
forever begin
@(negedge clk);
exp = mult13 * mult23;
if(exp == product) begin
\$display("successful");
end else begin
\$display("fail");
end
end
end
endmodule```

98 篇文章32 人订阅

0 条评论

## 相关文章

### IBM Watson提供的认知计算服务介绍

Cognitive Service Introduction Twitter:@huiwenhan Weibo:@huiwenhan Agenda Wats...

3578

10.8K3

### Android高效内存2：让图片占用尽可能少的内存

Android高效内存：让图片占用尽可能少的内存 一、让你的图片最小化 1.1 大图小图内存使用情况对比 大图：440 * 336    小图：220 * 16...

30411

1402

2452

3437

2291

1152

### 优化策略之Opt_design

opt_design [-retarget] [-propconst] [-sweep] [-bram_power_opt] [-remap]

3026

### #哆啦A梦

write('by dongdong', font=("Bradley Hand ITC", 30, "bold"))

1100