VHDL密码锁6位串行输入.docx
《VHDL密码锁6位串行输入.docx》由会员分享,可在线阅读,更多相关《VHDL密码锁6位串行输入.docx(24页珍藏版)》请在冰豆网上搜索。
VHDL密码锁6位串行输入
《电子设计自动化》
课程设计
题目:
数字密码锁电路(1.1)
院(系)信息科学与工程学院
专业15通信工程
届别
班级
学号
姓名
任课老师
数字密码锁电路,难度系数1.1
实验要求设计一个密码锁,有6位十进制数字密码,串行输入;能设置密码;有开锁和错误指示(LED);如果连续输错三次,则一刻钟内不能再开锁。
本设计的各个模块由相应的VHDL程序具体实现,并在QuartusⅡ9.0环境下进行了整体电路的模拟仿真,最终实现“密码锁设计”的要求。
实验设计要求6位串行输入,并且由于实验板输入键位的有限,还同时增加了输入密码与设置密码键位的重叠,使密码锁电路输入输出形成一个反馈,通过对输出的判断,让电路自动识别输入的数字是设置的密码还是输入的密码。
在程序初始载入实验板时,还要让密码锁的初始设置密码和输入密码相同,从而达到能够初始设置密码的逻辑要求。
同时因为实验板输出的LED灯有限,还要求设计的密码锁电路的显示能够在输入密码、设置密码和倒计时之间灵活智能选择,从而达到满足使用的要求。
密码锁在输入三次错误密码后需要开始一个一刻钟即900秒的倒计时,则需要设计一个逻辑电路使电路能够在输入和错误倒计时之间自由变化。
此为本实验设计的主要难点和创新。
1.系统设计.....................................................................4
2.单元电路设计.............................................................7
3.软件设计...................................................................12
4.系统测试...................................................................23
5.结论...........................................................................24
6.参考文献.....................................................................24
7.附录...........................................................................25
8.其他...........................................................................26
系统设计
设计要求:
设计一个密码锁,有6位十进制数字密码,串行输入;能设置密码;有开锁和错误指示(LED);如果连续输错三次,则一刻钟内不能再开锁。
系统设计方案:
先设计1.0难度的密码锁,此时不需要一刻钟计时模块。
该电路首先需要一个输入模块,由于实验板的限制,安排两个键位作为输入,分别实现6个密码位的选择和对确定位密码的输入,所以在输入模块之前,还需要通过计数器来分别得到两个输入;之后设计一个密码合成及选择模块,将得到的6个4位的密码相加得到一个24位的密码,方便之后的比较,同时需要在输入模块添加一个选择,分别确定此时的输入信息是设置密码还是输入密码;将得到的24位设置密码和输入密码分别放到一个确认模块,起到输入确认并且使初始信息清零的作用;最后将两个24位数据放入比较模块,确定密码锁的状态,状态的显示由LED灯实现;输出显示LED模块从输入模块之前接出,显示当前电路的输入;同时,在计数器之前需要加入消抖模块,使实验板能够稳定输入;在LED模块之前需要添加译码器,以输出正确显示。
下图为1.0密码锁各个模块及接线。
完成1.0难度密码锁之后设计一个计数器,通过对密码输入确认和输出状态的计数,当输入错误达到三次时,开始一个一刻钟的计时,由另外一个计数器完成。
该计数器的输入还需要一个50m分频模块,得到一个稳定的每秒输出一个电平跳变的输入;为了将900秒的计时显示到LED上,需要用除法器将计时的各个位拆分出来,再通过译码器显示到LED上。
最后还需要一个输出选择模块,通过对3计数器的数据识别,选择当前LED输出的是900秒计时还是当前输入数据。
下图为1.1难度密码锁最终的各个模块及接线。
其他方案:
除上述方法外,还可以将比较器放在输出选择模块之前,这样能够让程序在开发板上仿真时,位选之后不会将上一位的输入连带到本位;
如果去掉输入选择模块,可以增加一个输入为设置密码输入,即将输入密码和设置密码的输入分开;
倒计时模块采用的是从900倒计时到0,即“1110000110”到“0000000000”,然后输出cout为1;该程序也可以从“0000000000”累加到“1110000110”计数;
单元电路设计
消抖模块:
消除按键难以避免的抖动,以得到稳定的输入;
计数器:
本实验分别用到了3进制、6进制和10进制的计数器,每计数到一定量时计数器清零并输出一个高电平;
密码合成及选择模块:
将得到的6个4位的密码合成一个24位的密码并输出,方便之后的密码比较,密码合成通过&完成,通过对输出状态反馈(开锁输出‘1’,锁存输出‘0’)的识别,判断当前输入的数据是设置密码还是输入密码,作两个输出;
确认模块:
将得到的输入密码和设置密码确认输出到比较器,同时在程序载入实验板时,还未有输入的情况下,能够默认输入密码和设置密码都是24位0,使两者初始值相等(此时比较器输出为‘1’,反馈到该模块,输入的数据为设置密码),达到能设置密码的状态;
比较模块:
对得到的输入密码和设置密码进行比较,输出显示当前密码锁是锁存‘0’还是开锁状态‘1’;
译码器:
将得到的数据读取,使其输出的数据能够显示到LED上;
LED:
将6位密码显示在LED上;
50m分频:
每秒稳定输出一个电平跳变;
输出选择:
通过对3进制计数器的数据读取(输入错误三次输出cout为‘1’,否则为‘0’),选择输出是当前密码输入、设置密码输入还是900秒计时;
除法器:
将900秒计时的百位、十位和个位拆分出来,使其能通过译码器显示到LED上。
(该模块主要通过lpm_divide和lpm_constant实现,900秒的计时数据分别除常数100和10,再通过对商的后四位数据的读取得到各个位的大小)下图为除法器各模块及接线:
LED第二位显示默认为0模块:
将实验没有用到的led第二位显示输出默认为不显示;
LED输出选择模块:
选择led是显示倒计时还是此时输入密码
软件设计
软件:
QuartusⅡ9.0(CycloneⅡEP2C5T144C8);
硬件:
对应的FPGA开发板
程序清单
1.消抖模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYxiaodouIS
PORT(K_IN,CLK:
INSTD_LOGIC;
K_OUT:
OUTSTD_LOGIC);
END;
ARCHITECTUREoneOFxiaodouIS
SIGNALK_PRE:
STD_LOGIC;
SIGNALCOUNT:
INTEGERRANGE0TO3999999;
BEGIN
PROCESS(CLK,K_IN)BEGIN
IFCLK'EVENTANDCLK='1'THEN
IFK_IN=K_PRETHEN
IFCOUNT<3999999THEN
COUNT<=COUNT+1;
ELSECOUNT<=3999999;
ENDIF;
ELSECOUNT<=0;
ENDIF;
K_PRE<=K_IN;
ENDIF;
IFCOUNT=3999999THEN
K_OUT<=K_IN;
ENDIF;
ENDPROCESS;
END;
2.十进制计数器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcnt10IS
PORT(CLK,RST,EN:
INSTD_LOGIC;
CQ:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
COUT:
OUTSTD_LOGIC);
ENDcnt10;
ARCHITECTUREbehavOFcnt10IS
BEGIN
PROCESS(CLK,RST,EN)
VARIABLECQI:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IFRST='0'THENCQI:
=(OTHERS=>'0');--计数器异步复位
ELSIFCLK'EVENTANDCLK='1'THEN--检测时钟上升沿
IFEN='1'THEN--检测是否允许计数(同步使能)
IFCQI<9THENCQI:
=CQI+1;--允许计数,检测是否小于9
ELSECQI:
=(OTHERS=>'0');--大于9,计数值清零
ENDIF;
ENDIF;
ENDIF;
IFCQI=9THENCOUT<='1';--计数大于9,输出进位信号
ELSECOUT<='0';
ENDIF;
CQ<=CQI;--将计数值向端口输出
ENDPROCESS;
ENDbehav;
3.六进制计数器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYCNT6IS
PORT(CLK,RST,EN:
INSTD_LOGIC;
CQ:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
COUT:
OUTSTD_LOGIC);
ENDCNT6;
ARCHITECTUREbehavOFCNT6IS
BEGIN
PROCESS(CLK,RST,EN)
VARIABLECQI:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IFRST='0'THENCQI:
=(OTHERS=>'0');--计数器异步复位
ELSIFCLK'EVENTANDCLK='1'THEN--检测时钟上升沿
IFEN='1'THEN--检测是否允许计数(同步使能)
IFCQI<5THENCQI:
=CQI+1;--允许计数,检测是否小于9
ELSECQI:
=(OTHERS=>'0');--大于9,计数值清零
ENDIF;
ENDIF;
ENDIF;
IFCQI=5THENCOUT<='1';--计数大于9,输出进位信号
ELSECOUT<='0';
ENDIF;
CQ<=CQI;--将计数值向端口输出
ENDPROCESS;
ENDbehav;
4.倒计时的三进制计数器
libraryieee;
useieee.std_logic_1164.all;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
entitycnt3is
port(c,clk,rst:
instd_logic;
y:
outstd_logic);
endcnt3;
architectureoneofcnt3is
begin
process(clk,c)
variableb:
std_logic_vector(1downto0);
begin
IF(c='1'orrst='1')THENb:
=(OTHERS=>'0');
ELSIFCLK'EVENTANDCLK='0'THEN
IFb<3THENb:
=b+1;
ELSEb:
=(OTHERS=>'0');
ENDIF;
ENDIF;
IFb=3THENy<='1';
ELSEy<='0';
ENDIF;
ENDPROCESS;
endone;
5.输入模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYzongxuanIS
PORT(
D:
INSTD_LOGIC_VECTOR(3DOWNTO0);
B:
INSTD_LOGIC_VECTOR(3DOWNTO0);
code0,code1,code2,code3,code4,code5:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDENTITYzongxuan;
ARCHITECTUREbehavOFzongxuanIS
BEGIN
PROCESS(B)
BEGIN
IFB="0000"THENcode0<=D;
ELSIFB="0001"THENcode1<=D;
ELSIFB="0010"THENcode2<=D;
ELSIFB="0011"THENcode3<=D;
ELSIFB="0100"THENcode4<=D;
ELSEcode5<=D;
ENDIF;
ENDPROCESS;
ENDbehav;
6.密码合成及选择模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYjicunIS
PORT(P0,P1,P2,P3,P4,P5:
INSTD_LOGIC_VECTOR(3DOWNTO0);
CHANGE:
INSTD_LOGIC;
RCODE,ICODE:
OUTSTD_LOGIC_VECTOR(23DOWNTO0));
ENDjicun;
ARCHITECTUREbhvOFjicunIS
SIGNALCODE:
STD_LOGIC_VECTOR(23DOWNTO0);
BEGINPROCESS(CHANGE)
BEGIN
CODE<=p0&p1&p2&p3&p4&p5;
IFCHANGE='1'THEN
RCODE<=CODE;
ELSE
ICODE<=CODE;
ENDIF;
ENDPROCESS;
ENDbhv;
7.输出确认模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.All;
ENTITYquerenIS
PORT(
INCODE:
INSTD_LOGIC_VECTOR(23DOWNTO0);
OUTCODE:
OUTSTD_LOGIC_VECTOR(23DOWNTO0);
K:
INSTD_LOGIC);
endqueren;
ARCHITECTUREbhvOFquerenIS
BEGINPROCESS(k)
BEGIN
IFk='0'THEN
OUTCODE<=INCODE;
ENDIF;
ENDPROCESS;
ENDbhv;
8.比较模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.All;
ENTITYbijiaoIS
PORT(
RCODE,ICODE:
INSTD_LOGIC_VECTOR(23DOWNTO0);
L:
OUTSTD_LOGIC);
endbijiao;
ARCHITECTUREbhvOFbijiaoIS
BEGINPROCESS(RCODE,ICODE)
BEGIN
IFICODE/=RCODETHEN
L<='0';
ELSE
L<='1';
ENDIF;
ENDPROCESS;
ENDbhv;
9.译码器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYyimaqiIS
PORT(A:
INSTD_LOGIC_VECTOR(3DOWNTO0);
Y:
OUTSTD_LOGIC_VECTOR(6DOWNTO0));
ENDENTITYyimaqi;
ARCHITECTUREoneOFyimaqiIS
BEGIN
Y<="1000000"WHENA="0000"ELSE
"1111001"WHENA="0001"ELSE
"0100100"WHENA="0010"ELSE
"0110000"WHENA="0011"ELSE
"0011001"WHENA="0100"ELSE
"0010010"WHENA="0101"ELSE
"0000010"WHENA="0110"ELSE
"1111000"WHENA="0111"ELSE
"0000000"WHENA="1000"ELSE
"0010000"WHENA="1001"ELSE
"0001000"WHENA="1010"ELSE
"0000011"WHENA="1011"ELSE
"1000110"WHENA="1100"ELSE
"0100001"WHENA="1101"ELSE
"0000110"WHENA="1110"ELSE
"0001110"WHENA="1111"ELSE
NULL;
ENDARCHITECTUREone;
10.900秒计时
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitydaojishiis
port(clk,en:
instd_logic;
led0:
outstd_logic_vector(9downto0);
cout:
outstd_logic);
enddaojishi;
architecturebehavofdaojishiis
begin
process(clk,en)
variableled:
std_logic_vector(9downto0);
begin
ifen='0'thenled:
="1110000100";led0<="1110000100";
elsifclk'eventandclk='1'then
led:
=led-1;
endif;
ifled="0000000000"thencout<='1';elsecout<='0';endif;
led0<=led;
endprocess;
endbehav;
11.计时除100得商取后四位
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityjiusiis
port(a:
instd_logic_vector(9downto0);
b:
outstd_logic_vector(3downto0));
endjiusi;
architectureoneofjiusiis
begin
process(a)
begin
b<=a(3downto0);
endprocess;
end;
12.计时除100得余数再除10得商取后四位
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityqisiis
port(a:
instd_logic_vector(6downto0);
b:
outstd_logic_vector(3downto0));
endqisi;
architectureoneofqisiis
begin
process(a)
begin
b<=a(3downto0);
endprocess;
end;
13.50m分频
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycnt50Mis
port(clk:
instd_logic;
cout:
outstd_logic);
endcnt50M;
architectureoneofcnt50Mis
begin
process(clk)
variablec:
integerrange0to49999999;
begin
ifclk'eventandclk='1'then
ifc=49999999then
cout<='1';
c:
=0;
else
c:
=c+1;
cout<='0';
endif;
endif;
endprocess;
end;
14.选择是否读取输出状态
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYxuanIS
PORT(A:
INSTD_LOGIC;
B:
INSTD_LOGIC;
Y:
OUTSTD_LOGIC);
ENDENTITYxuan;
ARCHITECTUREoneOFxuanIS
BEGIN
PROCESS(B,A)
BEGIN
IFB='0'THENY<=A;
ELSE
Y<='1';
endif;
ENDPROCESS;
ENDARCHITECTUREo