安德鲁

[笔记].算法 - 乘积累加器.[Verilog]

0
阅读(4498)

出自Quartus II自带模板。

1. 无符号数乘积累加器


01 moduleunsigned_multiply_accumulate
02 #(parameterWIDTH=8)
03 (
04 inputclk, aclr, clken, sload,
05 input[WIDTH-1:0] dataa,
06 input[WIDTH-1:0] datab,
07 outputreg[2*WIDTH-1:0] adder_out
08 );
09
10 // Declare registers and wires
11 reg[WIDTH-1:0] dataa_reg, datab_reg;
12 regsload_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 assignmulta = 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@ (posedgeclkorposedgeaclr)
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 elseif(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 modulesigned_multiply_accumulate
02 #(parameterWIDTH=8)
03 (
04 inputclk, aclr, clken, sload,
05 inputsigned [WIDTH-1:0] dataa,
06 inputsigned [WIDTH-1:0] datab,
07 outputregsigned [2*WIDTH-1:0] adder_out
08 );
09
10 // Declare registers and wires
11 regsigned [WIDTH-1:0] dataa_reg, datab_reg;
12 regsload_reg;
13 regsigned [2*WIDTH-1:0] old_result;
14 wiresigned [2*WIDTH-1:0] multa;
15
16 // Store the results of the operations on the current data
17 assignmulta = 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@ (posedgeclkorposedgeaclr)
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 elseif(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 modulesum_of_four_multiply_accumulate
02 #(parameterINPUT_WIDTH=18,parameterOUTPUT_WIDTH=44)
03 (
04 inputclk, ena,
05 input[INPUT_WIDTH-1:0] dataa, datab, datac, datad,
06 input[INPUT_WIDTH-1:0] datae, dataf, datag, datah,
07 outputreg[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 assignmult_sum = (dataa * datab + datac * datad) + (datae * dataf + datag * datah);
16
17 // Store the value of the accumulation
18 always@ (posedgeclk)
19 begin
20 if(ena == 1)
21 begin
22 dataout <= dataout + mult_sum;
23 end
24 end
25 endmodule

4. 带异步复位的四乘积累加器


01 modulesum_of_four_multiply_accumulate_with_asynchronous_reset
02 #(parameterINPUT_WIDTH=18,parameterOUTPUT_WIDTH=44)
03 (
04 inputclk, ena, aclr,
05 input[INPUT_WIDTH-1:0] dataa, datab, datac, datad,
06 input[INPUT_WIDTH-1:0] datae, dataf, datag, datah,
07 outputreg[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 assignmult_sum = (dataa * datab + datac * datad) + (datae * dataf + datag * datah);
16
17 // Store the value of the accumulation
18 always@ (posedgeclk)
19 begin
20 if(ena == 1)
21 begin
22 dataout <= ((aclr == 1) ? 0 : dataout) + mult_sum;
23 end
24 end
25 endmodule
Baidu
map