浅谈状态机

article/2025/9/29 16:16:18

一、状态机原理

(一)有限状态机

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM(Finite State Machine),主要分为2大类:Moore状态机和Mealy状态机

(二)Moore状态机

摩尔状态机:当输出(output)只与当前状态有关时,所描述的状态机称为Moore型状态机。
在这里插入图片描述

(三)Mealy状态机

米利状态机:当输出(output)不仅与当前状态有关而且与输入(inputs)有关时,所描述的状态机称为Mealy型状态机。
在这里插入图片描述

(四)状态机描述方法

1.一段式
只有一个always块,把所有的逻辑(输入、输出、状态)都在一个always块的时序逻辑中实现。这种写法看起来很简洁,但是不利于维护,如果状态复杂一些容易出错。

2.两段式
有两个always 块,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺。

3.三段式
有三个always块,一个采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个always使用同步时序的方式描述每个状态的输出。
代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些。

(五)状态机标准评判标准

好的状态机的标准很多,最重要的几个方面如下:

第一,状态机要安全,是指FSM不会进入死循环,特别是不会进入非预知的状态,而且由于某些扰动进入非设计状态,也能很快的恢复到正常的状态循环中来。这里面有两层含义:其一要求该FSM的综合实现结果无毛刺等异常扰动;其二要求FSM要完备,即使受到异常扰动进入非设计状态,也能很快恢复到正常状态。
第二,状态机的设计要满足设计的面积和速度的要求。
第三,状态机的设计要清晰易懂、易维护。

二、状态机状态设计

(一)实验要求

根据以下描述功能用verilog编写一段代码,并用状态机来实现该功能。
(1)状态机:实现一个测试过程,该过程包括启动准备状态、启动测试、停止测试、查询测试结果、显示测试结果、测试结束返回初始化6个状态;用时间来控制该过程,90秒内完成该过程;
(2)描述状态跳转时间;
(3)编码实现。

(二)设计思路

在这里插入图片描述
在这里插入图片描述

(三)相关代码

module test(input  wire         clk,input  wire         rst_n,output wire  [3:0]  led
);
parameter   MAX_NUM = 26'd49_999_999;//记最大数,时间1s
parameter   C0 = 5'd5;//5s
parameter   C1 = 5'd20;//20s
parameter   C2 = 5'd18;//18s
parameter   C3 = 5'd25;//25s
parameter   C4 = 5'd14;//14s
parameter   C5 = 5'd8;//8s//状态空间
parameter S0  = 3'd0;//初始状态
parameter S1  = 3'd1;//准备状态
parameter S2  = 3'd2;//启动状态
parameter S3  = 3'd3;//停止状态
parameter S4  = 3'd4;//查询状态
parameter S5  = 3'd5;//结果状态reg  [4:0]  number;//每个模块计数
reg  [25:0] cnt;//计数寄存器
reg  [4:0]  state_time;//每个状态记录时
reg  [2:0]  flag;//状态标志reg [2:0]   cstate;//现态
reg [3:0]   led_r;
//1秒钟计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)  begin                          //按下复位键cnt<=26'd0; 		  //计数器清零endelse if(cnt == MAX_NUM)begincnt <= 26'd0;endelse begincnt <= cnt + 1'd1;end
end//各模块计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)  begin   	 //按下复位键state_time <= 1'd0;endelse if(cnt == MAX_NUM)beginstate_time <=  state_time + 1'd1;endelse if(state_time == number)beginstate_time <=  1'd0;endelse beginstate_time <=  state_time;end
end//状态切换
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincstate <= S0;number <= C0;flag <= 1'd0;end	else begincase(cstate)S0:beginif(state_time == 3'd5&&(!flag))begincstate <= S1;number <= C1;flag <= flag + 1'd1;endelse begincstate <= S0;endendS1:beginif(state_time == 5'd20&&(flag == 1))begincstate <= S2;number <= C2;flag <= flag + 1'd1;endelse begincstate <= S1;endendS2:beginif(state_time == 5'd18&&(flag == 2))begincstate <=S3;number <= C3;flag <= flag + 1'd1;endelse begincstate <= S2;endendS3:beginif(state_time == 5'd25&&(flag == 3))begincstate <=S4;number <= C4;flag <= flag + 1'd1;endelse begincstate <= S3;endendS4:beginif(state_time == 5'd14&&(flag == 4))begincstate <=S5;number <= C5;flag <= flag + 1'd1;endelse begincstate <= S4;endendS5:beginif(state_time == 5'd8 &&(flag == 5))begincstate <=S0;number <= C0;flag <= 1'd0;endelse begincstate <= S5;endenddefault:begin cstate <=S0;number <= C0;flag <= 1'd0;endendcaseend
end
//led灯状态
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginled_r <= 4'b0000;endelse begincase(cstate)S0:  led_r <= 4'b0001;S1:  led_r <= 4'b0011;S2:  led_r <= 4'b0111;S3:  led_r <= 4'b1111;S4:  beginif(cnt == MAX_NUM)beginled_r <= ~led_r;endelse beginled_r <= led_r ;endendS5:  led_r <=4'b0000;default:led_r <= 4'b0000;endcaseend
end
assign led = led_r;
endmodule

三、检测10010串的状态

(一)实验要求

画出可以检测10010串的状态图, 并用verilog编程实现之。

(二)设计思路

在这里插入图片描述

(三)相关代码

(1)状态处理模块 deal.v

//状态识别:10010
module deal(input   wire       clk, input   wire       rst_n,input   wire [1:0] key,output  wire [3:0] led 
);  
parameter MAX_NUM =26'd49_999_999;
parameter CNT_02 =24'd9_999_999;
//状态空间
parameter S0  = 3'd0;
parameter S1    = 3'd1;
parameter S2    = 3'd2;
parameter S3    = 3'd3;
parameter S4    = 3'd4;
parameter S5    = 3'd5;
reg [2:0]   cstate;
reg [25:0]  cnt_1s;
reg [23:0]  cnt_200ms;
reg [3:0]   led_r;//计数器1s
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_1s <= 26'd0;endelse if(cnt_1s == MAX_NUM)begincnt_1s <= 26'd0;endelse begincnt_1s <= cnt_1s + 1'd1;end
end//计数器0.2s
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_200ms <= 24'd0;endelse if(cnt_200ms == CNT_02)begincnt_200ms <= 24'd0;endelse begincnt_200ms <= cnt_200ms + 1'd1;end
end//密码切换
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincstate <= S0;end	else begincase(cstate)S0:beginif(key[1])begincstate <=S1;endelse if (key[0])begincstate <= S0;endelse begincstate <= S0;endendS1:beginif(key[0])begincstate <=S2;endelse if (key[1])begincstate <= S0;endelse begincstate <= S1;endendS2:beginif(key[0])begincstate <=S3;endelse if (key[1])begincstate <= S1;endelse begincstate <= S2;endendS3:beginif(key[1])begincstate <=S4;endelse if (key[0])begincstate <= S2;endelse begincstate <= S3;endendS4:beginif(key[0])begincstate <=S5;endelse if (key[1])begincstate <= S3;endelse begincstate <= S4;endendS5:beginif(cnt_1s == MAX_NUM)begincstate <= S0;endelse begincstate <= S5;endenddefault:cstate <= S0;endcaseend
endalways@(posedge clk or negedge rst_n)beginif(!rst_n)beginled_r <= 4'b0000;endelse begincase(cstate)S0:  led_r <= 4'b0000;S1:  led_r <= 4'b0001;S2:  led_r <= 4'b0011;S3:  led_r <= 4'b0111;S4:  led_r <= 4'b1111;S5:  beginif(cnt_200ms == CNT_02)beginled_r <= ~led_r;endelse beginled_r <= led_r ;endenddefault:led_r <= 4'b0000;endcaseend
end
assign led = led_r;
endmodule

(2)按键消抖模块key_debouce.v

module key_debouce(input    wire    clk,//1s震荡50_000_000次input    wire    rst_n,input    wire    key,//当前的按键取值output   wire     flag,//幻断抖动是否消除的标志信号,0为抖动,1为抖动结束output   wire     key_value//肖抖后稳定的按键值,给到蜂鸣器模块);parameter MAX_NUM =20'd1_000_000;//定义20ms延迟计数器,0.02s秒,1_000_000c次
reg  [19:0]  cnt_delay; 
//寄存一次key的值,用来判断按键是否消抖成功
reg  key_reg;
reg  flag_r;
reg  key_value_r;
//20ms延时计数器
always@(posedge clk or negedge rst_n)beginif(!rst_n)  begin                          //按下复位键key_reg <= 1'b1;    //key变为高电平cnt_delay <= 20'd0;  //计数器清零endelse beginkey_reg <= key;if(key_reg == 1'b1 && key == 1'b0 )begin//当这一次的key值和上一次的key值不相等时,证明按键状态在抖动cnt_delay <= MAX_NUM;//延迟计数器设置为20msendelse if(cnt_delay <= 20'd0)begincnt_delay<= 20'd0; endelse begincnt_delay <= cnt_delay - 1'd1;//抖动结束开始递减end	end
endalways@(posedge clk or negedge rst_n)
beginif(!rst_n)begin    flag_r <= 1'b0;      //按键初始值为低电平endelse if(cnt_delay == 20'd1) begin//初始赋值为0,,避免为0,倒计时20到1是20个数,倒计时结束flag_r <= 1'b1;endelse  beginflag_r <= 1'b0;end
end	always@(posedge clk or negedge rst_n)
beginif(!rst_n)begin    key_value_r <= 1'b1;       //按键初始值为低电平endelse if(cnt_delay == 20'd1) begin//初始赋值为0,,避免为0,倒计时20到1是20个数,倒计时结束key_value_r <= ~key;endelse  beginkey_value_r <= key_value;end
end	
assign flag = flag_r;
assign key_value = key_value_r;
endmodule

(3)顶层模块check.v

module check(input   wire       clk,//1s震荡50_000_000次input   wire       rst_n,input   wire [1:0] key,//当前的按键取值output  wire [3:0] led//肖抖后稳定的按键值,给到蜂鸣器模块);
wire [1:0] key_value;
wire [1:0] flag;
key_debouce inst_key_debouce(
.clk        (clk),//1s震荡50_000_000次
.rst_n      (rst_n),
.key        (key[1]),//当前的按键取值.flag       (flag[1]),//幻断抖动是否消除的标志信号,0为抖动,1为抖动结束
.key_value  (key_value[1])//肖抖后稳定的按键值,给到蜂鸣器模块);
key_debouce inst_key_debouce1(
.clk        (clk),//1s震荡50_000_000次
.rst_n      (rst_n),
.key        (key[0]),//当前的按键取值.flag       (flag[0]),//幻断抖动是否消除的标志信号,0为抖动,1为抖动结束
.key_value  (key_value[0])//肖抖后稳定的按键值,给到蜂鸣器模块);deal inst_deal(
.clk         (clk), 
.rst_n       (rst_n),
.key         ({(flag[1]&&key_value[1]),(flag[0]&&key_value[0])}),
.led         (led)
); 
endmodule

http://chatgpt.dhexx.cn/article/Pn90w9DN.shtml

相关文章

状态机与序列机

状态机由状态寄存器和组合逻辑电路构成&#xff0c;能够根据控制信号按照预先设定的状态进行状态转移&#xff0c;是协调相关信号动作、完成特定操作的控制中心。 一、线性序列机 序列机是什么&#xff1a;用计数器对时钟个数计数&#xff0c;根据相应时钟周期下的单个周期时…

状态机总结(简洁)

一、概念 状态机简写为 FSM&#xff08;Finite State Machine&#xff09;&#xff0c;也称为同步有限状态机&#xff0c;我们一般简称为状态机&#xff0c;之所以说“同步”是因为状态机中所有的状态跳转都是在时钟的作用下进行的&#xff0c;而“有限”则是说状态的个数是有…

有限状态机详解(转载)

以前总觉得有限状态机和无限状态机非常的难理解&#xff0c;原来也就是自己一直没有一个直观的认识&#xff0c;今天看到一篇博客&#xff0c;总算对有限状态机入门了。一看就懂。 转载地址&#xff1a;http://blog.csdn.net/zqixiao_09/article/details/50239337 我们知道&a…

状态机

有限状态机&#xff08;Finite State Machine或者Finite State Automata)是软件领域中一种重要的工具&#xff0c;很多东西的模型实际上就是有限状态机。最近看了一些游戏编程AI的材料&#xff0c;感觉游戏中的AI&#xff0c;第一要说的就是有限状态机来实现精灵的AI&#xff0…

状态机的深入理解

目录 1.什么是状态机 2. 生活中的状态机 3. 工程中的应用 4. 发散思考 1.什么是状态机 ■1.1 有向图 有向图是指由定点和边构成的集合&#xff0c;我们常用G&#xff08;E, V&#xff09;来表示一个有向图&#xff0c;其中定点之间由有向边进行连接就构成了有向图。有向图…

有限状态机

文章目录 有限状态机状态机的表示状态转移图二维表 实现穷举法查表法状态模式 总结 有限状态机 有限状态机(Finite State Machine) 缩写为 FSM。以下简称为状态机。 状态机有 3 个组成部分&#xff1a;状态、事件、动作。 状态&#xff1a;所有可能存在的状态。包括当前状态和…

什么是状态机?

前言 状态机在实际工作开发中应用非常广泛&#xff0c;在刚进入公司的时候&#xff0c;根据公司产品做流程图的时候&#xff0c;发现自己经常会漏了这样或那样的状态&#xff0c;导致整体流程会有问题&#xff0c;后来知道了状态机这样的东西&#xff0c;发现用这幅图就可以很…

什么是状态机(Finite-state machine)?

有限状态机 有限状态机(FSM)1、 什么是“状态”2、什么是状态机&#xff1f;3、状态机图怎么画&#xff1f;参考 有限状态机(FSM) 1、 什么是“状态” 先来解释什么是“状态”&#xff08; State &#xff09;。现实事物是有不同状态的&#xff0c;例如一个自动门&#xff0c…

什么是状态机?用C语言实现进程5状态模型

前言 状态机在实际工作开发中应用非常广泛&#xff0c;在刚进入公司的时候&#xff0c;根据公司产品做流程图的时候&#xff0c;发现自己经常会漏了这样或那样的状态&#xff0c;导致整体流程会有问题&#xff0c;后来知道了状态机这样的东西&#xff0c;发现用这幅图就可以很…

状态机(state machine)

一、状态机分类 Mealy状态机:输出取决于输入和当前状态 状态寄存器:由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。 状态是否改变、如何…

状态机(有限状态自动机 FSM)介绍以及常用状态机种类对比

目录 状态机概念 : 为什么需要状态机: 使用场景 状态机四要素: 常见类型状态机: Squirrel State Machine Spring Statemachine 状态机概念 : 概念 : 状态机是有限状态自动机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff…

STM32状态机编程----什么是状态机?

万事万物都有其状态 什么是状态 状态是人或事物表现出来的形态。是指现实&#xff08;或虚拟&#xff09;事物处于生成、生存、发展、消亡时期或各转化临界点时的形态或事物态势。 通过上面那句话&#xff0c;我们知道了状态就是一个对象在不同情况下对应的各种形态 做产品的…

什么是状态机?一篇文章就够了

1 概述 状态机[1]一般指有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;又称有限状态自动机&#xff08;英语&#xff1a;finite-state automaton&#xff0c;缩写&#xff1a;FSA&#xff09;&#xff0c;是表示有限…

C语言_有限状态机(FSM)

C语言_有限状态机&#xff08;Finite State Machine&#xff09; 基本介绍 许多小型或复杂的应用程序都使用有限状态机 (FSM)&#xff0c;C 语言中的有限状态机是嵌入式系统的流行设计模式之一&#xff0c;有限状态机使开发变得容易和顺利。 有很多设备使用事件基态&#xf…

Unity字体展示下载

Unity字体种类展示 这是字体包里面的图片,是不是很多种字体. 下载链接: https://download.csdn.net/download/qq_42603590/12001130 这是下载字体包的地方,很便宜.没有积分的可以留言,我发给你 有时候可能回复的不是很快(抱拳了) 喜欢的话点个赞,关注一下再走吧,谢谢

Unity 之 官网下载地址,方便各个版本的 Unity 安装包下载

Unity 之 官网下载地址&#xff0c;方便各个版本的 Unity 安装包下载 目录 Unity 之 官网下载地址&#xff0c;方便各个版本的 Unity 安装包下载 一、简单介绍 二、各个版本下载入口网址 一、简单介绍 在 Unity 的下载地址现在不是很好找&#xff0c;这里保存一下 Unity 各…

Unity入门之路0-Unity下载安装以及版本选择

文章目录 下载链接Unity Hub和Unity的关系UnityHub下载(Win)两者比较 Unity版本选择许可证问题 下载链接 一定不要百度或者去垃圾网站下载盗版网站 &#xff0c;Unity是正版免费的&#xff0c;官方很关注使用者的感受&#xff0c;所以下载官网的就没问题。 https://unity.cn/re…

UnityHub下载缓存位置

一、下载Unity各版本的编辑器 C:\Users\XXX\AppData\Local\Temp\unityhub-xxx-xxx-xxx-xxx 我电脑是 C:\Users\Administrator\AppData\Local\Temp\unityhub-xxxx-xxxx 如果你不需要备份安装包&#xff0c;那么这个缓存的文件夹&#xff0c;就与你无关了&#xff0c;因为安装完…

使用UnityHub下载任意版本Unity

目录 方法一 使用链接方法二 官网下载(适用于2018.4.23及以上版本) unityHub上只能下载官方指定的版本,很多其他版本不能下载,下面介绍的是在unityHub下载任意版本的方法 方法一 使用链接 举例: 2019.2.11f1版本的unity----> unityhub://2019.2.11f1/5f859a4cfee5 格式 unit…

Unity给游戏对象贴图、从官网下载资源、导入导出

1、新建项目、在项目场景中创建几何对象并修改参数 在层级“”中创建一个立方体&#xff08;3D对象&#xff09;&#xff0c;同理也创建一个球体 创建好的立方体会显示在场景视图中 &#xff08;从场景视图或层级视图中&#xff09;选中几何体&#xff0c;选择场景视图中竖排工…