课程设计报告课程设计题目:4位串行数字密码锁学号学生姓名:谢渊良专业:通信工程班级:1421302指导教师:钟凯2017年1月5日1.摘要随着科技的发展数字电路的各种产品广泛应用,传统的机械锁由于其构造的简单,安全性不高,电子密码锁其保密性高,使用灵活性好,安全系数高,使用方便,将会是未来使用的趋势。
本设计使用EDA设计使设计过程廷到高度自动化,其具有强大的设计功能、测试、仿真分析、管理等功能。
使用EDA环境完成电路的系统综合设计和仿真。
用VHDL可以更加快速、灵活地设计出符合各种要求的密码锁。
本设计基于Verilog HDL 语言来设计密码锁,先介绍设计要求和整体设计思想,随后对所使用各模块分别为键盘模块、连接模块、控制模块进行了介绍,给出各个模块的主要代码,在对各个模块的功能进行仿真。
关键字:密码锁 Verilog HDL2.设计内容设计一个4位数字密码锁子系统1)1.2设计要求开锁密码为4位二进制,当输入密码与锁内给定的密码一致时,方可开锁。
否则进入“错误”状态,发出报警信号。
2)锁内的密码可调。
3)串行数字密码锁的报警,直到按下复位开关,才停下。
此时,数字密码锁又自动等待下一个开锁状态。
3.系统设计本设计中,FPGA系统采用硬件描述语言Verilog按模块化方式进行设计,并用modersim软件对各个模块进行编写仿真。
3.1键盘模块键盘电路理想接口图:Set本模块采用2×2的扫描键盘电路,对输入信号进行采集,此模块的主要功能是每按下一个按键,flag产生一个矩形波,作为连接模块的触发信号。
同时key_value值为所按下键的编码值,与flag一同传入连接模块。
实际设计接口图:当输出kevalue:11值的时候,flag再次出现上跳沿。
实际上,上面的图写的测试文件是有一点错误的,当a扫描到第三个值(01)时,b在实际电路中应该是01而不是11,此时根据程序flag应置为1,当然此时flag本来就是1,不会发生错误。
在实际中,时钟频率跳的如此之快,人按一下按键的持续时间还是有的,所以flag应在按键按完后再下降下来。
不然多出很多无用的矩形波,这个装置就没用了。
3.2连接模块连接模块接口图:keyvalue送入连接模块进行运算,当连续四个0和1键按下时,中,如果按下的是set键,则set置1,如果按下的是0键,则a_led置1,若是1键,则b_led 置1。
这里有一个需要注意的点是,当第一次按了0键后马上按reset键,再按一下1键时,a的值是1,而不是0。
每次按了reset或set,a,b,c,d都是要重新赋值的,这才符合实际情况。
3.3控制模块:因为这个密码锁是循环使用的,就一定有不同的状态。
这里采用有限状态机的方法进行设计。
所以把开锁过程分为三个部分:1.等待输入状态;2.重设密码状态;3.输出结果状态;状态转换图如下所示:控制模块接口图:flag2 enad d_ledsetreseclkt设计原理:通过各种状态的转变,实现密码锁的开锁,报错,重设密码功能。
当密码错误是ena=1;当重设密码成功时c_led置为1;当输入密码成功开锁时d_led为1。
控制模块仿真如下:因为初设密码是0000,所以在第一个flag2的矩形波到来后,d_led出现一个矩形波,实际上不应该出现矩形,一直亮直到reset重置才行。
或者设计一个计数器都行,虽然只是一些小错误,但如果在实际验证中可能现象就不易观察了。
然后就是按下set键的模拟了,波形都达到了课设的要求。
这是令人欣喜的,虽然经过了很多次的修改,实在是很不容易。
4.实验心得我从第二个星期的星期一开始做,本来只是随便做一下,但是看到周围同学都热情高昂,我也深受感染,然后开始查资料,后面看到这个状态机的方法很不错,很方便的解决了状态的转换问题,然后我就尝试这个方法。
同时在写程序的时候我也遇到了很多了困难,其中最难找的错误就是逻辑错误,但是最终还是一一被我解决了。
心中的成就感还是有一些的。
通过此次的课设,使我对数字电路的设计有更深层次的了解(各种时序),对verilog语言的运用也更加熟练。
由于时间和心力有限的原因,使我只能止步各个模块的设计了。
本来还想联合仿真的,但是电脑里只装了modersim,其中又有一个键盘开关的硬件,还是比较难实现的。
我想,如果我的程序下载到fpga芯片里,那是一定会出现不少错误的,实际的情况往往更加复杂,这也是我的一大遗憾!最后我要感谢我的室友,感谢他们对我的关爱,在我将要放弃的时候鼓励我,使我积极向前。
在此,我还要特别感谢英明兄的无私帮助,减少了我找编译错误的时间。
还依稀记得上次的数电感觉也是如此,很不错啊。
附:Verilog程序代码1.1 Key_board_input:module key_board_input(clk,a,b,keyvalue,flag ,q,j);input clk;input[1:0] b;output reg[1:0] a;output reg[1:0] keyvalue;output reg flag;output reg q=1;output reg[1:0] j=0;always @(posedge clk)beginq=q+1;case(q)0:a=2'b01;1:a=2'b10;endcasecase({a,b})4'b10_01:beginkeyvalue=2'b00;flag=1;j=3;end4'b10_10:beginkeyvalue=2'b01;flag=1;j=3;end4'b01_01:beginkeyvalue=2'b10;flag=1;j=3;end4'b01_10:beginkeyvalue=2'b11;flag=1;j=3;enddefault:keyvalue=keyvalue;endcasebeginj=j+1;if(j==3) flag=0;endendendmodule1.2 key_board_test:`timescale 1s/1smodule key_board_test();reg clk;reg[1:0] b;wire[1:0] a;wire[1:0] keyvalue;wire flag;wire q;wire [1:0] j;key_board_input u2(clk,a,b,keyvalue,flag,q,j);initialbegin#0 clk=0;#2 clk=1;b=1;#2 clk=0;#2 clk=1;b=3;#2 clk=0;#2 clk=1;b=3;#2 clk=0;#2 clk=1;b=3;#2 clk=0;#2 clk=1;b=2;#2 clk=0;#2 clk=1;b=3;#2 clk=0;#2 clk=1;b=3;#2 clk=0;#2 clk=1;b=3;endendmodule2.1 connect:module connect(flag,keyvalue,a_led,b_led,flag2,a,b,c,d,set1,reset,jishu,jishu1,jishu2,hh);input flag;input [1:0]keyvalue;output reg a_led,b_led,flag2,a,b,c,d,set1,reset;output reg [1:0] jishu=2'b00;output reg [1:0]jishu1=0,jishu2=0,hh=0;always@(negedge flag)beginjishu2<=jishu2+1; jishu1<=jishu1+1;if(keyvalue<2)beginif(jishu==3)beginjishu<=0;endelsejishu<=jishu+1; endif(jishu==0)flag2=0;if(keyvalue==2)beginhh<=jishu1;jishu<=0;endif(jishu1==(hh+1))beginset1<=0;endif(keyvalue==2'd3)beginhh<=jishu2;jishu<=0;endif(jishu2==(hh+1))beginreset<=0;end/*if(jishu==0)flag2=0;/*??????set????*/ case(jishu)0:begincase(keyvalue)0:begina<=0;a_led=1;b_led=0;end1:begina=1;a_led=0;b_led=1;end2:beginset1=1;end3:beginreset=1;endendcaseend1:begincase(keyvalue)0:beginb=0;b_led=0;end1:beginb=1;a_led=0;b_led=1;end2:beginset1=1;end3:beginreset=1;end endcaseend2:begincase(keyvalue)0:beginc=0;a_led=1;b_led=0;end1:beginc=1;a_led=0;b_led=1;end2:beginend3:beginreset=1;end endcaseend3:begincase(keyvalue)0:begind=0;a_led=1;b_led=0;flag2=1;end1:begind=1;a_led=0;b_led=1;flag2=1;end2:beginset1=1;end3:beginreset=1;end endcaseendendcaseendendmodule2.2 connect_test:`timescale 1s/1smodule connect_test();reg flag;reg[1:0] keyvalue;wire a_led,b_led,flag2,a,b,c,d,set1,reset;wire [1:0]jishu;wire[1:0] jishu1,jishu2,hh;connect u2(flag,keyvalue,a_led,b_led,flag2,a,b,c,d,set1,reset,jishu,jishu1,jishu2,hh);initialbegin#0 flag=0;#2 flag=1;keyvalue=1;#2 flag=0;#2 flag=1;keyvalue=3;#2 flag=0;#2 flag=1;keyvalue=0;#2 flag=0;#2 flag=1;keyvalue=0;#2 flag=0;#2 flag=1;keyvalue=1;#2 flag=0;#2 flag=1;keyvalue=0;#2 flag=0;endendmodule3.1 control:modulecontrol(clk,flag2,a,b,c,d,set1,reset,control_set,ena,c_led,d_led,state,a1,b1,c1,d1,hhh);input clk,flag2,a,b,c,d,set1,reset;output reg ena,c_led,d_led,control_set;output reg[1:0] state=0;output reg a1=0,b1=0,c1=0,d1=0;output reg hhh=0;parameter in=2'b00,set=2'b01,out1=2'b10;always@(posedge clk or posedge set1 or posedge reset or flag2)begincase(state)in:beginif(reset==1)state=in;else if(set1==1)beginstate=set;control_set=1;endelse if (control_set==1&&hhh==1)beginstate=in;control_set=0;hhh=0;endelse if(flag2==1)state=out1;elsebeginena=0;control_set=0;d_led=0;endendset:beginif(reset==1)state=in;else if(set1==1)beginstate=set;control_set=1;endelse if(flag2==1&&control_set==1)begina1=a;b1=b;c1=c;d1=d;hhh=1;c_led=1;state=in;endendout1:beginif(reset==1)state=in;elsebeginif(a==a1&b==b1&c==c1&d==d1)ena=0;d_led=1;state=in;endelsebeginena=1;state=out1;endendenddefault:state=in;endcaseendendmodule3.2 control_test:`timescale 1s/1smodule control_test();reg clk,flag2,a,b,c,d,set1,reset;wire ena,c_led,d_led,control_set;wire [1:0] state;wire a1,b1,c1,d1;wire hhh;controlu2(clk,flag2,a,b,c,d,set1,reset,control_set,ena,c_led,d_led,state,a1,b1,c1,d1,hhh);always #10 clk=~clk;initialbegin clk=0;reset=0;flag2=0;a=0;b=0;c=0;d=0;set1=0;reset=0;#10 a=0;#20 b=0;#20 c=0;#20 d=0;flag2=1;#20 flag2=0;#50 reset=1;#20 reset=0;#50 set1=1;#20 a=1; set1=0;#20 b=1;#20 c=0;#20 d=0;flag2=1;#20 flag2=0;#20 reset=1;#20 reset=0;#80 a=0;#20 b=0;#20 c=0;#20 d=0;flag2=1;#20 flag2=0;#20 reset=1;#20 reset=0;endendmodule东华理工大学课程设计评分表学生姓名:谢渊良班级:1421302课程设计题目:4位串行数字密码锁。