天天看点

verilog实现8位硬件乘法器(booth法补码一位乘法)一 设计思路二 verilog代码

  • 一 设计思路
    • (一)输入、输出
    • (二)booth法运算规则
    • (三)步骤
  • 二 verilog代码
    • (一)程序代码变量说明
    • (二)程序代码结构说明
      • 1. 乘法器
      • 2. 根据附加位和乘数末位进行加法操作
      • 3. 移位
      • 4. 截取最后一步的部分积和乘数作为输出
    • (三)程序代码
    • (四)时序模拟图

一 设计思路

(一)输入、输出

  1. 输入:两个用补码表示的二进制数(1位符号位+7位数值位)

    [X]补 = X0.X1X2…X7

    [Y]补 = Y0.Y1Y2…Y7

    其中,X0、Y0为符号位。

  2. 输出:两个补码相乘的结果(用补码表示:1位符号位+14位数值位)

(二)booth法运算规则

Yi+1与Yi为相邻的两位

  1. Yi+1 - Yi = 0(即Yi+1Yi = 00或11):部分积加0,右移1位
  2. Yi+1 - Yi = 1(即Yi+1Yi = 10):部分积加[X]补,右移1位
  3. Yi+1 - Yi = -1(即Yi+1Yi = 01):部分积加[-X]补,右移1位

共需要做n+1次累加,n次位移,第n+1次(最后一步)不移位。

(三)步骤

  1. 输入:单符号位补码表示的x、y
  2. 初始化:依据输入的x,得到双符号位补码表示的[x]补和[-x]补

    初始部分积为0,附加位为0,乘数为输入的y

  3. 依据booth公式,进行7次加法、移位操作。
  4. 最后进行1次加法操作,截取最后一步部分积和乘数相应位数,得到结果out。

二 verilog代码

(一)程序代码变量说明

input [7:0] x,y; // 输入:补码表示的乘数x和被乘数y,1位符号位+7位数值位
	output [14:0] out; // 输出:补码表示的x×y的结果,1位符号位+14位数值位

	wire [8:0] xx,_x; // xx:双符号位[x]补,_xx:双符号位[-x]补(2位符号位+7位数值位)
	wire [8:0] partial_product[0:15]; // 双符号位补码表示的部分积(2位符号位+7位数值位),一次乘法运算过程中共需要16次对于部分积的操作(加、移位)
	wire [7:0] multiplicator[0:7]; // 单符号位补码表示的乘数(1位符号位+7位数值位),一次乘法运算过程中共需要8次对于部分积的操作(移位)
	wire extra[0:7]; // 附加位,一次乘法运算过程中共需要8次对于附加位的操作(移位)
           

(二)程序代码结构说明

1. 乘法器

module multiplier(x,y,out); // 乘法器
           

2. 根据附加位和乘数末位进行加法操作

module add( // 根据附加位和乘数末位进行加法操作
	input [8:0] partial_product,xx,_x,
	input [7:0] multiplicator,
	input extra,
	output [8:0] result);
           

3. 移位

module move(	// 移位
	input [8:0] partial_product_in,
	input [7:0] multiplicator_in,
	output [8:0] partial_product_out,
	output [7:0] multiplicator_out,
	output extra_out);
           

4. 截取最后一步的部分积和乘数作为输出

module cut( // 截取最后一步的部分积和乘数作为输出
	input [8:0] partial_product,
	input [7:0] multiplicator,
	output [14:0] out);
           

(三)程序代码

组合逻辑,booth法一位补码乘法

软件:Quartus II 9.0

module multiplier(x,y,out);
	input [7:0] x,y; // 1 bit for sign + 7 bit for number
	output [14:0] out; // 1 bit for sign + 14 bit for number
	
	wire [8:0] xx,_x; // 2 bit for sign + 7 bit for number
	wire [8:0] partial_product[0:15]; // 2 bit for sign + 7 bit for number
	wire [7:0] multiplicator[0:7]; // 1 bit for sign + 7 bit for number
	wire extra[0:7];

	assign xx = {x[7],x};
	assign _x = ~xx+1'b1;
	assign partial_product[0] = 0;
	assign multiplicator[0] = y;
	assign extra[0] = 0;
	
	add(partial_product[0],xx,_x,multiplicator[0],extra[0],partial_product[1]);
	move(partial_product[1],multiplicator[0],partial_product[2],multiplicator[1],extra[1]);
	
	add(partial_product[2],xx,_x,multiplicator[1],extra[1],partial_product[3]);
	move(partial_product[3],multiplicator[1],partial_product[4],multiplicator[2],extra[2]);
	
	add(partial_product[4],xx,_x,multiplicator[2],extra[2],partial_product[5]);
	move(partial_product[5],multiplicator[2],partial_product[6],multiplicator[3],extra[3]);
	
	add(partial_product[6],xx,_x,multiplicator[3],extra[3],partial_product[7]);
	move(partial_product[7],multiplicator[3],partial_product[8],multiplicator[4],extra[4]);
	
	add(partial_product[8],xx,_x,multiplicator[4],extra[4],partial_product[9]);
	move(partial_product[9],multiplicator[4],partial_product[10],multiplicator[5],extra[5]);
	
	add(partial_product[10],xx,_x,multiplicator[5],extra[5],partial_product[11]);
	move(partial_product[11],multiplicator[5],partial_product[12],multiplicator[6],extra[6]);
	
	add(partial_product[12],xx,_x,multiplicator[6],extra[6],partial_product[13]);
	move(partial_product[13],multiplicator[6],partial_product[14],multiplicator[7],extra[7]);
	
	add(partial_product[14],xx,_x,multiplicator[7],extra[7],partial_product[15]);
	
	cut(partial_product[15],multiplicator[7],out);
endmodule


module add(
	input [8:0] partial_product,xx,_x,
	input [7:0] multiplicator,
	input extra,
	output [8:0] result);
	
	wire [8:0] r1,r2;
	
	assign r1 = (extra==multiplicator[0]) ? 0 : xx;
	assign r2 = (!extra&multiplicator[0]) ? _x : r1;
	
	assign result = partial_product + r2;
endmodule


module move(
	input [8:0] partial_product_in,
	input [7:0] multiplicator_in,
	output [8:0] partial_product_out,
	output [7:0] multiplicator_out,
	output extra_out);
	
	assign extra_out = multiplicator_in[0];
	assign multiplicator_out = {partial_product_in[0],multiplicator_in[7:1]};
	assign partial_product_out = {partial_product_in[8],partial_product_in[8:1]};
endmodule


module cut(
	input [8:0] partial_product,
	input [7:0] multiplicator,
	output [14:0] out);
	
	assign out = {partial_product[7:0],multiplicator[7:1]};
endmodule
           

(四)时序模拟图

  1. 整数乘法

    数据类型选Signed Decimal

    verilog实现8位硬件乘法器(booth法补码一位乘法)一 设计思路二 verilog代码
  2. 定点小数乘法

    数据类型选Fractional

    verilog实现8位硬件乘法器(booth法补码一位乘法)一 设计思路二 verilog代码

继续阅读