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


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

      从被乘数的左边(最低位)开始,如果第 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

  • 相关阅读:
    容器的发展历程
    oracle数据库删除了表空间后连接数据库提示ORA-01033:ORACLE initialization or shutdown
    Oracle数据库忘记用户名和密码怎么办
    maven项目pom文件引入本地jar包并打包的配置
    Java 9 新特性,看这里就明白了
    springboot项目统一处理返回报文体
    在springboot中用实体类获取配置文件的属性值
    2017《面向对象程序设计》寒假作业二
    css 绝对定位元素居中显示
    js防抖
  • 原文地址:https://www.cnblogs.com/571328401-/p/13341391.html
Copyright © 2020-2023  润新知