2024年1月29日发(作者:)
改进Booth4位乘法器(verilog)(1)
原理本质还是Booth算法,也就是重新编码以后,来决定操作(移位或者加法运算).不过这次用的是牧猫同学介绍的改良Booth编码本,后来经过比较官方的定义应该叫”比特对编码”.只不过一次对乘数检测三个位,并生成一个两位代码来决定操作方式1)被乘数相加,2)移一位后相加/相减再移位3)仅仅移位运算…汗…截取百科里面的资料来说明吧.
判断位yi-1yiyi+1 操作内容
000
[zi+1]补=2-2[zi]补
001
[zi+1]补=2-2{[zi]补+[x]补}
010
[zi+1]补=2-2{[zi]补+[x]补}
011
[zi+1]补=2-2{[zi]补+2[x]补}
100
[zi+1]补=2-2{[zi]补+2[-x]补}
101
[zi+1]补=2-2{[zi]补+ [-x]补}
110
[zi+1]补=2-2{[zi]补+-x}补}
111
[zi+1]补=2-2[zi]补
由上表可见,操作中出现加2[x]补和加2[-x]补,故除右移两位的操作外,还有被乘数左移一位的操作;而加2[x]补和加2[-x]补,都可能因溢出而侵占双符号位,故部分积和被乘数采用三位符号位.
简化下来可以这么看
算法是比较简单的,这次笔记的重点在于体验一下数据通路控制器设计的思路.所以,仅仅是描写4位乘法器,当然,改良版的Booth算法的优点在4位运算中并不明
显,仅仅是减少了2次加法运算,然而n位数愈多,就会发现,加法运算的次数减少了n/2.
虽然这么简单,但是划分成了数据通道和控制器的确便于系统结构清晰,下图就是这次乘法器综合后结构.控制单元组织,协调和同步数据通道单元的操作,状态及控制单元产生装载,读取,移动存储内容的信号.
写乘法器的草稿之一如下图
首先,当然是研究Booth算法了,然后就是那一组数举例,对着每一次运算分析,理解算法每一步骤原因,再后就是画状态图,确定每一步的作用.然后就是写了…不过,这次写的时候,懂哥觉得难以平衡multiplier和multiplicant的移位和运算,于是参考了西里提书上的一个思路,就是在处理时序乘法器处理011(或者100)情况时,十分精巧地将被乘数移一位后和乘积相加,然后再移动一位,在这些动作之后,位置指针都同时到了下一位Yi中当两次移位后,正确地移到了运算结束后的位置.
丢状态图(真的就将就了嘛….word不好使)
然后丢程序
module mul(clk,
res_n,
start,
mul1,
mul2,
ready,
product);
parameter width=3'd4;
input clk,res_n;
input start;//signal to begin operate
input [width-1:0]mul1,mul2;//multiplier &multiplicant
output ready;//signal to end operate
output [2*width-1:0]product;
wire [2:0]Yi;
wire shift_2,shift_1,add,sub,load;
controller m1(clk,res_n,start,Yi,shift_1,shift_2,add,sub,load,ready);
datapath m2(clk,res_n,mul1,mul2,load,shift_1,shift_2,add,sub,Yi,product);
endmodule
改进Booth4位乘法器(Verilog)(2)
module controller(clk,
res_n,
start,
Yi,
shift_1,
shift_2,
add,
sub,
load,
ready);
parameter [8:0]
idle=0,
S1=9'b0000_0000_1,
S2=9'b0000_0001_0,
S3=9'b0000_0010_0,
S4=9'b0000_0100_0,
S5=9'b0000_1000_0,
S6=9'b0001_0000_0,
S7=9'b0010_0000_0,
S8=9'b0100_0000_0,
S9=9'b1000_0000_0;
input clk,res_n;
input start;
input [2:0]Yi;//from datapath to decide instructions
output shift_1,shift_2,add,sub,load;//instructions
output ready;
reg ready;
reg [8:0]current_S,next_S;
reg shift_1,shift_2,add,sub,load;
always@(posedge clk or negedge res_n)
begin
if(!res_n)
begin
current_S<=idle;
end
else current_S<=next_S;
end
always@(current_S or start or Yi)
begin
shift_2=0;
shift_1=0;
add=0;
sub=0;
load=0;
case(current_S)
idle:
begin
if(start)
begin
load=1;
next_S=S1;
end
else next_S=idle;//test if move out the "else"
end
S1:
begin
case(Yi)
3'b000:
begin
shift_2=1;
next_S=S2;
end
3'b010:
begin
add=1;
next_S=S3;
end
3'b100:
begin
shift_1=1;
next_S=S4;
end
3'b110:
begin
sub=1;
next_S=S3;
end
default:next_S=idle;
endcase
end
S2:
begin
case(Yi)
3'b000:
begin
shift_2=1;
next_S=S6;
end
3'b001:
begin
add=1;
next_S=S7;
end
3'b010:
begin
add=1;
next_S=S7;
end
3'b011:
begin
shift_1=1;
next_S=S8;
end
3'b100:
begin
shift_1=1;
next_S=S8;
end
3'b101:
begin
sub=1;
next_S=S7;
end
3'b110:
begin
sub=1;
next_S=S7;
end
3'b111:
begin
shift_2=1;
next_S=S6;
end
endcase
end
S3:
begin
shift_2=1;
next_S=S2;
end
S4:
begin
sub=1;
next_S=S5;
end
S5:
begin
shift_1=1;
next_S=S2;
end
S6:
begin
ready=1;
next_S=idle;
end
S7:
begin
shift_2=1;
next_S=S6;
end
S8:
begin
case(Yi[1:0])
3'b01:
begin
add=1;
next_S=S9;
end
3'b10:
begin
sub=1;
next_S=S9;
end
default:next_S=idle;
endcase
end
S9:
begin
shift_1=1;
next_S=S6;
end
default:next_S=idle;
endcase
end
endmodule
改进Booth4位乘法器(Verilog)(3)
module datapath(clk, res_n, mul1, mul2, load, shift_1, shift_2, add, sub,
Yi,product);
parameter width=3'd4;
input clk,res_n;
input [width-1:0]mul1,mul2;//multiplier &multiplicant for 4bit
input load,shift_1,shift_2,add,sub;//instructions from controller
output [2:0]Yi;//send to controller to decide instructions
output [2*width-1:0]product;
reg [width-1:0]multiplier;
reg [2*width-1:0]multiplicant,product;
reg Q;//the additon bit ;
assign Yi={multiplier[1:0],Q};
always@(posedge clk or negedge res_n)
begin
if(!res_n)
begin
multiplier<=0;multiplicant<=0;Q<=0;product<=0;
end
else if(load)
begin
case(mul1[width-1])//extent multiplicant
1:multiplicant<={4'b1111,mul1};//注意符号位的一起扩展!!
0:multiplicant<={4'b0000,mul1};
endcase
multiplier<=mul2;Q<=0;product<=0;
end
else if(shift_2)
begin
multiplier<=multiplier>>2;
multiplicant<=multiplicant<<2;
end
else if(shift_1)
begin
multiplier<=multiplier>>1;
multiplicant<=multiplicant<<1;
end
else if(add)
begin
product<=multiplicant+product;
end
else if(sub)
begin
product<=product-multiplicant;
end
end
endmodule
testbench
`timescale 1ns/1ns
module t_mul4;
parameter width=4'd4;
reg clk,res_n,start;
reg[width-1:0]mul1,mul2;
wire[2*width-1:0]product;
wire ready;
mul m(clk,res_n,start,mul1,mul2,ready,product);
initial
begin
clk=0;
res_n=1'b1;
mul1=4'b0111;
mul2=4'b1101;
#5 res_n=0;
#5 res_n=1'b1;
#5 start=1'b1;
#400 $stop;
end
always #5 clk=~clk;
endmodule
本文发布于:2024-01-29 17:23:38,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170652021817028.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |