信息工程学院
课程设计报告
课 程 EDA技术
题 目基于FPGA的密码锁研制
专 业电子信息科学与技术
学 号16181204191618120437
姓 名敬承川 涂 双
指 导 教 师肖敏
学 期2017-2018-1
工作时间:2018年11月至2018年12月
基于FPGA的密码锁研制
学生:敬承川、涂双
指导老师:肖敏
摘要:电子密码锁是通过输入密码来控制芯片和电路工作,从而控制步进电机对锁的开关,完成开锁和关锁的功能。本设计运用了基于可编程门阵列FPGA器件来设计电子密码锁,运用EDA技术自顶向下的设计方法,将电子密码锁系统分解为若干子系统,并进一步细化为若干模块,然后用硬件描述语言VHDL来设计这些模块,使用FPGA的EP2C35F672C8芯片进行硬件测试。测试结果表明该电子密码锁能够校验四组四位二进制密码,用FPGA器件构建电路,所有功能完全由硬件电路来实现,使得系统的可靠性较高,芯片中数据的保密性较高,本设计的四位电子密码锁具有红绿指示灯状态提示、数码显示、LED灯密码位提示、步进电机转动及16*16点阵汉字显示功能。
关键词:电子密码锁 可编程逻辑门阵列FPGA VHDL语言 QuartusⅡ
Development of code lock based on FPGA
Student: Jing ChengChuan,Tu Shuang
Advisor:Xiao Min
Abstract:Electronic cipher lock is to control chip and circuit work through password input, so as to control the stepper motor on the lock switch, complete the task of unlock, lock. The FPGA device design based on programmable gate array (FPGA) is used to design the electronic trick lock, the use of top-down design method of EDA technology, the electronic combination lock system is decomposed into several subsystems, and a further is divided into several modules, and then use hardware description language VHDL to design these modules, use EP2C35F672C8 chip of FPGA hardware testing. Test results show that the electronic combination lock can check four decimal number password, FPGA device with the structure system, all the algorithms completely by hardware circuit, makes the work reliability of the system is greatly improved, the confidentiality of the data is stored in the chip is higher, the design of the four electronic combination lock with the red and green light status indicators, digital display, LED lights password prompt, stepper motor rotation and 16 * 16 dot matrix Chinese character display function.
Keywords:Electronic Password LockFPGAVHDLQuartusⅡ
目录
1.绪论11
1.1选题的意义11
1.2设计的流程11
2.系统设计原理11
2.1 EDA技术及FPGA器件11
2.2系统设计原理及框图22
3.硬件部分33
3.1顶层设计原理图33
3.2 数码显示模块44
3.3 数码位选模块44
3.4 密码比较模块55
3.5 密码比较位控制模块66
3.7 分频模块77
3.8 D触发器88
3.9 各部分硬件使用情况88
4.软件部分99
4.1 QuartusⅡ介绍99
4.2VHDL语言介绍99
4.3硬件连接引脚1010
5.总体实验验证1111
总结1212
参考文献1313
附录VHDL程序1414
1.绪论
1.1选题的意义
随着社会物质财富的日益增长,安全防盗已成为人们所关注的焦点。传统的钥匙锁芯锁安全性低,需随时携带钥匙,无法满足一些特定场合的应用要求,特别是在人员经常变动的公共场所,如办公室、宾馆、汽车、银行柜员机等地方。电子密码锁越来越受到人们的青睐。目前使用的电子密码锁主要有两个方案:一是基于单片机用分立元件实现的,二是通过现代人体生物特征识别技术实现的,前者电路较复杂且灵活性差,无法满足应用要求;后者有其先进性但需考虑成本和安全性等诸多因素。因此,本设计做了一种新型电子密码锁,采用FPGA芯片,利用先进的EDA技术、ALTERA公司的QUATUSII软件开发平台进行设计。
1.2设计的流程
本设计主要工作流程:
- 、查阅文献,了解工作原理,确定方案;
- 、画系统总框图;
- 、确定硬件模块,设计模块电路方案,绘制总电路原理图;
- 、软件QuartusⅡ实现,使用VHDL语言设计;
- 、使用FPGA系列EP2C35F672C8芯片进行硬件测试;
- 、编写课程设计报告。
2.系统设计原理
2.1 EDA技术及FPGA器件
EDA(Electronic Design Automation,电子设计自动化)技术基于计算机辅助设计,它融合了应用电子技术、计算机技术、信息处理技术、智能化技术的最新成果,以实现技术--电子产品的自动设计。利用EDA工具,电子设计师可以完成概念、算法、协议等设计电子系统的工作,实现电子产品从电路设计、性能分析到设计的整个过程在计算机上自动完成。EDA是现代电子设计技术的核心,在现代集成电路设计中占据重要地位。
FPGA(Field Programmable Gate Array,现场可编程门阵列)作为可编程逻辑器件的典型代表,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。它的出现及日益完善适应了当今时代的数字化发展浪潮,它正广泛应用在现代数字系统设计中。
2.2系统设计原理及框图
<1>系统设计原理:
密码锁通过按键和拨码开关给芯片输入信号,芯片通过构建4-7线译码器译码后输出七线信号(八段数码管小数点位未使用)送数码管显示当前密码;芯片通过构建密码比较模块对输入密码进行比较,并输出LED灯,红绿灯、16*16点阵及步进电机控制信号。
通过以上流程,采用EDA技术,FPGA器件实现四位密码控制的电子密码锁功能。
<2>系统总框图:
本系统采用自顶向下的设计方式,各部分功能相互协调,流程明确。为了更加明确各部分的工作,因此在框图中单独把FPGA提出来看,实际上,密码比较模块是在FPGA内部做成的电路
系统总框图2-1
3.硬件部分
以下各模块设计后未进行软件仿真,而分别进行了硬件电路的实际验证,且符合模块设计要求,最后各模块组成顶层电路,再次进行验证,得到了预期的结果。
3.1顶层设计原理图
由于本设计各个模块分布较多且复杂,不利于采用VHDL语言编程实现各个模块的连接,而原理图能够直观表现各模块连接关系和信号流动方向,且便于设计中更改各部分模块的使用,故本设计顶层采用原理图的方式设计。
图3-1
3.2 数码显示模块
数码显示模块采b1,b2,b3,b4四个拨码开关输入4位二进制数,模块译码为七线输出,a,b,c,d,e,f,g分别输出数码管段码信号,实现实时显示拨码开关输入的密码值。供用户确认输入的各位密码值。
图3-2
3.3 数码位选模块
数码位选模块的功能主要是在输入按键按下一次后,k,k1,k2,k3中出现一位信号,控制数码管位选,按键不断按下,表示输入不同位的密码,k,k1,k2,k3依次输入一位高电平信号,a,b,c输出”000”--”011”信号,数码管依次在第0位到第3位显示输入的密码值。以此提示用户应该输入第几位密码。
图3-3
3.4 密码比较模块
密码比较模块中b1,b2,b3,b4代表输入的四位二进制密码,通过对预先设定的密码比较,如果相同,则持续输出高电平,反之,输出持续低电平;
通过密码比较位控制模块确定对比哪一组密码,在设计中,本模块初始化密码为”0001”,”0010”,”0100”,”1000”(取值顺序从左到右)数码管依次显示8421四位密码。密码输入错误则验证不成功。
图3-4
3.5 密码比较位控制模块
密码比较位控制模块中,k0每接收到按键一次高电平,则k,k1,k2,k3依次输出高电平,以此确定密码比较模块中应当比较的密码。(由于实际按键有抖动,按下一次按键会产生电平波动,故在编程中采用了多次高电平累加产生一次进位信号,从一定程度减小误操作)。
图3-5
3.6 点阵显示模块
<1>如图3-6-1点阵字选模块中,clkl 表示输入较低的时钟频率,使在实际显示中每个字变换的速度减慢,en信号由密码比较模块提供,它的高低电平能够控制点阵显示的两组汉字。
点阵扫描模块中,clkh 表示输入较高的时钟频率,使点阵各行扫描速度较快,达到一定速度后,人眼形成残影,从而实现显示汉字的功能。
点阵字库中存储了显示的汉字,扫描方式,通过接收字选信号和扫描信号,产生16+16位输出信号。
图3-6-1
<2>如图3-6-2为方便顶层原理图设计,简化顶层图形复杂度,故将图3-6-1中各模块整合为一个模块,并进行电路验证,原有功能成功实现,模块符合设计要求。
图3-6-2
3.7 分频模块
在电子密码锁中,我们采用的输入时钟信号(CLK)频率为1KHz,通过计数器计数产生震荡,实现分频的功能,图3-7-1中,clk10和clk20实现了不同的降频,用于不同模块需要的频率,图3-7-2中,clk200采用的是clk10和clk20级联的方式实现更大的分频功能的,原因是累计计数会增加误差,而采用级联的方式则减小了这一因素。
图3-7-1
图3-7-2
3.8 D触发器
D触发器使用在按键输入时的消抖电路中,他的使用方式参照了《EDA技术实用教程》中的---逻辑方式去毛刺,并减少了对D触发器的使用,使得按键脉冲能够及时送到相对应的电路中,完成后继操作。
图3-8
3.9 各部分硬件使用情况
以上介绍了各部分模块的设计方式及简单的功能描述,这里介绍一下对实验室硬件资源的使用情况。
<1> LED灯:LED1-LED4分别提示输入的密码是哪一位,4个LED灯同一时刻只能亮一个。
<2> 红绿灯:为方便验证设计,采用红绿灯分别指示密码是否输入正确。
<3> 16*16点阵:显示设计中所需要的汉字提示
<4> 步进电机:密码锁打开时,步进电机开始转动,从形象上表示开锁。
<5> 拨码开关:K1-K4输入组成四位二进制密码供用户输入密码及相关模块验证密码。
<6> 按键:使用S2按键,使数码管产生移位信号、密码验证模块选择验证模块以及LED灯的提示信号。
<7> 数码管:实时显示用户输入的密码值,只有当按键S2按下后才生效,故数码管实时显示的密码值不一定为输入的密码值。
4.软件部分
本设计主要工作是用电脑编程和绘制原理图进行的,运用了QuartusⅡ软件和VHDL硬件描述语言。
4.1 QuartusⅡ介绍
QuartusⅡ是Alt era提供的FPGA/CPLD开发集成环境,也可用于SOPC的设计环境。 QuartusⅡ提供完善的 timing closure 和 Logic Lock 基于块的设计流程。QuartusⅡ包括以timing closure和基于块的设计流为基本特征的PLD的软件,QuartusⅡ设计软件改进了性能、提升了功能性、解决了潜在的设计延迟等,在工业领域率先提供FPGA与mask-programmed devices开发的统一工作流程。QuartusⅡ是Altera公司的综合性CPLD/FPGA开发软件,原理图、VHDL、VERILOG HDL以及AHDL(ALTERA Hardware 支持Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。
在本设计中,我们使用的是Altera公司的QuartusⅡ6.0进行编译 。
4.2VHDL语言介绍
VHDL 的英文全名是VHSIC Hardware Description Language(VHSIC硬件描述语言)。VHSIC是Very High Speed Integrated Circuit的缩写,是20世纪80年代在美国国防部的资助下始创的,并最终导致了VHDL语言的出现。1987 年底,VHDL被 IEEE 和美国国防部确认为标准硬件描述语言。VHDL主要用于描述数字系统的结构,行为,功能和接口。除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可视部分,及端口)和内部(或称不可视部分),既涉及实体的内部功能和算法完成部分。在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。
VHDL语言的优点:设计方式多样、具有强大的硬件描述能力和移植能力、与器件无关、易于共享和复用
4.3硬件连接引脚
图4-3-1
图4-3-1
5.总体实验验证
<1>图片
<2> 实验验证过程见实验视频。
总结
本设计从最初的选题到报告的完结历时一个多月,其中经历了很多次实现方案的改动,与最初的模型有本质上的差别。在这个过程中,我对VHDL语言更加熟悉了,也熟悉了Quartus这个集成开发环境,操作相对以前更加熟练。在实际操作过程中,我遇到了许多问题,最棘手的问题是对VHDL语言的不熟悉,许多知识没有掌握,以至于在编写时经常遇到许多报错,有些错误还能折腾许多时间,由于设计时间相对较少,不支持我这样的慢速低效率,以至于许多预想模块都被搁置,同时采用了太多的小模块降低了电路的可靠性和稳定性。
非常感谢肖敏老师上课时孜孜不倦的讲解和对实验的指导,让我对EDA技术有了初步的了解。同时,感谢那些在设计中给予我们帮助的同学,使我发现并解决了许多问题,才能顺利完成课程设计。
参考文献
- 王显海、贾金玲.基于 FPGA的电子密码锁的研制.四川理工学院,2010年;
- 潘松、黄继业.EDA技术实用教程(第六版)[M].北京:科学出版社,2018年;
附录VHDL程序
1.D触发器
library ieee;
Use ieee .std_logic_1164.ALL;
ENTITY df IS
port (d,clk:in std_logic;
q:out std_logic);
END df;
ARCHITECTURE dff_art OF df IS
BEGIN
PROCESS (clk) IS
BEGIN
IF (clk'EVENT AND clk='1')THEN ---上升沿触发;
q<=d;
END IF;
END PROCESS;
END dff_art;
2.步进电机
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity bujingdianji is
port(
p, d,clk: in std_logic:='0';
coil : out std_logic_vector(3 downto 0));
end bujingdianji;
architecture bujingdianji_jcc of bujingdianji is
signal ind_coil: std_logic_vector(3 downto 0) :="0001";
signal clk_scan: std_logic;
signal phase,fangxiang: std_logic;
signal t: std_logic_vector(3 downto 0);
begin
coil <= t;
process
begin
wait until clk = '1';
clk_scan <= not clk_scan;
end process ;
process(clk)
variable b: std_logic;
begin
if(clk'event and clk='1') then
b:=(b and p);
if b='1' then
phase<=not phase;b:='0';
elsif P='0' then
phase<=phase;b:='1';
end if;
end if;
end process;
process(clk)
variable c:std_logic;
begin
if (clk'event and clk='1') then
c:=(c and d);
if c='1' then
fangxiang<=not fangxiang ;c:='0';
elsif d='0' then
fangxiang<=fangxiang;c:='1';
end if;
end if;
end process;
process
begin
wait until clk_scan= '0';
case phase is
when '1' =>
if fangxiang = '0' then
if ( (ind_coil = "1001" ) or (ind_coil = "0000")) then
ind_coil <= "0001" ;
else
ind_coil <= (ind_coil(2 downto 0) & ind_coil(3));
end if;
else
if ( (ind_coil= "1001" ) or (ind_coil = "0000")) then
ind_coil <= "1000";
else
ind_coil <= (ind_coil(0) & ind_coil(3 downto 1));
end if;
end if;
when others =>
ind_coil <= ind_coil;
end case;
t<=not ind_coil;
end process;
end bujingdianji_jcc;
3.点阵扫描
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dianzhensaomiao is
port(clkh:in std_logic;
q:out std_logic_vector(3 downto 0));
end dianzhensaomiao;
architecture dianzhensaomiao_jcc of dianzhensaomiao is
begin
process(clkh)
variable count:integer;
variable tmpe:std_logic_vector(3 downto 0);
begin
if clkh'event and clkh='1' then
if count<4 then
count:=count+1;
else
count:=0;
if tmpe="0000" then
tmpe:="1111";
else
tmpe:=tmpe-1;
end if;
end if;
end if;
q<=tmpe;
end process;
end dianzhensaomiao_jcc;
4.点阵字选
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dianzhenzixuan is
port(clkl,en:in std_logic;
zi:out std_logic_vector(3 downto 0));
end dianzhenzixuan;
architecture dianzhenzixuan_jcc of dianzhenzixuan is
begin
process(clkl)
variable tmpe:std_logic_vector(3 downto 0);
begin
if(en='1')then
if clkl'event and clkl='1'then
if tmpe="1111"then
tmpe:="0100";
else
tmpe:=tmpe+1;
end if;
end if;
else
if clkl'event and clkl='1'then
if tmpe="0011"then
tmpe:="0000";
Else tmpe:=tmpe+1;
end if;
end if;
end if;
zi<=tmpe;
end process;
end dianzhenzixuan_jcc;
5.点阵字库
library ieee;
use ieee.std_logic_1164.all;
entity dianzhenziku is
port(zi:in std_logic_vector(3 downto 0);
sao:in std_logic_vector(3 downto 0);
lie,hang:out std_logic_vector(15 downto 0));
end dianzhenziku;
architecture dianzhenziku_jcc of dianzhenziku is
begin
process(zi,sao)
begin
case zi is
when"0000"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--爱
when"0001"=>hang<="1111111111111101";lie<="0111111111111110";
when"0010"=>hang<="1111111111111011";lie<="0001001000010000";
when"0011"=>hang<="1111111111110111";lie<="0000100100100000";
when"0100"=>hang<="1111111111101111";lie<="0111111111111110";
when"0101"=>hang<="1111111111011111";lie<="0100010000000010";
when"0110"=>hang<="1111111110111111";lie<="0011111111111100";
when"0111"=>hang<="1111111101111111";lie<="0000100000000000";
when"1000"=>hang<="1111111011111111";lie<="0000111111111000";
when"1001"=>hang<="1111110111111111";lie<="0000110000001000";
when"1010"=>hang<="1111101111111111";lie<="0001001000010000";
when"1011"=>hang<="1111011111111111";lie<="0001000100100000";
when"1100"=>hang<="1110111111111111";lie<="0010000011000000";
when"1101"=>hang<="1101111111111111";lie<="0100000101100000";
when"1110"=>hang<="1011111111111111";lie<="1000001000010000";
when"1111"=>hang<="0111111111111111";lie<="0000110000001110";
when others=>null;
end case;
when"0001"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000"; --敬
when"0001"=>hang<="1111111111111101";lie<="0010001000100000";
when"0010"=>hang<="1111111111111011";lie<="1111111110100000";
when"0011"=>hang<="1111111111110111";lie<="0010001000111111";
when"0100"=>hang<="1111111111101111";lie<="0010001001000010";
when"0101"=>hang<="1111111111011111";lie<="0001000010000010";
when"0110"=>hang<="1111111110111111";lie<="0011111101000010";
when"0111"=>hang<="1111111101111111";lie<="0100001101000100";
when"1000"=>hang<="1111111011111111";lie<="1000001101000100";
when"1001"=>hang<="1111110111111111";lie<="0011101100101000";
when"1010"=>hang<="1111101111111111";lie<="0010101100010000";
when"1011"=>hang<="1111011111111111";lie<="0011101100110000";
when"1100"=>hang<="1110111111111111";lie<="0000001100101000";
when"1101"=>hang<="1101111111111111";lie<="0001001101000100";
when"1110"=>hang<="1011111111111111";lie<="0000111110000010";
when"1111"=>hang<="0111111111111111";lie<="0000001100000001";
when others=>null;
end case;
when"0010"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--承
when"0001"=>hang<="1111111111111101";lie<="0000011111000000";
when"0010"=>hang<="1111111111111011";lie<="0000000010000000";
when"0011"=>hang<="1111111111110111";lie<="0000001100000000";
when"0100"=>hang<="1111111111101111";lie<="0011000100000100";
when"0101"=>hang<="1111111111011111";lie<="0001100100101000";
when"0110"=>hang<="1111111110111111";lie<="0000111111110000";
when"0111"=>hang<="1111111101111111";lie<="0000100100100000";
when"1000"=>hang<="1111111011111111";lie<="0000111111010000";
when"1001"=>hang<="1111110111111111";lie<="0001000100010000";
when"1010"=>hang<="1111101111111111";lie<="0010111111101000";
when"1011"=>hang<="1111011111111111";lie<="0100000100000100";
when"1100"=>hang<="1110111111111111";lie<="1000000100000011";
when"1101"=>hang<="1101111111111111";lie<="0000010100000000";
when"1110"=>hang<="1011111111111111";lie<="0000001100000000";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"0011"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--川
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0000000000001000";
when"0011"=>hang<="1111111111110111";lie<="0001000000011000";
when"0100"=>hang<="1111111111101111";lie<="0001100000011000";
when"0101"=>hang<="1111111111011111";lie<="0001100110011000";
when"0110"=>hang<="1111111110111111";lie<="0001100110011000";
when"0111"=>hang<="1111111101111111";lie<="0001100110011000";
when"1000"=>hang<="1111111011111111";lie<="0001100110011000";
when"1001"=>hang<="1111110111111111";lie<="0001100110011000";
when"1010"=>hang<="1111101111111111";lie<="0001100110011000";
when"1011"=>hang<="1111011111111111";lie<="0001100110011000";
when"1100"=>hang<="1110111111111111";lie<="0011000000011000";
when"1101"=>hang<="1101111111111111";lie<="0110000000011000";
when"1110"=>hang<="1011111111111111";lie<="0000000000011000";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"0100"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--涂
when"0001"=>hang<="1111111111111101";lie<="0000000010000000";
when"0010"=>hang<="1111111111111011";lie<="0100000011000000";
when"0011"=>hang<="1111111111110111";lie<="0010000100100000";
when"0100"=>hang<="1111111111101111";lie<="0001001000010000";
when"0101"=>hang<="1111111111011111";lie<="0000010000001000";
when"0110"=>hang<="1111111110111111";lie<="0100101111110100";
when"0111"=>hang<="1111111101111111";lie<="0010000010000010";
when"1000"=>hang<="1111111011111111";lie<="0001000010000000";
when"1001"=>hang<="1111110111111111";lie<="0000111111111100";
when"1010"=>hang<="1111101111111111";lie<="0001000010000000";
when"1011"=>hang<="1111011111111111";lie<="0011001010100000";
when"1100"=>hang<="1110111111111111";lie<="1110010010010000";
when"1101"=>hang<="1101111111111111";lie<="0100100010001000";
when"1110"=>hang<="1011111111111111";lie<="0101001010000110";
when"1111"=>hang<="0111111111111111";lie<="0000000110000000";
when others=>null;
end case;
when"0101"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--双
when"0001"=>hang<="1111111111111101";lie<="1111111011111110";
when"0010"=>hang<="1111111111111011";lie<="1000001010000110";
when"0011"=>hang<="1111111111110111";lie<="0100001010000110";
when"0100"=>hang<="1111111111101111";lie<="0110001010000110";
when"0101"=>hang<="1111111111011111";lie<="0011001011000110";
when"0110"=>hang<="1111111110111111";lie<="0001101001000110";
when"0111"=>hang<="1111111101111111";lie<="0000111001101100";
when"1000"=>hang<="1111111011111111";lie<="0001110000111000";
when"1001"=>hang<="1111110111111111";lie<="0011011000111000";
when"1010"=>hang<="1111101111111111";lie<="0110001101101000";
when"1011"=>hang<="1111011111111111";lie<="1100000011001100";
when"1100"=>hang<="1110111111111111";lie<="1000000110000110";
when"1101"=>hang<="1101111111111111";lie<="0000001100000011";
when"1110"=>hang<="1011111111111111";lie<="0000000000000000";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"0110"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--好
when"0001"=>hang<="1111111111111101";lie<="0010000000000000";
when"0010"=>hang<="1111111111111011";lie<="0010000011111110";
when"0011"=>hang<="1111111111110111";lie<="1111111000000110";
when"0100"=>hang<="1111111111101111";lie<="0010001000001100";
when"0101"=>hang<="1111111111011111";lie<="0010001000011000";
when"0110"=>hang<="1111111110111111";lie<="0010011000010000";
when"0111"=>hang<="1111111101111111";lie<="0011011000010000";
when"1000"=>hang<="1111111011111111";lie<="0001110111111110";
when"1001"=>hang<="1111110111111111";lie<="0000010000010000";
when"1010"=>hang<="1111101111111111";lie<="0001111000010000";
when"1011"=>hang<="1111011111111111";lie<="0011001100010000";
when"1100"=>hang<="1110111111111111";lie<="0110000100010000";
when"1101"=>hang<="1101111111111111";lie<="1100000001010000";
when"1110"=>hang<="1011111111111111";lie<="0000000000110000";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"0111"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--酷
when"0001"=>hang<="1111111111111101";lie<="0000000000101000";
when"0010"=>hang<="1111111111111011";lie<="0111111100101000";
when"0011"=>hang<="1111111111110111";lie<="0001010001111111";
when"0100"=>hang<="1111111111101111";lie<="0111111111001000";
when"0101"=>hang<="1111111111011111";lie<="0101010100001000";
when"0110"=>hang<="1111111110111111";lie<="0101010101111111";
when"0111"=>hang<="1111111101111111";lie<="0101010100000000";
when"1000"=>hang<="1111111011111111";lie<="0110010101111111";
when"1001"=>hang<="1111110111111111";lie<="0100001101000001";
when"1010"=>hang<="1111101111111111";lie<="0100000101000001";
when"1011"=>hang<="1111011111111111";lie<="0111111101000001";
when"1100"=>hang<="1110111111111111";lie<="0100000101000001";
when"1101"=>hang<="1101111111111111";lie<="0111111101111111";
when"1110"=>hang<="1011111111111111";lie<="0000000001000001";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"1000"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--炫
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0001000000100000";
when"0011"=>hang<="1111111111110111";lie<="0101000111111100";
when"0100"=>hang<="1111111111101111";lie<="0101010001000000";
when"0101"=>hang<="1111111111011111";lie<="0011010010000100";
when"0110"=>hang<="1111111110111111";lie<="0001100100001000";
when"0111"=>hang<="1111111101111111";lie<="0001101111110000";
when"1000"=>hang<="1111111011111111";lie<="0001000000100000";
when"1001"=>hang<="1111110111111111";lie<="0001000001100000";
when"1010"=>hang<="1111101111111111";lie<="0001100011000000";
when"1011"=>hang<="1111011111111111";lie<="0011010110000000";
when"1100"=>hang<="1110111111111111";lie<="0010001100000000";
when"1101"=>hang<="1101111111111111";lie<="0100011111111100";
when"1110"=>hang<="1011111111111111";lie<="1000000000000110";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"1001"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--夺
when"0001"=>hang<="1111111111111101";lie<="0000000010000000";
when"0010"=>hang<="1111111111111011";lie<="0000000010000000";
when"0011"=>hang<="1111111111110111";lie<="0001111111111000";
when"0100"=>hang<="1111111111101111";lie<="0000000111000000";
when"0101"=>hang<="1111111111011111";lie<="0000001001000000";
when"0110"=>hang<="1111111110111111";lie<="0000010000100000";
when"0111"=>hang<="1111111101111111";lie<="0000100000010000";
when"1000"=>hang<="1111111011111111";lie<="0001000000001000";
when"1001"=>hang<="1111110111111111";lie<="0010000000010100";
when"1010"=>hang<="1111101111111111";lie<="0101111111111011";
when"1011"=>hang<="1111011111111111";lie<="0000000000010000";
when"1100"=>hang<="1110111111111111";lie<="0000001100010000";
when"1101"=>hang<="1101111111111111";lie<="0000000100010000";
when"1110"=>hang<="1011111111111111";lie<="0000000001010000";
when"1111"=>hang<="0111111111111111";lie<="0000000000110000";
when others=>null;
end case;
when"1010"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--目
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0000111111110000";
when"0011"=>hang<="1111111111110111";lie<="0000100000010000";
when"0100"=>hang<="1111111111101111";lie<="0000100000010000";
when"0101"=>hang<="1111111111011111";lie<="0000100000010000";
when"0110"=>hang<="1111111110111111";lie<="0000111111110000";
when"0111"=>hang<="1111111101111111";lie<="0000100000010000";
when"1000"=>hang<="1111111011111111";lie<="0000100000010000";
when"1001"=>hang<="1111110111111111";lie<="0000100000010000";
when"1010"=>hang<="1111101111111111";lie<="0000111111110000";
when"1011"=>hang<="1111011111111111";lie<="0000100000010000";
when"1100"=>hang<="1110111111111111";lie<="0000100000010000";
when"1101"=>hang<="1101111111111111";lie<="0000100000010000";
when"1110"=>hang<="1011111111111111";lie<="0000111111110000";
when"1111"=>hang<="0111111111111111";lie<="0000100000010000";
when others=>null;
end case;
when"1011"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--打
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0000100000000000";
when"0011"=>hang<="1111111111110111";lie<="0011111011111110";
when"0100"=>hang<="1111111111101111";lie<="0011111011111110";
when"0101"=>hang<="1111111111011111";lie<="0000100000110000";
when"0110"=>hang<="1111111110111111";lie<="0000100000110000";
when"0111"=>hang<="1111111101111111";lie<="0000110000110000";
when"1000"=>hang<="1111111011111111";lie<="0001100000110000";
when"1001"=>hang<="1111110111111111";lie<="0011100000110000";
when"1010"=>hang<="1111101111111111";lie<="0110100000110000";
when"1011"=>hang<="1111011111111111";lie<="0010100000110000";
when"1100"=>hang<="1110111111111111";lie<="0000100000110000";
when"1101"=>hang<="1101111111111111";lie<="0011100010110000";
when"1110"=>hang<="1011111111111111";lie<="0001100001110000";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"1100"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--开
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0011111111111100";
when"0011"=>hang<="1111111111110111";lie<="0011111111111100";
when"0100"=>hang<="1111111111101111";lie<="0000110000110000";
when"0101"=>hang<="1111111111011111";lie<="0000110000110000";
when"0110"=>hang<="1111111110111111";lie<="0111111111111110";
when"0111"=>hang<="1111111101111111";lie<="0111111111111110";
when"1000"=>hang<="1111111011111111";lie<="0000110000110000";
when"1001"=>hang<="1111110111111111";lie<="0000110000110000";
when"1010"=>hang<="1111101111111111";lie<="0000110000110000";
when"1011"=>hang<="1111011111111111";lie<="0000110000110000";
when"1100"=>hang<="1110111111111111";lie<="0000110000110000";
when"1101"=>hang<="1101111111111111";lie<="0001110000110000";
when"1110"=>hang<="1011111111111111";lie<="0011000000110000";
when"1111"=>hang<="0111111111111111";lie<="0110000000110000";
when others=>null;
end case;
when"1101"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--了
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0001111111111000";
when"0011"=>hang<="1111111111110111";lie<="0001111111111000";
when"0100"=>hang<="1111111111101111";lie<="0000000000011000";
when"0101"=>hang<="1111111111011111";lie<="0000000001111000";
when"0110"=>hang<="1111111110111111";lie<="0000000011100000";
when"0111"=>hang<="1111111101111111";lie<="0000000011000000";
when"1000"=>hang<="1111111011111111";lie<="0000000011000000";
when"1001"=>hang<="1111110111111111";lie<="0000000011000000";
when"1010"=>hang<="1111101111111111";lie<="0000000011000000";
when"1011"=>hang<="1111011111111111";lie<="0000000011000000";
when"1100"=>hang<="1110111111111111";lie<="0000010011000000";
when"1101"=>hang<="1101111111111111";lie<="0000011011000000";
when"1110"=>hang<="1011111111111111";lie<="0000001111000000";
when"1111"=>hang<="0111111111111111";lie<="0000000111000000";
when others=>null;
end case;
when"1110"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--心
when"0001"=>hang<="1111111111111101";lie<="0000000000000000";
when"0010"=>hang<="1111111111111011";lie<="0000000000000000";
when"0011"=>hang<="1111111111110111";lie<="0000110000000000";
when"0100"=>hang<="1111111111101111";lie<="0000110100000000";
when"0101"=>hang<="1111111111011111";lie<="0000110110000000";
when"0110"=>hang<="1111111110111111";lie<="0000110011000000";
when"0111"=>hang<="1111111101111111";lie<="0001110001000000";
when"1000"=>hang<="1111111011111111";lie<="0010110000001100";
when"1001"=>hang<="1111110111111111";lie<="0110110000000110";
when"1010"=>hang<="1111101111111111";lie<="1110110000000011";
when"1011"=>hang<="1111011111111111";lie<="1100110000001001";
when"1100"=>hang<="1110111111111111";lie<="1100110000001100";
when"1101"=>hang<="1101111111111111";lie<="0000111111111100";
when"1110"=>hang<="1011111111111111";lie<="0000011111111100";
when"1111"=>hang<="0111111111111111";lie<="0000000000000000";
when others=>null;
end case;
when"1111"=>
case sao is
when"0000"=>hang<="1111111111111110";lie<="0000000000000000";--锁
when"0001"=>hang<="1111111111111101";lie<="0001000000100000";
when"0010"=>hang<="1111111111111011";lie<="0001001000100010";
when"0011"=>hang<="1111111111110111";lie<="0011110100100100";
when"0100"=>hang<="1111111111101111";lie<="0010000010101000";
when"0101"=>hang<="1111111111011111";lie<="0111110111111100";
when"0110"=>hang<="1111111110111111";lie<="1101000100100100";
when"0111"=>hang<="1111111101111111";lie<="1001000100100100";
when"1000"=>hang<="1111111011111111";lie<="0111110100100100";
when"1001"=>hang<="1111110111111111";lie<="0001000100100100";
when"1010"=>hang<="1111101111111111";lie<="0001000100100100";
when"1011"=>hang<="1111011111111111";lie<="0001000000110000";
when"1100"=>hang<="1110111111111111";lie<="0001000001011000";
when"1101"=>hang<="1101111111111111";lie<="0001010011001100";
when"1110"=>hang<="1011111111111111";lie<="0001100110000100";
when"1111"=>hang<="0111111111111111";lie<="0001101100000011";
when others=>null;
end case;
end case;
end process;
end dianzhenziku_jcc;
6.电机使能
library ieee;
use ieee.std_logic_1164.all;
entity dianjishineng is
port(en,clkin:in std_logic;
clkout:out std_logic);
end dianjishineng;
architecturedianjishineng_jcc of dianjishineng is
begin
process(en)
begin
if(en='1') then
clkout<=clkin;
else clkout<='0';
end if;
end process;
end dianjishineng_jcc;
7.电机转向控制
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dianjizhuanxiang is
port(en,clk:in std_logic;
a,b:out std_logic);
end dianjizhuanxiang;
architecturedianjizhuanxiang_jcc of dianjizhuanxiang is
signal tmpe:integer range 0 to 500 ;
begin
process(clk)
begin
if(clk'event and clk='1') then
if(tmpe="111111") then
tmpe<=0;
else
tmpe<=tmpe+1;
end if;
end if;
end process;
process(en,tmpe)
begin
if(en='1') then
if(tmpe>="100000") then
a<='0'; b<='1';
else
a<='1';b<='0';
end if;
else
a<='0'; b<='0';
end if;
end process;
end dianjizhuanxiang_jcc;
8.10分频
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clk10 is
port(clk:in std_logic;
clkout:out std_logic);
end clk10;
architecture one of clk10 is
signalcount :std_logic_vector(2 downto 0);
signaltmpe :std_logic;
begin
process(clk)
begin
if(clk'event and clk ='1') then
if(count = "100") then
count <= (others => '0');
tmpe <= not tmpe;
else
count <= count + 1;
end if;
end if;
end process;
clkout <= tmpe;
end one;
9.20分频
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clk20 is
port(clk:in std_logic;
clkout:out std_logic);
end clk20;
architecture two of clk20 is
signalcount :std_logic_vector(3 downto 0);
signaltmpe :std_logic;
begin
process(clk)
begin
if(clk'event and clk ='1') then
if(count = "1001") then
count <= (others => '0');
tmpe <= not tmpe;
else
count <= count + 1;
end if;
end if;
end process;
clkout <= tmpe;
end two;
10.200分频
library ieee;
use ieee.std_logic_1164.all;
entity clk200 is
port(clk:in std_logic;
clkout:out std_logic);
end clk200;
architecture three of clk200 is
componentclk10 is
port(clk:in std_logic;
clkout:out std_logic);
end component clk10;
componentclk20 is
port(clk:in std_logic;
clkout:out std_logic);
end component clk20;
signaltmpe :std_logic;
begin
u1: clk10 port map(clk,tmpe);
u2: clk20 port map(tmpe,clkout);
end three;
11.密码比较模块(4个模块主体相同,只是存储的密码不同,可灵活改动)
library ieee;
use ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
entity mimabijiao is
port (b1,b2,b3,b4,k:in std_logic;
a:out std_logic);
end mimabijiao;
architecture mimabijiao_jcc of mimabijiao is
begin
process (b1,b2,b3,b4,k)
variable q:std_logic :='0';
begin
if(k'event and k='1')then
if ( b1='1' AND b2='0' AND b3='0' AND b4='0') then q:='1';
else q:='0';
end if;
end if;
a<=q;
end process;
end mimabijiao_jcc;
12.密码比较位控制
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bijiaowei is
port (k0:in std_logic;
k,k1,k2,k3:out std_logic);
signal m: std_logic_vector(3 downto 0):="0000";
end bijiaowei;
architecture bijiaowei_jcc of bijiaowei is
signal tmpe:std_logic_vector(3 downto 0);
begin
process (k0)
variable i: std_logic_vector(3 downto 0):="0000";
begin
if(k0='1') then i:=i+1;
if(i="1000") then i:="0000";
end if;
end if;
m<=i;
end process;
process (m)
begin
case m is
when "0001"=>tmpe<="1000";
when "0011"=>tmpe<="0100";
when "0101"=>tmpe<="0010";
when "0111"=>tmpe<="0001";
when others=>tmpe<="0000";
end case;
end process;
k <=tmpe(0);
k1<=tmpe(1);
k2<=tmpe(2);
k3<=tmpe(3);
end bijiaowei_jcc;
13.数码位选
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity shumaweixuan is
port (k,k1,k2,k3:in std_logic;
a,b,c:out std_logic);
end shumaweixuan;
architecture shumaweixuan_jcc of shumaweixuan is
signal tmpe:std_logic_vector(2 downto 0);
begin
process (k,k1,k2,k3)
variable i: std_logic_vector(3 downto 0):="0000";
begin
i:=k&k1&k2&k3;
case i is
when "0001"=>tmpe<="000";
when "0010"=>tmpe<="001";
when "0100"=>tmpe<="010";
when "1000"=>tmpe<="011";
when others=>tmpe<="111";
end case;
end process;
a <=tmpe(0);
b<=tmpe(1);
c<=tmpe(2);
end shumaweixuan_jcc;
14.数码显示模块(译码)
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY shumaxianshi IS
PORT (b1,b2,b3,b4:IN std_logic;
a,b,c,d,e,f,g:OUT std_logic);
END shumaxianshi;
ARCHITECTURE shumaxianshi_jcc OF shumaxianshi IS
SIGNAL data_tmp:std_logic_vector(6 DOWNTO 0);
BEGIN
PROCESS (b1,b2,b3,b4)
VARIABLE i: std_logic_vector(3 DOWNTO 0);
BEGIN
i:=b4&b3&b2&b1;
case i is
when "0000"=>data_tmp<="0111111";--数码译码
when "0001"=>data_tmp<="0000110";
when "0010"=>data_tmp<="1011011";
when "0011"=>data_tmp<="1001111";
when "0100"=>data_tmp<="1100110";
when "0101"=>data_tmp<="1101101";
when "0110"=>data_tmp<="1111101";
when "0111"=>data_tmp<="0100111";
when "1000"=>data_tmp<="1111111";
when "1001"=>data_tmp<="1101111";
when "1111"=>data_tmp<="1111100";
when others=>data_tmp<="1110111";
end case;
end process;
a<=data_tmp(0); b<=data_tmp(1); c<=data_tmp(2);
d<=data_tmp(3); e<=data_tmp(4); f<=data_tmp(5); g<=data_tmp(6);
end shumaxianshi_jcc;