数字逻辑与数字系统期末大作业——四位十进制密码锁

【设计要求】

(1) 设计一个开锁密码至少为 4 位数字(或更多)的密码锁。

(2) 当开锁按钮开关(可设置 8 位或更多,其中只有 4 位有效,其余位为虚设)的输入代码等于所设密码时启动开锁控制电路,用 F1 灯(代表绿灯)亮、F2 灯(代表红灯)灭表示开锁状态,并用数码管显示英文大写 OP。

(3) 从第一个按钮触动后的 10 秒内若未能将锁打开,则电路自动复位,同时用 F1 灯(代表绿灯)灭、F2 灯(代表红灯)亮表示关锁状态,并用数码管显示英文大写LC。

(4) 10 秒开锁倒计时要求用数码管显示

注: 附加功能根据本人能力自行添加(如:当操作者开始按动按钮能进行倒计时显示。密码锁中的 4 位密码可以修改,可以记录按键次数等等)

附加功能:

(1)开锁之后可以修改密码

(2)可以记录输入密码次数

(3)十进制显示输入密码

(4)三次输入错误之后锁死

注:十秒倒计时结束以后就没法继续输密码了,但是助教看的很松,操作分也给满了

  1 module mimasuo(clk,clk0,clk1,clk2,clk3,res,set,in,enter,inpw,rled,lled,state,red,green,led);
  2     input clk;//系统时钟
  3     input clk0,clk1,clk2,clk3;//用于转换十进制的模拟时钟信号
  4     input res;//电路总复位信号,拨码按键左1
  5     input set;//设置密码,左2
  6     input in;//输入密码,左3
  7     input enter;//确认键
  8     
  9     output reg [3:0] inpw;//右侧四个数码管位选,显示输入的密码
 10     output [6:0] rled;//右侧四个数码管段选
 11      reg xcount;//左1数码管位选,用于倒计时
 12     output reg [3:0]state;//左侧数码管位选,用于显示op和lc状态
 13     output reg [6:0] lled;//左侧数码管段选,显示倒计时
 14     output reg red;//红灯,表示关锁状态
 15     output reg green;//绿灯,表示开锁状态
 16     output reg [2:0] led;//记录输入次数的指示灯
 17     
 18     wire [3:0] in0,in1,in2,in3;//储存当前输入的四位密码
 19     reg [3:0] pw0,pw1,pw2,pw3;//储存设置的四位密码
 20     reg [3:0] count;//倒计时
 21     reg [3:0] num;//储存输入的数字
 22     reg tim;//分频用来输入数码管
 23     reg input_start,input_res;//输入开始信号,输入复位信号
 24     integer time_count,clock_count;//分频读秒
 25     integer cishu;//记录输入的次数
 26     integer cishu1;//记录成功的次数
 27 initial begin
 28     count = 4'b1010;//从10开始倒计时
 29     inpw = 4'b0001;//先定位最右侧的数码管
 30     time_count = 0;
 31     tim = 0;//分频初始都为0
 32     green = 1;
 33     red = 0;//初始先是开锁状态
 34     cishu = 0;//输入次数初始为0
 35     clock_count = 0;
 36     xcount = 1;
 37     state = 4'b0001;
 38     input_res = 0;
 39 end
 40 
 41 mo10jishu u0(clk0,input_res,input_start,in0);
 42 mo10jishu u1(clk1,input_res,input_start,in1);
 43 mo10jishu u2(clk2,input_res,input_start,in2);
 44 mo10jishu u3(clk3,input_res,input_start,in3);
 45 
 46 xianshi x1(clk,num,input_res,rled);//输入密码的显示
 47 //左侧数码管的显示
 48 always @(*)
 49 begin
 50 case(state)
 51 4'b1000:
 52 begin//倒计时
 53 if(count == 4'b1010)
 54     lled <= 7'b0110000;
 55 else
 56     lled <= 7'b1111110;
 57 end
 58 4'b0001:
 59 begin
 60 if(green)
 61 begin
 62     lled <= 7'b1100111;
 63 end
 64 else if(red)
 65 begin
 66     lled <= 7'b1001110;
 67 end
 68 end
 69 4'b0010://OP和LC
 70 begin
 71 if(green)
 72 begin
 73     lled <= 7'b11111110;
 74 end
 75 else if(red)
 76 begin
 77     lled <= 7'b0001110;
 78 end
 79 end
 80 4'b0100:
 81 if(xcount)
 82 begin
 83 case(count)
 84             4'b0000:
 85                 lled <= 7'b1111110;
 86             4'b0001:
 87                 lled <= 7'b0110000;
 88             4'b0010:
 89                 lled <= 7'b1101101;
 90             4'b0011:
 91                 lled <= 7'b1111001;
 92             4'b0100:
 93                 lled <= 7'b0110011;
 94             4'b0101:
 95                 lled <= 7'b1011011;
 96             4'b0110:
 97                 lled <= 7'b1011111;
 98             4'b0111:
 99                 lled <= 7'b1110000;
100             4'b1000:
101                 lled <= 7'b1111111;
102             4'b1001:
103                 lled <= 7'b1111011;
104             default:
105                 lled <= 7'b1111110;
106             endcase
107 end
108 endcase
109 end
110 
111 always @(posedge clk)
112 begin
113     if(in)
114     begin
115     green <= 0;
116     red <= 1;
117     if(cishu1)
118     begin
119         count <= 4'b1010;
120         clock_count <= 0;
121         cishu1 <= 0;
122     end//如果打开锁,则下次输密码时从头开始计时
123     if(count != 4'b0000&&~green)//倒计时
124     begin
125     xcount <= 1;
126         if(clock_count != 2500000000)
127         begin
128             clock_count <= clock_count + 1;
129         end
130         case(clock_count)
131             0:
132                 count <= 4'b1010;
133             250000000:
134                 count <= 4'b1001;
135             500000000:
136                 count <= 4'b1000;
137             750000000:
138                 count <= 4'b0111;
139             1000000000:
140                 count <= 4'b0110;
141             1250000000:
142                 count <= 4'b0101;
143             1500000000:
144                 count <= 4'b0100;
145             1750000000:
146                 count <= 4'b0011;
147             2000000000:
148                 count <= 4'b0010;
149             2250000000:
150                 count <= 4'b0001;
151             2500000000:
152                 count <= 4'b0000;
153         endcase
154     end
155     else if(~in)//不输入密码时,倒计时不显示
156     begin
157         count <= 4'b1001;
158         clock_count <= 0;
159     end
160     end
161     
162     if(count == 4'b0000&&~green)//倒计时结束
163     begin 
164         input_start <= 0;//停止输入
165         input_res <= 1;//输入清零
166         red <= 1;
167     end
168     else if(cishu < 4)//正常情况下
169     begin
170         input_start <= set|in;//输入密码和重置密码都可输入
171         input_res <= res|(set&in);//同时打开输入密码和重置密码时会置0
172     end
173     
174     if(green && set)//重置密码,只有锁开了才能重置密码
175     begin
176         pw0 <= in0;
177         pw1 <= in1;
178         pw2 <= in2;
179         pw3 <= in3;
180     end
181     
182     if(time_count == 200000)//显示数码管分频
183     begin
184         tim <= 1;
185         time_count <= 0;
186     end
187     else
188     begin
189         time_count <= time_count + 1;
190         tim <= 0;
191     end
192     
193     
194     if(in)
195     begin//密码输入成功
196         if(in0==pw0&&in1==pw1&&in2==pw2&&in3==pw3&&enter&&count!=4'b0000)
197         begin
198             green <= 1;
199             red <= 0;
200             count <= 4'b1010;
201             cishu1 <= cishu1 +1;
202            
203         end
204         else 
205         begin
206             green <= 0;
207         end
208     end  
209     
210     if(cishu > 3 && count != 4'b0000)//输入错误三次以后
211         begin
212                 input_start <= 0;
213                 input_res <= 1;
214                 led <= 3'b000;
215                 count <= 4'b0000;
216                 clock_count <= 0;
217         end
218 
219         case(cishu)//输一次密码亮一次灯
220         0:
221             led <= 3'b000;
222         1:
223             led <= 3'b001;
224         2:
225             led <= 3'b011;
226         3:
227             led <= 3'b111;
228         default: led<= 3'b000;
229         endcase
230 
231 end
232 
233 always @(posedge tim)
234 begin//右侧数码管动态显示
235     if(inpw == 4'b0001)
236     begin
237         inpw <= 4'b0010;
238         num <= in1;
239     end
240     else if(inpw == 4'b0010)
241     begin
242        inpw <= 4'b0100;
243        num <= in2;
244     end
245     else if(inpw == 4'b0100)
246     begin
247        inpw <= 4'b1000;
248         num <= in3;
249     end
250     else if(inpw == 4'b1000)
251     begin
252        inpw <= 4'b0001;
253        num <= in0;
254     end
255     //左侧数码管动态显示
256     if(state == 4'b0001)
257     state <= 4'b0010;
258     else if(state == 4'b0010)
259     state <= 4'b0100;
260     else if(state <= 4'b0100)
261     state <= 4'b1000;
262     else if(state <= 4'b1000)
263     state <= 4'b0001;
264 end
265 
266 always @(posedge enter)
267 begin
268 //每按一次确认键,输入次数+1
269 cishu <= cishu + 1;
270 
271 if(count == 4'b0000)
272 cishu <= 0;
273 
274 if(green)
275 cishu <= 0;
276 
277 end
278 endmodule

 

module xianshi(clk,num,res,out);//将二进制数转化成十进制数显示在数码管上
    input clk;
    input [3:0]num;
    input res;
    output reg [6:0]out;
always @(posedge clk or posedge res)
begin
    if(res)
        out <= 7'b1111110;
    else
    begin
        case(num)
            4'b0000:
                out <= 7'b1111110;
            4'b0001:
                out <= 7'b0110000;
            4'b0010:
                out <= 7'b1101101;
            4'b0011:
                out <= 7'b1111001;
            4'b0100:
                out <= 7'b0110011;
            4'b0101:
                out <= 7'b1011011;
            4'b0110:
                out <= 7'b1011111;
            4'b0111:
                out <= 7'b1110000;
            4'b1000:
                out <= 7'b1111111;
            4'b1001:
                out <= 7'b1111011;
            default:
                out <= 7'b1111110;
        endcase
    end
end
            
        
endmodule
module mo10jishu(clk,res,start,out);//模10计数器进行十进制输入
input clk;
input res;//复位信号
input start;//开始信号
output reg [3:0] out;//输出数字
always @(posedge clk or posedge res)//时钟上升沿或遇到复位信号
begin
    if(res)
        out <= 4'b0000;//置0
    else if(start)
        begin
            if(out == 4'b1001)
                out <= 4'b0000;//9下一个是0
            else
                out <= out + 4'b0001;
        end
end
endmodule

 

效果图:

 

总体代码是在这位学长的基础上修改,增加了功能:

https://blog.csdn.net/Carrot_kexin/article/details/120676663?utm_medium=distribute.wap_relevant.none-task-blog-2~default~baidujs_title~default-8.wap_blog_relevant_default&spm=1001.2101.3001.4242.5

报告写的不是很好,最后扣分了,建议多写一点字写的详细一点。

测试代码是随便写的,这个波形图能不能出来真的随缘了,我是有一个变量波形图没出来就给他截掉了,我和周围的同学这部分都是瞎写的

最后如果有问题可以给我发邮件3174465976@qq.com,尽量回复

 

posted @ 2022-01-20 15:18  小兔巴尼  阅读(354)  评论(0编辑  收藏  举报