您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 电子设计/PCB > 键盘及计算器VHDL仿真
电子设计自动化EDA简易计算器设计简易计算器设计——EDA实验报告一、实验内容实验要求:完成个位数的加减乘运算,输入用矩阵键盘,输出用数码管显示,每输入一次数据要显示在数码管上。矩阵键盘共16个按键,用其中10个做个位数的输入,用3个分别做加减乘运算,用其中1个做等于操作,各位数的运算结果最多两位,用动态扫描数码管显示运算结果。二、小组成员三、实现方法系统组成及连接原理如图所示,主要由由七个功能模块组成:分频模块(为键盘扫描模块和防抖模块提供时钟)、键盘扫描驱动模块(依次置零)、键盘按键值编码模块、键盘编码值防抖模块、运算模块,数码管显示驱动模块、动态扫描驱动模块。1.分频模块由于FPGA实验板的原始时钟频率高达33.8688MHz,所以不能直接接入设计模块中使用,就需要用到分频模块。将33.8688MHz分频到4KHz和10Hz来使用,一个用于行驱动扫描时钟,一个用于防抖模块。所以,采用写一个可变分频元件来调用。元件视图:分频行驱动键盘矩阵键值编码防抖运算数码管显动态显示数码管时钟电子设计自动化EDA简易计算器设计主要代码如下(完整代码见附录,下同):architectureRTLoffreq_divisioniscomponentfredivnisgeneric(n:positive);Port(clkin:inSTD_LOGIC;clkout:outSTD_LOGIC);endcomponent;beginU1:fredivngenericmap(n=3)portmap(clkin=clk,clkout=clkout_kb);endRTL;仿真结果如下图:达到预期的目的2.行驱动模块(依次对行置零):键盘扫描的原理就是检测行列信号然后判断出具体是按下了哪一个按键。所以,对行依次置零,当置零频率较快时,按下某一个按键后,一定能得到某一列的信号输出为零,如下图:电子设计自动化EDA简易计算器设计当行信号为1110时,若按下了0键,就会得到1110的列信号,立马就快可以译码出按键值,若按下4键、8键、C键则都不会有输出。主要代码如下:process(clkin)beginifclr='1'thencount=00;elsifrising_edge(clkin)thenifcount=11thencount=00;elsecount=count+1;endif;endif;endprocess;process(count)beginifcount=01thenkeydrv=1110;elsifcount=10thenkeydrv=1101;elsifcount=11thenkeydrv=1011;elsifcount=00thenkeydrv=0111;endif;endprocess;仿真结果如下图:达到预期的目的3.键值编码模块依据行驱动模块,当按下某一个按键后,立马可以根据行列和并位信号得到唯一的键盘编码值,用5位矢量来保存结果,当没有按键按下时,编码值一直保持着‘11111’不变,并在后端的模块中不对其做任何处理。以下列出部分编码表(完整编码表见附录):十进制数行&列HEX七段码HEX011101110EE11111107E411011110DE011001133511011101DD10110115B主要代码如下:电子设计自动化EDA简易计算器设计process(clk)beginifclr='0'thenifrising_edge(clk)theniftemp1=11101110thenkeyvalue1=00000;--0elsiftemp1=11101101thenkeyvalue1=00001;--1elsiftemp1=11101011thenkeyvalue1=00010;--2elsiftemp1=11100111thenkeyvalue1=00011;--3elsiftemp1=11011110thenkeyvalue1=00100;--4elsiftemp1=11011101thenkeyvalue1=00101;--5elsiftemp1=11011011thenkeyvalue1=00110;--6elsiftemp1=11010111thenkeyvalue1=00111;--7elsiftemp1=10111110thenkeyvalue1=01000;--8elsiftemp1=10111101thenkeyvalue1=01001;--9elsiftemp1=10111011thenkeyvalue1=01010;--10elsiftemp1=10110111thenkeyvalue1=01011;--11elsiftemp1=01111110thenkeyvalue1=01100;--12elsiftemp1=01111101thenkeyvalue1=01101;--13elsiftemp1=01111011thenkeyvalue1=01110;--14elsiftemp1=01110111thenkeyvalue1=01111;--15endif;endif;endif;endprocess;波形仿真如下图:电子设计自动化EDA简易计算器设计4.防抖模块键盘按键物理模型如下:通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。一般来说,软件消抖的方法是不断检测按键值,直到按键值稳定。实现方法:假设未按键时输入1,按键后输入为0,抖动时不定。可以做以下检测:检测到按键输入为0之后,延时5ms~10ms,再次检测,如果按键还为0,那么就认为有按键输入。延时的5ms~10ms恰好避开了抖动期。本模块是采用多次采样来达到防抖的,只有在给定的采样次数内,都保证采样结果一致时才会输出按键编码值。主要代码如下:casecountiswhen0000=test1=temp;when0001=test2=temp;when0010=test3=temp;when0011=test4=temp;when0100=test5=temp;when0101=test6=temp;when0110=test7=temp;when0111=test8=temp;when1000=test9=temp;when1001=test10=temp;when1010=test11=temp;when1011=test12=temp;电子设计自动化EDA简易计算器设计when1100=test13=temp;when1101=test14=temp;when1110=test15=temp;when1111=test16=temp;whenothers=null;endcase;iftest1=test5andtest2=test6andtest3=test7andtest4=test8andtest5=test9andtest6=test10andtest7=test11andtest8=test12andtest9=test13andtest10=test14andtest11=test15andtest12=test16andtest1/=UUUUUUUUthen仿真波形如下:从图中可以看出最终temp1从临时信号temp得到最终输出,达到防抖:5.运算模块当前段的模块经过防抖处理以后得到稳定的按键信号,比如1+2=3,转化为编码值就是11101101101110110111110111100111=EDBBEB7DE7(具体编码表见附录)主要代码如下:ifysfh=0thenresult=first+second;elsifysfh=1thenresult=first-second;elsifysfh=2thenresult=first*second;endif;n=n+'1';elsifn=100thenn=000;endif;endif;endprocess;process(n)beginifn=001thenkeyvaluein=conv_std_logic_vector(first,8);elsifn=011thenkeyvaluein=conv_std_logic_vector(second,8);elsifn=100thenkeyvaluein=conv_std_logic_vector(result,8);endif;endprocess;仿真波形如下:以1+3=4和5x6=30为例:编码:01+03=0405X06=1E电子设计自动化EDA简易计算器设计6.数码管显示模块以及动态扫描模块由于次两个模块是密切相关的,所以统一到一起验证。经过运算得到最终的显示结果后,要在七段数码管中显示,就必须有每一个数的七段码,同时,由于前面的运算模块的结果最大可以达到81,也就是需要8位二进制,两位十进制来表示,所以就必须通过显示模块来分离出十位和个位。分离出十位和个位以后,就必须要利用动态扫描使两个数都能显示出来。因为8个七段数码管的abcdefg位是连在一起的,只有利用分时间隔来显示,一次使能一个数码管,显示一位数,当频率较高时,就可以得到两位数的显示效果。数码管显示模块主要代码如下:ifnum=0thenten:=0;one:=10;elsifnum10andnum0thenten:=0;one:=num;elsifnum20andnum9thenten:=1;one:=num-10;elsifnum30andnum19thenten:=2;one:=num-20;elsifnum40andnum29thenten:=3;one:=num-30;elsifnum50andnum39thenten:=4;one:=num-40;elsifnum60andnum49thenten:=5;one:=num-50;elsifnum70andnum59then电子设计自动化EDA简易计算器设计ten:=6;one:=num-60;elsifnum80andnum69thenten:=7;one:=num-70;elsifnum90andnum79thenten:=8;one:=num-80;elsifnum100andnum89thenten:=9;one:=num-90;endif;t=conv_std_logic_vector(ten,4);o=conv_std_logic_vector(one,4);动态扫描模块主要代码如下:ifcount=00thenshowout=show1;en=00000010;elsifcount=01thenshowout=show2;en=00000001;endif;仿真波形如下:数码显示模块Show1是十位数,show2是个位数,分别为7E(七段码十六进制)和30,即01。扫描显示模块数码管使能信号en依次在01和02中变化,翻译成八段码就是00000001和00000010电子设计自动化EDA简易计算器设计四、模块调用将上述模块按照层次调用,就可以得到最顶层的文件,完成计算器的所有要求功能。调用图如下:最终的仿真波形如下:01=showout01100003002=showout11011016D03=showout111100179时钟模块:分频行驱动键盘编码防抖模块运算模块数码管显示扫描显示顶层文件键盘后端处理电子设计自动化EDA简易计算器设计由以上波形可以看出:01+02=03的计算完成了。五、总结本次EDA设计实践,完成
本文标题:键盘及计算器VHDL仿真
链接地址:https://www.777doc.com/doc-1974909 .html