[笔记].算法 - 乘积累加器.[Verilog]
0赞
发表于 2010/8/24 12:29:15
阅读(4498)
出自Quartus II自带模板。
1. 无符号数乘积累加器
01 |
module unsigned_multiply_accumulate |
02 |
#( parameter WIDTH=8) |
03 |
( |
04 |
input clk, aclr, clken, sload, |
05 |
input [WIDTH-1:0] dataa, |
06 |
input [WIDTH-1:0] datab, |
07 |
output reg [2*WIDTH-1:0] adder_out |
08 |
); |
09 |
10 |
// Declare registers and wires |
11 |
reg [WIDTH-1:0] dataa_reg, datab_reg; |
12 |
reg sload_reg; |
13 |
reg [2*WIDTH-1:0] old_result; |
14 |
wire [2*WIDTH-1:0] multa; |
15 |
16 |
// Store the results of the operations on the current data |
17 |
assign multa = dataa_reg * datab_reg; |
18 |
19 |
// Store the value of the accumulation (or clear it) |
20 |
always @ (adder_out, sload_reg) |
21 |
begin |
22 |
if (sload_reg) |
23 |
old_result <= 0; |
24 |
else |
25 |
old_result <= adder_out; |
26 |
end |
27 |
28 |
// Clear or update data, as appropriate |
29 |
always @ ( posedge clk or posedge aclr) |
30 |
begin |
31 |
if (aclr) |
32 |
begin |
33 |
dataa_reg <= 0; |
34 |
datab_reg <= 0; |
35 |
sload_reg <= 0; |
36 |
adder_out <= 0; |
37 |
end |
38 |
else if (clken) |
39 |
begin |
40 |
dataa_reg <= dataa; |
41 |
datab_reg <= datab; |
42 |
sload_reg <= sload; |
43 |
adder_out <= old_result + multa; |
44 |
end |
45 |
end |
46 |
endmodule |
2. 有符号数乘积累加器
01 |
module signed_multiply_accumulate |
02 |
#( parameter WIDTH=8) |
03 |
( |
04 |
input clk, aclr, clken, sload, |
05 |
input signed [WIDTH-1:0] dataa, |
06 |
input signed [WIDTH-1:0] datab, |
07 |
output reg signed [2*WIDTH-1:0] adder_out |
08 |
); |
09 |
10 |
// Declare registers and wires |
11 |
reg signed [WIDTH-1:0] dataa_reg, datab_reg; |
12 |
reg sload_reg; |
13 |
reg signed [2*WIDTH-1:0] old_result; |
14 |
wire signed [2*WIDTH-1:0] multa; |
15 |
16 |
// Store the results of the operations on the current data |
17 |
assign multa = dataa_reg * datab_reg; |
18 |
19 |
// Store (or clear) old results |
20 |
always @ (adder_out, sload_reg) |
21 |
begin |
22 |
if (sload_reg) |
23 |
old_result <= 0; |
24 |
else |
25 |
old_result <= adder_out; |
26 |
end |
27 |
28 |
// Clear or update data, as appropriate |
29 |
always @ ( posedge clk or posedge aclr) |
30 |
begin |
31 |
if (aclr) |
32 |
begin |
33 |
dataa_reg <= 0; |
34 |
datab_reg <= 0; |
35 |
sload_reg <= 0; |
36 |
adder_out <= 0; |
37 |
end |
38 |
else if (clken) |
39 |
begin |
40 |
dataa_reg <= dataa; |
41 |
datab_reg <= datab; |
42 |
sload_reg <= sload; |
43 |
adder_out <= old_result + multa; |
44 |
end |
45 |
end |
46 |
endmodule |
3. 四乘积累加器
01 |
module sum_of_four_multiply_accumulate |
02 |
#( parameter INPUT_WIDTH=18, parameter OUTPUT_WIDTH=44) |
03 |
( |
04 |
input clk, ena, |
05 |
input [INPUT_WIDTH-1:0] dataa, datab, datac, datad, |
06 |
input [INPUT_WIDTH-1:0] datae, dataf, datag, datah, |
07 |
output reg [OUTPUT_WIDTH-1:0] dataout |
08 |
); |
09 |
10 |
// Each product can be up to 2*INPUT_WIDTH bits wide. |
11 |
// The sum of four of these products can be up to 2 bits wider. |
12 |
wire [2*INPUT_WIDTH+1:0] mult_sum; |
13 |
14 |
// Store the results of the operations on the current inputs |
15 |
assign mult_sum = (dataa * datab + datac * datad) + (datae * dataf + datag * datah); |
16 |
17 |
// Store the value of the accumulation |
18 |
always @ ( posedge clk) |
19 |
begin |
20 |
if (ena == 1) |
21 |
begin |
22 |
dataout <= dataout + mult_sum; |
23 |
end |
24 |
end |
25 |
endmodule |
4. 带异步复位的四乘积累加器
01 |
module sum_of_four_multiply_accumulate_with_asynchronous_reset |
02 |
#( parameter INPUT_WIDTH=18, parameter OUTPUT_WIDTH=44) |
03 |
( |
04 |
input clk, ena, aclr, |
05 |
input [INPUT_WIDTH-1:0] dataa, datab, datac, datad, |
06 |
input [INPUT_WIDTH-1:0] datae, dataf, datag, datah, |
07 |
output reg [OUTPUT_WIDTH-1:0] dataout |
08 |
); |
09 |
10 |
// Each product can be up to 2*INPUT_WIDTH bits wide. |
11 |
// The sum of four of these products can be up to 2 bits wider. |
12 |
wire [2*INPUT_WIDTH+1:0] mult_sum; |
13 |
14 |
// Store the results of the operations on the current inputs |
15 |
assign mult_sum = (dataa * datab + datac * datad) + (datae * dataf + datag * datah); |
16 |
17 |
// Store the value of the accumulation |
18 |
always @ ( posedge clk) |
19 |
begin |
20 |
if (ena == 1) |
21 |
begin |
22 |
dataout <= ((aclr == 1) ? 0 : dataout) + mult_sum; |
23 |
end |
24 |
end |
25 |
endmodule |