FPGA基于verilog HDL的密码锁.docx
《FPGA基于verilog HDL的密码锁.docx》由会员分享,可在线阅读,更多相关《FPGA基于verilog HDL的密码锁.docx(31页珍藏版)》请在冰豆网上搜索。
FPGA基于verilogHDL的密码锁
EDA课程设计
课设名称:
密码锁
课设日期:
2014。
6。
23——7。
5
姓名:
陈飞
学号:
110250101
哈尔滨工业大学(威海)
信电学院电子信息工程
2014。
6
一。
所用软件与硬件介绍
1。
1所用软件介绍
QuartusII是Altera公司的综合性PLD/FPGA开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(AlteraHardwareDescriptionLanguage)等多种设计输入形式,内嵌的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。
QuartusII可以在XP、Linux以及Unix上使用,除了可以使用TCL脚本完成设计流程外,提供了完善的用户图形界面设计方式。
具有运行速度快,界面统一,功能集中,易学易用等特点.
QuartusII支持Altera的IP核,包含了LPM/MegaFunction宏功能模块库,使用户可以充分利用成熟的模块,简化了设计的复杂性、加快了设计速度。
对第三方EDA工具的良好支持也使用户可以在设计流程的各个阶段使用熟悉的第三方EDA工具。
此外,QuartusII通过和DSPBuilder工具与Matlab/Simulink相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统(SOPC)开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。
MaxplusII作为Altera的上一代PLD设计软件,由于其出色的易用性而得到了广泛的应用。
目前Altera已经停止了对MaxplusII的更新支持,QuartusII与之相比不仅仅是支持器件类型的丰富和图形界面的改变.Altera在QuartusII中包含了许多诸如SignalTapII、ChipEditor和RTLViewer的设计辅助工具,集成了SOPC和HardCopy设计流程,并且继承了MaxplusII友好的图形界面及简便的使用方法.
1.2所用硬件介绍
硬件的总体设计:
故由上图,将整个硬件电路部分主要分成五个部分,即:
FPGA电路设计,数码管显示驱动电路设计,温度传感器电路设计,报警电路设计,键盘矩阵控制电路设计。
I.FPGA芯片的介绍
在本次课程设计中选用Altera公司CycloneII系列FPGA器件.
Altera公司2004年推出了新款CycloneII系列FPGA器件。
CycloneIIFPGA的成本比第一代Cyclone器件低30%,逻辑容量大了三倍多,可满足低成本大批量应用需求。
随着低复杂度FPGA器件成本的不断下降,具有灵活性和及时面市优势的FPGA与ASIC相比更有竞争性,在数字消费市场上的应用也急剧增加。
第一代Cyclone系列迄今发售了3百多万片,在全球拥有3,000多位客户,对大批量低成本数字消费市场有着巨大的影响,该市场消纳了三分之一的器件。
同时,CycloneII器件系列也在电信、计算机外设、工业和汽车市场上获得了巨大的进步.CycloneII器件包含了许多新的特性,如嵌入存储器、嵌入乘法器、PLL和低成本的封装,这些都为诸如视频显示、数字电视(DTV)、机顶盒(STB)、DVD播放器、DSL调制解调器、家用网关和中低端路由器等批量应用进行了优化。
CycloneII器件采用TSMC90nm低K绝缘材料工艺技术,这种技术结合Altera低成本的设计方式,使之能够在更低的成本下制造出更大容量的器件。
这种新的器件比第一代Cyclone产品具有两倍多的I/O引脚,且对可编程逻辑,存储块和其它特性进行了最优的组合,具有许多新的增强特性
低成本的配置器件编辑Altera为配置CycloneIIFPGA提供了低成本的串行配置器件.这些串行配置器件定价为批量应用,成本是相应CycloneIIFPGA的10%。
四个串行配置器件(1Mbit,4Mbit,16Mbit和64Mbit)提供了节省空间的8脚和16脚SOIC封装。
器件中任何不用于配置的存储器可用于一般存储,进一步增强其价值。
IP编辑Altera也为CylconeII器件客户提供了40多个可定制IP核,Altera和AlteraMegafunction伙伴计划(AMPPSM)合作者提供的不同的IP核是专为CycloneII架构优化的,包括:
NiosII嵌入式处理器;DDRSDRAM控制器;FFT/IFFT;PCI编译器;FIR编译器;NCO编译器;POS-PHY编译器;ReedSolomon编译器;Viterbi编译器等等。
II。
数码管显示器
液晶显示器按其功能可分为三类,笔段式液晶显示器,字符点阵式液晶显示器和图形点阵式液晶显示器。
前两种可以显示数字,字符,符号等.而图形点阵式液晶显示器还可以显示汉子和任意图形,达到图文并茂的鲜果。
在本课程设计中,受到试验箱的限制,在这里使用的是基本的数码管显示。
当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的字样了。
如:
显示一个“2”字,那么应当是a亮b亮g亮e亮d亮f不亮c不亮dp不亮。
LED数码管有一般亮和超亮等不同之分,也有0.5寸、1寸等不同的尺寸.小尺寸数码管的显示笔画常用一个发光二极管组成,而大尺寸的数码管由二个或多个发光二极管组成,一般情况下,单个发光二极管的管压降为1。
8V左右,电流不超过30mA.发光二极管的阳极连接到一起连接到电源正极的称为共阳数码管,发光二极管的阴极连接到一起连接到电源负极的称为共阴数码管。
常用LED数码管显示的数字和字符是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
二.系统设计
2.1设计思想
2.1。
1课题背景
众所周知,随着科学技术的发展,以及数字电路的各种产品广泛应用,传统意义上的机械锁应用领域有限,且方便性不高。
由于其构造简单,多数采用物理性结构且多数有常识的人对其构造了如指掌,安全性不高.相对机械锁,电子密码锁其保密性高,使用灵活性好,安全系数高,可实时改变其密码,使用极其方便,在当今社会得到了极其广泛的应用,也将是未来发展的趋势。
本设计使用EDA设计,使设计过程得到高度自动化,其具有强大的设计、测试、仿真分析、管理等功能。
使用EDA环境完成电路的系统综合设计和仿真。
在数字信息技术高速发展的今天,越来越多的地方需要电子密码锁来进行信息的加密与保密,而这种功能是传统机械锁无法实现的,因此,电子密码锁的设计越来越重要。
其设计直接关系到其使用的安全性,灵活性,实用性,以及用户体验。
所以,在这个背景下,学会和掌握密码锁的设计是尤其重要的,而且要在这个基础上,不断提高其灵活,实用,及用户体验性。
2。
1。
2设计目的
1.以往机械锁使用繁琐,安全性低,灵活性差,应用领域有限。
而密码锁可以应用于各个领域,如电子产品的保密,系统程序的保密等各种数字信息产品的加密保密。
还可通过外接物理系统,取代传统机械锁,应用于日常生活的方方面面,例如最基本的门锁。
可以说电子密码锁功能强大,安全性高,灵活性强,必将是未来发展的趋势。
本设计基于VerilogHDL语言来设计密码锁,可以快速、灵活地设计出符合各种要求的密码锁.
2。
掌握FPGA的设计方法与应用.
2。
2工作原理及系统框图
1、四个键,确认键,开始复位键,解密键,更改密码键.
2、密码长度为5位,设置一个初始密码88888。
3、在系统上电时,输入88888(数码管同步显示),按下确认键即可开锁(密码正确,LED灯亮)。
4、开锁状态下,按下更改密码键即可通过4*4矩阵键盘输入新密码。
5、新密码数据格式为0~F
6、按确认键,新密码生效。
7、按下解密键,输入新密码,按下确认键可解锁.
8、重复上述步骤,输入新密码,即可开锁,且密码正确情况下LED灯亮
若密码不正确,则LED灯不亮,锁闭,可继续输入密码,当三次输入密码错误时蜂鸣器响予以警告。
9、以上为整个系统的工作原理及状态。
10、实验参考框图。
11、总体框图如下
总体框图
总原理图:
2。
3.子模块输入输出和功能
密码锁分为六个个模块:
①顶层模块、②数码显示模块、③蜂鸣器模块、④控制模块、⑤LED灯指示模块、⑥密码输入模块。
其中由顶层模块调其他分模块来实现密码锁功能。
1.顶层及控制模块
实现几个模块的配合工作,它能实现对密码的设置和显示,同时在密码正确时LED灯亮,错误三次时通过蜂鸣器发出警报。
2.数码管显示模块
数码管常用于电子产品的显示部分,原理简单易于实现,这里为5个密码,需要5个数码管来显示。
6个输入,其中CLK为时钟信号,segData1--5为每个密码.两个输出,segCtl[7。
。
0]对数码管片选,segData[7.。
0]为译码后的段控制信号。
3、蜂鸣器模块
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用各类电子产品中作发声器件。
如图为其原理图:
图1.1蜂鸣器原理图结构
蜂鸣器功能实现:
程序共有两个输入信号分别为ENA,clk,输出为COUT,密码输入错误三次,ENA置1,COUT置1,蜂鸣器响,需要注意的是,蜂鸣器模块时钟频率不能过快。
5。
LED灯指示模块
为了显示明显,用了所有LED,给同一pass_LED信号,低电平有效.
6。
键盘输入模块
实时动态扫描,输出按键有效值key_value[4。
。
0],及按键标志位key_flag。
三.软件设计
3。
1程序流程图和状态机
程序流程图:
状态机:
3.2程序清单
(1)Dingceng模块
moduledingceng(clk,key_GM,key_QR,key_JM,key_RST,key_ready,key_value,M1,M2,M3,M4,M5,filed_alarm,pass_led);
inputclk;
inputkey_GM,key_QR,key_JM,key_RST,key_ready;
input[4:
0]key_value;
output[3:
0]M1;
output[3:
0]M2;
output[3:
0]M3;
output[3:
0]M4;
output[3:
0]M5;
outputfiled_alarm;
outputpass_led;
reg[3:
0]M1;
reg[3:
0]M2;
reg[3:
0]M3;
reg[3:
0]M4;
reg[3:
0]M5;
regfiled_alarm,pass_led;
regJM_flag;
regGM_flag;
regsign;
reg[2:
0]main_state;
reg[3:
0]Old1;
reg[3:
0]Old2;
reg[3:
0]Old3;
reg[3:
0]Old4;
reg[3:
0]Old5;//cunfangyuanshimima
reg[2:
0]Q,QQ;//jilumimsshurucishu
reg[1:
0]try_times;
parameterDD=3'b000,
RS=3’b001,
JM=3’b010,
GM=3’b011,
QR=3’b100;
always@(posedgeclk)
if(!
key_RST)main_state〈=RS;
else
begin
case(main_state)
DD:
begin
if(!
key_JM)main_state〈=JM;
elseif((key_GM==0)&&(JM_flag==1))
begin
pass_led<=1;
GM_flag<=1;
filed_alarm〈=0;
main_state〈=GM;
end
else
main_state<=DD;
end
RS:
begin
M1〈=0;M2<=0;M3〈=0;M4〈=0;M5<=0;
Old1〈=8;Old2<=8;Old3<=8;Old4〈=8;Old5<=8;
filed_alarm〈=0;
JM_flag<=0;
try_times〈=0;
main_state<=DD;
pass_led<=1;Q〈=0;QQ〈=0;
sign〈=0;
end
JM:
begin
if(key_ready==1)sign〈=1;
else
if(key_ready==0&&sign==1)
begin
sign<=0;
case(Q)
0:
beginM1<=key_value;Q〈=3'b001;main_state〈=DD;end
1:
beginM2〈=key_value;Q<=3'b010;main_state〈=DD;end
2:
beginM3<=key_value;Q〈=3'b011;main_state<=DD;end
3:
beginM4〈=key_value;Q<=3’b100;main_state〈=DD;end
4:
beginM5〈=key_value;Q<=3'b000;main_state<=QR;end
endcase
end
else
main_state〈=JM;
end
GM:
begin
if(key_ready==1)sign〈=1;
else
if(key_ready==0&&sign==1)
begin
sign〈=0;
case(QQ)
0:
beginM1<=key_value;QQ<=3'b001;main_state〈=DD;end
1:
beginM2〈=key_value;QQ〈=3’b010;main_state<=DD;end
2:
beginM3<=key_value;QQ<=3'b011;main_state〈=DD;end
3:
beginM4〈=key_value;QQ<=3’b100;main_state<=DD;end
4:
beginM5〈=key_value;QQ〈=3'b000;main_state<=QR;end
endcase
end
else
main_state〈=GM;
end
QR:
if(key_QR==0)
begin
if(GM_flag==1)
begin
Old1<=M1;
Old2<=M2;
Old3<=M3;
Old4〈=M4;
Old5<=M5;
GM_flag<=0;
main_state〈=DD;
end
else
if((Old1==M1)&&(Old2==M2)&&(Old3==M3)&&(Old4==M4)&&(Old5==M5))
begin
pass_led<=0;
filed_alarm〈=0;
try_times〈=2'b00;
JM_flag〈=1;
M1〈=0;M2〈=0;M3<=0;M4<=0;M5<=0;
main_state〈=DD;
end
elseif(try_times>2’b01)
begin
filed_alarm〈=1;
pass_led<=1;
try_times〈=2'b00;
main_state<=DD;
M1<=0;M2<=0;M3<=0;M4<=0;M5〈=0;
end
else
begin
try_times<=try_times+2'b01;
pass_led〈=1;
filed_alarm<=0;
main_state<=DD;
M1<=0;M2<=0;M3<=0;M4<=0;M5〈=0;
end
end
elsemain_state〈=QR;
default:
;
endcase
end
endmodule
(2)键盘模块keyboard
modulekeyboard(
clk,
rst,
inrow,outcol,//行输入,列读出
key_value,//键值
key_flag,
);
inputclk,rst;//时钟25mhz
input[3:
0]inrow;
output[3:
0]outcol;
output[4:
0]key_value;
outputkey_flag;
regclock;//定义25时钟
regkey_flag;//按键标志位
regjud_flag;//按键标志位
reg[3:
0]col;//行输入扫描值
reg[3:
0]inrow_reg;//寄存扫描列值
reg[3:
0]outcol_reg;//寄存扫描行值
reg[2:
0]state;//状态标志-判断是否有按键按下
reg[4:
0]key_value;//读取按键值
reg[19:
0]count;
reg[7:
0]keynum_1;//寄存扫描列值
//产生25hz时钟
always@(posedgeclk)
begin
count〈=count+1;
if(count〉=20’d50000)
begin
clock<=~clock;
count<=0;
end
end
////////////////////////////////////////////
//通过6状态状态机完成对键盘的扫描:
总确定是否有按键—〉逐行扫描—>统一处理
always@(posedgeclock)
if(rst==1)
begin
state<=0;key_flag〈=1'b0;
end
else
begin
case(state)
0:
//初值0
begin
col<=4'b0000;//行扫描输入值
key_flag〈=1’b0;
if(inrow!
=4’b1111)//有键按下
begin
state〈=1;
col〈=4'b1110;//开始扫描
end
elsestate<=0;//总体判断是否有按键按下,确定按键标志位
end
1:
begin
if(inrow!
=4'b1111)
begin
state<=5;//有按键时直接进入状态5
end
else
begin
state〈=2;
col〈=4'b1101;
end
end
2:
begin
if(inrow!
=4'b1111)
begin
state<=5;
end
else
begin
state〈=3;col〈=4'b1011;
end
end
3:
begin
if(inrow!
=4’b1111)
begin
state〈=5;
end
else
begin
state<=4;col〈=4’b0111;
end
end
4:
begin
if(inrow!
=4’b1111)
begin
state〈=5;
end
elsestate<=0;
end
5:
begin
if(inrow!
=4’b1111)
begin
inrow_reg〈=inrow;//保存扫描行值//读得
outcol_reg<=col;//保存扫描列值
key_flag〈=1'b1;//有键按下为1
state〈=0;//连续扫描状态5直至无按键按下,从0开始
end
elsestate〈=0;
end
endcase
end
/////////////////////////////////////////////////////////
always@(clock)
begin
if(keynum_1=={outcol_reg,inrow_reg})
begin//连续2次检测到的按键值相同,稳定
jud_flag〈=1;
end
else
begin
jud_flag〈=0;
keynum_1〈={outcol_reg,inrow_reg};
end
end
//对键盘扫描结果译码得到按键数值
always@(posedgekey_flag)
begin
//if(key_flag==1’b1)
begin
case({outcol_reg,inrow_reg})
8'b1110_1110:
beginkey_value<=0;end
8'b1110_1101:
beginkey_value〈=1;end
8'b1110_1011:
beginkey_value<=2;end
8’b1110_0111:
beginkey_value〈=3;end
8'b1101_1110:
beginkey_value<=4;end
8’b1101_1101:
beginkey_value<=5;end
8’b1101_1011:
beginkey_value〈=6;end
8'b1101_0111:
beginkey_value〈=7;end
8’b1011_1110:
beginkey_value<=8;end
8’b1011_1101:
beginkey_value〈=9;end
8’b1011_1011:
beginkey_value〈=10;end
8’b1011_0111:
beginkey_value〈=11;end
8’b0111_1110:
beginkey_value<=12;end
8'b0111_1101:
beginkey_value〈=13;end
8’b0111_1011:
beginkey_value<=14;end
8’b0111_0111:
beginkey_value〈=15;end
default:
key_value〈=16;//无按键按下或无效按键组合
endcase
end
end
assignoutcol=col;
endmodule
(3)显示模块show
moduleshow
(
CLK,
segData,segCtl,segData_1,segData_2,segData_3,segData_4,segData_5
);
inputCLK;
outputreg[7:
0]segData;
outputreg[4:
0]segCtl;
input[3:
0]segData_1;
input[3:
0]segData_2;
input[3:
0]segData_3;
input[3:
0]segData_4;
input[3:
0]segData_5;
reg[7:
0]segDataReg;//段选扫描
reg[4:
0]segC