FPGA开发基础之三段式状态机

article/2025/9/19 22:47:33

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,程序的运行其本质也是状态机,根据输入完成输出,得到新的状态。

在平时硬件电路的设计中经常需要用到状态机,例如CPU的取指、译码、执行,这个流程可以使用状态机来控制,相比于流水线能够有效的较少资源的消耗,再或者序列检测上,也可以使用状态机。

状态机有一段、二段、和三段式,三段式的写法复杂些,但是相比于两段式可以使输出信号由寄存器来驱动,能够有效的消除组合逻辑的不稳定与毛刺等隐患。

首先给出三段式状态机的通用形式:

三段式状态机

Mealy型(米勒型)三段式状态机

当前输出与当前状态和输入有关

parameter S0=3'b000,state1=3'b001,state2=3'b010,S3=3'b011;reg [2:0] current_state;
reg [2:0] next_state;//在第一个always块中只实现状态的迁移,将第二个always块中计算出的次态在时钟上升沿复制给current_state
always @(posedge clk or negedge rst_n)
beginif(!rst_n)begincurrent_state<=0;next_state<=0;endelsebegincurrent_state<=next_state;end
end//在第二个always块中计算next_state,使用组合逻辑来完成
always @(*)
begincase(current_state)S0:if(..) //当然此刻的if判断也能用三目运算法来实现,看上去会更便捷一些:next_state=S1;elsenext_state=S0;S1:if(..) next_state=state?;elsenext_state=state?;S2:if(..) next_state=state?;elsenext_state=state?;S3:if(..) next_state=state?;elsenext_state=state?;default:next_state=S0;endcase   
end
//在第三个always块中计算输出,在满足什么情况下输出
always @(posedge clk or negedge rst_n)
beginif(!rst_n)beginsignal_out<=0;endelsebeginif(current_state==state?&&signal_in==?)signal_out<=1;elsesignal_out<=0;    end
end

Moore型(摩尔型)三段式状态机

当前输出仅仅与当前状态有关

parameter S0=3'b000,state1=3'b001,state2=3'b010,S3=3'b011;reg [2:0] current_state;
reg [2:0] next_state;//在第一个always块中只实现状态的迁移,将第二个always块中计算出的次态在时钟上升沿复制给current_state
always @(posedge clk or negedge rst_n)
beginif(!rst_n)begincurrent_state<=0;next_state<=0;endelsebegincurrent_state<=next_state;end
end//在第二个always块中计算next_state,使用组合逻辑来完成
always @(*)
begincase(current_state)S0:if(..) //当然此刻的if判断也能用三目运算法来实现,看上去会更便捷一些:next_state=S1;elsenext_state=S0;S1:if(..) next_state=state?;elsenext_state=state?;S2:if(..) next_state=state?;elsenext_state=state?;S3:if(..) next_state=state?;elsenext_state=state?;default:next_state=S0;endcase   
end
//在第三个always块中计算输出,在满足什么情况下输出
always @(posedge clk or negedge rst_n)
beginif(!rst_n)beginsignal_out<=0;endelsebeginif(current_state==state?)signal_out<=1;elsesignal_out<=0;    end
end

两种三段式状态机的状态图会有区别

测试用例

接下来我们使用具体的场景来介绍两者不同

设计一个状态机,用来检测序列 10111,要求:

1、进行非重叠检测 即101110111 只会被检测通过一次

2、寄存器输出且同步输出结果

信号示意图:

在这里插入图片描述

输入描述:

输入信号 clk rst data
类型 wire

输出描述:

输出信号 flag
类型 reg

首先第一件事就是画出状态转移,在此刻我们一定要注意到,flag是在检测完成的这一个周期拉高的,而不是下个周期

Mealy型(米勒型)状态图——输出与输入和现态有关

这个时候我们来解析这张图

在这里插入图片描述

复位之后当前状态是S0,假设在第一个时钟上升沿之前,data输入1,则通过第二个always组合逻辑块,会计算出next_state=S1,在第一个时钟上升沿,next_state=S1就会被赋值给current_state,也就是说从第一个上升沿之后到第二个上升沿之前,current会一直保持S1的状态。

假设在第一个上升沿之后到第二个上升沿之前,data输入变为了0,那么同理,组合逻辑会计算出新的next_state=S2,在第二个时钟上升沿倘若data不发生变化,则新的next_state会被赋值给current_state,从第二个上升沿之后到第三个上升沿之前,current会一直保持S2的状态。

假设在第二个上升沿之后到第三个上升沿之前,data输入变为了1,那么同理,组合逻辑会计算出新的next_state=S3,在第三个时钟上升沿倘若data不发生变化,则新的next_state会被赋值给current_state,从第三个上升沿之后到第四个上升沿之前,current会一直保持S3的状态。

假设在第三个上升沿之后到第四个上升沿之前,data输入变为了1,那么同理,组合逻辑会计算出新的next_state=S4,在第四个时钟上升沿倘若data不发生变化,则新的next_state会被赋值给current_state,从第四个上升沿之后到第五个上升沿之前,current会一直保持S4的状态。

假设在第四个上升沿之后到第五个上升沿之前,data输入变为了1,此时注意,前面我们谈到过,在这个题目中,在完成序列检测的这一个周期,flag就要拉高,此时我们需要第五个上升沿将flag拉高,因此需要在第三个always语句块中定位到这个时刻,也就是current_state= =S4&&data= =1,这也就是输出和现态以及输入都有关,之后current_state将变为S0,重新进行一轮新的检测。

`timescale 1ns/1nsmodule sequence_test1(input wire clk  ,input wire rst  ,input wire data ,output reg flag
);parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5;reg [2:0] current_state;reg [2:0] next_state;always @(posedge clk or negedge rst)beginif(!rst)begincurrent_state<=0;next_state<=0;endelsebegincurrent_state<=next_state;endendalways @(*)begincase(current_state)S0:beginnext_state<=data==1?S1:S0;endS1:beginnext_state<=data==0?S2:S0;endS2:beginnext_state<=data==1?S3:S0;endS3:beginnext_state<=data==1?S4:S0;endS4:beginnext_state<=S0;endenddefault:nex_state<=S0;endcaseendalways @(posedge clk or negedge rst)beginif(!rst)beginflag<=0;endelsebeginif(current_state==S4&&data==1) flag<=1;elseflag<=0;endendendmodule

Moore型(摩尔型)状态图——输出只与现态有关

在这里插入图片描述

Moore型(摩尔型)状态机与米勒型稍有不同,下面我们尝试用摩尔状态机来解决这个问题

倘若在某个时钟上升沿时,当前current_state=S4时,此时若data=1,按照题目的要求,在这个上升沿结束之后flag就应该立刻拉高,而Moore型状态机的输出只与现态有关,在这个时刻current_state=S4,仅仅根据这个条件我们无法判断输出是0还是1,若将flag拉高了,但是data为0,那就是错误的,因此在当前时刻必须结合输入才能得出正确的输出,在下一个时钟上升沿,检测到current_state=S5时才能将flag拉高,这是才是正确的,因此Moore型状态机相比Mealy状态机会延迟一个周期。

代码如下

`timescale 1ns/1nsmodule sequence_test1(input wire clk  ,input wire rst  ,input wire data ,output reg flag
);parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5;reg [2:0] current_state;reg [2:0] next_state;always @(posedge clk or negedge rst)beginif(!rst)begincurrent_state<=0;next_state<=0;endelsebegincurrent_state<=next_state;endendalways @(*)begincase(current_state)S0:beginnext_state<=data==1?S1:S0;endS1:beginnext_state<=data==0?S2:S0;endS2:beginnext_state<=data==1?S3:S0;endS3:beginnext_state<=data==1?S4:S0;endS4:beginnext_state<=data==1?S5:S0;endS5:beginnext_state<=S0;enddefault:nex_state<=S0;endcaseendalways @(posedge clk or negedge rst)beginif(!rst)beginflag<=0;endelsebeginif(current_state==S5) ,flag<=1;elseflag<=0;endendendmodule

修改后的Moore型(摩尔型)状态机

我们可以通过将判断条件改为next_state==S5,这种方式将输出提前一个周期,因为next_state本就是根据current_state和data得出的,所以提前一个周期用也无妨。

`timescale 1ns/1nsmodule sequence_test1(input wire clk  ,input wire rst  ,input wire data ,output reg flag
);parameter S0=0,S1=1,S2=2,S3=3,S4=4,S5=5;reg [2:0] current_state;reg [2:0] next_state;always @(posedge clk or negedge rst)beginif(!rst)begincurrent_state<=0;next_state<=0;endelsebegincurrent_state<=next_state;endendalways @(*)begincase(current_state)S0:beginnext_state<=data==1?S1:S0;endS1:beginnext_state<=data==0?S2:S0;endS2:beginnext_state<=data==1?S3:S0;endS3:beginnext_state<=data==1?S4:S0;endS4:beginnext_state<=data==1?S5:S0;endS5:beginnext_state<=S0;enddefault:nex_state<=S0;endcaseendalways @(posedge clk or negedge rst)beginif(!rst)beginflag<=0;endelsebeginif(next_state==S5) ,flag<=1;elseflag<=0;endendendmodule

这种方法相比于Mealy机多了一个状态S5


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

相关文章

关于三段式状态机第三段是组合逻辑还是时序逻辑的问题?

由于本人一直以来&#xff0c;用的三段式状态机&#xff0c;第三段写法都是组合逻辑写法&#xff0c;但是近期有小伙伴面试小公司&#xff0c;写到状态机的第三段时候&#xff0c;按照我一直用到的组合逻辑来写第三段&#xff0c;提供输出&#xff0c;被提出了质疑&#xff0c;…

【状态机设计】Moore、Mealy状态机、三段式、二段式、一段式状态机书写规范

目录 状态机介绍 状态机类型 Moore 型状态机 Mealy 型状态机 状态机设计流程 自动售卖机 状态机设计&#xff1a;3 段式&#xff08;推荐&#xff09; 实例 实例 状态机修改&#xff1a;2 段式 实例 状态机修改&#xff1a;1 段式&#xff08;慎用&#xff09; 实…

状态机的描述方法案例分析(一段式、二段式、三段式)

上篇博文讲了&#xff1a;FPGA中有限状态机的状态编码采用格雷码还是独热码&#xff1f; 那篇博文讲了状态机的状态编码是用格雷码还是独热码的问题&#xff0c;以及两者之间的优劣。状态机的描述方式采用的是一段式描述方式&#xff0c;也就是将整个状态机全部写到一个always…

FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)

1、状态机 1.1、理论 FPGA不同于CPU的一点特点就是CPU是顺序执行的&#xff0c;而FPGA是同步执行&#xff08;并行&#xff09;的。那么FPGA如何处理明显具有时间上先后顺序的事件呢&#xff1f;这个时候我们就需要使用到状态机了。 状态机简写为 FSM&#xff08;Finite Sta…

三段式状态机_verilog

这是一篇转载的文章&#xff0c;但是个人理解笔者将前两个always块结构搞错了&#xff0c;自行纠正了一下。 原文链接 https://www.jianshu.com/p/5eee434ab24d 1. 三段式要求 有限状态机采用三段式风格&#xff0c;即三个always块描述状态机. 第一个时序逻辑always块用来描…

2021-08-21Verilog三段式状态机的写法,标准示例和仿真。

Verilog三段式状态机的写法&#xff0c;标准示例和仿真。 第一段&#xff1a;同步状态转移。第一个always块格式化描述次态寄存器迁移到现态寄存器。 第二段&#xff1a;当前状态判断接下来的状态。组合逻辑always模块&#xff0c;描述状态转移条件判断用current_state 第三段&…

verilog 3段式状态机

3段式状态机&#xff1a; 3段式状态机写法&#xff0c;写出下图状态转换图。 1 确定输入输出信号&#xff0c;及其类型&#xff08;是wire还是reg&#xff09;&#xff1b; 2 声明内部信号&#xff0c;一般需要定义current_state和next_state&#xff1b; 3 用3个always语句描…

三段式状态机设计

状态机设计需满足的几个要求&#xff1a; 1. 三段式要求 有限状态机采用三段式风格&#xff0c;即三个always块描述状态机. 第一个组合逻辑always块用来描述下一状态的转移&#xff08;next state logic&#xff09; 第二个时序逻辑always块用来描述当前状态.&#xff08;cur…

三段式状态机浅析

三段式状态机 文章目录 三段式状态机三段式状态机优点书写格式formater整形器状态机书写举例 关注作者 三段式状态机优点 将组合逻辑与时序逻辑分开&#xff0c;所写代码层次清晰&#xff0c;方便理解和后续的维护相较两段式状态机&#xff0c;解决了输出毛刺的影响。 书写格…

(三段式)有限状态机【原理+实例】

状态机的基本要素&#xff1a;输入、输出、状态。 状态机根据状态变化是否与输入条件有关分为两类&#xff1a;即Moore型状态机和Mealy型状态机。 Moore型状态机的状态变化仅和当前状态有关&#xff0c;而与输入条件无关&#xff1b; Mealy型状态机的状态变化不仅和当前状态…

状态机设计(一段式、两段式和三段式)

三段式状态机 第一段&#xff0c;时序always块&#xff0c;状态跳转 第二段&#xff0c;组合always块&#xff0c;状态更新 第三段&#xff0c;时序always块&#xff0c;输出控制 两段式状态机 两段式状态机是把三段式状态机的第二段和第三段合为一段&#xff0c;那么两段式…

FPGA——三段式状态机(1)

状态机全称是有限状态机&#xff08;Finite State Machine、FSM&#xff09;&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态机可根据控制信号完成预定的状态转换&#xff0c;由组合逻辑电路和寄存器组成&#xff0c;可由状态转换表或状态转…

状态机详解(一段式、二段式、三段式)

一、有限状态机FSM&#xff08;Finite State Machine&#xff09; 组成元素&#xff1a; 输入、状态、状态转移条件、输出。 可以分为两类&#xff1a; Mealy状态机&#xff1a;时序逻辑的输出不仅取决于当前状态&#xff0c;还与输入有关&#xff1b; Moore状态机&#xff1a…

三段式状态机理解浅析

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/weixin_43070186/article/details/82085463 关于FSM的写法按照always块的个数来划分可以分为一段式…

彻底搞懂状态机(一段式、两段式、三段式)

转自&#xff1a;https://blog.csdn.net/wordwarwordwar/article/details/78509445 实例&#xff1a;FSM实现10010串的检测 状态转移图&#xff1a;初始状态S0&#xff0c;a 0,z 0.如果检测到1&#xff0c;跳转到S1。 下一状态S1&#xff0c;a 1,z 0.如果检测到0&#xff…

Verilog:三段式状态机(数字钟)

状态机在FPGA的设计中是至关重要的&#xff0c;使用的频率也很高&#xff0c;废话不多说在这里介绍一下三段式状态机如何设计。 设计状态机首先要清楚状态有几种&#xff0c;状态转移图是怎样的&#xff0c;各个状态的输出是怎样的。了解了这三样之后就可以开始设计实验所需要的…

三段式有限状态机

一段式、二段式、三段式状态机是按照书写FSM时使用的always块数目进行划分的&#xff0c;一般而言对于简单的状态机&#xff0c;可以使用一段式&#xff0c;其代码量以及使用资源都最少&#xff0c;但如果状态机较复杂&#xff0c;一段式状态机会对代码维护产生很大的不便&…

状态机,从细节出发(一段式、两段式、三段式,moore型、mealy型)

目录 前言 一、状态机要素 二、状态机描述方法 1、一段式描述方法 2、两段式描述方法 3、三段式描述方法 三、关系 1、一段式与三段式 2、两段式与三段式 3、三种FSM描述方法比较表 四、状态机的种类 1、Moore型状态机 2、Mealy型状态机 3、注意点 五、举例 1、…

时间复杂度与空间复杂度分析(递归与非递归比较)

时间复杂度&#xff1a; 一般情况下&#xff0c;算法中基本操作重复的次数就是问题规模n的某个函数f&#xff08;n&#xff09;&#xff0c;进而分析f&#xff08;n&#xff09;随n的变化情况并确定T&#xff08;n&#xff09;的数量级。这里用‘o’来表示数量级&#xff0c;给…

数据结构:时间复杂度空间复杂度(递归)

转载文章 时间复杂度&#xff1a; 一般情况下&#xff0c;算法中基本操作重复执行的次数是问题规模n的某个函数f(n)&#xff0c;进而分析f(n)随n的变化情况并确定T(n)的数量级。这里用"O"来表示数量级&#xff0c;给出算法的时间复杂度。 T(n)O(f(n)); 它表示随着问…