EDA课设八位乘法计数器.docx
《EDA课设八位乘法计数器.docx》由会员分享,可在线阅读,更多相关《EDA课设八位乘法计数器.docx(18页珍藏版)》请在冰豆网上搜索。
EDA课设八位乘法计数器
河北科技大学
课程设计报告
学生姓名:
**学号:
**
专业班级:
****
课程名称:
EDA技术课程设计
学年学期:
2016—2017学年第2学期
指导教师:
武瑞红寇平勉
2017年6月
课程设计成绩评定表
学生姓名
**
学号
***
成绩
专业班级
***
起止时间
2017.6.19——2017.6.30
设计题目
八位乘法计数器
指
导
教
师
评
语
指导教师:
年月日
一、课程设计目
二、课程设计原理
三、课程设计内容
四、课程设计结果
五、心得体会
一、课程设计目
该乘法器是有由8位加法器构成以时序方式设计8位乘法器,采用逐项移位相加方法来实现相乘。
用乘数各位数码,从低位开始依次与被乘数相乘,每相乘一次得到积称为部分积,将第一次(由乘数最低位与被乘数相乘)得到部分积右移一位并与第二次得到部分积相加,将加得和右移一位再与第三次得到部分积相加,再将相加结果右移一位与第四次得到部分积相加。
直到所有部分积都被加过一次。
下面分解8位乘法器层次结构,分为以下4个模块:
右移寄存器模块:
这是一个8位右移寄存器,可将乘法运算中被乘数加载于其中,同时进行乘法运算移位操作。
加法器模块:
这是一个8位加法器,进行操作数加法运算。
1位乘法器模块:
完成8位与1位乘法运算。
④锁存器模块:
这是一个16位锁存器,同时也是一个右移寄存器,在时钟信号控制下完成输入数值锁存与移位。
按照上述算法,可以得到下图所示之框图和简单流程图。
图中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存放值即所要求积。
二、课程设计原理
该乘法器是有由8位加法器构成以时序方式设计8位乘法器,采用逐项移位相加方法来实现相乘。
用乘数各位数码,从低位开始依次与被乘数相乘,每相乘一次得到积称为部分积,将第一次(由乘数最低位与被乘数相乘)得到部分积右移一位并与第二次得到部分积相加,将加得和右移一位再与第三次得到部分积相加,再将相加结果右移一位与第四次得到部分积相加。
直到所有部分积都被加过一次。
下面分解8位乘法器层次结构,分为以下4个模块:
右移寄存器模块:
这是一个8位右移寄存器,可将乘法运算中被乘数加载于其中,同时进行乘法运算移位操作。
加法器模块:
这是一个8位加法器,进行操作数加法运算。
1位乘法器模块:
完成8位与1位乘法运算。
④锁存器模块:
这是一个16位锁存器,同时也是一个右移寄存器,在时钟信号控制下完成输入数值锁存与移位。
按照上述算法,可以得到下图所示之框图和简单流程图。
图中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存放值即所要求积。
三、课程设计内容
(1)8位移位寄存器reg_8设计
8位移位寄存器是在时钟(r8_clk'eventandr8_clk='1')信号作用下,当r8_load='1'时,将8位乘数加载进入;而当r8_load='0'时,对数据进行移位操作,同时定义一个信号reg8用来装载新数据及移位后操作数,完成这些操作后,寄存器最低位reg8(0)传送给r8_out输出。
元件实体原理图如下图:
该模块元件程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityreg_8is--实体描述
port(r8_clk,r8_load:
instd_logic;
r8_in:
instd_logic_vector(7downto0);
r8_out:
outstd_logic);
endreg_8;
architecturearc_reg_8ofreg_8is--结构体描述
signalreg8:
std_logic_vector(7downto0);--定义信号变量
begin
process(r8_clk,r8_load)
begin
ifr8_clk'eventandr8_clk='1'then--时钟上升沿到来
ifr8_load='1'then--锁存新数据
reg8<=r8_in;
else
reg8(6downto0)<=reg8(7downto1);--数据右移
endif;
endif;
endprocess;
r8_out<=reg8(0);--输出最低位
endarc_reg_8;
仿真波形图如下:
(2)8位加法器adder_8设计
)该加法器由两个四位二进制加法器组成。
其中设计四位二进制加法器时,为了避免加法运算时产生溢出,故定义了三个信号量ss,aa,bb,将加数a4_a,a4_b分别与0连接后赋值给aa,bb,形成5位二进制数,然后aa,bb与进位位a4_in相加赋值给ss,最后将ss低四位赋值给和a4_s,同时将ss最高位送给a4_out输出。
元件实体原理图如右图:
其程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityadder_4is--实体描述
port(a4_in:
instd_logic;
a4_a,a4_b:
instd_logic_vector(3downto0);
a4_s:
outstd_logic_vector(3downto0);
a4_out:
outstd_logic);
endadder_4;
architecturearc_adder_4ofadder_4is--结构体描述
signalss:
std_logic_vector(4downto0);--定义信号变量
signalaa,bb:
std_logic_vector(4downto0);
begin
aa<='0'&a4_a;--为避免溢出,将0与a4_a连接
bb<='0'&a4_b;--将0与a4_b连接
ss<=aa+bb+a4_in;--执行加法运算
a4_s<=ss(3downto0);--输出结果
a4_out<=ss(4);--进位位
endarc_adder_4;
其仿真波形为:
)设计8位加法器时,采用例化语句,定义信号量carry_out,将4位加法器U1a4_out赋给carry_out,再将carry_out值给4位加法器U2进位位a4_in,8位加法器高四位和低四位分别来自四位加法器U1和U2。
其连接电路图如下
元件实体原理图如右图:
其程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityadder_8is--实体描述
port(a8_in:
instd_logic;
a8_a,a8_b:
instd_logic_vector(7downto0);
a8_s:
outstd_logic_vector(7downto0);
a8_out:
outstd_logic);
endadder_8;
architecturearc_adder_8ofadder_8is--结构体描述
componentadder_4--元件例化,调用4位加法器声明
port(a4_in:
instd_logic;
a4_a,a4_b:
instd_logic_vector(3downto0);
a4_s:
outstd_logic_vector(3downto0);
a4_out:
outstd_logic);
endcomponent;
signalcarry_out:
std_logic;--定义信号变量
begin
u1:
adder_4--例化语句
portmap(a8_in,a8_a(3downto0),a8_b(3downto0),a8_s(3downto0),carry_out);
u2:
adder_4
portmap(carry_out,a8_a(7downto4),a8_b(7downto4),a8_s(7downto4),a8_out);
endarc_adder_8;
仿真结果如图所示:
(3)1位乘法器multi_1设计
利用循环语句FOR-LOOP完成8位二进制数与1位二进制乘法运算,将8位二进制数m1_y从最低位到最高位与1位二进制m1_x分别做与运算,最后将结果依次送到m1_out输出。
即当m1_x为1时,m1_out输出为m1_y;当m1_x为0时,m1_out输出全为零。
元件实体原理图如右图:
其程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitymulti_1is--实体描述
port(m1_x:
instd_logic;
m1_y:
instd_logic_vector(7downto0);
m1_out:
outstd_logic_vector(7downto0));
endmulti_1;
architecturearc_multi_1ofmulti_1is--结构体描述
begin
process(m1_x,m1_y)
begin
foriin0to7loop--循环完成8位与1位乘法运算
m1_out(i)<=m1_y(i)andm1_x;
endloop;
endprocess;
endarc_multi_1;
其仿真电路图如下:
(4)16位移位寄存器reg_16设计
当清零信号(r16_clr='1')到来时,定义信号变量reg16清零;否则在时钟信号r16_clk上升沿到来时,将reg16低8位进行移位操作,同时将8位数据输入r16_in锁存到reg16高8位,最后赋值给r16_out输出。
元件实体原理图如右图:
其程序如下:
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityreg_16is--实体描
port(r16_clk,r16_clr:
instd_logic;
r16_in:
instd_logic_vector(8downto0);
r16_out:
outstd_logic_vector(15downto0));
endreg_16;
architecturearc_reg_16ofreg_16is--结构体描述
signalreg16:
std_logic_vector(15downto0);--定义信号变量
begin
process(r16_clk,r16_clr)
begin
ifr16_clr='1'then--clr为高电平,清零
reg16<="00000";
elsifr16_clk'eventandr16_clk='1'then--时钟上升沿到来
reg16(6downto0)<=reg16(7downto1);--右移,并锁存低八位
reg16(15downto7)<=r16_in;--将输入锁存到高8位
endif;
endprocess;
r16_out<=reg16;--数据输出
endarc_reg_16;
(5)8位乘法器顶层设计
元件实体原理图如图:
其顶层电路如图:
如上图所示,当STAR上升沿到来,将乘数a锁存到REG_8中,同时将16位移位寄存器REG_16清零,然后随着时钟CLK上升沿到来,对REG_8中乘数进行移位操作,最低位在前,由低到高逐位输出。
1位乘法器中进行与8位被乘数相乘运算,并与锁存在16位寄存器reg_16中高8位进行相加,其和(包含进位)在下一个时钟上升沿到来时锁存到16位寄存器中。
如此进行直到第八个时钟上升沿到来时,reg_16输出即为所求乘积。
其顶层程序如下:
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitymulti_8is--实体描述
port(clk,start:
instd_logic;
a,b:
instd_logic_vector(7downto0);
result:
outstd_logic_vector(15downto0));
endmulti_8;
architecturearc_multi_8ofmulti_8is--结构体描述
componentmulti_1--调用1位乘法器声明
port(m1_x:
instd_logic;
m1_y:
instd_logic_vector(7downto0);
m1_out:
outstd_logic_vector(7downto0));
endcomponent;
componentadder_8--调用8位加法器声明
port(a8_in:
instd_logic;
a8_a,a8_b:
instd_logic_vector(7downto0);
a8_s:
outstd_logic_vector(7downto0);
a8_out:
outstd_logic);
endcomponent;
componentreg_8--调用8位寄存器声明
port(r8_clk,r8_load:
instd_logic;
r8_in:
instd_logic_vector(7downto0);
r8_out:
outstd_logic);
endcomponent;
componentreg_16--调用16位寄存器声明
port(r16_clk,r16_clr:
instd_logic;
r16_in:
instd_logic_vector(8downto0);
r16_out:
outstd_logic_vector(15downto0));
endcomponent;
signalgndint,newstart,qb:
std_logic;--定义信号变量
signalandsd:
std_logic_vector(7downto0);
signaldtbin:
std_logic_vector(8downto0);
signaldtbout:
std_logic_vector(15downto0);
begin
result<=dtbout;
gndint<='0';
process(clk,start)
begin
ifstart='1'thennewstart<='1';
elsifclk='0'thennewstart<='0';
endif;
endprocess;
u1:
reg_8--例化语句
portmap(clk,newstart,a,qb);
u2:
multi_1
portmap(qb,b,andsd);
u3:
adder_8
portmap(gndint,dtbout(15downto8),andsd,dtbin(7downto0),dtbin(8));
u4:
reg_16
portmap(clk,newstart,dtbin,dtbout);
endarc_multi_8;
仿真波形如图所示:
输出波形分析:
输入时,置被乘数为b=D5H=11010101,置乘数a=93H=10010011
当START信号时钟上升沿到来,result输出为:
00000000000000000000=0000H
同时将乘数a锁存至8位寄存器reg_8中
当第一个时钟上升沿到来,reg_8输出a最低位1与被乘数a送至1位乘法器进行乘法运算,得到结果:
11010101与16寄存器reg_16高8位,此时即00000000送入8位加法器进行相加,得到结果即:
011010101,送入reg_16并通过reg_16进行低8位移位后对输入进行锁存,即输出结果result为:
0110101010000000=6A80H
当第二个时钟上升沿到来,reg_8输出a第二低位1,与被乘数a送至1位乘法器进行乘法运算,得到结果:
11010101与16寄存器reg_16高8位,此时即01101010送入8位加法器进行相加,得到结果即:
100111111,送入reg_16并通过reg_16进行低8位移位后对输入进行锁存,即输出结果result为:
1001111111000000=9FC0H
同理,我们可以得到接下来3~7个时钟上升沿到来移位相加后放至reg_16中移位锁存结果:
4FE0H27F0H7E78H3F3CH1F9EH
而当第8个时钟上升沿到来时,其最终结果为:
7A4FH,即为所要求a,b乘积
四、课程设计结果
五、心得体会
经过近两个星期学习与实验,完成了乘法器设计。
初步掌握了电子设计自动化方法,对VHDL语言也有了一定了解。
同时也感受到了QuartusⅡ强大。
要对其深入了解,还需进一步学习。
才能从分发挥其作用。
乘法器设计过程中遇到主要问题及解决方法已在各小结中给出。
整个课程设计中也有很多体会。
首先就是不能心急,总想着一步完成是不可能。
要思路清晰,先从整体入手,有了整体想法之后,再将其细化分成个小模块,完成个小模块设计最后将各模块进行连线。
也就是对应于由底向上设计方法。
对于小规模设计,此方法简单易于接受。
当我们对于自己设计没有清晰地思路时,最好不要参考其他已完成作品,因为这样再设计自己作品时,就会很容易走上别人老路,总是会想着去按照他人方法进行设计,缺少了创新地方。
当我们有了自己想法或者有部分想不明白时候再去参考他人作品,与他人进行交流,这样对比之中找出自己不足,才能有更深刻理解与认识。
最后,完成了个模块设计,每个模块都发现不出太大问题,满怀期待将各模块连接到一起,却得不出想要结果,大家都会比较着急。
这种情况,我们只需按照信号传递过程,从头到到尾一块一块连接,并一步步仿真,就会很容易检查到问题所在。
总之,在时间充裕情况下,完全可以不用心急,这样既可以踏实地学到很多知识,同时也可完成自己理想设计,最后非常感谢武老师耐心细致教导才使得课设顺利完成。