当前位置: 首页 > news >正文

时序逻辑电路——有限状态机FSM

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

状态机的优势

  有限状态机(Finite State Machine, FSM)在硬件设计中十分常见,其稳定性高、速度快、面积小也更容易维护。

状态机的类型

  状态机分成Moore状态机和Mealy状态机。
(1)Moore型状态机:输出信号只取决于当前状态。
(2)Mealy型状态机:输出信号不仅取决于当前状态,还取决于输入信号的值。
  它们的区别就在于输出信号是否与输入信号有关,造成的结果是:
  实现相同功能时,Moore型状态机需要比Mealy型状态机多一个状态,且Moore型状态机的输出比Mealy型延后一个时钟周期。
在这里插入图片描述

在这里插入图片描述

  对于Moore状态机来说,优势在于

  • ​时序稳定性:输出仅由当前状态决定,在时钟边沿同步更新,避免输入信号毛刺导致的输出抖动。
  • ​设计简单:输出逻辑与输入解耦,代码结构清晰(如三段式状态机中输出独立于转移逻辑)。
  • ​同步性:适合对输出稳定性要求高的场景(如控制信号生成、显示驱动)。
      劣势在于
  • ​延迟较高:输出必须等待时钟边沿更新,响应速度可能不足(如高速通信协议)。
  • ​状态数可能更多:若相同状态需根据输入产生不同输出,需拆分成多个状态,增加复杂度
      对于Mealy状态机来说,优势在于
  • ​响应速度快:输出可随输入立即变化,无需等待时钟边沿,适合实时性要求高的场景。
  • ​状态数更少:因输出与输入相关,可能通过合并相似状态减少状态数量(例如用输入条件区分行为)。
  • ​资源占用低:在某些设计中,由于状态合并,寄存器资源消耗可能更少。
      劣势在于
  • 时序风险:输入信号的毛刺或异步变化可能导致输出不稳定(需额外同步逻辑)。
  • ​设计复杂度高:输出逻辑需同时处理状态和输入,代码调试难度增加。
  • ​时序收敛挑战:组合逻辑路径(输入→输出)可能成为关键路径,影响最大时钟频率。

状态机的描述方式

  以下面状态转移图为例,对一段式、二段式以及三段式状态机进行描述。状态转移线上的0/0等表示的意思是过程中data/flag的值,其中data为输入,flag为输出,可以看出,该状态机伪Mealy状态机,因为输出和输出的data有关。
在这里插入图片描述

  如果通过Moore状态机实现,会多一个状态,如下图所示。
在这里插入图片描述

1. 一段式

  一段式状态机只有一个always块,既实现状态跳转又实现逻辑输出。这种写法看起来很简洁,但是不利于维护,如果状态复杂一些就很容易出错,不推荐这种方法。

module fsm1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
	parameter S0 = 'd0;
	parameter S1 = 'd1;
	parameter S2 = 'd2;
	parameter S3 = 'd3;

	reg [1:0] state;
    //第一段,状态跳转+时序逻辑输出
	always @(posedge clk or negedge rst)begin
		if(!rst)begin
			state <= S0;
			flag <= 1'b0;
		end
		else begin
			if(state==S0)begin
				state <= (!data)?S0:S1;
				flag <= 1'b0;
			end
			else if(state==S1)begin
				state <= (!data)?S1:S2;
				flag <= 1'b0;
			end
			else if(state==S2)begin
				state <= (!data)?S2:S3;
				flag <= 1'b0;
			end
			else if(state==S3)begin
				state <= (!data)?S3:S0;
				flag <= data? 1'b1:1'b0;
			end
			else begin
				state <= S0;
				flag <= 1'b0;
			end
		end
	end

//*************code***********//
endmodule

2. 二段式

  二段式状态机有两个always block,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺,因此为了保险起见,二段式状态机实现会对输出多打一拍。二段式的输出是组合逻辑输出,因此在数字电路设计中,二段式状态机通常用于实现Moore型状态机。

module fsm2(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);

//*************code***********//
	parameter S0 = 'd0;
	parameter S1 = 'd1;
	parameter S2 = 'd2;
	parameter S3 = 'd3;
	parameter S4 = 'd4;
	reg [2:0] curr_state;
	reg [2:0] next_state;

    //第一段,时序逻辑
	always @(posedge clk or negedge rst)begin
		if(!rst)
			curr_state <= S0;
		else
			curr_state <= next_state;
	end
    //第二段,组合逻辑,状态跳转+输出
	always @(*)begin
		case(curr_state)
		S0: begin
			next_state = (!data)?S0:S1;
			flag = 1'b0;
		end
		S1:begin
			next_state = (!data)?S1:S2;
			flag = 1'b0;
		end
		S2:begin
			next_state = (!data)?S2:S3;
			flag = 1'b0;
		end
		S3:begin
			next_state = (!data)?S3:S4;
			flag = 1'b0;
		end
		S4:begin
			next_state = (!data)?S0:S1;
			flag = 1'b1;
		end
		default:begin
				next_state = S0;
				flag = 1'b0;
		end
		endcase
	end

//*************code***********//
endmodule

3. 三段式

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

module fsm1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
	parameter S0 = 'd0;
	parameter S1 = 'd1;
	parameter S2 = 'd2;
	parameter S3 = 'd3;

	reg [1:0] curr_state;
	reg [1:0] next_state;
    //第一段
	always @(posedge clk or negedge rst)begin
		if(!rst)
			curr_state <= S0;
		else
			curr_state <= next_state;
	end
    //第二段
	always @(*)begin
		case(curr_state)
		S0	:next_state = (!data)?S0:S1;
		S1	:next_state = (!data)?S1:S2;
		S2	:next_state = (!data)?S2:S3;
		S3	:next_state = (!data)?S3:S0;
		default:next_state = S0;
		endcase
	end
    //第三段,组合逻辑输出
	always @(posedge clk or negedge rst)begin
		if(!rst)
			flag <= 1'b0;
		else if(curr_state==S3 && data)
			flag <= 1'b1;
		else	
			flag <= 1'b0;
	end

//*************code***********//
endmodule

总结

  对于Moore状态机和Mealy状态机,需要根据实际应用场景自行选择。而状态机的描述方法,更倾向于使用三段式状态机,逻辑清晰且便于维护。

相关文章:

  • 一文速通C++非类型模板参数
  • 《几何原本》命题I.2
  • 神经网络代码入门解析
  • Docker项目部署-部署Java应用
  • 二分查找-I(C++)
  • 【通俗讲解电子电路】——从零开始理解生活中的电路(二)
  • Tomcat部署
  • 无问西东、继续前行!!
  • 机器学习预备知识
  • Leetcode1 两数之和 python两种方法实现
  • 基于SpringBoot的绿城郑州爱心公益网站设计与实现现(源码+SQL脚本+LW+部署讲解等)
  • ASP.NET MVC项目部署到IIS后,w3wp.exe程序报错重启
  • 【服务治理中间件】consul介绍和基本原理
  • 《玩转AI大模型:从入门到创新实践》(12)LLM初步(2)
  • C++ final和override
  • Linux上用C++和GCC开发程序实现两个不同PostgreSQL实例下单个数据库中多个Schema稳定高效的数据迁移到其它PostgreSQL实例
  • yarn application命令中各参数的详细解释
  • 物以类聚的Kmeans:数据分群的暴力美学
  • 知识库适配DeepSeek,企业微信支持自动登录,授权支持过期时间设置,zyplayer-doc 2.4.9 发布啦!
  • C语言:整数、浮点数在内存中的存储
  • 济南建设项目竣工验收公示网站/千锋教育的it培训怎么样
  • 服务器放多个网站/营销培训内容有哪些
  • 个人或主题网站建设实验体会/住房和城乡建设部
  • 网站建设一般多少/自媒体软文发布平台
  • 个人工作室网站怎么做/网络推广一般都干啥
  • 基于h5的个人网站建设/公司软文推广