基于移位相加法的乘法器的实现

一、移位相加法实现乘法的原理

  从被乘数的左边(最低位)开始,如果第 i 位为 1,则乘数左移 i (i = 0,1,2,······,size -1)位之后与之前的值相加,若最低位为 0 ,则保持不变,直至被乘数的最高位。

  如:a = b = 101

  a x b = 25

  sum = 0;

  101 第0位为 1, sum = sum + a  << 0

  101 第1位为 0 ,sum = sum 

    101 第3位为 1, sum = sum + a << 2

二、移位相加法实现8bit乘法器源码

  1 // *********************************************************************************
  2 // Project Name : mul_add
  3 // Email        : 
  4 // Create Time  : 2020/07/18 20:20
  5 // Module Name  : mul_add
  6 // editor        : qing
  7 // Version        : Rev1.0.0
  8 // *********************************************************************************
  9 
 10 module mul_add(
 11     input                    sclk        ,
 12     input                    s_rst_n        ,
 13 
 14     input                    start        ,
 15     input        [7:0]        x            ,  // 乘数
 16     input        [7:0]        y            ,  // 被乘数
 17 
 18     output     reg    [15:0]        result        
 19     );
 20 
 21 //========================================================================
 22 // =========== Define Parameter and Internal signals =========== 
 23 //========================================================================/
 24 reg        [7:0]    cnt                 ;
 25 reg        [15:0]    x_r                    ;  // 乘数的中间变量    
 26 reg                flag                ;
 27 reg        [15:0]    result_r            ;
 28 
 29 //=============================================================================
 30 //****************************     Main Code    *******************************
 31 //=============================================================================
 32 
 33 always @(*) begin
 34     x_r = {8'd0,x};
 35 end
 36 
 37 always @(posedge sclk or negedge s_rst_n) begin  // cnt
 38     if(!s_rst_n)
 39         cnt <= 0;
 40     else if(start == 1'b1)
 41         cnt <= 7;
 42     else if(cnt == 0)
 43         cnt <= cnt;
 44     else
 45         cnt <= cnt - 1'b1;
 46 end
 47 
 48 always @(posedge sclk or negedge s_rst_n) begin
 49     if(!s_rst_n)
 50         flag <= 1'b0;
 51     else if(start == 1'b1)
 52         flag <= 1'b1;
 53     else if(cnt == 0)
 54         flag <= 1'b0;
 55 end
 56 
 57 always @ (posedge sclk or negedge s_rst_n) begin
 58     if(s_rst_n == 1'b0) begin
 59          result_r <= 0;
 60     end
 61     else if(flag == 1'b1)begin
 62         case(cnt)
 63             8'd7:begin
 64                 if(y[0] == 1'b1)
 65                      result_r <=  result_r + x_r;
 66                 else
 67                      result_r <=  result_r;
 68             end
 69             8'd6:begin
 70                 if(y[1] == 1'b1)
 71                      result_r <=  result_r + (x_r << 1);
 72                 else
 73                      result_r <=  result_r;
 74             end
 75             8'd5:begin
 76                 if(y[2] == 1'b1)
 77                      result_r <=  result_r + (x_r << 2);
 78                 else
 79                      result_r <=  result_r;
 80             end
 81             8'd4:begin
 82                 if(y[3] == 1'b1)
 83                      result_r <=  result_r + (x_r << 3);
 84                 else
 85                      result_r <=  result_r;
 86             end
 87             8'd3:begin
 88                 if(y[4] == 1'b1)
 89                      result_r <=  result_r + (x_r << 4);
 90                 else
 91                      result_r <=  result_r;
 92             end
 93             8'd2:begin
 94                 if(y[5] == 1'b1)
 95                      result_r <=  result_r + (x_r << 5);
 96                 else
 97                      result_r <=  result_r;
 98             end
 99             8'd1:begin
100                 if(y[6] == 1'b1)
101                      result_r <=  result_r + (x_r << 6);
102                 else
103                      result_r <=  result_r;
104             end
105             8'd0:begin
106                 if(y[7] == 1'b1)
107                      result_r <=  result_r + (x_r << 7);
108                 else
109                      result_r <=  result_r;
110             end
111             default:begin
112                  result_r <= 0;
113             end
114         endcase
115     end
116     else
117          result_r <= 0;
118 end       
119 
120 //assign result = ((cnt == 0) && (flag == 1'b1)) ? result_r : result;
121 
122 always @(posedge sclk or negedge s_rst_n) begin
123     if(!s_rst_n)
124         result <= 0;
125     else if(cnt == 0 && flag == 1'b1)
126         result <= result_r;
127 end
128 
129 
130 endmodule
View Code

testbench:

 1 `timescale 1ns/1ps
 2 module mul_add_tb;
 3     reg                sclk        ;
 4     reg                s_rst_n        ;
 5     reg                start        ;
 6     reg        [7:0]    x            ;
 7     reg        [7:0]    y            ;
 8     wire    [15:0]    result        ;
 9 
10 mul_add mul_add_inst(
11     .sclk        (sclk        ),
12     .s_rst_n    (s_rst_n    ),
13     .start        (start        ),
14     .x            (x            ),
15     .y            (y            ),
16     .result        (result        )
17     );
18 
19 initial
20     sclk = 1'b0;
21     always #10 sclk = ~sclk;
22 
23 initial
24     begin
25         #1;
26         s_rst_n = 1'b0;
27         x = 8'd0;
28         y = 8'd0;
29         start = 1'b0;
30         #21;
31         s_rst_n = 1'b1;
32         #21;
33 
34         x = 8'd4;
35         y = 8'd5;
36         start = 1'b1;
37         #25;
38         start = 1'b0;
39 
40         #200;
41         x = 8'd22;
42         y = 8'd30;
43         #31;
44         start = 1'b1;
45         #25;
46         start = 1'b0;
47 
48     end
49 endmodule
View Code

Modelsim仿真结果:

 移位相加法实现乘法的优点是占用的资源较少;缺点是速度比较慢,一个结果的输出需要花费多个时钟周期,在高位宽乘法运算中极为明显

该乘法器所占用的资源是所有类型乘法器中最少的,在低速的信号处理中有广泛的使用(还未完全理解)

 1 module mul_add(
 2     input                    sclk        ,
 3     input                    s_rst_n        ,
 4 
 5     //input                    start        ,
 6     input        [7:0]        x            ,  // 乘数
 7     input        [7:0]        y            ,  // 被乘数
 8 
 9     output reg    [15:0]        result        
10     );
11 
12 //========================================================================
13 // =========== Define Parameter and Internal signals =========== 
14 //========================================================================/
15 reg        [7:0]    cnt                 ;
16 reg        [15:0]    x_r                    ;  // 乘数的中间变量    
17 reg        [7:0]    y_r                    ;  // 被乘数的中间变量
18 reg        [15:0]    result_r            ;  // 运算结果的中间变量
19 reg        [2:0]    state                 ;  //     
20 
21 parameter         S0        =    3'd0    ;
22 parameter         S1        =    3'd1    ;    
23 parameter         S2        =    3'd2    ;    
24 
25 //=============================================================================
26 //****************************     Main Code    *******************************
27 //=============================================================================
28 
29 
30 
31 always @ (posedge sclk or negedge s_rst_n) begin
32     if(s_rst_n == 1'b0) begin
33         result <= 0;
34         cnt <= 0;
35         y_r <= 0;
36         state <= S0;
37     end
38     else begin
39         case(state)
40             S0:begin
41                 x_r <= {8'd0,x};
42                 y_r <= y;
43                 cnt <= 0;
44                 result_r <= 0;
45                 state <= S1;
46             end
47 
48             S1:begin
49                 if(cnt == 7)
50                     state <= S2;
51                 else begin
52                     if(y_r[0] == 1'b1)
53                         result_r <= result_r + x_r; // 和左移零位相似
54                     else
55                         result_r <= result_r;
56                         y_r <= y_r >> 1;    // 被乘数右移一位
57                         x_r <= x_r << 1;    // 乘加一次后,被乘数左移一位
58                         cnt <= cnt + 1'b1;
59                         state <= S1;
60                 end
61             end
62 
63             S2:begin
64                 result <= result_r;
65                 state <= S0;
66             end
67             default:;
68         endcase
69     end        
70 end
71 endmodule
View Code

原文地址:https://www.cnblogs.com/571328401-/p/13341391.html