北邮 数电实验作业参考 #可更改密码的密码箱

本文介绍了一个基于VerilogHDL设计的密码保险箱,包括其功能描述、密码验证和在FPGA开发板上的实现。设计者强调了安全性和密码输入流程,并展示了主要模块的代码和管脚绑定图,旨在提供实用的参考或解决方案。
摘要由CSDN通过智能技术生成

各位好我是Toporanger  本人只会写代码 不会教人 毕竟自己的代码也是改来改去最终成功的 如果有不够精简的地方还请见谅 

我会先贴下代码 然后贴上管脚的绑定图  无论是拿来救急还是作为参考都希望帮助到你们

题目:设计一个密码保险箱。

调研市场需求,自行确定保险箱的功能。能被市场认可的产品才是好产品;销量越大,产品设计越成功。你的箱子你做主!要求:

1. 用文字准确描述密码箱的功能和安全性。

2. Verilog HDL实现并在FPGA开发板上验证。

代码:

主函数:

`timescale 1ns / 1ps

// 模块hw_4: 实现一个简单的密码锁功能,包括密码输入、状态显示和密码修改
module hw_4 (
    input clk,       // 时钟信号
    input rst,       // 复位信号
    input key1,      // 按键1,用于密码修改模式
    input key2,      // 按键2,用于确认密码修改
    input key3,      // 按键3,用于密码输入验证
    input sw1, sw2, sw3, sw4, // 开关,用于密码输入
    output reg led1, led2, led3, led4, // LED灯,显示开关状态
    output reg seg_led1,  // 密码状态灯,正确时熄灭
    output reg seg_led2,  // 密码锁状态灯,解锁时熄灭
    output reg seg_led3   // 密码修改状态灯,修改模式时熄灭
);

    // 密码和尝试次数寄存器
    reg [3:0] password;
    reg [3:0] count;

    // 按键脉冲信号(假设有外部电路或逻辑生成这些脉冲信号)
    wire key1_pulse;
    wire key2_pulse;
    wire key3_pulse;

    // 主逻辑
    always @(posedge clk) begin
        if (!rst) begin
            // 复位逻辑,初始化状态和密码
            seg_led1 <= 1'b1;
            seg_led3 <= 1'b1;
            password <= 4'b0100; // 初始密码设为"0100"
            seg_led2 <= 1'b1;
            count <= 4'b0000;
        end
        else if (count == 4'b0110) begin
            // 密码输入次数超限,锁定
            seg_led2 <= 1'b0;
        end
        else begin
            // 密码输入逻辑
            if (seg_led1 && seg_led3 && key3_pulse) begin
                count <= count + 1'b1;
            end
            // 显示开关状态
            led1 <= sw1;
            led2 <= sw2;
            led3 <= sw3;
            led4 <= sw4;

            // 密码验证逻辑
            if (seg_led2 && seg_led3 && key3_pulse) begin
                case ({sw1, sw2, sw3, sw4})
                    password: seg_led1 <= 1'b0; // 密码正确
                    default: seg_led1 <= 1'b1;  // 密码错误
                endcase
            end

            // 进入密码修改模式
            if (seg_led2 && !seg_led1 && key1_pulse) begin
                seg_led3 <= 1'b0;
            end

            // 确认并修改密码
            if (seg_led2 && !seg_led1 && !seg_led3 && key2_pulse) begin
                seg_led3 <= 1'b1;
                seg_led1 <= 1'b1;
                password <= {sw1, sw2, sw3, sw4}; // 更新密码
                count <= 4'b0000; // 重置尝试次数
            end
        end
    end
endmodule


 

消抖模块:

module debounce (clk,rst,key,key_pulse);
 
        parameter       N  =  1;                      //要消除的按键的数量
 
    input             clk;
        input             rst;
        input     [N-1:0]   key;                        //输入的按键                    
    output  [N-1:0]   key_pulse;                  //按键动作产生的脉冲    
 
        reg     [N-1:0]   key_rst_pre;                //定义一个寄存器型变量存储上一个触发时的按键值
        reg     [N-1:0]   key_rst;                    //定义一个寄存器变量储存储当前时刻触发的按键值
 
        wire    [N-1:0]   key_edge;                   //检测到按键由高到低变化是产生一个高脉冲
 
        //利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中
        always @(posedge clk  or  negedge rst)
          begin
             if (!rst) begin
                 key_rst <= {N{1'b1}};                //初始化时给key_rst赋值全为1,{}中表示N个1
                 key_rst_pre <= {N{1'b1}};
             end
             else begin
                 key_rst <= key;                     //第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre
                 key_rst_pre <= key_rst;             //非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值
             end    
           end
 
        assign  key_edge = key_rst_pre & (~key_rst);//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平
 
        reg    [17:0]      cnt;                       //产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器     
 
        //产生20ms延时,当检测到key_edge有效是计数器清零开始计数
        always @(posedge clk or negedge rst)
           begin
             if(!rst)
                cnt <= 18'h0;
             else if(key_edge)
                cnt <= 18'h0;
             else
                cnt <= cnt + 1'h1;
             end  
 
        reg     [N-1:0]   key_sec_pre;                //延时后检测电平寄存器变量
        reg     [N-1:0]   key_sec;                    
 
 
        //延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效
        always @(posedge clk  or  negedge rst)
          begin
             if (!rst) 
                 key_sec <= {N{1'b1}};                
             else if (cnt==18'h3ffff)
                 key_sec <= key;  
          end
       always @(posedge clk  or  negedge rst)
          begin
             if (!rst)
                 key_sec_pre <= {N{1'b1}};
             else                   
                 key_sec_pre <= key_sec;             
         end      
       assign  key_pulse = key_sec_pre & (~key_sec);     
 
endmodule

管脚图 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值