news 2026/4/23 11:14:25

19.三段式状态机

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
19.三段式状态机

写状态机时总感觉逻辑混乱,调试起来一头雾水?
或者状态跳转总是出问题,时序怎么都调不顺?

使用三段式状态机——让代码结构清晰、调试轻松!

一、为什么需要三段式

如果把状态机的所有逻辑都写在一个always块里,就像把所有工具扔进一个工具箱——找起来费劲,用起来混乱

三段式状态机就是把状态机拆成三个明确的部分:

  1. 状态定义:明确有哪些状态

  2. 次态逻辑:决定下一步去哪

  3. 输出逻辑:每个状态下要做什么

这样拆开,调试时就能精准定位问题:是状态定义错了?跳转条件不对?还是输出有问题?

二、编写三段式状态机

第一段,状态定义

首先,明确你的状态机有哪些状态,并用寄存器保存当前状态。

// 状态定义(推荐独热码,一个状态一个bit,避免歧义) parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; reg [1:0] current_state, next_state; // 状态寄存器(时序逻辑,每个时钟沿更新) always @(posedge clk or posedge reset) begin if (reset) current_state <= S0; // 复位时回到初始状态 else current_state <= next_state; // 正常工作时状态更新 end

状态编码可以用二进制、独热码(one-hot)或格雷码。独热码虽然占用资源多,但逻辑简单、不易出错,特别适合初学者。

第2段,次态逻辑

根据当前状态和输入信号,决定下一个状态是什么。

// 次态逻辑(组合逻辑,立即计算) always @(*) begin case (current_state) S0: if (input_condition) // 满足条件才跳转 next_state = S1; else next_state = S0; // 不满足就保持 S1: next_state = S2; // 无条件跳转到S2 S2: next_state = S0; // 执行完回到初始状态 default: next_state = S0; // 防错,默认回到初始状态 endcase end

如果多个状态都能跳转到同一个状态,代码该怎么写更简洁?

第3段:输出逻辑

输出逻辑有两种写法,根据需求选择:

写法一:组合逻辑输出(立即响应)

// 组合逻辑输出(当前状态一变,输出立刻变) always @(*) begin case (current_state) S0: output = 1'b0; S1: output = 1'b1; // 进入S1时,output立刻变1 S2: output = 1'b0; default: output = 1'b0; endcase end

写法二:时序逻辑输出(延迟一拍)

// 时序逻辑输出(等到下一个时钟沿才变化) always @(posedge clk) begin if (reset) output <= 1'b0; else begin case (current_state) S1: output <= 1'b1; // 进入S1后,下个时钟沿output才变1 default: output <= 1'b0; endcase end end

稳定无毛刺,但响应慢一拍。

关键选择:你的输出需要立刻生效,还是可以等一个时钟周期?根据实际需求选择

三、三段式的优势

  1. 结构清晰:调试时一眼就能看出问题在哪一段

  2. 时序友好:状态更新和输出分离,更容易满足时序约束

  3. 维护简单:加状态、改跳转条件都不会牵一发而动全身

  4. 可读性强:别人接手你的代码也能快速看懂

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:13:35

如何5分钟搭建个人文件展示平台:DirectoryLister完全指南

如何5分钟搭建个人文件展示平台&#xff1a;DirectoryLister完全指南 【免费下载链接】DirectoryLister &#x1f4c2; Directory Lister is the easiest way to expose the contents of any web-accessible folder for browsing and sharing. 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/4/23 12:53:48

Sol2完全指南:C++与Lua交互的性能优化实战

Sol2完全指南&#xff1a;C与Lua交互的性能优化实战 【免费下载链接】sol2 Sol3 (sol2 v3.0) - a C <-> Lua API wrapper with advanced features and top notch performance - is here, and its great! Documentation: 项目地址: https://gitcode.com/gh_mirrors/so/s…

作者头像 李华
网站建设 2026/4/23 9:55:52

Gutenberg框架终极升级指南:从0.6到0.7的完整迁移方案

Gutenberg框架终极升级指南&#xff1a;从0.6到0.7的完整迁移方案 【免费下载链接】Gutenberg Modern framework to print the web correctly.                                                项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/4/23 9:56:53

Mbed OS RTOS内核深度解析:构建高可靠物联网应用的底层支撑

Mbed OS RTOS内核深度解析&#xff1a;构建高可靠物联网应用的底层支撑 【免费下载链接】mbed-os Arm Mbed OS is a platform operating system designed for the internet of things 项目地址: https://gitcode.com/gh_mirrors/mb/mbed-os 在物联网设备开发中&#xff…

作者头像 李华
网站建设 2026/4/23 14:34:22

工业控制中STLink引脚图接线错误避坑手册

工业控制中 ST-Link 接线避坑实战指南&#xff1a;从引脚误解到稳定调试在工业现场的嵌入式开发一线&#xff0c;你是否经历过这样的场景&#xff1f;STM32 板子焊好了&#xff0c;电源正常&#xff0c;代码也写得没问题&#xff0c;可一连 ST-Link——“No target detected.”…

作者头像 李华
网站建设 2026/4/23 11:32:18

Jupyter转换为Python脚本:py文件脱离notebook运行TensorFlow

Jupyter转换为Python脚本&#xff1a;py文件脱离notebook运行TensorFlow 在AI项目从实验走向上线的过程中&#xff0c;一个常见的痛点浮现出来&#xff1a;我们在Jupyter Notebook里调试得完美无缺的模型&#xff0c;到了生产环境却频频出错。不是依赖版本不一致&#xff0c;就…

作者头像 李华