安德鲁

[笔记].算法 - 乘积求和器.[Verilog]

0
阅读(2197)

出自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