8位二进制乘法电路
•1.设计要求
8位二进制乘法采用移位相加的方法。即用乘数的各位数码,从低位开始依次与被乘数相乘,每相乘一次得到的积称为部分积,将第一次(由乘数最低位与被乘数相乘)得到的部分积右移一位并与第二次得到的部分积相加,将加得的和右移一位再与第三次得到的部分积相加,再将相加的结果右移一位与第四次得到的部分积相加。直到所有的部分积都被加过一次。例如:被乘数(M7M6M5M4M3M2M1M0)和乘数(N7N6N5N4N3N2N1N0)分别为11010101和10010011,其计算过程如下:
1 1 0 1 0 1 0 1
× 1 0 0 1 0 0 1 1
1 1 0 1 0 1 0 1 N0与被乘数相乘的部分积,部分积右移一位
1 1 0 1 0 1 0 1 N1与被乘数相乘的部分积
+ 1 1 0 1 0 1 0 1
1 0 0 1 1 1 1 1 1 1
1 0 0 1 1 1 1 1 1 1 两个部分积之和,部分积之和右移一位
+ 0 0 0 0 0 0 0 0 N2与被乘数相乘的部分积
0 1 0 0 1 1 1 1 1 1 1
0 1 0 0 1 1 1 1 1 1 1 与前面部分积之和相加,部分积之和右移一
+ 0 0 0 0 0 0 0 0 N4与被乘数相乘的部分积
· · ·
· · · N7与被乘数相乘的部分积
+ 1 1 0 1 0 1 0 1
1 1 1 1 0 1 0 0 1 0 0 1 1 1 1 与前面部分积之和相加
0 1 1 1 1 0 1 0 0 1 0 0 1 1 1 右移一位得到最后的积
•按照这种算法,可以得到下图所示之框图和简单流程图。图中Y寄存器存放被乘数M,B寄存器存放乘数N,A累加器存放部分积。A和Y中的数据在加法器中相加后送入A中,而A和B相级联又构成了一个16bit的移位寄存器,当它工作于移位模式时,可以实现数据的右移。由于乘数的每一位不是0就是1 ,对应的部分积不是0就是被乘数本身,所以实际作部分积相加这一步时,只要根据乘数的对应位判断:如该位为1 ,则将累加器中的数据加上被乘数再移位;如该位为0时,就不加被乘数而直接移位。运算时首先将累加器A清零,并将被乘数M和乘数N分别存入寄存器Y和B,然后依据寄存器B中最右一位B0(数据N0)确定第一个部分积。将此部分积送入A累加器以后,将A连同寄存器B右移一位,部分积的最低位被移进寄存器B的最左位,乘数的最低位N0被移出寄存器B,而乘数的次低位N1被移至寄存器B的B0位。第二次仍然依据B0位的数据(N1)来确定第二个部分积,将部分积与累加器中的数据相加后右移一位,N1又被移出寄存器,数据N2被移到B0位置。。。这样,经过8次部分积相加位的操作,完成1次乘法运算,乘数N恰好被移出寄存器B,寄存器B中保存的就是运算积的低8位数据。移位相加的次数应用一个计数器来控制,每移位一次,计数器计一个数。当计数器计得8个数时,发出一个信号,使电路停止操作,并输出运算结果(流程图是按减法计数器设计的,也可使用加法计数器)。
•
电路框图简单流程图
2.设计方案总结
(1)8位移位寄存器模块。可将乘法运算中的被乘数加载于其中,同时进行乘法运算的移位操作。
(2)8位加法器模块。这是一个8位加法器,进行操作数的加法运算。
(3)一位乘法电路模块。完成8位与1位的乘法运算。
(4)乘法控制电路模块。当结果得到时使程序停止。
(5)16位移位锁存器。在时钟信号的控制下完成输入数值的锁存与移位。其最终结果就是要求结果。
3.系统程序设计及仿真图。
(1)8位移位寄存器
源代码:
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity reg is
port( reg_clk,load:in std_logic;
reg_in:in std_logic_vector(7 downto 0);
reg_out:out std_logic);
end reg;
architecture arc_reg of reg is
signal reg8:std_logic_vector(7 downto 0);
begin
process( reg_clk,load)
begin
if reg_clk'event and reg_clk='1' then
if load='1' then
reg8<=reg_in;
else
reg8(6 downto 0)<=reg8(7 downto 1);
end if;
end if;
end process;
reg_out<=reg8(0);
end arc_reg;
仿真图:
(2)8位加法电路
源代码:
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity adder is
port(adder_in :in std_logic;
a4,b4:in std_logic_vector(3 downto 0);
s4:out std_logic_vector(3 downto 0);
adder_out:out std_logic);
end adder;
architecture arc_adder of adder is
signal ss:std_logic_vector(4 downto 0);
signal aa,bb:std_logic_vector(4 downto 0);
begin
aa<='0'&a4;
bb<='0'&b4;
ss<=aa+bb+adder_in;
s4<=ss(3 downto 0);
adder_out<=ss(4);
end arc_adder;
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity adder_8 is
port(a8_in :in std_logic;
a8,b8:in std_logic_vector(7 downto 0);
s8:out std_logic_vector(7 downto 0);
a8_out:out std_logic);
end adder_8;
architecture arc_adder_8 of adder_8 is
component adder
port(adder_in :in std_logic;
a4,b4:in std_logic_vector(3 downto 0);
s4:out std_logic_vector(3 downto 0);
adder_out:out std_logic);
end component;
signal carry_out:std_logic;
begin
u1:adder
port map(a8_in,a8(3 downto 0),b8(3 downto 0),s8(3 downto 0),carry_out);
u2:adder
port map(carry_out,a8(7 downto 4),b8(7 downto 4),s8(7 downto 4),a8_out);
end arc_adder_8;
仿真图:
(3)一位乘法电路模块。
源代码:
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity multi is
port( x:in std_logic;
y:in std_logic_vector(7 downto 0);
m1_out:out std_logic_vector(7 downto 0));
end multi;
architecture arc_multi of multi is
begin
process(x,y)
begin
for i in 0 to 7 loop
m1_out(i)<=y(i)and x;
end loop;
end process;
end arc_multi;
仿真图:
(4)乘法控制电路模块。当结果得到时使程序停止。
源代码:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_11.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ARICTL
IS
PORT ( CLK2:IN STD_LOGIC; START:IN
STD_LOGIC;
CLKOUT:OUT STD_LOGIC; RSTALL:OUT
STD_LOGIC;
ARIEND:OUT STD_LOGIC );
END ARICTL;
ARCHITECTURE ART OF ARICTL IS
SIGNAL
CNT4B:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
RSTALL<=START;
PROCESS (CLK2,START)
BEGIN
IF START = '1' THEN CNT4B<= "0000";
ELSIF CLK2'EVENT AND CLK2 = '1' THEN
IF CNT4B<8 THEN
CNT4B<=CNT4B+1;
END IF;
END IF;
END PROCESS;
PROCESS (CLK2,CNT4B,START)
BEGIN
IF START = '0' THEN
IF CNT4B<8 THEN
CLKOUT <=CLK2; ARIEND<= '0';
ELSE CLKOUT <= '0'; ARIEND<= '1';
END IF;
ELSE CLKOUT <=CLK2; ARIEND<= '0';
END IF;
END PROCESS;
END ART;
仿真图:
(5)16位移位锁存器。在时钟信号的控制下完成输入数值的锁存与移位。其最终结果就是要求结果。
源代码:
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity reg_16 is
port(r16_clk,r16_clr:in std_logic;
r16_in:in std_logic_vector(8 downto 0);
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);
begin
process(r16_clk,r16_clr)
begin
if r16_clr='0' then
if r16_clk'event and r16_clk='1' then
reg16(6 downto 0)<=reg16(7 downto 1);
reg16(15 downto 7)<=r16_in;
end if;
end if;
end process;
r16_out<=reg16;
end arc_reg_16;
仿真图:
(6)顶层程序即8*8移位乘法器源程序
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity multi_8 is
port(clk,start:in std_logic;
a,b:in std_logic_vector(7 downto 0);
ARIEND:OUT STD_LOGIC;
result:out std_logic_vector(15 downto 0));
end multi_8;
architecture arc_multi_8 of multi_8 is
component ARICTL
PORT ( CLK2:IN STD_LOGIC; START:IN
STD_LOGIC;
CLKOUT:OUT STD_LOGIC; RSTALL:OUT
STD_LOGIC;
ARIEND:OUT STD_LOGIC );
END component;
component multi
port( x:in std_logic;
y:in std_logic_vector(7 downto 0);
m1_out:out std_logic_vector(7 downto 0));
end component;
component adder_8
port(a8_in :in std_logic;
a8, b8:in std_logic_vector(7 downto 0);
s8:out std_logic_vector(7 downto 0);
a8_out:out std_logic);
end component;
component reg
port(reg_clk,load:in std_logic;
reg_in:in std_logic_vector(7 downto 0);
reg_out:out std_logic);
end component;
component reg_16
port(r16_clk,r16_clr:in std_logic;
r16_in:in std_logic_vector(8 downto 0);
r16_out:out std_logic_vector(15 downto 0));
end component;
signal gndint,newstart,qb:std_logic;
signal intclk:std_logic;
signal andsd:std_logic_vector(7 downto 0);
signal dtbin:std_logic_vector(8 downto 0);
signal dtbout:std_logic_vector(15 downto 0);
begin
result<=dtbout;
gndint<='0';
u1:ARICTL
port map(clk,start,intclk,newstart,ARIEND);
u2:reg
port map(intclk,newstart,a,qb);
u3:multi
port map(qb,b,andsd);
u4:adder_8
port map(gndint,dtbout(15 downto 8),andsd,dtbin(7 downto 0),dtbin(8));
u5:reg_16
port map(intclk,newstart,dtbin,dtbout);
end arc_multi_8;
仿真图:
A,B分别为两个乘数分别取88和A8,输入时钟CLK,START相当于一个开关,将其拨到高电平再拨回来乘法就开始了,ARIEND为计算结束标志用指示灯显示。结果RESULT用指示灯显示移位8次得010*********即5940
4.心得体会
本次作业做的是8*8乘法器。从刚开始学EDA到做出这次作业这中间其实并不是很顺利。我认为其中最困难的地方就是设计思路的得出以及其中遇到的各种问题包括程序的改正和仿真的不断尝试以及在板子上的不断调试。由于在题目中有一些讲解以及框图所以设计思路还是比较容易就得出了。接下来就分模块一一编好所需模块程序,在这中间程序不断更改不断编译直至其正确,然后进行仿真,若是仿真不正确还要再检查程序直至其仿真正确。这是一个最漫长最困难也是最重要的一步,虽然这个过程很困难但只要坚持下来成功就不远了,当看到最后仿真结果正确时其心情是无比愉快的。然后就是到实验室加板子,这个过程中遇到的困难也不少,只要你不断尝试不断找其中的问题解决问题就一定能成功。检验没问题之后这个作业才算结束。
通过这次课程设计对EDA技术有了更进一步的熟悉,使我对VHDL语言有了更为深刻的理解,对学到的知识也有更加深刻的掌握。VHDL是EDA技术的重要组成部分,其具有与具体硬件电路无关和与设计平台无关的特性,并且具有良好的电路行为描述和系统描述的能力,并在语言易读性和层次化、结构化设计方面,表现了强大的生命力和应用潜力。其主要的也是最大的优点就在于设计者可以专心致力于其功能的实现,而不需要对不影响功能的与工艺有关的因素花费过多的时间和精力。在实际操作中发现设计和课本上的知识有很大联系,但又高于课本,一个简单的原理要把它应用以及和其他功能综合起来就有些困难。
EDA的学习只能算是个入门,这个领域的发展空间非常大,应用范围也非常广泛,而且我相信在将来还会有更加广阔的应用前景。因此在以后的学习过程中,我不能因为课程学习的结束而结束了我对这个领域的探索,相反我会更加努力的去学习它。感谢老师孜孜不倦的教诲,让我不仅学到了知识,也学到了做人做事的一些道理,为我提供了很多帮助。下载本文