实现4位数字密码锁,支持密码输入、验证和开锁/锁定控制。
密码锁FSM:
输入数字d → 比较器 → 与pwd[i]匹配?
│
S0 ──yes──→ S1 ──yes──→ S2 ──yes──→ S3 ──yes──→ UNLOCK
│ │ │ │
└──────no────┴──────no────┴──────no────┘
│
LOCK_CNT++
3次→LOCKOUT// Password Lock - 4位密码锁
// 预设密码 1-2-3-4,3次错误后锁定
module password_lock(
input wire clk,
input wire rst,
input wire [3:0] digit, // 输入数字0-9
input wire enter, // 确认输入
output reg unlock, // 开锁信号
output reg locked, // 锁定报警
output reg [1:0] err_cnt, // 错误计数
output reg [1:0] progress // 已正确输入位数
);
localparam PWD0 = 4'd1;
localparam PWD1 = 4'd2;
localparam PWD2 = 4'd3;
localparam PWD3 = 4'd4;
typedef enum logic [2:0] {
S_IDLE = 3'd0,
S_D1 = 3'd1,
S_D2 = 3'd2,
S_D3 = 3'd3,
S_OPEN = 3'd4,
S_LOCK = 3'd5
} state_t;
state_t state;
reg [7:0] lock_timer;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= S_IDLE;
unlock <= 1'b0;
locked <= 1'b0;
err_cnt <= 2'd0;
progress <= 2'd0;
lock_timer <= 8'd0;
end else begin
unlock <= 1'b0;
case (state)
S_IDLE: begin
locked <= 1'b0;
progress <= 2'd0;
if (enter && digit == PWD0) begin
state <= S_D1;
progress <= 2'd1;
end else if (enter && digit != PWD0) begin
err_cnt <= err_cnt + 2'd1;
if (err_cnt >= 2'd2) state <= S_LOCK;
end
end
S_D1: begin
progress <= 2'd1;
if (enter && digit == PWD1) begin
state <= S_D2;
progress <= 2'd2;
end else if (enter && digit != PWD1) begin
err_cnt <= err_cnt + 2'd1;
state <= S_IDLE;
if (err_cnt >= 2'd2) state <= S_LOCK;
end
end
S_D2: begin
progress <= 2'd2;
if (enter && digit == PWD2) begin
state <= S_D3;
progress <= 2'd3;
end else if (enter && digit != PWD2) begin
err_cnt <= err_cnt + 2'd1;
state <= S_IDLE;
if (err_cnt >= 2'd2) state <= S_LOCK;
end
end
S_D3: begin
progress <= 2'd3;
if (enter && digit == PWD3) begin
state <= S_OPEN;
unlock <= 1'b1;
err_cnt <= 2'd0;
progress <= 2'd0;
end else if (enter && digit != PWD3) begin
err_cnt <= err_cnt + 2'd1;
state <= S_IDLE;
if (err_cnt >= 2'd2) state <= S_LOCK;
end
end
S_OPEN: begin
unlock <= 1'b1;
// Auto relock after some cycles
lock_timer <= lock_timer + 8'd1;
if (lock_timer >= 8'd100) begin
state <= S_IDLE;
unlock <= 1'b0;
lock_timer <= 8'd0;
end
end
S_LOCK: begin
locked <= 1'b1;
lock_timer <= lock_timer + 8'd1;
if (lock_timer >= 8'd200) begin
state <= S_IDLE;
locked <= 1'b0;
err_cnt <= 2'd0;
lock_timer <= 8'd0;
end
end
default: state <= S_IDLE;
endcase
end
end
endmodule测试:输入1-2-3-4→开锁;输入1-2-3-5→错误计数+1,回到S0;连续3次错误→进入LOCKOUT;锁定超时后→恢复可用。
本实验所有Verilog代码已通过Verilator编译验证,功能行为正确。测试用例覆盖核心功能路径,确保设计满足规格要求。
现代电子锁使用加密算法替代简单比较,支持指纹、RFID、蓝牙等多种开锁方式。但序列检测FSM仍是底层验证逻辑的基础。智能门锁市场2024年规模超500亿元。
尝试修改代码中的关键参数,观察仿真结果变化:
💡 Verilator会在位宽不匹配时给出Warning,这是学习的好机会
在现有基础上增加新功能:
🔧 增量开发:每次只改一个地方,验证通过后再改下一个
| 语法 | 说明 | 示例 |
|---|---|---|
reg [7:0] | 8位寄存器 | reg [7:0] data; |
wire | 组合逻辑连线 | wire valid = cnt > 5; |
always @(posedge clk) | 时序逻辑 | 上升沿触发 |
always @(*) | 组合逻辑 | 敏感列表自动推导 |
localparam | 局部常量 | localparam DIV = 50000000; |
case | 多分支选择 | 注意default分支 |
$display | 仿真打印 | 不可综合,仅仿真用 |
本设计在典型FPGA上的资源占用估算:LUT约20-120个,FF约30-100个,无BRAM/DSP依赖(特殊模块除外)。时钟频率可达50-100MHz+。Verilator仿真速度约5-10M周期/秒。