当前位置:网站首页>状态机实验
状态机实验
2022-08-03 23:35:00 【三个刺客】
一:实验任务
画出可以检测10010串的状态图,并用verilog编程实现
思路:
使用按键KEY1和KEY2分别代表0和1,这里要使用按键消抖,可以参考我的另一篇博客中的按键消抖FPGA按键消抖+蜂鸣器
通过有限的6个状态进行切换,当识别到数字串10010时,LED闪烁2s。
状态图:
设计按键消抖模块
key_debounce.v
module key_debounce(
input wire clk,
input wire rst_n,
input wire key,
output reg flag, //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
output reg key_value //消抖后稳定的按键值给到蜂鸣器模块和LED模块
);
//定义20ms延迟计数器,0.2s,1_000_000次
reg [19:0] delay_cnt;
//寄存依次key的值用来判断按键是否消抖成功
reg key_reg;
//按下按键20ms延时计数器
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
begin
key_reg <= 1'b1; //复位信号,设置按键无效
delay_cnt <= 1'b0; //计数器设置为0
end
else
begin
key_reg <= key;
if(key_reg ^ key) //当这一次key值和上一次key值不一样,证明正在抖动
delay_cnt <= 20'd1_000_000; //延迟时间20ms
else if(delay_cnt > 0)
delay_cnt <= delay_cnt - 1; //没有抖动,开始20ms倒计时
else
delay_cnt <= 1'b0;
end
end
//根据延时计数器获取按键状态以及按键值
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
begin
flag <= 1'b0; //复位信号,设置信号标志为抖动
key_value <= 1'b1; //设置抽样值为1
end
else
begin
if(delay_cnt == 20'd1) //倒计时1_000_000到1
begin
flag <= 1'b1;
key_value <= key; //稳定20ms后将key值给到key_value
end
else
begin
flag <= 1'b0;
key_value <= key_value; //20ms内先不取样
end
end
end
endmodule
设计状态机模块Verilog HDL文件
fsm_10010.v
module fsm_10010(
input clk,
input rst_n,
input [1:0] key,
output wire [3:0] led
);
parameter MAX_NUM = 24'd9_999_999;//0.2s计时器
parameter T = 4'd10;//2s,100_000_000次
reg [2:0] cstate; //现态
//状态划分
localparam state_0 = 0; //初始状态
localparam state_1 = 1; //按下1
localparam state_10 = 2; //按下10
localparam state_100 = 3; //按下100
localparam state_1001 = 4; //按下1001
localparam state_10010 = 5; //按下10010
reg [3:0] cnt = 0; //计时器赋初值为0
reg [23:0] cnt_02 = 0;
reg time_flag;//计时标志,1:开始计时,0:结束计时
reg [3:0] led_r;
//0.2计数器模块
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_02 <= 1'b0; //按下复位键,清零
else if(cnt_02 == MAX_NUM)
cnt_02 <= 1'b0;
else
cnt_02 <= cnt_02 + 1'b1;
end
//2s计数器模块
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 1'b0;//按下复位键,清零
else if(time_flag == 1'b1)begin//开始计时
if(cnt_02 == MAX_NUM)begin
if(cnt < T)begin
cnt <= cnt + 1'b1;
end
else begin
cnt <= 1'b0;//cnt计数达到最大就清空
end
end
else begin
cnt <= cnt;//其余时间保持
end
end
else begin
cnt <= 1'b0;//不计时,cnt清空
end
end
//状态切换模块
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cstate <= state_0;
end
else
case(cstate)
state_0: begin
if(key[1] == 1'b1) //该状态持续时间为1s,1s后,下一次状态更改为led1亮
cstate <= state_1;
else if(key[0] == 1'b1)
cstate <= state_0;
else
cstate <= state_0;
end
state_1: begin
if(key[0] == 1'b1)
cstate <= state_10;
else if(key[1] == 1'b1)
cstate <= state_0;
else
cstate <= state_1;
end
state_10: begin
if(key[0] == 1'b1)
cstate <= state_100;
else if(key[1] == 1'b1)
cstate <= state_0;
else
cstate <= state_10;
end
state_100: begin
if(key[1] == 1'b1)
cstate <= state_1001;
else if(key[0] == 1'b1)
cstate <= state_0;
else
cstate <= state_100;
end
state_1001: begin
if(key[0] == 1'b1)begin
cstate <= state_10010;
time_flag <= 1'b1;//开始计时
end
else if(key[1] == 1'b1)
cstate <= state_0;
else
cstate <= state_1001;
end
state_10010: begin
if(cnt == T)begin
cstate <= state_0;
time_flag <= 1'b0;//结束计时
end
else
cstate <= state_10010;
end
default: ;
endcase
end
//第三段:跟随状态输出
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)
led_r <= 4'b0001;
else
case(cstate)
state_10010:if(cnt_02 == 24'd4_999_999)
led_r <= 4'b1111;
else if(cnt_02 == MAX_NUM)
led_r <= 4'b0000;
else
led_r <= led_r;
default : led_r <= 4'b0001;
endcase
end
assign led = led_r;
endmodule
设计顶层模块
top_fsm_10010.v
module top_fsm_10010(
input wire clk,
input wire rst_n,
input wire [1:0] key,
output wire [3:0] led
);
wire [1:0] flag;
wire [1:0] key_value;
//例化按键KEY1
key_debounce inst_key_debounce(
.clk (clk ),
.rst_n (rst_n ),
.key (key[0] ),
.flag (flag[0] ), //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
.key_value(key_value[0]) //消抖后稳定的按键值给到蜂鸣器模块和LED模块
);
//例化按键KEY2
key_debounce inst_key_debounce1(
.clk (clk ),
.rst_n (rst_n ),
.key (key[1] ),
.flag (flag[1] ), //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
.key_value(key_value[1]) //消抖后稳定的按键值给到蜂鸣器模块和LED模块
);
//例化状态机
fsm_10010(
.clk (clk ),
.rst_n(rst_n ),
.key ({~key_value[1]&&flag[1],~key_value[0]&&flag[0]}),
.led (led)
);
endmodule
查看RTL门级电路
边栏推荐
猜你喜欢
YOLOv7改进之二十二:涨点神器——引入递归门控卷积(gnConv)
ML之yellowbrick:基于titanic泰坦尼克是否获救二分类预测数据集利用yellowbrick对LoR逻辑回归模型实现可解释性(阈值图)案例
CAS: 178744-28-0, mPEG-DSPE, DSPE-mPEG, methoxy-polyethylene glycol-phosphatidylethanolamine supply
Fluorescein-PEG-CLS, cholesterol-polyethylene glycol-fluorescein scientific research reagent
rosbridge-WSL2 && carla-win11
Cloud platform construction solutions
软件测试内卷严重,如何提升自己的竞争力呢?
一文搞定 SQL Server 执行计划
密码学基础以及完整加密通讯过程解析
Scala基础【正则表达式、框架式开发原则】
随机推荐
重新认识浏览器的渲染过程
Why Flutter Flutter of tutorials is the best choice for business?
1067 Sort with Swap(0, i)
【论文阅读】TRO 2021: Fail-Safe Motion Planning for Online Verification of Autonomous Vehicles Using Conve
The longest substring that cannot have repeating characters in a leetcode/substring
SolidEdge ST8安装教程
Creo 9.0二维草图的诊断:重叠几何
Binary search tree to solve the fallen leaves problem
二叉搜索树解决落叶问题
Unity2021发布WebGL雾效消失问题
Analysys Analysis: The transaction scale of China's online retail B2C market in Q2 2022 will reach 2,344.47 billion yuan
HNUCM 2022年暑假ACM搜索专项练习
电子邮件安全或面临新威胁!
Software testing is seriously involution, how to improve your competitiveness?
BMN: Boundary-Matching Network for Temporal Action Proposal Generation Reading Notes
双目IMU标定kalibr
响应式织梦模板除尘器类网站
Kotlin - extension functions and operator overloading
初始 List 接口
【RYU】rest_router.py源码解析