热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

FPGA之道(52)状态机的概念

文章目录前言状态机的概念状态机简介状态机的组成六要素状态集合初态终态输入符号集输出符号集状态转移函数状态机的工作四要素现态输入输出次态前言本文摘选自《FPGA之道》,


文章目录

  • 前言
  • 状态机的概念
    • 状态机简介
    • 状态机的组成六要素
      • 状态集合
      • 初态
      • 终态
      • 输入符号集
      • 输出符号集
      • 状态转移函数
    • 状态机的工作四要素
      • 现态
      • 输入
      • 输出
      • 次态


前言

本文摘选自《FPGA之道》,对于状态机,作者花了大篇幅来叙述,对于状态机的深刻理解,让人佩服,以至于平日里认识到的状态机,以为就是真理,可见真理还需要不断的认识。这里为了不让博文篇幅过长,选择多篇博客来记录状态机这一大知识点。


状态机的概念


状态机简介

简单的说,状态机就是一幅描绘着状态变迁的状态转移图,它体现着系统对外界事件的反应和行为。
假设现在是周五的晚上,经过一周的劳累,你此刻正躺在床上思考着周六的假日安排:好久没运动了,也许明天可以叫上小明一起去踢足球,听说足球场附近新开了家冷饮店,运动后再喝杯冷饮那感觉肯定不错。糟糕!天气预报好像说明天有雨,虽说天气预报的准确性为50%,但是万一真下雨就没法踢球了,这样吧,最近好像刚刚上映了一部大片,如果下雨的话就约上小强去附近的电影院看电影吧,顺便吃一顿馋了很久的涮火锅。可是不知道他们两个明天有没有空呢?现在时间已经不早了,恐怕他们都睡了,还是不要打电话过去打扰比较好,这样吧,如果下雨或小明没空我就联系小强看电影,如果他们都没空的话我就自己在家打游戏好了。
至此,在你的脑海中其实已经完成了一个状态机的设计,而你在周六一天的行为则可以用如下状态转移图来预见和描述:
在这里插入图片描述
上述便是一个关于状态机的简单例子,由此可见状态机几乎存在于科研与生活中的各个方面,而FPGA中的状态机其实跟你脑海中的状态机是很类似的,因此完全可以主动的采用状态机的思想来帮助我们进行FPGA设计,以及明确FPGA的行为。
上例中的状态机其实更为准确的称谓应该是有限状态机。事实上,为了使状态机的实现成为可能,状态转移图中的内容不可能为无限多,例如自然数序列——1、2、3、4、5、……,如果将每一个自然数看做一个状态节点的话,那么其状态转移图是没有尽头的,由于状态数目无限,也就无法被存储,从而无法被实现。也许你会说,自然数序列可以看做一个只有两个状态的状态机:初始状态——输出n=1、自增状态——输出n=n+1,这样状态便可以存储,状态机也就可以实现了。很遗憾,这样的状态机仍然是不可能实现的,因为此时输出的n值是没有上限的,我们都知道,数值越大,需要占用的存储位宽就越大,如果n的值没有界限,那么其最终也是无法被存储的,从而整个状态机也是无法被实现的。同理可得,如果状态机的输入没有界限的话,状态机也是无法被实现的。
综上所述,有限状态机——Finite State Machine,简称FSM,是指状态节点数和输入、输出范围皆有限的状态机,在本书的其余部分,如无特别说明,提到的状态机皆为有限状态机。
最后,需要明确的一点是,虽然有限状态机的状态节点和输入、输出皆为有限的,但这并不意味着它仅能进行有限次的处理,这是因为有限状态机可以形成闭环系统,所以可以用有限个状态处理无限的事件,从而达到化有限为无穷的境界。例如,宇宙中物质的三个最基本状态——固态、液态、气态——的状态转移图如下:
在这里插入图片描述
从上例可以看出,虽然该状态机仅有三个状态,输入(六个触发条件)、输出(状态本身即为输出)也是有限的,但是它却永远不会结束,因为宇宙中的物质状态转换永远也不会停止……好吧,至少几十亿年不会停止。


状态机的组成六要素

简单的了解了状态机之后,我们来介绍一下组成状态机的六大要素:


状态集合

状态集合是组成状态机的必备要素,该集合里包含了状态机所能达到的所有状态。状态集合不能为空,必须包含至少一个状态节点,不过通常我们所讨论的状态机都具有至少两个状态节点,因为如果仅有一个状态节点的话,状态机便不存在状态跳转现象,因此它的性质和特点也就得不到体现。例如,【状态机简介】小节中两个示例的状态集合分别为:
{起床、找小明、找小强、踢足球、喝冷饮、看电影、吃火锅、打游戏、睡觉};
{气态、液态、固态}。


初态

初态是状态机的第二个必备要素,它是整个状态机开始工作的起点。虽然“先有蛋还是先有鸡”的问题一直没有得到很好的解决,但是现实中的状态机,一定要有一个固定的初始状态,否则你根本无法确定状态机后续的一系列行为。因此,初态是相对的、而不是绝对的,它为状态机的其他状态提供了参考坐标,从而让整个状态机的行为变得可预测、可表述,这就好比我们平时讨论日期、温度、海拔等等概念一样,如果没有公元纪元、绝对零度、海平面,上述所有的一切都变得没有任何意义。
例如,我们很容易看出【状态机简介】小节中第一个示例的初始状态为——起床。不过对于第二个示例,初态似乎很难确定,这时,请谨记——初态是一个相对的参考态,因此,第二个示例中的任何一个状态都可能是初态,那么到底应该选哪个做为初态呢?就从你开始观察的那一刻算起吧,如果你观测的那一刻是固态,那么初态就是固态。


终态

终态是状态机的结束状态,即若状态机到达终态,它的使命也将完成,从此不再工作。终态与初态不同,因为它并不是组成状态机的一个必备要素,事实上,大部分运行在FPGA上的状态机是没有终态的,因为它们都需要用有限的状态来处理无限的事件。
例如,我们很容易看出【状态机简介】小节中的第一个示例的结束状态为——睡觉。不第二个示例中并没有终态,……好吧,状态机将会运行至“山无棱、天地合”的那一刻!


输入符号集

输入符号集是驱动状态机进行状态转换的主要因素,不过状态机的状态转换其实并不一定需要外界的事件触发,因此输入符号集也不是组成状态机的必备要素,但是大部分运行在FPGA上的状态机还是需要输入符号集的,至少大多数情况下,它们都需要一个复位信号来让状态机进入初态。
例如,【状态机简介】小节中的两个示例的输入符号集分别为:
{天气情况、小明空闲情况、小强空闲情况};
{气化、液化、凝固、融化、升华、凝华}。


输出符号集

输出符号集是状态机传递给外界的反馈,不过与输入符号集不同,输出符号集是组成状态机的一个必备要素,因为一个对外界毫无影响、或者在外界看来毫无变化的状态机,其本身就是一件没有任何意义的事情,因此没有必要存在。
例如,【状态机简介】小节中两个示例的输出符号集其实非常丰富,分别概括为:
{吃了什么?、喝了什么?、玩了什么?……};
{温度变化、体积变化、状态变化……}。


状态转移函数

状态转移函数决定了状态机的行为,它是状态机的必备因素之一,也是状态机中最重要一个组成因素。状态转移函数的表现形式可以有很多种,例如带有说明的有向箭头、状态转移表格等等。
例如,【状态机简介】小节中两个示例的状态转移图形中的有向箭头及附在箭头上的说明。


状态机的工作四要素

状态机在工作的时候,出于对状态机内在因果关系的考虑,将状态机的工作状态划分为四个要素——现态、输入、输出、次态。其中,“现态”和“输入”是因,“输出”和“次态”是果,分别介绍如下:


现态

现态,是指状态机当前所处的状态。


输入

输入,一般指外部事件,当一个外部事件发生后,状态机便会根据状态转移函数发生相应的状态跳转,或者状态机将会更新自己的输出情况。通常在FPGA中,根据输入信号是异步的还是同步的又可将状态机分为异步状态机和同步状态机,不过鉴于稳定性的考虑,以后提到和FPGA相关的状态机全部为同步状态机,而对于异步输入信号,可以参考【本篇->编程思路->时钟及时钟域->跨时钟域问题】章节中的相关处理方法,同步化后再送至状态机。


输出

输出,是由现态或者现态和输入共同决定,如果这两者都没有变化,那么输出也不应该有变化。输出符号集是必须的,但具体到某一状态或者某一输入触发事件,输出并不是必需的,有时候带来的仅仅是状态迁移而已。


次态

次态,是根据现态、输入及状态转移函数所得出的,状态机将要跳转至的新状态。次态是相对于现态而言的,一旦状态迁移完成,次态便成为了新的现态。


推荐阅读
  • 深入理解父组件与子组件的引用和访问
    本文详细介绍了如何在Vue.js中通过$children和$refs属性实现父组件对子组件的访问,并提供了具体的代码示例及最佳实践。 ... [详细]
  • LeetCode 540:有序数组中的唯一元素
    来源:力扣(LeetCode),链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array。题目要求在仅包含整数的有序数组中,找到唯一出现一次的元素,并确保算法的时间复杂度为 O(log n) 和空间复杂度为 O(1)。 ... [详细]
  • Søren Kierkegaard famously stated that life can only be understood in retrospect but must be lived moving forward. This perspective delves into the intricate relationship between our lived experiences and our reflections on them. ... [详细]
  • PyCharm中配置Pylint静态代码分析工具
    本文详细介绍如何在PyCharm中配置和使用Pylint,帮助开发者进行静态代码检查,确保代码符合PEP8规范,提高代码质量。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 优化ASM字节码操作:简化类转换与移除冗余指令
    本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
author-avatar
mobiledu2502885017
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有