[笔记].算法 - 乘积求和器.[Verilog]
0赞
发表于 2010/8/25 11:14:45
阅读(2058)
出自Quartus II自带模板。
1. 四乘积求和器
01 |
module sum_of_four_multipliers |
02 |
#( parameter WIDTH=18) |
03 |
( |
04 |
input clk, ena, |
05 |
input [WIDTH-1:0] dataa, datab, datac, datad, |
06 |
input [WIDTH-1:0] datae, dataf, datag, datah, |
07 |
output reg [2*WIDTH+1:0] dataout |
08 |
); |
09 |
10 |
always @ ( posedge clk) |
11 |
begin |
12 |
if (ena == 1) |
13 |
begin |
14 |
dataout <= (dataa * datab + datac * datad) + (datae * dataf + datag * datah); |
15 |
end |
16 |
end |
17 |
endmodule |
2. 带流水线寄存器的两乘积求和器
01 |
module sum_of_two_multipliers_pipeline |
02 |
#( parameter WIDTH=16) |
03 |
( |
04 |
input clock, aclr, |
05 |
input [WIDTH-1:0] dataa, datab, datac, datad, |
06 |
output reg [2*WIDTH:0] result |
07 |
); |
08 |
09 |
reg [WIDTH-1:0] dataa_reg, datab_reg, datac_reg, datad_reg; |
10 |
reg [2*WIDTH-1:0] mult0_result, mult1_result; |
11 |
12 |
always @ ( posedge clock or posedge aclr) begin |
13 |
if (aclr) begin |
14 |
dataa_reg <= {(WIDTH){ 1'b0 }}; |
15 |
datab_reg <= {(WIDTH){ 1'b0 }}; |
16 |
datac_reg <= {(WIDTH){ 1'b0 }}; |
17 |
datad_reg <= {(WIDTH){ 1'b0 }}; |
18 |
mult0_result <= {(2*WIDTH){ 1'b0 }}; |
19 |
mult1_result <= {(2*WIDTH){ 1'b0 }}; |
20 |
result <= {(2*WIDTH+1){ 1'b0 }}; |
21 |
end |
22 |
else begin |
23 |
dataa_reg <= dataa; |
24 |
datab_reg <= datab; |
25 |
datac_reg <= datac; |
26 |
datad_reg <= datad; |
27 |
mult0_result <= dataa_reg * datab_reg; |
28 |
mult1_result <= datac_reg * datad_reg; |
29 |
result <= mult0_result + mult1_result; |
30 |
end |
31 |
end |
32 |
33 |
endmodule |
3. 扫描链模式的四乘积求和器
01 |
module sum_of_four_multipliers_scan_chain |
02 |
#( parameter WIDTH=18) |
03 |
( |
04 |
input clk, ena, |
05 |
input [WIDTH-1:0] dataa, |
06 |
input [WIDTH-1:0] datab0, datab1, datab2, datab3, |
07 |
output reg [2*WIDTH+1:0] dataout |
08 |
); |
09 |
10 |
// Four scan chain registers |
11 |
reg [WIDTH-1:0] a0, a1, a2, a3; |
12 |
13 |
always @ ( posedge clk) |
14 |
begin |
15 |
if (ena == 1) |
16 |
begin |
17 |
18 |
// The scan chain (which mimics the behavior of a shift register) |
19 |
a0 <= dataa; |
20 |
a1 <= a0; |
21 |
a2 <= a1; |
22 |
a3 <= a2; |
23 |
24 |
// The order of the operands is important for correct inference |
25 |
dataout <= (a3 * datab3 + a2 * datab2) + (a1 * datab1 + a0 * datab0); |
26 |
end |
27 |
end |
28 |
endmodule |
4. 串连的八乘积求和器
01 |
module sum_of_eight_multipliers_chainout |
02 |
#( parameter WIDTH=18) |
03 |
( |
04 |
input clk, ena, |
05 |
input [WIDTH-1:0] a0, a1, a2, a3, a4, a5, a6, a7, |
06 |
input [WIDTH-1:0] b0, b1, b2, b3, b4, b5, b6, b7, |
07 |
output reg [2*WIDTH+1:0] dataout |
08 |
); |
09 |
10 |
// Declare wires |
11 |
wire [2*WIDTH+1:0] sum1, sum2; |
12 |
13 |
// Store the results of the first two sums |
14 |
assign sum1 = (a0 * b0 + a1 * b1) + (a2 * b2 + a3 * b3); |
15 |
assign sum2 = (a4 * b4 + a5 * b5) + (a6 * b6 + a7 * b7); |
16 |
17 |
always @ ( posedge clk) |
18 |
begin |
19 |
if (ena == 1) |
20 |
begin |
21 |
dataout <= sum1 + sum2; |
22 |
end |
23 |
end |
24 |
endmodule |
5. 带广泛的数据通路的两乘积求和器
01 |
module sum_of_two_multipliers_wide_datapath |
02 |
#( parameter WIDTH_A=36, WIDTH_B=18) |
03 |
( |
04 |
input clk, ena, |
05 |
input [WIDTH_A-1:0] a0, a1, |
06 |
input [WIDTH_B-1:0] b0, b1, |
07 |
output reg [WIDTH_A+WIDTH_B:0] dataout |
08 |
); |
09 |
10 |
always @ ( posedge clk) |
11 |
begin |
12 |
if (ena == 1) |
13 |
begin |
14 |
dataout <= a0 * b0 + a1 * b1; |
15 |
end |
16 |
end |
17 |
endmodule |