电子
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
自动化EDA 简易计算器设计
简易计算器设计
——EDA实验报告一、实验
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
实验要求:完成个位数的加减乘运算,输入用矩阵键盘,输出用数码管显示,每输入一次数据要显示在数码管上。矩阵键盘共16个按键,用其中10个做个位数的输入,用3个分别做加减乘运算,用其中1个做等于操作,各位数的运算结果最多两位,用动态扫描数码管显示运算结果。
二、小组成员
三、实现方法
系统组成及连接原理如图所示,主要由由七个功能模块组成:分频模块(为键盘扫
描模块和防抖模块提供时钟)、键盘扫描驱动模块(依次置零)、键盘按键值编码模
块、键盘编码值防抖模块、运算模块,数码管显示驱动模块、动态扫描驱动模块。
1.分频模块
由于FPGA实验板的原始时钟频率高达33.8688MHz,所以不能直接接入设计模块中使用,就需要用到分频模块。将33.8688MHz分频到4KHz和10Hz来使用,一个用于行驱动扫描时钟,一个用于防抖模块。所以,采用写一个可变分频元件来调用。元件视图:
主要代码如下(完整代码见附录,下同):
architecture RTL of freq_division is
component fredivn is
generic(n:positive);
Port ( clkin:in STD_LOGIC;
clkout:out STD_LOGIC);
end component;
begin
U1:fredivn
generic map(n=>3)
port map(clkin=>clk,clkout=>clkout_kb);
end RTL;
仿真结果如下图:达到预期的目的
2.行驱动模块(依次对行置零):
键盘扫描的原理就是检测行列信号然后判断出具体是按下了哪一个按键。所以,对行依次置零,当置零频率较快时,按下某一个按键后,一定能得到某一列的信号输出为零,如下图:
当行信号为1110时,若按下了0键,就会得到1110的列信号,立马就快可以译码出按键值,若按下4键、8键、C键则都不会有输出。
主要代码如下:
process(clkin)
begin
if clr='1' then count<="00";
elsif rising_edge(clkin) then
if count="11" then count<="00";
else count<=count+1;
end if;
end if;
end process;
process(count)
begin
if count="01" then keydrv<="1110";
elsif count="10" then keydrv<="1101";
elsif count="11" then keydrv<="1011";
elsif count="00" then keydrv<="0111";
end if;
end process;
仿真结果如下图:达到预期的目的
3.键值编码模块
依据行驱动模块,当按下某一个按键后,立马可以根据行列和并位信号得到唯一的键盘编码值,用5位矢量来保存结果,当没有按键按下时,编码值一直保持着‘11111’不变,并在后端的模块中不对其做任何处理。
process(clk)
begin
if clr='0' then
if rising_edge(clk) then
if temp1="11101110" then
keyvalue1<="00000"; --0 elsif temp1="11101101" then
keyvalue1<="00001"; --1 elsif temp1="11101011" then
keyvalue1<="00010"; --2 elsif temp1="11100111" then
keyvalue1<="00011"; --3 elsif temp1="11011110" then
keyvalue1<="00100"; --4 elsif temp1="11011101" then
keyvalue1<="00101"; --5 elsif temp1="11011011" then
keyvalue1<="00110"; --6 elsif temp1="11010111" then
keyvalue1<="00111"; --7 elsif temp1="10111110" then
keyvalue1<="01000"; --8 elsif temp1="10111101" then
keyvalue1<="01001"; --9 elsif temp1="10111011" then
keyvalue1<="01010"; --10 elsif temp1="10110111" then
keyvalue1<="01011"; --11 elsif temp1="01111110" then
keyvalue1<="01100"; --12 elsif temp1="01111101" then
keyvalue1<="01101"; --13 elsif temp1="01111011" then
keyvalue1<="01110"; --14 elsif temp1="01110111" then
keyvalue1<="01111"; --15 end if;
end if;
end if;
end process;
波形仿真如下图:
4.防抖模块
键盘按键物理模型如下:
通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。一般来说,软件消抖的方法是不断检测按键值,直到按键值稳定。实现方法:假设未按键时输入1,按键后输入为0,抖动时不定。可以做以下检测:检测到按键输入为0之后,延时5ms~10ms,再次检测,如果按键还为0,那么就认为有按键输入。延时的5ms~10ms恰好避开了抖动期。
本模块是采用多次采样来达到防抖的,只有在给定的采样次数内,都保证采样结果一致时才会输出按键编码值。
主要代码如下:
case count is
when "0000"=> test1<=temp;
when "0001"=> test2<=temp;
when "0010"=> test3<=temp;
when "0011"=> test4<=temp;
when "0100"=> test5<=temp;
when "0101"=> test6<=temp;
when "0110"=> test7<=temp;
when "0111"=> test8<=temp;
when "1000"=> test9<=temp;
when "1001"=> test10<=temp;
when "1010"=> test11<=temp;
when "1011"=> test12<=temp;
温馨推荐
您可前往百度文库小程序
享受更优阅读体验
不去了
立即体验
when "1100"=> test13<=temp;
when "1101"=> test14<=temp;
when "1110"=> test15<=temp;
when "1111"=> test16<=temp;
when others=>null;
end case;
if test1=test5 and test2=test6 and test3=test7 and test4=test8 and test5=test9 and test6=test10 and test7=test11 and test8=test12 and test9=test13 and test10=test14 and test11=test15 and test12=test16 and test1 /= "UUUUUUUU" then
仿真波形如下:
从图中可以看出最终temp1从临时信号temp得到最终输出,达到防抖:
5.运算模块
当前段的模块经过防抖处理以后得到稳定的按键信号,比如1+2=3,转化为编码值就是11101101 10111011 01111101 11100111 => ED BB EB 7D E7(具体编码表见附录) 主要代码如下:
if ysfh=0 then result<=first+second;
elsif ysfh=1 then result<=first-second;
elsif ysfh=2 then result<=first*second;
end if; n<=n+'1';
elsif n="100" then
n<="000";
end if;
end if;
end process;
process (n)
begin
if n="001"then keyvaluein<=conv_std_logic_vector(first,8);
elsif n="011"then keyvaluein<=conv_std_logic_vector(second,8);
elsif n="100"then keyvaluein<=conv_std_logic_vector(result,8);
end if;
end process;
仿真波形如下:
以1+3=4和5x6=30为例:
编码:01 + 03 =04 05 X 06 =1E
6.数码管显示模块以及动态扫描模块
由于次两个模块是密切相关的,所以统一到一起验证。
经过运算得到最终的显示结果后,要在七段数码管中显示,就必须有每一个数的七段码,同时,由于前面的运算模块的结果最大可以达到81,也就是需要8位二进制,两位十进制来表示,所以就必须通过显示模块来分离出十位和个位。
分离出十位和个位以后,就必须要利用动态扫描使两个数都能显示出来。因为8个七段数码管的abcdefg位是连在一起的,只有利用分时间隔来显示,一次使能一个数码管,显示一位数,当频率较高时,就可以得到两位数的显示效果。
数码管显示模块主要代码如下:
if num=0 then
ten:=0;one:=10;
elsif num<10 and num>0then
ten:=0;one:=num;
elsif num<20 and num>9 then
ten:=1;one:=num-10;
elsif num<30 and num>19 then
ten:=2;one:=num-20;
elsif num<40 and num>29 then
ten:=3;one:=num-30;
elsif num<50 and num>39 then
ten:=4;one:=num-40;
elsif num<60 and num>49 then
ten:=5;one:=num-50;
elsif num<70 and num>59 then
ten:=6;one:=num-60;
elsif num<80 and num>69 then
ten:=7;one:=num-70;
elsif num<90 and num>79 then
ten:=8;one:=num-80;
elsif num<100 and num>89 then
ten:=9;one:=num-90;
end if;
t<=conv_std_logic_vector(ten,4);
o<=conv_std_logic_vector(one,4);
动态扫描模块主要代码如下:
if count="00" then
showout<=show1;en<="00000010";
elsif count="01" then
showout<=show2;en<="00000001";
end if;
仿真波形如下:
数码显示模块
Show1是十位数,show2是个位数,分别为7E(七段码十六进制)和30,即01。
扫描显示模块
数码管使能信号en依次在01和02中变化,翻译成八段码就是00000001和00000010
四、 模块调用
将上述模块按照层次调用,就可以得到最顶层的文件,完成计算器的所有要求功能。 调用图如下:
最终的仿真波形如下:
01 =>showout 0110000 30
02 =>showout 1101101 6D
03 =>showout 1111001 79
由以上波形可以看出:01 + 02 = 03的计算完成了。
五、
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
本次EDA设计实践,完成了从VHDL代码编写到硬件实现的整个流程,掌握了一些FPGA 的相关概念以及ISE软件和Active-HDL软件的使用方法。最重要的就是组员之间的合作,因为VHDL程序是模块化编写的,所以不同模块是由不同人来完成编译的,要达到各个模块之间能够良好的衔接通信,就必须有一个很好的沟通交流,把大家的思路集中起来,一起讨论、编写、调试程序。
【附录一】
完整程序:
【附录二】
芯片参数及开发平台
芯片参数
类型 SpartarⅡ
型号XC2S50
速率 -4
封装 PQ208
开发平台软件
Xilinx ISE 10.1