十六位硬件乘法器电路设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程名称电子设计自动化
题目十六位硬件乘法器电路
院系班级信息学院11电子信息工程A班姓名
学号
指导老师凌朝东
2013 年 12 月 5 日
题目名称:
十六位硬件乘法器电路
摘要:
设计一个16位硬件乘法器电路.要求2位十进制乘法,能用LED数码管同时显示乘数,被乘数和积的值.本设计利用Quartus II软件为设计平台,通过移位相加的乘法原理:即从被乘数的最低位开始,若为1,则乘数左移后与上一次的和相加;若为0,左移后以全零相加,直至被乘数的最高位。
经软件仿真和硬件测试验证后,以达到实验要求。
目录
1.题目名称 (2)
2.摘要 (2)
3.目录 (3)
4.正文 (4)
4.1. 系统设计 (4)
4.1 设计要求 (4)
4.2 系统设计方案 (4)
4.2 单元电路设计 (4)
4.2.1十进制计算模块 (5)
4.2.2 BCD码转二进制模块 (5)
4.2.3 8位右移寄存器模块 (6)
4.2.4 8位加法器模块 (7)
4.2.5 1乘法器multi_1模块 (7)
4.2.6 16位移位寄存器reg_16模块 (8)
4.2.7 16位二进制转BCD码B_BCD模块 (9)
4.2.8 8位乘法器multi_8x8顶层设计 (10)
4.3 软件设计 (12)
4.3.1设计平台和开发工具 (12)
4.3.2程序流程方框图 (13)
4.4 系统测试 (14)
4.1仿真分析 (14)
4.2硬件验证 (15)
5. 结论 (15)
6. 参考文献 (15)
7. 附录 (15)
4.正文
4.1系统设计
1.1设计要求
题目要求设计一个16位硬件乘法器电路.要求2位十进制乘法;能用LED数码管同时显示乘数,被乘数和积的信息.设置一个乘法使能端,控制乘法器的计算和输出.
1.2系统设计方案
此设计问题可分为乘数和被乘数输入控制模块,乘法模块和输出乘积显示模块基本分.
乘数和被乘数的输入模块使输入的十进制数转化为二进制数输入乘法模块,乘法模块利用移位相加的方法将输入的两组二进制数进行相乘,并将16位乘积输出到乘积输出显示模块.显示模块将输入的二进制数按千,百,十,个位分别转化为十进制数输出.
乘数和被乘数的输入可用数据开关K1~K10分别代表数字1,2,…,9,0,用编码器对数据开关K1~K10的电平信号进行编码后输入乘法器进行计算.但此方案所用硬件资源较多,输入繁琐,故不采取.
方案二是利用硬件箱自带16进制码发生器,由对应的键控制输出4位2进制构成的1位16进制码,数的范围是0000~1111,即0H~FH.每按键一次,输出递增1,输出进入目标芯片的4位2进制数将显示在该键对应的数码管.
乘数和被乘数的输入模块将16进制码的A~F码设计成输出为null.使得减少了无用码的输入.
两数相乘的方法很多,可以用移位相加的方法,也可以将乘法器看成计数器,乘积的初始值为零,每一个时钟周期将乘数的值加到积上,同时乘数减一,这样反复执行,直到乘数为零.本设计利用移位相加的方法使得程序大大简化.
系统总体电路组成原理图如下图所示:
4.2单元电路设计
下面分解8位乘法器的层次结构,分为以下7个模块:
1. 十进制计算模块:使用4个十进制计数模块,输入乘数的十位个位,被乘数的十位个位。
2. BCD码转二进制模块:实现将输入的8位BCD码转化成二进制
3. 右移寄存器模块:这是一个8位右移寄存器,可将乘法运算中的被乘数加载于其中,同时进行乘法运算的移位操作。
4. 加法器模块:这是一个8位加法器,进行操作数的加法运算。
5. 1位乘法器模块:完成8位与1位的乘法运算。
6. 锁存器模块:这是一个16位锁存器,同时也是一个右移寄存器,在时钟信号的控制下完成输入数值的锁存与移位。
7. 二进制转BCD码模块:将16位寄存器的值(积)转化成BCD码,配合数码管显示
4.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;
4.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;
4.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;
4.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;
4.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;
4.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;
4.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;
4.2.8 顶层设计8位乘法器multi_8x8
当输入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
4.3软件设计
4.3.1 设计平台和开发工具
本设计是基于quartusII电路设计软件为平台,借用PC机和GW48EDA/SOPC实验箱为设计工具,运用VHDL 硬件描述语言在Cyclone II系列的EP2C5T144C6芯片为设计对象实现的.
Quartus II 是Altera公司的综合性PLD开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。
VHDL是非常告诉集成电路硬件描述语言,是可以描述硬件电路的功能,信号连接关系及定时关系的语言,它能比电路原理图更有效地表示硬件电路的特性.使用VHDL语言,可以就系统的总体要求出发,自上至下地设计内容细化,最后完成系统硬件的整体设计.VHDL程序结构包括:实体,结构体,配置,包集合及库.主要特
点是:a.功能强大,灵活性高;器件无关性;可移植性好;自顶向下的设计方法等.
利用quartusII软件设计的流程图3如图所示
4.3.2 程序流程方框图电路框图:
简单流程图:
4.4系统测试
4.4.1仿真分析(最高工作频率 Mkhz,资源使用情况个LCs,个I/O,个REG)1. 22*12=242
2. 31*24=744
3.53*27=1431
4.38*44=1672
4.4.2 硬件验证(实验箱编号,目标芯片型号:,电路模式:)
被乘数
乘数
标称值
测量值
误差
结论:经过VHDL程序的设计到软件仿真,再到硬件测试成功,功能的实现,表明这次EDA课程设计非常成功,设计要求全部达成,达到了预期效果.
参考文献:<<EDA技术与VHDL>>第五版,清华大学出版社
附录:仪器设备清单: PC机
GW48EDA/SOPC实验箱。