我的新博客

booth乘法

booth乘法节省面积、速度较移位相加速度也更快。

一个例子:14乘以-5,乘数和被乘数都用5bit补码表示,结果有10bit表示。

14的补码:01110, -5的补码11011 ,正确结果为-70:11 1011 1010

image

使用一个状态机实现这个乘法,IDLE下初始化等待数据输入,再进行加法和移位,次数由输入位宽决定,最后数据输出。

程序代码如下:

   1:  // **************************************************************
   2:   
   3:   
   4:  // File name     :  booth.v
   5:  // Module name  :  BOOTH
   6:  // Full name     :   multiply based on booth's algorithm
   7:  //
   8:  // Author        :  Yang Li     
   9:  // Email         :  yangli0534@gmail.com
  10:  // Date          :   2013/11/24
  11:  // Version       :  V 1.0 
  12:  // 
  13:  //Abstract        : an implementation of multiplier based on booth's algorithm 
  14:   // multiplier ,multiplicand :2's complement
  15:  // 
  16:  // Modification history
  17:  // ------------------------------------------------------------------------------------------------------
  18:   
  19:  // *********************************************************************
  20:   
  21:   module booth
  22:   #(parameter WIDTH =8 )
  23:   (
  24:   
  25:       input wire             sys_clk,
  26:        input wire             sys_rst_n,
  27:        input wire [WIDTH-1:0] multiplicand,
  28:        input wire [WIDTH-1:0] multiplier,
  29:        input wire             data_av,
  30:        output reg            rfd,
  31:        output reg            rdy,
  32:        output reg [2*WIDTH-1:0] product,
  33:        output reg [2*WIDTH-1:0] product_r 
  34:   );
  35:   //*********************
  36:  //parameter DECLARATION
  37:  //*********************
  38:   localparam [3:0] IDLE  = 4'b0001, 
  39:                    ADD   = 4'b0010,
  40:                        // TAP   = 5'b00100,
  41:                         SHIFT = 4'b0100,
  42:                         DONE  = 4'b1000;
  43:   
  44:   //localparam N= log2(WIDTH) ;
  45:   localparam N=5;
  46:   localparam WIDTH_PROD = 2*WIDTH;
  47:  //*********************
  48:  //INNER SIGNAL DECLARATION
  49:  //*********************
  50:   reg [WIDTH-1:0] multiplicand_add, multiplicand_minus;//鍔犺涔樻暟锛屽噺琚箻鏁
  51:   reg [WIDTH-1:0] upper_r, lower_r;//楂樺崐鍜屼綆鍗
  52:   reg booth_r;  //booth bit
  53:   reg [3:0] state_curr, state_next;
  54:   reg [N-1:0] cnt_r;//
  55:   
  56:   reg [WIDTH-1:0] upper, lower;//楂樺崐鍜屼綆鍗
  57:   reg booth;  //booth bit
  58:   reg [N-1:0] cnt;//
  59:    //reg [WIDTH_PROD-1:0] product;
  60:   
  61:   always @(posedge sys_clk or negedge sys_rst_n)
  62:   begin: MULTIPLICAND 
  63:       if(!sys_rst_n)
  64:            begin
  65:                  multiplicand_add <= 0;
  66:                   multiplicand_minus <= 0;
  67:              end
  68:       else if(rfd)
  69:            begin
  70:                  multiplicand_add <= multiplicand;
  71:                   multiplicand_minus <= ~multiplicand + 1'b1;
  72:             end        
  73:   end  
  74:   
  75:   always @(posedge sys_clk or negedge sys_rst_n)
  76:   begin: STATE_CTRL
  77:       if(!sys_rst_n) begin
  78:            state_curr <= IDLE;
  79:              upper_r <= 0;
  80:              lower_r <= 0;
  81:              booth_r <=0;
  82:              cnt_r <= 0;
  83:              end
  84:        else begin
  85:             state_curr <= state_next;  
  86:              upper_r <= upper;
  87:              lower_r <= lower;
  88:              booth_r <= booth;
  89:              cnt_r <= cnt;
  90:             end    
  91:   end
  92:   
  93:   always @(*)
  94:   begin:STATE_NEXT 
  95:        state_next = state_curr;
  96:       case(state_curr)
  97:           IDLE: begin
  98:                  if(data_av)
  99:                       state_next = ADD;
 100:              end
 101:             ADD:  
 102:                  state_next = SHIFT;
 103:            // TAP:
 104:          //     state_next = SHIFT;        
 105:              SHIFT: begin
 106:                  if(cnt_r==WIDTH)
 107:                       state_next = DONE;
 108:                   else
 109:                       state_next = ADD;
 110:              end
 111:              DONE:  
 112:                  state_next = IDLE;
 113:               
 114:              default: state_next = IDLE;
 115:       endcase
 116:   
 117:   end
 118:   
 119:   always @*
 120:   begin: OUT 
 121:       rfd  = 1'b0;
 122:        rdy  = 1'b0;
 123:        product  = 0;
 124:        cnt  = cnt_r;
 125:        upper  = upper_r;
 126:        lower  = lower_r;
 127:        booth =booth_r;
 128:       case(state_curr)
 129:        IDLE: begin
 130:            rfd  = 1'b1;
 131:              cnt = 0;
 132:              upper = 0;
 133:              booth = 1'b0;
 134:              if(data_av)
 135:                  lower  = multiplier;
 136:        end
 137:        ADD: begin
 138:            cnt = cnt_r + 1'b1;
 139:            case({lower_r[0],booth_r})
 140:                 2'b00:  upper  = upper_r;                
 141:                  2'b01:  upper  = upper_r + multiplicand_add;  
 142:                  2'b10:  upper  = upper_r + multiplicand_minus;  
 143:                  2'b11:  upper  = upper_r;
 144:                  
 145:              endcase
 146:        end
 147:        //TAP: begin
 148:        
 149:       // end
 150:        
 151:        SHIFT: begin
 152:              
 153:                   
 154:                   upper  = {upper_r[WIDTH-1],upper_r[WIDTH-1:1]};
 155:                   lower  = {upper_r[0],lower_r[WIDTH-1:1]};
 156:                   booth  = lower_r[0];
 157:                    
 158:        end
 159:        
 160:        DONE: begin
 161:              product ={upper_r, lower_r};
 162:                rdy = 1'b1;
 163:        end
 164:        endcase
 165:        
 166:   end
 167:   
 168:    always @(posedge sys_clk or negedge sys_rst_n)
 169:    begin: register
 170:    if(!sys_rst_n)
 171:       product_r <= 0;
 172:    else if(rdy)
 173:       product_r <= product;
 174:    end
 175:    
 176:   endmodule
 177:   

仿真结果

image


 
Do first what you dread the most.

posted @ 2013-11-24 16:28  Leon#0534  阅读(1959)  评论(2编辑  收藏  举报

我的新博客

专注天线学习,欢迎交流 yangli0534@gmail.com - 创建于 2010年

我永远是茫茫EE领域的一名小学生。