数字逻辑与数字系统期末大作业——四位十进制密码锁
【设计要求】
(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
效果图:
总体代码是在这位学长的基础上修改,增加了功能:
报告写的不是很好,最后扣分了,建议多写一点字写的详细一点。
测试代码是随便写的,这个波形图能不能出来真的随缘了,我是有一个变量波形图没出来就给他截掉了,我和周围的同学这部分都是瞎写的
最后如果有问题可以给我发邮件3174465976@qq.com,尽量回复