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

FPGA_状态机工作原理

FPGA_状态机介绍和工作原理

  • 状态机工作原理
    • Mealy 状态机模型
    • Moore 状态机模型
    • 状态机描述方式
    • 代码格式
  • 总结

状态机工作原理

状态机全称是有限状态机(Finite State Machine、FSM),是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

状态机分为摩尔(Moore)型有限状态机与米利(Mealy)型有限状态机。摩尔状态机输出是只由输入确定的有限状态机(不直接依赖于当前状态)。米利有限状态机的输出不止与其输入有关还于它的当前状态相关,这也是与摩尔有限状态机的不同之处。

➢ Mealy 状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入状态。
➢ Moore 状态机:组合逻辑的输出只取决于当前状态。

Mealy 状态机模型

在这里插入图片描述

Moore 状态机模型

在这里插入图片描述

状态机描述方式

可分为一段式、两段式以及三段式。
一段式,整个状态机写到一个 always 模块里面。在该模块中既描述状态转移,又描述状态的输入和输出。

两段式,用两个 always 模块来描述状态机。其中一个 always 模块采用同步时序描述状态转移,另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律及其输出。

三段式,在两个 always 模块描述方法基础上,使用三个 always 模块,一个 always 模块采用同步时序描述状态转移,一个 always 采用组合逻辑判断状态转移条件,描述状态转移规律,另一个 always 模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。实际应用中三段式状态机使用最多,因为三段式状态机将组合逻辑和时序分开,有利于综合器分析优化以及程序的维护;并且三段式状态机将状态转移与状态输出分开,使代码看上去更加清晰易懂,提高了代码的可读性,推荐大家使用三段式状态机,本文也着重讲解三段式。

三段式状态机的基本格式是:
第一个 always 语句实现同步状态跳转;
第二个 always 语句采用组合逻辑判断状态转移条件;
第三个 always 语句描述状态输出(可以用组合电路输出,也可以时序电路输出)。在开始编写状态机代码之前,一般先画出状态跳转图,这样在编写代码时思路会比较清晰,下面以一个 7 分频为例(对于分频等较简单的功能,可以不使用状态机,这里只是演示状态机编写的方法),状态跳转图如下图所示:
在这里插入图片描述

代码格式

状态跳转图画完之后,接下来通过 parameter 来定义各个不同状态的参数,如下

parameter S0 = 7'b0000001; //独热码定义方式
parameter S1 = 7'b0000010;
parameter S2 = 7'b0000100;
parameter S3 = 7'b0001000;
parameter S4 = 7'b0010000;
parameter S5 = 7'b0100000;
parameter S6 = 7'b1000000;

这里是使用独热码的方式来定义状态机

接下来还需要定义两个 7 位的寄存器,一个用来表示当前状态,另一个用来表示下一个状态,如下所示:

reg [6:0] curr_st ; //当前状态
reg [6:0] next_st ; //下一个状态

接下来就可以使用三个 always 语句来开始编写状态机的代码,第一个 always 采用同步时序描述状态
转移,第二个 always 采用组合逻辑判断状态转移条件,第三个 always 是描述状态输出,一个完整的三段
式状态机的例子如下代码所示:

module divider7_fsm (
//系统时钟与复位
input sys_clk ,
input sys_rst_n ,//输出时钟
output reg clk_divide_7 
);//parameter define parameter S0 = 7'b0000001; //独热码定义方式parameter S1 = 7'b0000010;parameter S2 = 7'b0000100;parameter S3 = 7'b0001000;parameter S4 = 7'b0010000;parameter S5 = 7'b0100000;parameter S6 = 7'b1000000; //reg define reg [6:0] curr_st ; //当前状态reg [6:0] next_st ; //下一个状态//*****************************************************//** main code//***************************************************** //状态机的第一段采用同步时序描述状态转移always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)curr_st <= S0;elsecurr_st <= next_st;end//状态机的第二段采用组合逻辑判断状态转移条件always @(*) begincase (curr_st)S0: next_st = S1;S1: next_st = S2;S2: next_st = S3;S3: next_st = S4;S4: next_st = S5;S5: next_st = S6;S6: next_st = S0;default: next_st = S0;endcaseend//状态机的第三段描述状态输出(这里采用时序电路输出)always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)clk_divide_7 <= 1'b0;else if ((curr_st == S0) | (curr_st == S1) | (curr_st == S2) | (curr_st == S3))clk_divide_7 <= 1'b0;else if ((curr_st == S4) | (curr_st == S5) | (curr_st == S6))clk_divide_7 <= 1'b1; else;endendmodule

总结

从代码中可以看出,输出的分频时钟 clk_divide_7 只与当前状态(curr_st)有关,而与输入状态无关,所以属于摩尔型状态机。状态机的第一段对应摩尔状态机模型的状态寄存器,用来记忆状态机当前所处的状态;状态机的第二段对应摩尔状态机模型产生下一状态的组合逻辑 F;状态机的第三段对应摩尔状态机产生输出的组合逻辑 G,因为采用时序电路输出有很大的优势,所以这里第三段状态机是由时序电路
输出的。
在这里插入图片描述
状态机时序电路输出模型

采用这种描述方法虽然代码结构复杂了一些,但是这样做的好处是可以有效地滤去组合逻辑输出的毛刺,同时也可以更好的进行时序计算与约束,另外对于总线形式的输出信号来说,容易使总线数据对齐,减小总线数据间的偏移,从而降低接收端数据采样出错的频率。

相关文章:

  • el-table多选表格 实现默认选中 删除选中列表取消勾选等联动效果
  • SHCTF 山河CTF Reverse方向[Week1]全WP 详解
  • Ansible 的脚本 --- playbook 剧本
  • ITSource 分享 第5期【校园信息墙系统】
  • 【数据结构练习题】删除有序数组中的重复项
  • 基于SSM的汽车维修管理系统
  • 图像处理入门 1(Introduction to image processing)
  • Java架构师软件工程全流程
  • 基于单片机16位智能抢答器设计
  • 【vim 学习系列文章 12 -- vimrc 那点事】
  • 安装k8s
  • Python中的split()函数
  • JVM——GC垃圾回收器
  • 基于aop 代理 Sentinel Nacos配置控制包装类实现原理
  • TELUS Ventures(泰勒斯)
  • [译]CSS 居中(Center)方法大合集
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • co.js - 让异步代码同步化
  • Django 博客开发教程 16 - 统计文章阅读量
  • PHP那些事儿
  • Quartz初级教程
  • React系列之 Redux 架构模式
  • Shadow DOM 内部构造及如何构建独立组件
  • Spring框架之我见(三)——IOC、AOP
  • Vue小说阅读器(仿追书神器)
  • 飞驰在Mesos的涡轮引擎上
  • 蓝海存储开关机注意事项总结
  • 聊聊redis的数据结构的应用
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 物联网链路协议
  • 小程序测试方案初探
  • 新书推荐|Windows黑客编程技术详解
  • Linux权限管理(week1_day5)--技术流ken
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • 通过调用文摘列表API获取文摘
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #mysql 8.0 踩坑日记
  • ( 10 )MySQL中的外键
  • (1)(1.9) MSP (version 4.2)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (分布式缓存)Redis分片集群
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (数据结构)顺序表的定义
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • ***利用Ms05002溢出找“肉鸡
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET MVC之AOP
  • .net下的富文本编辑器FCKeditor的配置方法
  • .php文件都打不开,打不开php文件怎么办