C语言布斯乘法算法,布斯Booth算法带符号位的乘法verilog语言实现booth算法

Booth算法的推倒表示看不懂,举例说明:算法的计算过程。

求M*Q的值 M=5,Q=6

按二进制分解M和Q :M3M2M1M0×Q3Q2Q1Q0:

0110×0101

(有符号数用补码表示,最高位表示正负)

1、添加辅助位:A=0000  Q-1=0

2、控制逻辑判断:

Q0Q-1=01

时:A=A+M 然后 A、Q、Q-1算术右移

(AQQ-1整体右移 如:表中的第一次右移AQQ-1=1010 0101 0,符号位填1

A=1101,Q=0010,Q-1=1)

Q0Q-1=10 时:A=A-M

然后 A、Q、Q-1算术右移

补码加减:(A-M)补码=A补码+(-M)补码

Q0Q-1=00或11 时:A、Q、Q-1算术右移

补码右移:空位填1

3、Q有几位就做几次右移运算。(如:01000×011,做3次右移结束)

4、结果即为AQ(0001 1110,即 6×5=30)。

运算过程和结果

A

Q

Q-1

M

初值

0000

0101

0

0110

A-M

1010

0101

0

0110

A,Q,Q-1右移

1101

0010

1

0110

A+M

0011

0010

1

0110

A,Q,Q-1右移

0001

1001

0

0110

A-M

1011

1001

0

0110

A,Q,Q-1右移

1101

1100

1

0110

A+M

0011

1100

1

0110

A,Q,Q-1右移

0001

1110

0

0110

verilog算法过程:

`timescale 1ns/1ps

//-----------------------------//

//----有符号数乘法

//-----------------------------//

module Booth_mult #(

parameter DW = 8

)(

input clk,

input rst_n,

input data_i_en,

input [DW-1:0] mult_a,

input [DW-1:0] mult_b,

output reg data_o_en,

output reg [DW+DW-1:0] result

);

parameter S_IDLE = 3'd0;

parameter S_JUDGE = 3'd1;

parameter S_01_ADD_SHIF = 3'd2;

parameter S_10_SUB_SHIF = 3'd3;

parameter S_00_11_SHIF = 3'd4;

parameter S_DONE = 3'd5;

reg [DW-1:0] mult_a_r;

reg [DW-1:0] mult_b_r;

reg [DW-1:0] assist_data = 'b0;

reg assist_bit = 0;

reg [DW-1:0] shift_count = 0;

wire [1:0] ctrl_bits;

assign ctrl_bits = {mult_b_r[0],assist_bit};

reg [2:0] state_nxt,state_cur;

always @(posedge clk or negedge rst_n)begin

if(!rst_n)

state_cur <= 3'b0;

else

state_cur <= state_nxt;

end

wire is_s_idle = state_cur == 3'b0;

wire is_s_judge = state_cur == 3'b1;

wire is_s_01_add_shif = state_cur == 3'd2;

wire is_s_10_sub_shif = state_cur == 3'd3;

wire is_s_00_11_shif = state_cur == 3'd4;

wire is_s_done = state_cur == 3'd5;

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

mult_a_r <= 'b0;

else if(data_i_en)

mult_a_r <= mult_a;

else

mult_a_r <= mult_a_r;

end

always @(*) begin

case(state_cur)

S_IDLE : if(data_i_en == 1'b1)

state_nxt = S_JUDGE;

else

state_nxt = S_IDLE;

S_JUDGE : begin

if(shift_count == DW)

state_nxt = S_DONE;

else if(ctrl_bits == 2'b01)

state_nxt = S_01_ADD_SHIF;

else if(ctrl_bits == 2'b10)

state_nxt = S_10_SUB_SHIF;

else if(ctrl_bits == 2'b00 || ctrl_bits == 2'b11)

state_nxt = S_00_11_SHIF;

else

state_nxt = S_JUDGE;

end

S_01_ADD_SHIF : state_nxt = S_JUDGE;

S_10_SUB_SHIF : state_nxt = S_JUDGE;

S_00_11_SHIF : state_nxt = S_JUDGE;

S_DONE : state_nxt = S_IDLE;

default : state_nxt = 3'd0;

endcase

end

//------------shift_count移位计数器------------------//

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

shift_count <= 0;

else if(is_s_idle)

shift_count <= 0;

else if(is_s_judge)

shift_count <= shift_count + 'b1;

else

shift_count <= shift_count;

end

//--------assist_data reg 也就是辅助位A----------------//

wire [DW-1:0] ass_add_multa = is_s_01_add_shif ? (assist_data +

mult_a_r) : 0;

wire [DW-1:0] ass_sub_multa = is_s_10_sub_shif ? (assist_data -

mult_a_r) : 0;

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

assist_data <= 'b0;

else if(is_s_done)

assist_data <= 'b0;

else if(is_s_01_add_shif)

assist_data <= {ass_add_multa[DW-1],ass_add_multa[DW-1:1]};

else if(is_s_10_sub_shif)

assist_data <= {ass_sub_multa[DW-1],ass_sub_multa[DW-1:1]};

else if(is_s_00_11_shif)

assist_data <= {assist_data[DW-1],assist_data[DW-1:1]};

else

assist_data <= assist_data;

end

//------------------mult_b_r 也就是Q

--------------------------------//

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

mult_b_r <= 'b0;

else if(is_s_done)

mult_b_r <= 'b0;

else if(data_i_en)

mult_b_r <= mult_b;

else if(is_s_01_add_shif)

mult_b_r <= {ass_add_multa[0],mult_b_r[DW-1:1]};

else if(is_s_10_sub_shif)

mult_b_r <= {ass_sub_multa[0],mult_b_r[DW-1:1]};

else if(is_s_00_11_shif)

mult_b_r <= {assist_data[0],mult_b_r[DW-1:1]};

else

mult_b_r <= mult_b_r;

end

//-------------assist_bit

也就是Qn-1------------------------------------------------------------------//

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

assist_bit <= 1'b0;

else if(is_s_done)

assist_bit <= 1'b0;

else if(is_s_01_add_shif || is_s_10_sub_shif ||

is_s_00_11_shif)

assist_bit <= mult_b_r[0];

else

assist_bit <= assist_bit;

end

//---------------乘积={A,Q} =

{assist_data,mult_b_r}-------------------------//

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

result <= 'd0;

else if(is_s_done)

result <= {assist_data,mult_b_r};

else

result <= result;

end

//-----------------输出有效---------------------------------------------//

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

data_o_en <= 1'b0;

else if(is_s_idle)

data_o_en <= 1'b0;

else if(is_s_done)

data_o_en <= 1'b1;

else

data_o_en <= data_o_en;

end

endmodule

测试平台:

`timescale 1ns/1ps

`define BIT_DW 8 //8位乘法器

`define RANDOM_BS 2**(`BIT_DW-1)

module Booth_mult_tb;

reg clk,rst_n,data_i_en;

reg [5:0] mult_dw;

reg [`BIT_DW-1:0]mult_a,mult_b;

wire data_o_en;

wire [`BIT_DW+`BIT_DW-1:0] result;

always #5 clk = ~clk;

initial begin

clk = 0;

rst_n = 0;

mult_a = 0;

mult_b = 0;

data_i_en = 0;

#60 @(posedge clk);

rst_n = 1;

while(1) begin

data_i_en = 1;

mult_a = $random%`RANDOM_BS;

mult_b = $random%`RANDOM_BS;

@(posedge clk)

data_i_en = 0;

wait(data_o_en == 1'b1);

@(posedge clk)

if($signed(result) == $signed(mult_a)*$signed(mult_b))

begin

$display("mult_a = %d,mult_b = %d,result =

%d",$signed(mult_a),$signed(mult_b),$signed(result));

$display("\n test pass \n");

end

else begin

$display("mult_a = %d,mult_b = %d,result =

%d",$signed(mult_a),$signed(mult_b),$signed(result));

$display("\n test error \n");

#20;

$stop;

end

end

end

Booth_mult #(`BIT_DW) u_Booth_mult(

.clk(clk),

.rst_n(rst_n),

.data_i_en(data_i_en),

.mult_a(mult_a),

.mult_b(mult_b),

.data_o_en(data_o_en),

.result(result)

);

endmodule

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值