java乘法器_乘法器verilog实现

今天重新补习了一下二进制原码,反码和补码之间的关系以及正数变负数,负数变正数之间的关系。瞬间感觉好晕,赶紧仔细研究:

原码就是符号位加上真值的绝对值。正数原码是其本身,负数符号位为1.

正数的反码和补码都是其本身,负数反码为符号位不变,其余各位依次取反;补码为符号位不变,其余各位依次取反后加1。

这都好理解,那一个正数怎么变为负数呢?

注意计算机内存储负数是其补码形式! 正数取反后加1就得到负数(其实是负数的补码),例如:7二进制为0111;取反后为1000;然后+1为1001=(-7)补码。

同理负数取反+1后得到正数的补码=正数本身。

好了理清了上述关系 下面实现一个booth算法乘法器:

booth算法其实就是一种位操作,直接上例子

bit[1]

bit[2]

位操作

0

0

无操作

0

1

+被乘数

1

0

-被乘数

1

1

无操作

例如4*2 被乘数为4(0100),乘数为2(0010),都为4bit,因此result应有9bit空间。

第一步:被乘数正数:0100 负数为:1100,result={4’d0,0010,0}

第二步:判断result[1:0] ,为00 则无操作,result向右移一位,补高位与原来高位一致为result={4’d0,0001,0}

第三步:判断result[1:0],为10则减被乘数,result[9:6]+4’b1100={1100,0001,0},result向右移一位,高位补1,result={1110,0000,1}

第四步:判断result[1:0],为01则加被乘数,result[9:6]+4’b0100={0010,0000,1},result向右移一位,高位补0,result={0001,0000,0}

第五步:判断result[1:0],为00则无操作,result向右移一位,高位补0,result={0000,0001,0}

第六步:最后结果取result[9:1]={0000,1000}=8;

中间判断次数为寄存器宽度,即4bit执行4次,然后去高8为最后结果。

下面为位宽8bit的booth乘法器verilog代码:

//-----------------------------------------------------------------------------//Title :

//Project : //-----------------------------------------------------------------------------//File : multiplier.v//Author : caoshan//Created : //Last modified : //-----------------------------------------------------------------------------//Description :-----------------------------------------------------------------------------//Copyright (c) by This model is the confidential and//proprietary property of and the possession or use of this//file requires a written license from .//------------------------------------------------------------------------------//Modification history :-----------------------------------------------------------------------------

module multiplier(/*autoarg*/

//Outputs

done_flag, mul_result,//Inputs

clk, rst_n, start_en, mul_cand_data, mul_data

);//parameter WIDTH = 8;//system interface

inputclk;inputrst_n;inputstart_en;input [7:0] mul_cand_data;input [7:0] mul_data;outputdone_flag;output [15:0] mul_result;/*autoinput*/

/*autooutput*/

/*autoreg*/

//Beginning of automatic regs (for this module's undeclared outputs)

regdone_flag;//reg [2*WIDTH-1:0] mul_result;//End of automatics

/*autowire*/

//===========================================================//state machine//=======================================================

parameter IDLE = 3'd0;

parameter LOCK_DATA = 3'd1;

parameter IMPROVE_MC = 3'd2;

parameter IMPROVE_M = 3'd3;

parameter JUDGE = 3'd4;

parameter MUL_MOV = 3'd5;

parameter MUL_END = 3'd6;

reg [2:0] curr_state;reg [2:0] next_state;reg [7:0] mul_cand_data_ff1;reg [7:0] mul_cand_data_ff2;reg [7:0] mul_data_ff;reg [16:0] mul_result_ff;reg [7:0] cnt;always @ (posedge clk or negedge rst_n)begin

if(rst_n == 0)

curr_state<=IDLE;elsecurr_state<=next_state;end

always @ (*)beginnext_state=IDLE;case(curr_state)

IDLE:begin

if(start_en)

next_state=LOCK_DATA;elsenext_state=IDLE;endLOCK_DATA:beginnext_state=IMPROVE_MC;endIMPROVE_MC:beginnext_state=IMPROVE_M;endIMPROVE_M:beginnext_state=JUDGE;endJUDGE:beginnext_state=MUL_MOV;endMUL_MOV:begin

if(cnt >= 7)

next_state=MUL_END;elsenext_state=JUDGE;endMUL_END:beginnext_state=IDLE;end

default: next_state =IDLE;endcase //case (curr_state)

end //always @ (*)//-------------------------------------//state machine change

always@(posedge clk or negedge rst_n)begin

if(rst_n==0)beginmul_cand_data_ff1<= 0;

mul_cand_data_ff2<= 0;

mul_data_ff<= 0;end

else if(curr_state == IMPROVE_MC)beginmul_cand_data_ff1<=mul_cand_data;

mul_cand_data_ff2<= ~mul_cand_data + 1'b1;

mul_data_ff <=mul_data;end

end

always @ (posedge clk or negedge rst_n)begin

if(rst_n == 0)

mul_result_ff<= 0;else if(curr_state ==IMPROVE_M)

mul_result_ff<= {8'd0,mul_data_ff,1'b0};else if(curr_state == JUDGE)begin

if(mul_result_ff[1:0]==2'b01)

mul_result_ff <= {(mul_result_ff[16:9] + mul_cand_data_ff1[7:0]),mul_result_ff[8:0]};else if(mul_result_ff[1:0]== 2'b10)

mul_result_ff <= {(mul_result_ff[16:9] + mul_cand_data_ff2[7:0]),mul_result_ff[8:0]};end

else if(curr_state ==MUL_MOV)

mul_result_ff<= {mul_result_ff[16],mul_result_ff[16:1]};end //always @ (posedge clk or negedge rst_n)

always @ (posedge clk or negedge rst_n)begin

if(rst_n == 0)

cnt<= 0;else if((curr_state == MUL_MOV)&&(cnt < 7))

cnt<= cnt + 1'b1;

else if((cnt >=7 )&&(curr_state ==MUL_END))

cnt<= 0;end

always@(posedge clk or negedge rst_n)begin

if(rst_n == 0)

done_flag<= 0;else if(curr_state ==MUL_END)

done_flag<= 1;elsedone_flag<= 0;end

reg[16:0] mul_result_ff2;always @ (posedge clk or negedge rst_n)begin

if(rst_n == 0)

mul_result_ff2<= 0;else if(curr_state ==MUL_END)

mul_result_ff2<=mul_result_ff;end

assign mul_result = mul_result_ff2[16:1];endmodule //

testbench:

//-----------------------------------------------------------------------------//Title :

//Project : //-----------------------------------------------------------------------------//File : test_bench.v//Author : cs//Created : //Last modified : //-----------------------------------------------------------------------------//Description :-----------------------------------------------------------------------------//Copyright (c) by This model is the confidential and//proprietary property of and the possession or use of this//file requires a written license from .//------------------------------------------------------------------------------//Modification history :-----------------------------------------------------------------------------

moduletestbench();regclk;regrst_n;regstart_en;reg [7:0] mul_cand_data;reg [7:0] mul_data;wiredone_flag;wire [15:0] mul_result;//------------------------------------------------------------------------------

multiplier u_multiplier(/*autoinst*/

//Outputs

.done_flag (done_flag),

.mul_result (mul_result[15:0]),//Inputs

.clk (clk),

.rst_n (rst_n),

.start_en (start_en),

.mul_cand_data (mul_cand_data[7:0]),

.mul_data (mul_data[7:0]));always #20 clk = ~clk;initial

beginclk= 0;

rst_n= 0;

#100rst_n= 1;end

reg [3:0] i;always@(posedge clk or negedge rst_n)begin

if(rst_n==0)beginstart_en<= 0;

mul_cand_data<= 0;

mul_data<= 0;

i<= 0;end

else

case(i)0:begin

if(done_flag)beginstart_en= 0;

i<= i + 1'b1;

end

else beginstart_en<= 1'b1;

mul_cand_data <= 8'd5;

mul_data <= 8'd8;

end

end //case: 0

1:begin

if(done_flag)beginstart_en= 0;

i<= i + 1'b1;

end

else beginstart_en<= 1'b1;

mul_cand_data <= 8'b11111100;

mul_data <= 8'd4;

end

end //case: 1

2:begin

if(done_flag)beginstart_en= 0;

i<= i + 1'b1;

end

else beginstart_en<= 1'b1;

mul_cand_data <= 8'd127;

mul_data <= 8'b10000001;

end

end //case: 2

3:begin

if(done_flag)beginstart_en= 0;

i<= i + 1'b1;

end

else beginstart_en<= 1'b1;

mul_cand_data <= 8'b10000001;

mul_data <= 8'b10000001;

end

end //case: 3

4:begini<=4'd4;

mul_cand_data <= 0;

mul_data <= 0;

end

endcase //case (i)

end //always@ (posedge clk or negedge rst_n)

initial

begin$fsdbDumpfile ("./testbench.fsdb");

$fsdbDumpvars;// end

endmodule

仿真结果

d23589b0a284599c1eb80156fbf1b302.png

2015年4月9日

cslegend

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值