16位(8x8)硬件乘法器设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
EDA课程设计16位(8x8)硬件乘法器设计学校:华侨大学
学院:信息与工程学院
班级:10集成
姓名:项传煜
学号:1015251031
老师:凌朝东
目录
摘要
一.设计要求
二.正文
2.1. 系统设计
2.1.1 系统设计方案 (3)
2.1.2 系统设计原理 (4)
2.2. 各子模块设计
2.2.1 十进制加计数器设计 (5)
2.2.2 BCD码转二进制码BCD_B的设计 (5)
2.2.3 8位移位寄存器reg_8的设计 (6)
2.2.4 8位加法器adder_8的设计 (7)
2.2.5 1位乘法器multi_1的设计 (7)
2.2.6 16位移位寄存器reg_16的设计 (8)
2.2.7 16位二进制转BCD码B_BCD的设计 (9)
2.3. 软件设计
2.3.1 设计平台和开发工具 (10)
2.3.2 程序流程方框图 (10)
2.3.3 实现功能 (11)
2.3.4 8位乘法器的顶层设计 (11)
2.4. 系统测试
2.4.1 乘法器使用 (13)
2.4.2 仪器设备 (13)
2.4.3 测试数据 (14)
2.5. 结论 (14)
三.测试结果仿真图 (14)
四.参考文献 (15)
五.附录:设计说明书及使用说明书 (15)
摘要
本设计通过对一个8×8的二进制乘法器的设计,学习利用VHDL语言来描述简单的算法,掌握利用移位相加方法实现乘法运算的基本原理。
在此次设计中该乘法器是由十进制计数器,BCD码(输入)转二进制码,8位寄存器,8位加法器,16位寄存器,8x1乘法器,二进制码转BCD码(输出显示)7个模块构成的以时序方式设计的8位乘法器,采用逐项移位相加的方法来实现相乘。
设计中乘数,被乘数的十位和个位分别采用cnt10(十进制加法器)来输入,经拼接符“&”拼接成8位BCD码,再由BCD_B(BCD码转二进制码)转化成二进制码后计算,计算结果由B_BCD(二进制转BCD码)转化成BCD码输入到数码管中显示。
此次设计的创新点在于cnt10,BCD_B,B_BCD的设计,使得电路的输入简单,显示方式为十进制,符合人们的习惯。
使用中只要输入乘数,被乘数,按下键3(脉冲)就可以直接得出结果,显示结果稳定。
可以满足两位十进制乘法的计算。
一.设计要求
设计一个十六位(8*8)硬件乘法器(难度系数1.0)
要求:2位十进制乘法;能同时显示乘数,被乘数和积的信息(LED数码管)。
二.正文
2.1. 系统设计
2.1.1 系统设计方案
方案一:直接生成乘法器,再配合输入,输出电路,构成2位十进制乘法器,该方案简单,原理清晰明了,但占用资源比较多,且不易于了解内部结构,及其乘法原理。
方案二:移位相加方法实现乘法运算再配合输入,输出电路,构成2位十进制乘法器,该方案原理简单,占用资源少,易于初学者掌握移位相加方法实现乘法运算的原理,但电路模块较多。
方案选择:由于现在属初学阶段,掌握原理较为重要,故经小组讨论,一致同意采用方案二。
2.1.2 系统设计原理
在此次设计中该乘法器是由十进制计数器,BCD码(输入)转二进制码,8位寄存器,8位加法器,16位寄存器,8x1乘法器,二进制码转BCD码(输出显示)7个模块构成的以时序方式设计的8位乘法器,采用逐项移位相加的方法来实现相乘。
设计中乘数,被乘数的十位和个位分别采用cnt10(十进制加法器)来输入,经拼接符“&”拼接成8位BCD码,再由BCD_B (BCD码转二进制码)转化成二进制码后计算,计算结果由B_BCD(二进制转BCD码)转化成BCD码输入到数码管中显示。
例如:被乘数(M7M6M5M4M3M2M1M0)和乘数(N7N6N5N4N3N2N1N0)分别为11010101和10010011,其计算过程如下:
2.2. 各子模块设计
下面分解8位乘法器的层次结构,分为以下7个模块:
1. 十进制计算模块:使用4个十进制计数模块,输入乘数的十位个位,被乘数的十位个位。
2. BCD码转二进制模块:实现将输入的8位BCD码转化成二进制
3. 右移寄存器模块:这是一个8位右移寄存器,可将乘法运算中的被乘数加载于其中,同时进行乘法运算的移位操作。
4. 加法器模块:这是一个8位加法器,进行操作数的加法运算。
5. 1位乘法器模块:完成8位与1位的乘法运算。
6. 锁存器模块:这是一个16位锁存器,同时也是一个右移寄存器,在时钟信号的控制下完成输入数值的锁存与移位。
7. 二进制转BCD码模块:将16位寄存器的值(积)转化成BCD码,配合数码管显示
2.2.1 十进制加计数器设计
十进制计数器在每个时钟来临时计数,clk=1时清零,用于输入乘数,被乘数的个位,十位Library ieee; --0到9计数器
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_1164.all;
Entity cnt10 is
Port (clk,clr: in std_logic;
q: out std_logic_vector(3 downto 0));
end cnt10;
architecture behav of cnt10 is
begin
process(clk,clr)
variable cqi: std_logic_vector(3 downto 0);
begin
if clr='1' then cqi:="0000";
elsif clk'event and clk='1' then
if cqi=9 then cqi:="0000";
else cqi:=cqi+1;
end if;
end if;
q<=cqi;
end process;
end behav;
2.2.2 BCD码转二进制码BCD_B的设计
将十进制计数器产生的十位和个位合并后,为BCD码,而计算时使用二进制码计算,所以采用该模块来转化
Library ieee; --(0到99)BCD码转二进制码
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_1164.all;
Entity BCD_B is
Port ( a: in std_logic_vector(7 downto 0);
q: out std_logic_vector(7 downto 0));
end BCD_B;
architecture behav of BCD_B is
signal a1,a2,a3,a4,cq: std_logic_vector(7 downto 0);
begin
process(a)
begin
a1<="0000"&a(3 downto 0);
a2<="0000"&a(7 downto 4);
a3<=a2(6 downto 0)&'0';
a4<=a2(4 downto 0)&"000";
cq<=a4+a3+a1;
q<=cq;
end process;
end behav;
2.2.3 8位移位寄存器reg_8的设计
8位移位寄存器是在时钟(r8_clk'event and r8_clk='1')信号作用下,当r8_load='1'时,将8位乘数加载进入;而当r8_load='0'时,对数据进行移位操作,同时定义一个信号reg8用来装载新数据及移位后的操作数,完成这些操作后,寄存器的最低位reg8(0)传送给r8_out输出。
library ieee; ---8位移位寄存器
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity reg_8 is
port(r8_clk,clr,r8_load:in std_logic;
r8_in:in std_logic_vector(7 downto 0);
r8_out:out std_logic);
end reg_8;
architecture arc_reg_8 of reg_8 is
signal reg8:std_logic_vector(7 downto 0);
begin
process(r8_clk,clr,r8_load)
begin
if clr='1'then
reg8<="00000000";
elsif r8_clk'event and r8_clk='1' then
if r8_load='1' then
reg8<=r8_in;
else
reg8(6 downto 0)<=reg8(7 downto 1);
end if;
end if;
end process;
r8_out<=reg8(0);
end arc_reg_8;
2.2.4 8位加法器adder_8的设计
该加法器由八位二进制加法器组成。
其中设计八位二进制加法器时,为了避免加法运算时产生溢出,故定义了三个信号量ss,aa,bb,将加数a8_a,a8_b分别与0连接后赋值给aa,bb,形成9位二进制数,然后aa,bb相加赋值给ss,最后将ss的低八位赋值给和a8_s,同时将ss的最高位送给a8_out输出。
library ieee; --8位加法器
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity adder_8 is
port(a8_a,a8_b:in std_logic_vector(7 downto 0);
a8_s:out std_logic_vector(7 downto 0);
a8_out:out std_logic);
end adder_8;
architecture arc_adder_8 of adder_8 is
signal ss:std_logic_vector(8 downto 0);
signal aa,bb:std_logic_vector(8 downto 0);
begin
aa<='0'&a8_a; bb<='0'&a8_b; ss<=aa+bb;
a8_s<=ss(7 downto 0);
a8_out<=ss(8);
end arc_adder_8;
2.2.5 1位乘法器multi_1的设计
利用if语句来完成8位二进制数与1位二进制的乘法运算,最后将结果送到m1_out输出。
即当m1_x为1时,m1_out输出为m1_y;当m1_x为0时,m1_out输出全为零。
library ieee; --1位乘法器
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity multi_1 is
port(m1_x:in std_logic;
m1_y:in std_logic_vector(7 downto 0);
m1_out:out std_logic_vector(7 downto 0));
end multi_1;
architecture arc_multi_1 of multi_1 is
begin
process(m1_x,m1_y)
begin
if m1_x='1' then m1_out<=m1_y;
else m1_out<="00000000";
end if;
end process;
end arc_multi_1;
2.2.6 16位移位寄存器reg_16的设计
当清零信号(clr='1')到来时,定义信号变量reg_16归零;信号(r16_clr='1')到来时,定义信号变量reg16清零;否则在时钟信号r16_clk上升沿到来时,将reg16的低8位进行移位操作,同时将8位的数据输入r16_in锁存到reg16的高8位,最后赋值给r16_out输出,cout控制位输出1。
library ieee; -- 16位移位寄存器
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity reg_16 is
port(r16_clk,clr,r16_clr:in std_logic;
r16_in:in std_logic_vector(8 downto 0);
cout:out std_logic;
r16_out:out std_logic_vector(15 downto 0));
end reg_16;
architecture arc_reg_16 of reg_16 is
signal reg16:std_logic_vector(15 downto 0);
signal i: std_logic_vector(3 downto 0);
begin
process(r16_clk,r16_clr)
begin
if clr='1'then cout<='0';reg16<="0000000000000000";
elsif r16_clr='1' then
reg16<="0000000000000000"; cout<='0';i<="0000";
elsif r16_clk'event and r16_clk='1' then
if (i="1000") then reg16<=reg16;cout<='1';
else
reg16(6 downto 0)<=reg16(7 downto 1);
reg16(15 downto 7)<=r16_in;
i<=i+1;
end if;
end if;
end process;
r16_out<=reg16;
end arc_reg_16;
2.2.7 16位二进制转BCD码B_BCD的设计
当reg_16乘积结束时,cout输出1,为B_BCD的使能信号,r16_out为B_BCD的输入信号,随着时钟上升沿的到来,开始转化,16个周期后完成16为二进制码到BCD码的转化,输出接数码管显示
Library ieee; --16位二进制转BCD码(0到9999)
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_1164.all;
Entity B_BCD is
Port ( clk,ena:in std_logic;
a: in std_logic_vector(15 downto 0);
q: out std_logic_vector(15 downto 0));
end B_BCD;
architecture behav of B_BCD is
begin
process(clk,a)
variable i: std_logic_vector(4 downto 0);
variable in_a,out_a :std_logic_vector(15 downto 0);
begin
if ena='0'then
in_a:=a; i:="00000"; out_a:="0000000000000000";
elsif clk'event and clk='1' then
if i="10000" then out_a:=out_a;
else out_a:=out_a(14 downto 0)&in_a(15);
in_a:=in_a(14 downto 0)&'0';
i:=i+1;
if i<"10000" then
if out_a( 3 downto 0)>4 then out_a( 3 downto 0):=out_a( 3 downto 0)+3;
end if;
if out_a( 7 downto 4)>4 then out_a( 7 downto 4):=out_a( 7 downto 4)+3;
end if;
if out_a(11 downto 8)>4 then out_a(11 downto 8):=out_a(11 downto 8)+3;
end if;
if out_a(15 downto 12)>4 then out_a(15 downto 12):=out_a(15 downto 12)+3;
end if;
end if; end if; end if ;
q<=out_a;
end process; end behav;
2.3. 软件设计
2.3.1 设计平台和开发工具
EDA软件(Quartus II 7.2)
2.3.2 程序流程方框图
图1.电路框图
图2.简单流程图
按照上述算法,首先由计数器输入乘数被乘数,经BCD_B转化成二进制码,记作a,b。
图中8位移位寄存器reg_8存放(二进制)乘数a,从a的最低位开始,每次从reg_8中移出一位,送至1×8位乘法器multi_1中,同时将被乘数加至multi_1中,进行乘法运算,运算的结果再送至8位加法器adder_8中,同时取出16位移位寄存器reg_16的高8位与之进行相加,相加后结果即部分积存入reg_16中,进行移位后并保存。
这样经过8次对乘数a的移位操作,所以的部分积已全加至reg_16中,此时锁存器reg_16存放的值即所要求的积,再经过B_BCD 转化成BCD码显示。
2.3.3 实现功能
实现两位十进制(0~99)乘法的计算。
2.3.4 8位乘法器的顶层设计
当输入a,b后,随着STAR上升沿到来,将乘数a锁存到REG_8中,同时将16位的移位寄存器REG_16清零,然后随着时钟CLK上升沿的到来,对REG_8中的乘数进行移位操作,最低位在前,由低到高逐位输出。
1位乘法器中进行与8位被乘数的相乘运算,并与锁存在16位寄存器reg_16中的高8位进行相加,其和(包含进位)在下一个时钟的上升沿到来时锁存到16位寄存器中。
如此进行直到第八个时钟上升沿到来时,reg_16的输出即为所求的乘积,此时reg_16输出端cout输出高电平,B_BCD使能端有效,随着时钟的到来后,开始二进制到BCD码的转化,16个时钟后转化完成,输出结果。
由(clr)清零端归零后,可以进行下一次的计算。
其顶层程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity multi_8x8 is
port(clk,clk_a1,clk_a0,clk_b1,clk_b0,clr,start:in std_logic;
out_a1,out_a0,out_b1,out_b0: buffer std_logic_vector(3 downto 0);
result: out std_logic_vector(15 downto 0));
end multi_8x8;
architecture arc_multi_8x8 of multi_8x8 is
component cnt10 --调用0到9计数器声明
Port (clk,clr: in std_logic;
q: out std_logic_vector(3 downto 0));
end component;
component BCD_B --调用0到99)BCD码转二进制码声明
Port ( a: in std_logic_vector(7 downto 0);
q: out std_logic_vector(7 downto 0));
end component;
component B_BCD --调用16位二进制转BCD码(0到9999)声明Port ( clk,ena:in std_logic;
a: in std_logic_vector(15 downto 0);
q: out std_logic_vector(15 downto 0));
end component;
component multi_1 --调用1位乘法器声明
port(m1_x:in std_logic;
m1_y:in std_logic_vector(7 downto 0);
m1_out:out std_logic_vector(7 downto 0));
end component;
component adder_8 --调用8位加法器声明
port(a8_a,a8_b:in std_logic_vector(7 downto 0);
a8_s:out std_logic_vector(7 downto 0);
a8_out:out std_logic);
end component;
component reg_8 --调用8位寄存器声明
port(r8_clk,clr,r8_load:in std_logic;
r8_in:in std_logic_vector(7 downto 0);
r8_out:out std_logic);
end component;
component reg_16 --调用16位寄存器声明
port(r16_clk,clr,r16_clr:in std_logic;
r16_in:in std_logic_vector(8 downto 0);
cout:out std_logic;
r16_out:out std_logic_vector(15 downto 0));
end component;
signal q_a,cout:std_logic;
signal andsd,a,b,aa,bb:std_logic_vector(7 downto 0);
signal dtbin:std_logic_vector(8 downto 0);
signal dtbout:std_logic_vector(15 downto 0);
begin
aa<=out_a1&out_a0;
bb<=out_b1&out_b0;
u1:cnt10 --例化语句
port map(clk_a1,clr,out_a1);
u2:cnt10
port map(clk_a0,clr,out_a0);
u3:cnt10
port map(clk_b1,clr,out_b1);
u4:cnt10
port map(clk_b0,clr,out_b0);
u5:BCD_B
port map(aa,a);
u6:BCD_B
port map(bb,b);
u7:reg_8
port map(clk,clr,start,a,q_a);
u8:multi_1
port map(q_a,b,andsd);
u9:adder_8
port map(dtbout(15 downto 8),andsd,dtbin(7 downto 0),dtbin(8));
u10:reg_16
port map(clk,clr,start,dtbin,cout,dtbout);
u11:B_BCD
port map(clk,cout,dtbout,result);
end arc_multi_8x8
2.4. 系统测试
2.4.1 乘法器使用
键8为被乘数十位输入,键7为被乘数个位输入,键6为乘数十位输入,键5为乘数个位输入,键4为清零键,键3为“=“键。
如需进行下一次计算,则需要按一下清零键。
2.4.2 仪器设备
采用的设备是GW48_EDA系统实验箱,模式为模式3。
采用的芯片为Altera公司Cyclone||系列的EP2C5T144C8。
2.4.3 测试数据
乘数被乘数积
11 15 165
23 56 1288
78 80 6240
98 98 9604
5 85 425
58 79 4582
78 98 7644
2.5. 结论
经过多次系统测试,我们所设计的16位硬件乘法器满足设计要求,能够实现2位十进制数相乘,并能同时显示乘数,被乘数和积的信息,乘积结果正确显示稳定,基本满足设计要求。
通过本次设计让我们大致了解一个系统的设计流程,增加了对VHDL语言的认识及使用,并提高了我们的思考能力和团结合作能力。
尽管在设计中遇到了一些困难,如二进制转化为BCD 码整个系统的简化过程等。
但最后通过查找资料都得了很好的解决。
三.测试结果仿真图
仿真图1:5*85=425
仿真图2:58*79=4582
仿真图2:78*98=7644
四.参考文献
1.EDA技术与VHDL(第三版)潘松,黄继业编著清华大学出版社
2. EDA原理及应用实验教程(第一版)何宾编著清华大学出版社
3.EDA技术与应用(第三版)江国强编著电子工业出版社
附录:设计说明书及使用说明书
十六位硬件乘法器设计说明书
一、系统的功能、技术指标
该系统能够实现2位十进制(0~99)乘法,能同时显示乘数、被乘数和积的信息,用数码管显示。
乘数和被乘数的十位和个位能够分别输入,在输完乘数和被乘数后,按下等于键,马上能够看到结果显示。
一轮计算完后,需清零才能再次计算。
二、系统的工作原理
2.1系统框图
输出高八位
2.2模块功能
十进制计数器 a1: 用来输入被乘数的十位数的BCD 码
十进制计数器 a0:用来输入被乘数的个位数的BCD 码
十进制计数器 b1:用来输入乘数的十位数的BCD 码
十进制计数器 b0:用来输入乘数的个位数的BCD 码
二进制码转BCD 码:用来把结果转化为十进制码显示出来
BCD 码转二进制码:把输入的乘数和被乘数转化为二进制码
8位移位寄存器: 把乘数的二进制码从低位到高位依次移出来
一位乘法器: 使乘数移出来的每一位和被乘数相乘
加法器: 乘数的每一位与被乘数相乘相加
锁存器: 通过移位锁存的方式把积算出来,并锁存
三、系统的实现方法
在该系统中计数器、转码器、移位寄存器、一位乘法器、加法器、锁存器都是采用
PLD 器件实现的。
显示部件为普通的8为数码显示管,开关为单脉冲形式的按键开关、采用5V 直流供电。
四、设计要求
设计一个六位(8*8)的硬件乘法器。
能实现2位十进制(0~99)乘法,能同时显示乘数、被乘数和积的信息,用数码管显示。
五、设计完成
该系统能完成两位十进制简单的乘法要求。
十进制计数器 a1 十进制计数器 a0 十进制计
数器 b1
十进制计
数器
b0 BCD 码转二进制码
BCD 码转二进制码 一位乘
法器 8位移位寄存器
加法器 二进制码转BCD 码 锁存器
十六位硬件乘法器使用说明书
一、引脚锁定
1.根据乘法器原理图选择最佳电路图结构模式,这里我们选择模式3,以下是模式3电路结
构图:
2.输入端分配按键,从键1~~键8中给乘法器原理图中的使能计算(start)、清零(clr)、乘
数个位(clk_b0)、乘数十位(clk_b1)、被乘数个位(clk_a0)、被乘数十位(clk_a1)各分配一个按键,我们按顺序从键3到键8依次分配。
给时钟(clk)锁定在clk0.
输出端:result[15...0]锁定在锁定在数码管1、数码管2、数码管3、数码管4上,乘数个位(out_b0[3...0])锁定在数码管5上,乘数十位(out_b1[3...0])锁定在数码管6上,被乘数个位(out_a0[3...0])锁定在数码管7上,被乘数十位(out_a1[3...0])锁定在数码管8上。
二、使用操作说明
1. 键8为被乘数十位输入,键7为被乘数个位输入,键6为乘数十位输入,键5为乘数个位输入,键4为清零键,键3为“=“键。
如需进行下一次计算,则需要按一下清零键。
2. 乘数和被乘数在前四位数码管上显示。
当数据输入完成后,按下键3(“=”),后四位数码管显示积。