文档库

最新最全的文档下载
当前位置:文档库 > 基于VHDL的多功能电子钟

基于VHDL的多功能电子钟

数字系统课程设计报告

课程设计题目:基于vhdl语言的电子钟

组员:陈洪彬,麦俊辉,缪超

课程设计要求:

设计一个用4位数码管显示的电子钟,包括整点报时,闹钟功能,4按键输入

采用 VHDL 语言描述系统功能,并在 QUARTUS II 工具软件中进行仿真,下载到 EDA 实验板进行验证。编写设计报告,要求包括方案选择、程序代码清单、调试过程、测试结果及心得体会。

一、软硬件资源分析

实验室提供了Altera公司的cyclone系列EP1C6Q240C8实验开发板,该开发板提供了四个自由按键,八个发光LED,蜂鸣器,四个七段数码管,四位拨码开关等等硬件资源。我们所设计的数字钟用到了四个自由按键用于对显示的选择,对设置时间的选择,还有用于用于设置时间时的加一操作,四个七段数码管用于显示,蜂鸣器用于整点报时和闹钟,还有四个发光LED用于判断自由按键的通断。以下列表对数字钟中用到的硬件资源进行说明:

基于VHDL的多功能电子钟

基于VHDL的多功能电子钟

总体设计框图:

基于VHDL的多功能电子钟

基于VHDL的多功能电子钟

基于VHDL的多功能电子钟

Key1的1表示闹钟,0表示时钟;

Key2则是‘时-分’切换或者‘时分-分秒’切换。

各模块介绍

基于VHDL的多功能电子钟

(1)分频器

在数字钟的设计中,采用了芯片内部提供的

50MHz 全局时钟,将其分频率后产生一个接近 1Hz

秒时钟 clk1,一个 2Hz 左右的闪烁时钟clk2,一

个显示模块800Hz的clk3,一个用于消抖模块的

20000Hz的clk4。clk1作用是:每秒产生一个脉冲,

触发“秒”的累加。clk2作用是:在修改状态下通

过判断clk2的电平值来决定数码管的亮灭。clk3作

用是:作为扫描频率刷新数码管的示数。具体做法

是令clk不断产生50MHz的方波,同时clk作为累加

器的触发源。当累加器累计到一定数目时,使

clk1,clk2,clk3,clk4的电平发生跳转,从而输出

不同频率的方波。

设计要点:例如要产生20000Hz,即周期50us。50,000,000/20000=2500,即使50MHz的晶振频率作为累加触发源,累计到1250个方波则使clk4状态反转。

程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

ENTITY distribu1 IS

PORT(

clk:IN STD_LOGIC;--晶振时钟

clk1: BUFFER STD_LOGIC; --1Hz,用于秒的增加

clk2: BUFFER STD_LOGIC;--2Hz,用于修改时间的闪烁

clk3: BUFFER STD_LOGIC;--800Hz,显示模块的扫描时钟

clk4: BUFFER STD_LOGIC);--20000Hz消除抖动的扫描时钟END ENTITY distribu1;

ARCHITECTURE one OF distribu1 IS

BEGIN

dividefreq1Hz:PROCESS(clk) --1Hz

VARIABLE z1: integer range 0 to 25000000;

BEGIN

IF(clk'event AND clk='1')THEN

z1:=z1+1;

if z1=25000000 then

z1:=0;

clk1<= not clk1; --25,000,000 END IF;

END IF;

END PROCESS dividefreq1Hz;

dividefreq2Hz:PROCESS(clk) --2Hz

VARIABLE z2: integer range 0 to 12500000;

BEGIN

IF(clk'event AND clk='1')THEN

z2:=z2+1;

if z2=12500000 then

z2:=0;

clk2<= not clk2;

END IF;

END IF;

END PROCESS dividefreq2Hz;

dividefreq800Hz:PROCESS(clk) --800Hz

VARIABLE z3: integer range 0 to 31250;

BEGIN

IF(clk'event AND clk='1')THEN

z3:=z3+1;

if z3=31250 then

z3:=0;

clk3<= not clk3;

END IF;

END IF;

END PROCESS dividefreq800Hz;

dividefreq02MS:PROCESS(clk) --0.05ms,20000Hz

VARIABLE z4 : integer range 0 to 1250;

BEGIN

IF(clk'event AND clk='1')THEN

z4:=z4+1;

if z4=1250 then

z4:=0;

clk4<= not clk4;

END IF;

END IF;

END PROCESS dividefreq02mS;

END one;

仿真:由于信号频率相差较大,所以仿真结果以clk4为代表,另外几个信号没有显示得出来:

基于VHDL的多功能电子钟

(2)消除抖动模块

该数字钟将用到 4个自由按键,故程序只对这四个开关进行去抖。

去抖原理如下:机械开关在按下时都会一定的抖动,对应信号线电平的变化有一个不稳定期,在读取按键状态时必须避开这个不稳定期,以免造成误判。本文采用了这延迟算法进行去抖。利用频率较高的时钟(本文采用了扫描时钟 clk)反复读取按键状态,并利用一个寄存器来记录当前状态出现的次数,如果当前状态与前一次读取的状态不一样,则将计

基于VHDL的多功能电子钟

数寄存器清零;如果当前状态与前一次读取

的状态一致,刚计数寄存器加 1。当计数寄

存器达到一定值 N 时便认为按键已按下并

产生了一个电平改变。

设计要点:虽然我们采用4位自由开关,

实际上其中key1,key2,和key3充当拨码开

关的功能,而key4实现按键功能拨码开关与

自由按键的处理是不同的,因为拨码开关是

有两个稳定状态的,即可任意长时间处于‘0’或‘1’态,而自由按键只有一个稳态,例如在实验板上,未进行操作时自由按键的输出默认是高电平,如果按一下,变为低电平,操作者一旦松手,按键输出自动恢复为高电平。因此在处理时,让自由按键一次按便输出一个脉冲(相当于进行了两次电平转换,而不是一次)。

程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY debounce2 IS

PORT(

clk4: IN STD_LOGIC; --消除抖动的扫描时钟

key1in:IN STD_LOGIC;--按键的输入

key1out:BUFFER STD_LOGIC;--按键的输出

key2in:IN STD_LOGIC;

key2out:BUFFER STD_LOGIC;

key3in:IN STD_LOGIC;

key3out:BUFFER STD_LOGIC;

key4in:IN STD_LOGIC;

key4out:BUFFER STD_LOGIC);

END debounce2 ;

ARCHITECTURE behave OF debounce2 IS

BEGIN

pkey1:PROCESS(clk4,key1out)

VARIABLE count1 : integer range 0 to 100; ---处理抖动的时为0.2msX100=20ms

BEGIN

if key1in='0' then

IF(clk4'EVENT AND clk4 = '1') THEN

if count1=100 then count1:=count1;--20ms后结束处理

else count1:=count1+1;

end if;

if count1=99 then key1out<= not key1out; --延时到后状态反转

else key1out<=key1out;

end if;

end if;

else count1:=0;

end if;

END PROCESS pkey1;

pkey2:PROCESS(clk4,key2out)

VARIABLE count2 : integer range 0 to 100;

BEGIN

if key2in='0' then

IF(clk4'EVENT AND clk4 = '1') THEN

if count2=100 then count2:=count2;

else count2:=count2+1;

end if;

if count2=99 then key2out<= not key2out;

else key2out<=key2out;

end if;

end if;

else count2:=0;

end if;

END PROCESS pkey2;

pkey3:PROCESS(clk4,key3out)

VARIABLE count3 : integer range 0 to 100;

begin

if key3in='0' then

IF(clk4'EVENT AND clk4 = '1') THEN

if count3=100 then count3:=count3;

else count3:=count3+1;

end if;

if count3=99 then key3out<=not key3out;

else key3out<=key3out;

end if;

end if;

else count3:=0;

end if;

END PROCESS pkey3;

pkey4:PROCESS(clk4,key4out) --Key4out不同以上处理

VARIABLE count4 : integer range 0 to 100;

BEGIN

if key4in='0' then

IF(clk4'EVENT AND clk4 = '1') THEN

if count4=100 then count4:=count4;

else count4:=count4+1;

end if;

if count4=99 then key4out<= '1';--延时20ms后给key4out 一个上升沿

else key4out<='0';---其余时间key4out都为'0'

end if;

end if;

else count4:=0;

end if;

END PROCESS pkey4;

END behave;

我们在仿真时,由于消抖时时钟周期要求过大,我们对消抖时间对应的时钟周期进行改动,将其改小,从而从仿真中可以看出消抖的效果,我们设消抖的延迟时间为八个时钟周期,则仿真结果如下:

基于VHDL的多功能电子钟

从图中看出,已经实现消抖。

(3)时间设置模块:

主要分为手动增值和自动增值两个进程。当key4按下,且key3out=’1’时进入手动增值模式。Key2和key1在不同状态对应不同的情况,分别是时钟小时,时钟分钟,闹钟小时,闹钟分钟。自动增值和手动增值都要在更新了要加的值之后才进行上述的增值。由于更新的需要,要把输出端的“a”和“b”互相传输,所以设置了一组“ain”和“bin”来过渡,且VHDL不能把输出口值赋给输入口,所以在原理图上强制把输出口连接到输入口。

小时部分:将小时分成两位分别设置,当小时十位为0010,个位是0011,即为23点的时候,再加一就将十位个位都设置为0000。而其他情况中,小时将加从0000到0010(2)循环运行。而小时个位为从0000到1001(即为9)循环运行。当分钟部分,十位为0101,而个位为1001(即59分)再加一时,小时个位加一;当小时个位从1001(9)加一时,小时十位加一。时间设置时,选定设置位,key4in按下时,选定位加一。

分钟部分:分钟部分也分为十位及个位分别设置,当小时为十位0101而个位是1001(即59分)时,再加一就将十位和个位都清零。而其他情况,十位按照0000到0101(0到5)循环,个位从0000到1001(0到

基于VHDL的多功能电子钟

59秒)再加一时,分钟个位加一;当分钟个位从1001

(9)加一时,分钟十位加一。时间设置时,选定设置

位,key4in按下时,选定位加一。

秒钟部分:跟分钟一样,秒钟部分也分为十位及个

位分别设置,当十位0101而个位是1001(即59分)

时,再加一就将十位和个位都清零。而其他情况,十位

按照0000到0101循环,个位从0000到1001(0到9)

循环。其正常时间工作时个位在1HZ脉冲上升沿来到时

加一。时间设置时,选定设置位,key4in按下时,选定

位加一。

闹钟时间设置:本模块分4个进程,分别对闹钟时

间的小时十位,小时个位,分钟十位,分钟个位进行检

测,每个进程均以芯片的晶振50MHz进行触发。对分

钟个位,来一个时钟的上升沿,检测按键输出状态,当

key1out='1' and key2out='0' and key3out='1' 时每输入

一个key4in信号脉冲使得key4out来上升沿则闹钟设置

的分钟个位加1,当个位加到9,再加一次则复位为0;

下一个进程检测分钟十位,每来一个时钟上升沿,在对

应的按键状态下,当个位为9时,再来一个key4out上

升沿脉冲则分钟十位加1,当加到十位为5,个位为9,

则再加一次就复位为0。同样原理设计闹钟小时部分。

自动增值则是由每一个1Hz的clk上升沿触发,每秒加一次。

程序如下:

library ieee;

use ieee.std_logic_1164.all;

use IEEE.STD_LOGIC_ARITH.ALL;

use ieee.std_logic_unsigned.all;

entity shijian2 is

port(

clk:in std_logic;

key1out:in std_logic; ---按键状态

key2out:in std_logic;

key3out:in std_logic;

key4out:in std_logic;

hou1a:buffer std_logic_vector(3 downto 0); -- 手动修改后的时间数据

hou2a:buffer std_logic_vector(3 downto 0);

min1a:buffer std_logic_vector(3 downto 0);

min2a:buffer std_logic_vector(3 downto 0);

seth1a: buffer std_logic_vector(3 downto 0); ---手动修改后或没有修改的闹钟数据

seth2a: buffer std_logic_vector(3 downto 0);

setm1a: buffer std_logic_vector(3 downto 0);

setm2a: buffer std_logic_vector(3 downto 0);

hou1b:buffer std_logic_vector(3 downto 0); ---每1秒自动加1的时钟数据

hou2b:buffer std_logic_vector(3 downto 0);

min1b:buffer std_logic_vector(3 downto 0);

min2b:buffer std_logic_vector(3 downto 0);

sec1b:buffer std_logic_vector(3 downto 0);

sec2b:buffer std_logic_vector(3 downto 0);

hou1ain:in std_logic_vector(3 downto 0); --若之前为手动修改时间模式的数据,

hou2ain:in std_logic_vector(3 downto 0); --要把修改后的时钟数据赋值给“b”代表显示模式的数据(即刷新)

min1ain:in std_logic_vector(3 downto 0);

min2ain:in std_logic_vector(3 downto 0);

hou1bin:in std_logic_vector(3 downto 0); ----用于更新a的值

hou2bin:in std_logic_vector(3 downto 0);

min1bin:in std_logic_vector(3 downto 0);

min2bin:in std_logic_vector(3 downto 0)

);

end entity shijian2;

architecture one of shijian2 is

begin

--hou1ain<=hou1a;-----已在电路图上连线

--hou2ain<=hou2a;

--min1ain<=min1a;

--min2ain<=min2a;

--hou1bin<=hou1b;

--hou2bin<=hou2b;

--min1bin<=min1b;

--min2bin<=min2b;

shoudong:process(key1out,key2out,key3out,key4out) ----手动修改

begin

if key3out='0' then

hou1a<=hou1bin; ----更新a的值

hou2a<=hou2bin;

min1a<=min1bin;

min2a<=min2bin;

elsif(key4out'event and key4out='1') then

if(key3out='1'AND key2out='0' AND key1out='0')then ----校时钟小时位,手动加1脉冲

if hou2a="0011" and hou1a="0010" then ----检查进位,“a"代表手动修改模式的数据

hou2a<="0000";

hou1a<="0000";

elsif hou2a="1001" then

hou1a<=hou1a+1;

hou2a<="0000";

else hou2a<=hou2a+1;

end if;

elsif (key3out='1'AND key2out='1' AND key1out='0')then-----校时钟分钟位,手动加1脉冲

if min2a="1001" and min1a="0101" then ----检查进位

min2a<="0000";

min1a<="0000";

elsif min2a="1001" then

min2a<="0000";

min1a<=min1a+1;

else min2a<=min2a+1;

end if;

elsif (key3out='1'AND key2out='0' AND key1out='1')then ------校闹钟小时位,手动加1脉冲if seth2a="0011" and seth1a="0010" then ----检查进位

seth2a<="0000";

seth1a<="0000";

elsif seth2a="1001" then

seth1a<=seth1a+1;

seth2a<="0000";

else seth2a<=seth2a+1;

end if;

elsif (key3out='1'AND key2out='1' AND key1out='1')then ------校闹钟分钟位,手动加1脉冲if setm2a="1001" and setm1a="0101" then ----检查进位

setm2a<="0000";

setm1a<="0000";

elsif setm2a="1001" then

setm2a<="0000";

setm1a<=setm1a+1;

else setm2a<=setm2a+1;

end if;

end if;

end if;

end process;

zidong:process(key1out,key3out,key4out,clk) ----每1秒自动加1

if( key3out='1' and key1out='0') then ---若之前为手动修改时间模式,要把修改后的时钟数据赋给“b”(即刷新)

---key3out的“1”代表修改,key1out的“0”代表时钟而不是闹钟

hou1b<=hou1ain; --“b”代表显示模式的数据

hou2b<=hou2ain;

min1b<=min1ain;

min2b<=min2ain;

elsif key4out='0' then ----key4没有按下

if( clk'event and clk='1') then

if sec2b="1001" then

sec2b<="0000";

sec1b<=sec1b+1;

if sec1b="0101" then

sec1b<="0000";

min2b<=min2b+1;

if min2b="1001" then

min2b<="0000";

min1b<=min1b+1;

if min1b="0101" then

min1b<="0000";

if hou1b="0010" and hou2b="0011" then

hou1b<="0000";

hou2b<="0000";

elsif hou2b="1001" then

hou2b<="0000";

hou1b<=hou1b+1;

else hou2b<=hou2b+1;

end if;

end if;

end if;

end if;

ELSE sec2b<=sec2b+1;

end if;

END IF;

END IF;

end process;

仿真:(由于仿真限制,仿真用了clk代替clk1)

1)手动增值

基于VHDL的多功能电子钟

2)自动增值

基于VHDL的多功能电子钟

(4)按键显示发光LED模块:

基于VHDL的多功能电子钟

此模块主要功能是帮助确认按键所处的状态,从而确定数字钟显示的内容。这个模块利用发光LED与按键消抖后的输出相连,当输出为低电平时,即按键按下时,点亮LED,而输出为高电平时,即没有按下按键时,LED熄灭。

仿真结果:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

---------按键显示模块,按键按下,相应的led则发光或熄

ENTITY ledkey IS

PORT( key1out:IN STD_LOGIC; architecture behave of ledkey is key2out:IN STD_LOGIC; begin

key3out:IN STD_LOGIC; process(key1out,key2out,key3out) key4out:IN STD_LOGIC; begin

led1out: out STD_LOGIC; if key1out='0' then led1out<='0';

led2out: out STD_LOGIC; else led1out<='1';

led3out: out STD_LOGIC; end if;

led4out: out STD_LOGIC); if key2out='0' then led2out<='0'; end entity; else led2out<='1';

end if;

if key3out='0' then led3out<='0';

else led3out<='1';

end if;

if key4out='0' then led4out<='0';

else led4out<='1';

end if;

end process;

end behave;

仿真结果:

基于VHDL的多功能电子钟

(5)声音模块:

基于VHDL的多功能电子钟

本模块只包括1个进程,进程分为3个判断的

部分。分别为闹钟时间到的发声和整点报时到的发

声。第一个部分判断是否处于时钟显示模式且key4

是否按下,如果都满足则赋高电平给蜂鸣器输出端

口beep,使其不发出声音。第二个部分判断时钟

时间是否与闹钟时间相等,若是,则把低电平信号

赋给蜂鸣器输出端口beep,直到手动按停。如果

期间按键4按下key4out='0'则停止发声。第三个部

分判断是否整点到了。到了59分,52秒,54秒,

56秒时把clk3赋给beep,使其发声,58秒时赋一

个高电平‘1’给beep,达到最后一个音的音调

变高的效果。其余的50,21,53,55,57,59秒赋低电平

给蜂beep高电平停止发声。

程序:

library ieee;

use ieee.std_logic_1164.all;

use IEEE.STD_LOGIC_ARITH.ALL;

use ieee.std_logic_unsigned.all;

entity alarm is

port(

key1out:in std_logic;

key2out:in std_logic;

key3out:in std_logic;

key4out:in std_logic;

seth1a:in std_logic_vector(3 downto 0);

seth2a:in std_logic_vector(3 downto 0);

setm1a:in std_logic_vector(3 downto 0);

setm2a:in std_logic_vector(3 downto 0);

hou1b:in std_logic_vector(3 downto 0);

hou2b:in std_logic_vector(3 downto 0);

min1b:in std_logic_vector(3 downto 0);

min2b:in std_logic_vector(3 downto 0);

sec1b:in std_logic_vector(3 downto 0);

sec2b:in std_logic_vector(3 downto 0);

clk3:in std_logic;--------用于整点报时的音调变化

beep:out std_logic

);

end entity alarm;

architecture one of alarm is

begin

process(key4out,seth1a,seth2a,setm1a,setm2a,hou1b,hou2b,min1b,min2b,sec1b,sec2b)

begin

if key4out'event and key4out='1' then--------手动按停声音

if(key3out='0' AND key2out='0' AND key1out='0') or

(key3out='0' AND key2out='1' AND key1out='0')then

beep<='1';

end if;

end if;

if(seth1a=hou1b and seth2a=hou2b and setm1a=min1b and setm2a=min2b and sec1b="0000" and sec2b="0000")then

----闹钟时间到

beep<='0';

end if;

if(min1b="0101" and min2b="1001") then--------整点时间到

if(sec1b="0101") then

if(sec2b="0010" or sec2b="0100" or sec2b="0110") then beep<=clk3;----从52,54,56秒响

elsif(sec2b="1000") then beep<='0';----58秒的音调变高

else beep<='1';----59秒自动停止声音

end if;

else beep<='1';

end if;

end if;

end process;

end one;

仿真:

以下18:00前后,先是整点闹钟响,接着整点报时响。

基于VHDL的多功能电子钟

(6)译码显示以及闪烁模块:

思路:此模块包含4位数码管位选,段选,判断输出显示状态或者设置(修改)状态,判断是否闪烁等功能。通过判断key1~key3的状态来确定给4位数码管输出的内容。

程序分为两个进程,第一个进程用来决定位选与段选。位选部分使用累加器实现每进入一次程序依次循环选中每一位数码管。然后根据检测的情况(时间时--分,时间分—秒,闹钟时--分,闹钟分--秒)把要显示的内容从“中间量”以BCD码的形式赋值给“最终量”,再判断“最终量”代表的数字值,再把数字值相应的段选码送给段选。位选与段选的数据送至数码管就能实现译码显示功能。

第二个进程有两个用途:a.用来更新显示内容,通过不断把即时要显示的内容(时--分或分--秒或不显示)送至“中间量”,由第一个进程送出去输出。b.用来控制闪烁,由clk2(2Hz)判断数码管的亮灭,当clk2=1,把时—分或分—秒的BCD码赋值给“中间量”,即为数码管“亮”;当clk2=0,按情况把选择要闪烁的那两位用“1111”(在进程一内被判定为“灭”)代替BCD码赋值给“中间量”,这样进程一可表现为“灭”。

程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY display2 IS

PORT(

clk2:IN STD_LOGIC; --半秒的驱动

clk3:IN STD_LOGIC; --扫描数码管的驱动频率

dout:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --段选

selout:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --位选

hou1a:in std_logic_vector(3 downto 0); --修改模式的时钟数据

hou2a:in std_logic_vector(3 downto 0);

min1a:in std_logic_vector(3 downto 0);

min2a:in std_logic_vector(3 downto 0);

seth1a:in std_logic_vector(3 downto 0); --闹钟数据(只有一种模式)

seth2a:in std_logic_vector(3 downto 0);

setm1a:in std_logic_vector(3 downto 0);

setm2a:in std_logic_vector(3 downto 0);

hou1b:in std_logic_vector(3 downto 0); --显示模式的时钟数据

hou2b:in std_logic_vector(3 downto 0);

min1b:in std_logic_vector(3 downto 0);

min2b:in std_logic_vector(3 downto 0);

sec1b:in std_logic_vector(3 downto 0);

sec2b:in std_logic_vector(3 downto 0);

key1out:in std_logic;

key2out:in std_logic;

key3out:in std_logic);

END ENTITY display2 ;

ARCHITECTURE behave OF display2 IS

signal sel:std_logic_vector(2 downto 0);

signal h1:std_logic_vector(3 downto 0);

signal h2:std_logic_vector(3 downto 0);

signal m1:std_logic_vector(3 downto 0);

signal m2:std_logic_vector(3 downto 0);

BEGIN--input time as BCD code for each digit

disp1:process(clk3,sel) --传输数据给数码管

begin

if (clk3'event AND clk3='1') then --循环改变位选

if sel="100" then

sel<="001";

else sel<=sel+1;

end if;

if sel="001" then

selout<="0111";

case h1 is --h1,h2,m1,m2是最后要显示的数据(第一级) when "0000"=>dout<="00001100";

when "0001"=>dout<="01101111";

when "0010"=>dout<="10101000";

when "0011"=>dout<="00101001";

when "0100"=>dout<="01001011";

when "0101"=>dout<="00011001";

when "0110"=>dout<="00011000";

when "0111"=>dout<="01101101";

when "1000"=>dout<="00001000";

when "1001"=>dout<="00001001";

when others=>dout<="11111111";

end case;

elsif sel="010" then

selout<="1011";

case h2 is

when "0000"=>dout<="00000100"; when "0001"=>dout<="01100111"; when "0010"=>dout<="10100000"; when "0011"=>dout<="00100001"; when "0100"=>dout<="01000011"; when "0101"=>dout<="00010001"; when "0110"=>dout<="00010000"; when "0111"=>dout<="01100101"; when "1000"=>dout<="00000000"; when "1001"=>dout<="00000001"; when others=>dout<="11110111"; end case;

elsif sel="011" then

selout<="1101";

case m1 is

when "0000"=>dout<="00001100"; when "0001"=>dout<="01101111"; when "0010"=>dout<="10101000"; when "0011"=>dout<="00101001"; when "0100"=>dout<="01001011"; when "0101"=>dout<="00011001"; when "0110"=>dout<="00011000"; when "0111"=>dout<="01101101"; when "1000"=>dout<="00001000"; when "1001"=>dout<="00001001"; when others=>dout<="11111111"; end case;

elsif sel="100" then

selout<="1110";

case m2 is

when "0000"=>dout<="00001100"; when "0001"=>dout<="01101111"; when "0010"=>dout<="10101000"; when "0011"=>dout<="00101001"; when "0100"=>dout<="01001011"; when "0101"=>dout<="00011001"; when "0110"=>dout<="00011000"; when "0111"=>dout<="01101101"; when "1000"=>dout<="00001000";