数字密码锁

1.设计要求: 用 verilog 语言设计一个数字密码锁,需要满足以下基本功能:

(1). 密码为 4 位,每位密码为数字 0-5,4 位密码各不相同。 (2). 具有使能输入端 en,用于控制密码锁的开启和关闭。密码锁开启, 允许输入密码;密码锁关闭,禁止输入密码。 (3). 具有清零输入端 clr,用于清除已输入的密码,重新进行密码输入。 (4). 可输出显示密码正确与否。 进阶功能: (1). 具有密码修改功能,允许修改预设的四位密码。 (2). 密码连续输错 3 次以上,密码锁输出显示锁定,不允许再进行密码 输入。 (3). 可自定义添加其他功能。 编写 testbench 验证功能并下板验证。

2.基本功能:

Stay状态:

    stay:begin //等待状态(测试各输出是否能够正常输出)

      unlock_led <= 1;

      error_led <= 1;

      inpw3 <= 8;

      inpw2 <= 8;

      inpw1 <= 8;

      inpw0 <= 8;

      s <= 3;

      if(en) begin //若en为1,则进入输入(inpt)状态

        state <= inpt;

        unlock_led <= 0;

        error_led <= 0;

        inpw3 <= 10; //显示横线

      end

    end

当en=1时,进入输入状态,当clr=0时清0,

inpt:begin //输入密码状态

      unlock_led <= 0;

      error_led <= 0;

      if(en) begin //使能端en为1,进行密码输入

        case(s)

         3:begin

          inpw3 <= pw;

          s <= s-1;

          inpw2 <= 10; //显示横线

        end

        2:begin

          inpw2 <= pw;

           s <= s-1;

          inpw1 <= 10; //显示横线

         end

        1:begin

          inpw1 <= pw;

          s <= s-1;

          inpw0 <= 10; //显示横线

        end

        0:begin

          inpw0 <= pw;

          s <= 3;

          state <= check;

         end

        default;

        endcase

      end

      else begin  //若en为0,返回stay状态

      state <= stay;

      end

    end

当最后一个数字输入后,进入check状态进行检测,

check:begin //密码检测状态

      if(en) begin

        inpw3 <= 10;

        inpw2 <= 10;

        inpw1 <= 10;

        inpw0 <= 10;

        if((inpw3==password3)&&

        (inpw2==password2)&&

        (inpw1==password1)&&

        (inpw0==password0)) begin

          state <= ulock;

          t <= 3; //错误计数重置

        end

        else begin

          state <= er;

          t <= t-1; //错误次数计数

        end

      end

      else begin

        state <= stay;

      end

    end

如果与设置的密码相符,则进入ulock状态,解锁,会有unlock_led <= 1;error_led <= 0;显示;

ulock:begin //密码正确,解锁成功状态

      unlock_led <= 1;

      error_led <= 0;

      state <= stay;

    end  

如果不符则进入er状态,会有unlock_led <= 0;error_led <= 1;显示,并且此时数码管上显示EEEE。

er:begin //密码错误

        inpw3 <= 11; //显示E

        inpw2 <= 11;

        inpw1 <= 11;

        inpw0 <= 11;

      unlock_led <= 0;

      error_led <= 1;

      state <= stay;     

    end

3.进阶功能

如果set=1,则进入密码输入状态

setpw:begin //更改密码状态

      unlock_led <= 0;

      error_led <= 0;

      inpw3 <= 10; //显示横线

      inpw2 <= 12;

      inpw1 <= 12;

      inpw0 <= 12;

     

      case(s)

         3:begin

          password3 <= pw;

          s <= s-1;

          inpw3 <= pw;

          inpw2 <= 10; //显示横线

        end

        2:begin

          password2 <= pw;

          s <= s-1;

          inpw3 <= password3;

          inpw2 <= pw;

          inpw1 <= 10; //显示横线

         end

        1:begin

          password1 <= pw;

          s <= s-1;

          inpw3 <= password3;

          inpw2 <= password2;

          inpw1 <= pw;

          inpw0 <= 10; //显示横线

        end

        0:begin

          password0 <= pw;

          s <= 3;

          inpw3 <= password3;

          inpw2 <= password2;

          inpw1 <= password1;

          inpw0 <= pw;

          state <= stay;

         end

        default;

        endcase

    end

如果错误超过三次,计数的t由3减为0,进入lock状态,数码管上显示lock

lock:begin //错误3次,上锁

      inpw3 <= 13; //显示L

      inpw2 <= 0; //显示O

      inpw1 <= 14; //显示C

      inpw0 <= 15; //显示K

      error_led <= 1;

      unlock_led <= 0;

    end

二、仿真

    #50 en=1; //测试初始密码:2023

    #10 pw=2;

    #10 pw=0;

    #10 pw=2;

    #10 pw=3;

    #10 pw=0;

    #40 en=0;

数码管3: 0100100对应2

数码管2:1000000对应0

数码管1:0100100对应0

数码管0:0110000对应3

之后数码管全部变为0111111,及为横杠,unlock_led 变为 1,解锁成功

#50 en=1; //输入错误密码:1111

    pw=1;

    #100 en=0;

数码管上显示的数字均变为1111001,对应1,此时error_led 变为 1;数码管均显示0000110,及E,未能解锁

    #50 set=1;//设置新密码为:1211

    #10 set=0;

    pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #10 pw=0;

数码管


3:1111001对应1

数码管2:0100100对应2

数码管1:1111001对应1

数码管0:1111001对应1

及密码变为了1211

    #50 en=1;//输入原始密码:2023

    #10 pw=2;

    #10 pw=0;

    #10 pw=2;

    #10 pw=3;

    #40 en=0;

 输入密码2023后

数码管3: 0100100对应2

数码管2:1000000对应0

数码管1:0100100对应0

数码管0:0110000对应3

之后数码管上显示的数字均变为1111001,对应1,此时error_led 变为 1;数码管均显示0000110,及E,未能解锁

#50 en=1;//输入新密码:1211

    #10 pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #40 en=0;

 数码管3:1111001对应1

数码管2:0100100对应2

数码管1:1111001对应1

数码管0:1111001对应1

之后数码管全部变为0111111,及为横杠,unlock_led 变为 1,解锁成功

#50 en=1;//输入错误密码:2222

    #10 pw=2;

    #400 //错误输入超过3次

    en=0;

 数码管数字均变为0100100,对应2,之后数码管变为0001110,及对应E

重复输入达到三次之后

 数码管3:1000111,对应L

数码管2:1000000,对应O

数码管1:1000110,对应C

数码管0:0000111,对应K

再输入依旧时lock,及超过三次后锁定

#50 en=1;//输入新密码:1211,测试是否能够继续输入密码

    #10 pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #40 en=0;

再次输入正确密码,但此时

数码管3:1000111,对应L

数码管2:1000000,对应O

数码管1:1000110,对应C

数码管0:0000111,对应K

依旧保持不变,及超过三次后锁定,不允许再输入密码

    #100 $finish;

end

endmodule

三、
顶层电路图

附录

完整的代码

module digital_lock(

  input wire clr, //清零输入

  input wire en, //使能输入

  input wire [3:0] pw, //4位密码输入

  input wire set, //设置密码按键

  input wire clk,

  output reg unlock_led, //密码正确输出标志

  output reg error_led, //密码错误标志

  output reg [6:0] shumaguan3, //数码管

  output reg [6:0] shumaguan2,

  output reg [6:0] shumaguan1,

  output reg [6:0] shumaguan0

);

reg [3:0] password3; //密码储存

reg [3:0] password2;

reg [3:0] password1;

reg [3:0] password0;

reg [3:0] inpw3; //输入密码储存

reg [3:0] inpw2;

reg [3:0] inpw1;

reg [3:0] inpw0;

reg [2:0] state; //状态机

reg [1:0] s; //置位计数

reg [1:0] t; //错误次数记录

//状态定义

parameter [3:0] stay=0,inpt=1,setpw=2,check=3,ulock=4,er=5,lock=6;

initial begin //初始状态

  state = stay;

  s = 3;

  t = 3;

  password3 = 2; //初始密码2023

  password2 = 0;

  password1 = 2;

  password0 = 3;

end

always @(posedge clk) begin

  if(clr) begin //清零输入

    state <= stay;

    s <= 3;

  end

  else if(set) begin //进入修改密码状态

    state <= setpw;

    s <= 3;

    unlock_led <= 0;

    error_led <= 0;

    inpw3 <= 10; //显示横线

    inpw2 <= 12; //显示右边框

    inpw1 <= 12;

    inpw0 <= 12;

  end

  else if(t==0) begin //失败3次后上锁

    state <= lock;

    inpw3 <= 13; //显示L

    inpw2 <= 0; //显示O

    inpw1 <= 14; //显示C

    inpw0 <= 15; //显示K

    error_led <= 1;

    unlock_led <= 0;

  end

  else begin

    case (state) //各个状态

   

   

   

    stay:begin //等待状态(测试各输出是否能够正常输出)

      unlock_led <= 1;

      error_led <= 1;

      inpw3 <= 8;

      inpw2 <= 8;

      inpw1 <= 8;

      inpw0 <= 8;

      s <= 3;

      if(en) begin //若en为1,则进入输入(inpt)状态

        state <= inpt;

        unlock_led <= 0;

        error_led <= 0;

        inpw3 <= 10; //显示横线

      end

    end

   

   

   

   

    inpt:begin //输入密码状态

      unlock_led <= 0;

      error_led <= 0;

      if(en) begin //使能端en为1,进行密码输入

        case(s)

         3:begin

          inpw3 <= pw;

          s <= s-1;

          inpw2 <= 10; //显示横线

        end

        2:begin

          inpw2 <= pw;

           s <= s-1;

          inpw1 <= 10; //显示横线

         end

        1:begin

          inpw1 <= pw;

          s <= s-1;

          inpw0 <= 10; //显示横线

        end

        0:begin

          inpw0 <= pw;

          s <= 3;

          state <= check;

         end

        default;

        endcase

      end

      else begin  //若en为0,返回stay状态

      state <= stay;

      end

    end

   

    setpw:begin //更改密码状态

      unlock_led <= 0;

      error_led <= 0;

      inpw3 <= 10; //显示横线

      inpw2 <= 12;

      inpw1 <= 12;

      inpw0 <= 12;

     

      case(s)

         3:begin

          password3 <= pw;

          s <= s-1;

          inpw3 <= pw;

          inpw2 <= 10; //显示横线

        end

        2:begin

          password2 <= pw;

          s <= s-1;

          inpw3 <= password3;

          inpw2 <= pw;

          inpw1 <= 10; //显示横线

         end

        1:begin

          password1 <= pw;

          s <= s-1;

          inpw3 <= password3;

          inpw2 <= password2;

          inpw1 <= pw;

          inpw0 <= 10; //显示横线

        end

        0:begin

          password0 <= pw;

          s <= 3;

          inpw3 <= password3;

          inpw2 <= password2;

          inpw1 <= password1;

          inpw0 <= pw;

          state <= stay;

         end

        default;

        endcase

    end

    check:begin //密码检测状态

      if(en) begin

        inpw3 <= 10;

        inpw2 <= 10;

        inpw1 <= 10;

        inpw0 <= 10;

        if((inpw3==password3)&&

        (inpw2==password2)&&

        (inpw1==password1)&&

        (inpw0==password0)) begin

          state <= ulock;

          t <= 3; //错误计数重置

        end

        else begin

          state <= er;

          t <= t-1; //错误次数计数

        end

      end

      else begin

        state <= stay;

      end

    end

   

   

    ulock:begin //密码正确,解锁成功状态

      unlock_led <= 1;

      error_led <= 0;

      state <= stay;

    end  

   

    er:begin //密码错误

        inpw3 <= 11; //显示E

        inpw2 <= 11;

        inpw1 <= 11;

        inpw0 <= 11;

      unlock_led <= 0;

      error_led <= 1;

      state <= stay;     

    end

    lock:begin //错误3次,上锁

      inpw3 <= 13; //显示L

      inpw2 <= 0; //显示O

      inpw1 <= 14; //显示C

      inpw0 <= 15; //显示K

      error_led <= 1;

      unlock_led <= 0;

    end

    default;

    endcase

  end

end

//数码管显示

always @ (*) begin

    // 将二进制数转换为七段数码管的控制信号

    // 0为亮,1为灭

    case (inpw3)

        4'b0000: shumaguan3 = 7'b1000000; // 0

        4'b0001: shumaguan3 = 7'b1111001; // 1

        4'b0010: shumaguan3 = 7'b0100100; // 2

        4'b0011: shumaguan3 = 7'b0110000; // 3

        4'b0100: shumaguan3 = 7'b0011001; // 4

        4'b0101: shumaguan3 = 7'b0010010; // 5

        4'b0110: shumaguan3 = 7'b0000010; // 6

        4'b0111: shumaguan3 = 7'b1111000; // 7

        4'b1000: shumaguan3 = 7'b0000000; // 8

        4'b1001: shumaguan3 = 7'b0010000; // 9

        4'b1010: shumaguan3 = 7'b0111111; //10显示横线

        4'b1011: shumaguan3 = 7'b0000110; //11显示E

        4'b1100: shumaguan3 = 7'b1110000; //12显示右半框

        4'b1101: shumaguan3 = 7'b1000111; //13显示L

        4'b1110: shumaguan3 = 7'b1000110; //14显示C

        4'b1111: shumaguan3 = 7'b0000111; //15显示K

        default: shumaguan3 = 7'b1111111; // 灭

    endcase

    case (inpw2)

        4'b0000: shumaguan2 = 7'b1000000; // 0

        4'b0001: shumaguan2 = 7'b1111001; // 1

        4'b0010: shumaguan2 = 7'b0100100; // 2

        4'b0011: shumaguan2 = 7'b0110000; // 3

        4'b0100: shumaguan2 = 7'b0011001; // 4

        4'b0101: shumaguan2 = 7'b0010010; // 5

        4'b0110: shumaguan2 = 7'b0000010; // 6

        4'b0111: shumaguan2 = 7'b1111000; // 7

        4'b1000: shumaguan2 = 7'b0000000; // 8

        4'b1001: shumaguan2 = 7'b0010000; // 9

        4'b1010: shumaguan2 = 7'b0111111; //10显示横线

        4'b1011: shumaguan2 = 7'b0000110; //11显示E

        4'b1100: shumaguan2 = 7'b1110000; //12显示右半框

        4'b1101: shumaguan2 = 7'b1000111; //13显示L

        4'b1110: shumaguan2 = 7'b1000110; //14显示C

        4'b1111: shumaguan2 = 7'b0000111; //15显示K

        default: shumaguan2 = 7'b1111111; // 灭

    endcase

    case (inpw1)

        4'b0000: shumaguan1 = 7'b1000000; // 0

        4'b0001: shumaguan1 = 7'b1111001; // 1

        4'b0010: shumaguan1 = 7'b0100100; // 2

        4'b0011: shumaguan1 = 7'b0110000; // 3

        4'b0100: shumaguan1 = 7'b0011001; // 4

        4'b0101: shumaguan1 = 7'b0010010; // 5

        4'b0110: shumaguan1 = 7'b0000010; // 6

        4'b0111: shumaguan1 = 7'b1111000; // 7

        4'b1000: shumaguan1 = 7'b0000000; // 8

        4'b1001: shumaguan1 = 7'b0010000; // 9

        4'b1010: shumaguan1 = 7'b0111111; //10显示横线

        4'b1011: shumaguan1 = 7'b0000110; //11显示E

        4'b1100: shumaguan1 = 7'b1110000; //12显示右半框

        4'b1101: shumaguan1 = 7'b1000111; //13显示L

        4'b1110: shumaguan1 = 7'b1000110; //14显示C

        4'b1111: shumaguan1 = 7'b0000111; //15显示K

        default: shumaguan1 = 7'b1111111; // 灭

    endcase

    case (inpw0)

        4'b0000: shumaguan0 = 7'b1000000; // 0

        4'b0001: shumaguan0 = 7'b1111001; // 1

        4'b0010: shumaguan0 = 7'b0100100; // 2

        4'b0011: shumaguan0 = 7'b0110000; // 3

        4'b0100: shumaguan0 = 7'b0011001; // 4

        4'b0101: shumaguan0 = 7'b0010010; // 5

        4'b0110: shumaguan0 = 7'b0000010; // 6

        4'b0111: shumaguan0 = 7'b1111000; // 7

        4'b1000: shumaguan0 = 7'b0000000; // 8

        4'b1001: shumaguan0 = 7'b0010000; // 9

        4'b1010: shumaguan0 = 7'b0111111; //10显示横线

        4'b1011: shumaguan0 = 7'b0000110; //11显示E

        4'b1100: shumaguan0 = 7'b1110000; //12显示右半框

        4'b1101: shumaguan0 = 7'b1000111; //13显示L

        4'b1110: shumaguan0 = 7'b1000110; //14显示C

        4'b1111: shumaguan0 = 7'b0000111; //15显示K

        default: shumaguan0 = 7'b1111111; // 灭

    endcase

end

endmodule

     

      

仿真:

`timescale 1ns/1ps

module digital_lock_tb;

reg clr;

reg en;

reg [3:0] pw;

reg set;

reg clk;

wire unlock_led;

wire error_led;

wire [6:0] shumaguan3;

wire [6:0] shumaguan2;

wire [6:0] shumaguan1;

wire [6:0] shumaguan0;

digital_lock u1(   

    .clr(clr),

    .en(en),

    .set(set),

    .pw(pw),

    .clk(clk),

    .unlock_led(unlock_led),

    .error_led(error_led),

    .shumaguan3(shumaguan3),

    .shumaguan2(shumaguan2),

    .shumaguan1(shumaguan1),

    .shumaguan0(shumaguan0)

);

always begin

#5 clk = ~clk;

end

initial begin

    en=0;

    clr=0;

    set=0;

    pw=0;

        clk=0;

    #50 en=1; //测试初始密码:2023

    #10 pw=2;

    #10 pw=0;

    #10 pw=2;

    #10 pw=3;

    #10 pw=0;

    #40 en=0;

    #50 en=1; //输入错误密码:1111

    pw=1;

    #100 en=0;

    #50 set=1;//设置新密码为:1211

    #10 set=0;

    pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #10 pw=0;

    #50 en=1;//输入原始密码:2023

    #10 pw=2;

    #10 pw=0;

    #10 pw=2;

    #10 pw=3;

    #40 en=0;

    #50 en=1;//输入新密码:1211

    #10 pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #40 en=0;

    #50 en=1;//输入错误密码:2222

    #10 pw=2;

    #400 //错误输入超过3次

    en=0;

    #50 en=1;//输入新密码:1211,测试是否能够继续输入密码

    #10 pw=1;

    #10 pw=2;

    #10 pw=1;

    #10 pw=1;

    #40 en=0;

    #100 $finish;

end

endmodule

  • 22
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值