8位十进制乘法器

XX 学院课程论文

(2012 -2013学年第一学期)

课程论文题目:8位乘法器的设计学生姓名:

8位十进制乘法器

EDA期末考试

设计报告

设计题目:8位乘法器的设计学校:XX学院

系别:电子信息工程系

班别:10电本2班

姓名:XXX

学号:

组员:

指导老师:

摘要:本设计通过对一个8×8的二进制乘法器的设计。在此次设计

中该乘法器是由十进制计数器、BCD码(输入)转二进制码、8位寄

存器、8位加法器、 16位寄存器、8x1乘法器、二进制码转BCD码

(输出显示)7个模块构成的以时序方式设计的8位乘法器,采用逐

项移位相加的方法来实现相乘。设计中乘数,被乘数的十位和个位

分别采用cnt10(十进制加法器)来输入,经拼接符“&”拼接成8

位BCD码,再由BCD_B(BCD码转二进制码)转化成二进制码后计算,

计算结果由B_BCD(二进制转BCD码)转化成BCD码输入到数码管中显

示。

关键词:VHDL语言、十进制计数器、BCD码转二进制码、8位寄

存器、8位加法器、16位寄存器、8x1乘法器、二进制转BCD码

一、设计功能要求

能设置输入两个乘数(十进制),按操作键后以十进制的方式显示乘积。二、设计原理

本设计中该乘法器是由十进制计数器,BCD码(输入)转二进制码,8位寄存器,8位加法器, 16位寄存器,8x1乘法器,二进制码转BCD码(输出显示)7个模块构成的以时序方式设计的8位乘法器,采用逐项移位相加的方法来实现相乘。设计中乘数,被乘数的十位和个位分别采用cnt10(十进制加法器)来输入,经拼接符“&”拼接成8位BCD码,再由BCD_B(BCD码转二进制码)

转化成二进制码后计算,计算结果由B_BCD(二进制转BCD码)转化成BCD码输入到数码管中显示。使用中只要输入乘数,被乘数,按下键3(脉冲)就可以直接得出结果,显示结果稳定。可以满足两位十进制乘法的计算。

三、整体结构图:输出高八位

8位十进制乘法器

四、设计步骤:

4.1 利用VHDL语言来实现各个结构模块,其实现的用途及功能如下:

1. 十进制计算模块:使用4个十进制计数模块,输入乘数的十位个位,被乘数的十位个位。

2. BCD码转二进制模块:实现将输入的8位BCD码转化成二进制

3. 8位右移寄存器模块:将乘法运算中的被乘数加载于其中,同时进行乘法

运算的移位操作。

4. 8位加法器模块:进行操作数的加法运算。

5. 1位乘法器模块:完成8位与1位的乘法运算。

6. 16位锁存器模块:这是一个16位锁存器,同时也是一个右移寄存器,在时钟信号的控制下完成输入数值的锁存与移位。

7. 二进制转BCD码模块:将16位寄存器的值(积)转化成BCD码,配合数码管显示

4.2 利用VHDL语言来实现各个结构模块如下:

4.2.1十进制加计数器设计:

十进制计数器在每个时钟来临时计数,clk=1时清零,用于输入乘数,被乘数的个位,十位。

Library ieee; --使用ieee设计库--0到9计数器

Use ieee.std_logic_unsigned.all; - --允许用户对操作符重新定义

Use ieee.std_logic_1164.all; -- 使用std_logic_1164 程序包

Entity cnt10 is -- 实体名cnt10

Port (clk,clr: in std_logic; --clk时钟频率,rst清零

q: out std_logic_vector(3 downto 0)); --四位输出

end cnt10;

architecture behav of cnt10 is -- 结构体名behav

begin

process(clk,clr) –-时钟,清零为敏感信号

variable cqi: std_logic_vector(3 downto 0); --定义计数器

begin

if clr='1' then cqi:="0000"; --如果clr='1',则cqi:="0000"

elsif clk'event and clk='1' then----否则,若clk为上升沿,即上升沿触发if cqi=9 then cqi:="0000";--如果cqi=9,则cqi:="0000"

else cqi:=cqi+1; --否则cqi自加1

end if;

end if;

q<=cqi; 输出

end process;

end behav;

编译cnt10.vhd生成原理图文件,如下图:

8位十进制乘法器

图1 cnt10封装图

4.2.2 BCD码转二进制码BCD_B的设计:

将十进制计数器产生的十位和个位合并后,为BCD码,而计算时使用二进制码计算,所以采用该模块来转化。

Library ieee; --使用ieee设计库--(0到99)BCD码转二进制码Use ieee.std_logic_unsigned.all;-- 允许用户对操作符重新定义

Use ieee.std_logic_1164.all; -- 使用std_logic_1164 程序包

Entity BCD_B is --实体名BCD_B

Port ( a: in std_logic_vector(7 downto 0); --输入8位

q: out std_logic_vector(7 downto 0)); --输出8位

end BCD_B;

architecture behav of BCD_B is --结构体名behav

signal a1,a2,a3,a4,cq: std_logic_vector(7 downto 0);--定义四个内部信号

begin

process(a)--a为敏感信号

begin

a1<="0000"&a(3 downto 0); --"0000"与a的低四位连接

a2<="0000"&a(7 downto 4); --"0000"与a的高四位连接

a3<=a2(6 downto 0)&'0'; --a2的0位到6位与'0'连接

a4<=a2(4 downto 0)&"000";--a2的0位到4位与"000"连接

cq<=a4+a3+a1;--赋值

q<=cq; --输出

end process;

end behav;

编译BCD_B.vhd生成原理图文件,如下图

8位十进制乘法器

图2 BCD_B封装图

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; --使用ieee设计库---8位移位寄存器

use ieee.std_logic_1164.all;--使用std_logic_1164 程序包

use ieee.std_logic_unsigned.all;-- 允许用户对操作符重新定义

use ieee.std_logic_arith.all;--定义了相关的算术运算符和数据类型转换函数entity reg_8 is --实体名reg_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 reg_8;

architecture arc_reg_8 of reg_8 is --结构体名arc_reg_8

signal reg8:std_logic_vector(7 downto 0); --定义一个内部信号,其位宽为8位

begin

process(r8_clk,clr,r8_load)----三个敏感信号

begin

if clr='1'then

reg8<="00000000";--如果clr='1,则执行reg8<="00000000"

elsif r8_clk'event and r8_clk='1' then-- 否则,若r8_clk为上升沿,即上升沿触发

if r8_load='1' then

reg8<=r8_in;--如果r8_load='1',则执行reg8<=r8_in

else

reg8(6 downto 0)<=reg8(7 downto 1); --否则执行

end if; -- reg8(6 downto 0)<=reg8(7 downto 1) end if;

end process;

r8_out<=reg8(0); --输出

end arc_reg_8;

编译reg_8.vhd生成原理图文件,如下图:

8位十进制乘法器

图3 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; --使用ieee设计库--8位加法器

use ieee.std_logic_1164.all----使用std_logic_1164程序包;

use ieee.std_logic_unsigned.all;-- 允许用户对操作符重新定义

use ieee.std_logic_arith.all;-- 定义了相关的算术运算符和数据类型转换函数entity adder_8 is --实体名adder_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 adder_8;

architecture arc_adder_8 of adder_8 is --结构体名arc_adder_8

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;

编译adder_8.vhd生成原理图文件,如下图:

8位十进制乘法器

图4 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; --使用ieee设计库--1位乘法器

use ieee.std_logic_1164.all;--使用std_logic_1164程序包

use ieee.std_logic_unsigned.all;-- 允许用户对操作符重新定义

use ieee.std_logic_arith.all;-- 定义了相关的算术运算符和数据类型转换函数entity multi_1 is --实体名multi_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 multi_1;

architecture arc_multi_1 of multi_1 is ---结构体名arc_multi_1

begin

process(m1_x,m1_y)---两个敏感信号

begin

if m1_x='1' then m1_out<=m1_y;--如果m1_x='1'则执行m1_out<=m1_y else m1_out<="00000000";--否则执行m1_out<="00000000"

end if;

end process;

end arc_multi_1;

编译multi_1.vhd生成原理图文件,如下图:

8位十进制乘法器

图5 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; -- 使用ieee设计库-- 16位移位寄存器

use ieee.std_logic_1164.all;--使用std_logic_1164程序包

use ieee.std_logic_unsigned.all;-- 允许用户对操作符重新定义

use ieee.std_logic_arith.all;-- 定义了相关的算术运算符和数据类型转换函数entity reg_16 is --实体名reg_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 reg_16;

architecture arc_reg_16 of reg_16 is --结构体名arc_reg_16

signal reg16:std_logic_vector(15 downto 0); --定义内部信号reg16,位宽为16位

signal i: std_logic_vector(3 downto 0);--定义内部信号i,位宽为4位

begin

process(r16_clk,r16_clr) --两个敏感信号

begin --当清零信号(clr='1')到来时

if clr='1'then cout<='0';reg16<="0000000000000000";--定义信号变量reg_16归零

elsif r16_clr='1' then --否则信号(r16_clr='1')到来时

reg16<="0000000000000000"; cout<='0';i<="0000";-定义信号变量reg16清零

elsif r16_clk'event and r16_clk='1' then --时钟信号r16_clk上升沿到来时

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; --r16_out输出

end arc_reg_16;编译reg_16.vhd生成原理图文件,如下图:

8位十进制乘法器

图6 reg_16封装图

4.2.7 16位二进制转BCD码B_BCD的设计:

当reg_16乘积结束时,cout输出1,为B_BCD的使能信号,r16_out为B_BCD 的输入信号,随着时钟上升沿的到来,开始转化,16个周期后完成16为二进制码到BCD码的转化,输出接数码管显示

Library ieee; ---使用ieee设计库--16位二进制转BCD码(0到9999)Use ieee.std_logic_unsigned.all;--- 允许用户对操作符重新定义

Use ieee.std_logic_1164.all; ---使用std_logic_1164程序包

Entity B_BCD is ---实体名B_BCD

Port ( clk,ena:in std_logic;--- clk时钟,ena使能

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 ---结构体名behav

begin

process(clk,a) ---敏感信号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-检查半字节+3 是否大于7,也就是检查半字节是否大于 4

if out_a( 3 downto 0)>4 then out_a( 3 downto 0):=out_a( 3 downto 0)+3;

end if; --如果大于4加 3

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;

编译B_BCD.vhd生成原理图文件,如下图:

8位十进制乘法器

图7 B_BCD封装图

4.2.8 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;---使用ieee设计库

use ieee.std_logic_1164.all;---使用std_logic_1164程序包

相关推荐
相关主题
热门推荐