状态机设计中的关键技术
⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。
🔥文章和代码已归档至【Github仓库:hardware-tutorial】,需要的朋友们自取。或者公众号【AIShareLab】回复 FPGA 也可获取。
文章目录
- 状态编码
- 格雷码
- 独热码(one-hot编码)
- 如何消除输出端产生的毛刺
- 1.具有流水线输出的Mealy状态机
- 2.在状态位里编码输出的Moore状态机
- 如何使用One-hot编码方案设计状态机
状态编码
在使用Verilog HDL描述状态机时,通常用参数定义语句parameter指定状态编码。状态编码方案一般有三种:自然二进制编码、格雷(Gray)编码和独热码(one-hot编码)。对应于图所示的状态图的各种编码方案如表所示。
有限状态机的编码方案
状态机编码对状态机速度和面积关系重大
常用编码
- 二进制码(binary)
- 格雷码(Gray)
- 独热码(one-hot)
二进制码与格雷码是压缩状态编码,使用最少的状态位进行编码。
二进制编码的优点是使用的状态向量最少,但从一个状态转换到相邻状态时,可能有多个比特位发生变化,瞬变次数多,易产生毛刺。
格雷码
特点是当前状态改变时,状态向量中仅一位发生变化,因此当系统的状态变化是基于异步的输入信号时,格雷编码能够避免进入错误的状态。
格雷码既可以消除状态转换时多状态信号传输延迟产生的毛刺,又可降低功耗。
独热码(one-hot编码)
N个状态使用N个触发器(FF)
- 减少了状态寄存器之间的组合逻辑级数,因此提高了运行速度 ;
- 触发器(FF)数量增加,组合逻辑电路减少;
- 任何状态都可以直接添加/删除等修改而不会影响状态机的其余部分;
- 由于译码简单,可提高速度,且易于修改。
独热码(one-hot编码)的特点是:状态数等于触发器(FF)的数目,冗余的触发器带来的好处是译码电路的简单化,因此它的速度非常快,此外由于FPGA器件内部触发器的数量是固定的且比较丰富,所以one-hot编码非常适合于FPGA设计。
独热码的缺点
- 变化的状态位越多,组合输出稳定前所需的时间就越长,产生的毛刺就越多 ;
- 多个寄存器可能受异步输入的影响,使得亚稳态发生的概率有所增加 ;
状态机复杂状态跳转的分支很多时,要合理的分配状态编码,保证每个状态跳转都仅有1位发生变化,这是很困难的事情。
不管使用哪种编码,状态机中的各个状态都应该使用符号常量,而不应该直接使用编码数值,赋予各状态有意义的名字对于设计的验证和代码的可读性都是有益的。
编码方法 | 面积 | 速度 | 状态数量 |
---|---|---|---|
Binary (顺序二进制) | 较好 | 较差 | Log2(state N) |
One-hot | 较差 | 较好 | States Number |
Gray | 较好 | 较差 | Log2(state N) |
如何消除输出端产生的毛刺
前面介绍的普通状态机由组合逻辑电路决定电路的输出.当组合逻辑较大时,若状态触发器的值发生变化或者输入信号发生变化,由于各信号在组合逻辑内部经过的路径不一样,就容易在输出端产生毛刺。
下面介绍两种常用消除毛刺的方法:
1.具有流水线输出的Mealy状态机
为了消除毛刺,可以在普通Mealy的输出逻辑后加一组输出寄存器,将寄存器的输出值作为输出向量,这种Mealy状态机的等效方框如图所示。
2.在状态位里编码输出的Moore状态机
这种方法的指导思想是将状态寄存器和输出向量统一进行编码,即将状态位本身作为输出信号,其等效状态框图如下所示。
下面以图所示的状态图说明在状态位里编码输出的方法。图中,状态机共有三个状态:IDLE,START和WAIT,输入信号为:input_1,input_2,input_3,input_4。这些输入信号的不同逻辑组合就构成了状态之间跳转的条件。
该状态机需要控制两个输出信号:output_1和output_2。可以采用4bits的状态编码,其中高两位表示当前的状态,末尾两位控制output_1和output_2的输出。IDLE状态编码为4’b0000,START状态编码为4’b0101,WAIT状态编码为 4’b1011。
参考程序如下所示:
module FSM1 (nRST, CP, input_1, input_2, input_3, input_4, output_1, output_2) ;input input_1, input_2, input_3, input_4; //定义输入变量input nRST, CP;output output_1, output_2 ; //定义输出变量wire output_1, output_2; reg [ 3 : 0 ] Current_state, Next_state;//状态参量的定义,根据前面所述的全译码状态编码
parameter [ 3 : 0 ] IDLE = 4'b0000, START = 4'b0101, WAIT = 4'b1011;
//The first always block, sequential state transition
always @(posedge CP or negedge nRST) if (!nRST) //当系统复位时,状态寄存器置为IDLE状态Current_state <= IDLE; //设置初态(IDLE)else //状态寄存器进行状态存储,将下一状态存储到状态寄存器成为当前状态Current_state <= Next_state;
// The second always block, combinational condition judgment
always @(Current_state or input_1 or input_2 or input_3 or input_4) case(Current_state) //根据当前状态和状态转换条件进行译码IDLE:if(input_1 && input_2) Next_state = START;else Next_state = IDLE;START:if(input_3) Next_state = WAIT;else Next_state = START; WAIT: if(input_4) Next_state = IDLE;else Next_state = WAIT; default: Next_state = IDLE;endcase
//状态机的输出逻辑
assign output_1 = Current_state[1];
assign output_2 = Current_state[0];
endmodule
如何使用One-hot编码方案设计状态机
对状态机的各个状态赋予一组特定的二进制数称为状态编码。比较常用的有自然二进制码、格雷码和One-hot编码。自然二进制码和格雷码的编码方案使用的触发器较少,其编码效率较高,但负责根据当前状态和状态转换条件进行译码的组合电路会比较复杂,其逻辑规模也较大,使得次态逻辑在传输过程中需要经过多级逻辑,从而影响电路的工作速度。
One-hot编码方案使用n位状态触发器表示具有n个状态的状态机,每个状态与一个独立的触发器相对应,并且在任何时刻其中只有一个触发器有效(其值为1)。虽然这种方案会使用较多的触发器,但它的编码方式非常简单,可有效地简化组合电路,并换得工作可靠性和工作速度的提高。在大规模可编程逻辑器件如FPGA中,触发器数量较多而门逻辑相对较少,One-hot编码方案有时反而更有利于提高器件资源的利用率。
定义当前状态向量state为一个5-bits向量,末尾的两位表示状态机输出,state[2]为1表示状态IDLE,state[3]为1表示状态START,state[4]为1表示状态WAIT。
下面是基于One-Hot编码方式的状态机实现代码:
module FSM2 (nRST, CP, input_1, input_2, input_3, input_4, output_1, output_2) ;input input_1, input_2, input_3, input_4; //定义输入变量input nRST, CP;output output_1, output_2 ; //定义输出变量wire output_1, output_2; reg [ 4 : 0 ] state, Next_state;parameter [ 4 : 0 ] IDLE = 5’b001_00, //状态参量,末尾两位表示对应的输出START = 5’b010_01,WAIT = 5’b100_11;//状态对应在state中的表示位置,One-hot
parameter [2:0] IDLE_POS = 3'd2, // IDLE POSitionSTART_POS = 3'd3, // START POSitionWAIT_POS = 3'd4; // WAIT POSitionalways @(posedge CP or negedge nRST) //状态存储if (!nRST) state <= IDLE;else state <= Next_state;
always @(input_1 or input_2 or input_3 or input_4)//状态转移逻辑beginNext_state = IDLE; //设置初态case(1’b1) //One-Hot编码实现状态转移时,//每次取state的一位与1比较state[IDLE_POS]:if(input_1 && input_2)Next_state = START;else Next_state = IDLE;state[START_POS]:if(input_3)Next_state = WAIT;else Next_state = START; state[WAIT_POS]: if(input_4)Next_state = IDLE;else Next_state = WAIT; default: Next_state = IDLE;endcase
end
//状态机的输出逻辑
assign output_1 = state[1];
assign output_2 = state[0];
endmodule
One-hot编码特点:指定各个状态在状态编码中的表示位,采用参量定义方式指定One-hot状态编码;使用always语句描述状态寄存器的状态存储;使用敏感表和case语句描述状态转换逻辑,在case语句中只采用一位寄存器比较方式;使用assign语句描述状态编码控制的状态机输出。
参考文献:
- Verilog HDL与FPGA数字系统设计,罗杰,机械工业出版社,2015年04月
- Verilog HDL与CPLD/FPGA项目开发教程(第2版), 聂章龙, 机械工业出版社, 2015年12月
- Verilog HDL数字设计与综合(第2版), Samir Palnitkar著,夏宇闻等译, 电子工业出版社, 2015年08月
- Verilog HDL入门(第3版), J. BHASKER 著 夏宇闻甘伟 译, 北京航空航天大学出版社, 2019年03月
相关文章:

状态机设计中的关键技术
⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。 🔥文章和代码已归档至【Github仓库…...

单片机开发---ESP32S3移植NES模拟器(二)
书接上文 《单片机开发—ESP32-S3模块上手》 《单片机开发—ESP32S3移植lvgl触摸屏》 《单片机开发—ESP32S3移植NES模拟器(一)》 暖场视频,小时候称这个为—超级曲线射门!!!!!&am…...

微信小程序nodej‘s+vue警局便民服务管理系统
本文首先介绍了设计的背景与研究目的,其次介绍系统相关技术,重点叙述了系统功能分析以及详细设计,最后总结了系统的开发心得在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括“最多跑一次”微信小程序的网络应用,在外国小程序的使用已经是很普遍的方…...
第18章 MongoDB $type 操作符教程
MongoDB $type 操作符 描述 在本章节中,咱们将继续讨论MongoDB中条件操作符 $type。 $type操作符是基于BSON类型来检索集合中匹配的数据类型,并return 结果。 MongoDB 中可以使用的类型如下表所示: 类型数字备注Double1 String2 Object3…...
【MySQL主从复制】快速配置
本文配置环境Windows和Linux。 windows主 Linux 从 一、主库配置 首先保证Linux和防火墙开启3306端口或关闭防火墙。 登录Mysql管理员账户: GRANT REPLICATION slave,reload,super ON *.* TO root@从库ip地址 IDENtIFIED BY root; flush privileges; 本地的mysql可以被:…...

Typescript - interface 关键字(通俗易懂的详细教程)
前言 简单来说,Interface 就是一种描述对象或函数的东西。 您可以把 interface 理解为形状,真实开发情况下,一个对象需要有什么样的属性,函数需要什么参数或返回什么样的值,数组应该是什么样子的,一个类和继…...

【计组】内存和总线
课程链接:深入浅出计算机组成原理_组成原理_计算机基础-极客时间 一、虚拟内存和内存保护 日常使用的操作系统下,程序不能直接访问物理内存。内存需要被分成固定大小的页(Page),再通过虚拟内存地址(Virtu…...

CUDA中的数学方法
CUDA中的数学方法 文章目录CUDA中的数学方法1. Standard FunctionsSingle-Precision Floating-Point FunctionsDouble-Precision Floating-Point Functions2. Intrinsic FunctionsSingle-Precision Floating-Point FunctionsDouble-Precision Floating-Point Functions参考手册…...

Elasticsearch基本概念和索引原理
一、Elasticsearch是什么? Elasticsearch是一个基于文档的NoSQL数据库,是一个分布式、RESTful风格的搜索和数据分析引擎,同时也是Elastic Stack的核心,集中存储数据。Elasticsearch、Logstash、Kibana经常被用作日志分析系统&…...
《NFL橄榄球》:堪萨斯城酋长·橄榄1号位
堪萨斯城酋长队(Kansas City Chiefs)是位于密苏里州堪萨斯城的职业美式橄榄球队;目前在全国橄榄球联盟隶属于美国橄榄球联合会(AFC)西区;其夏季训练营在威斯康星大学河瀑校区举行。 酋长队的前身是达拉斯得州佬队,这支…...

python+django在线教学网上授课系统vue
随着科技的进步,互联网已经开始慢慢渗透到我们的生活和学习中,并且在各个领域占据着越来越重要的部分,很多传统的行业都将面临着巨大的挑战,包括学习也不例外。现在学习竞争越来越激烈,人才的需求量越来越大࿰…...

二叉搜索树之AVL树
AVL树的概念二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年 发明了一种解决上…...

全栈自动化测试技术笔记(二):准备工作的切入点
自动化测试技术笔记(二):准备工作的切入点 上篇整理的技术笔记,聊了自动化测试的前期调研工作如何开展,最后一部分也提到了工作的优先级区分。 这篇文章,接上篇文章的内容,来聊聊自动化测试前期的准备工作࿰…...

57 长短期记忆网络(LSTM)【动手学深度学习v2】
57 长短期记忆网络(LSTM)【动手学深度学习v2】 深度学习学习笔记 学习视频:https://www.bilibili.com/video/BV1JU4y1H7PC/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 长短期记忆网络(LSTM)…...
算法第十五期——动态规划(DP)之各种背包问题
目录 0、背包问题分类 1、 0/1背包简化版 【代码】 2、0/ 1背包的方案数 【思路】 【做法】 【代码】 空间优化1:交替滚动 空间优化2:自我滚动 3、完全背包 【思路】 【代码】 4、分组背包 核心代码 5、多重背包 多重背包解题思路1:转化…...

实现复选框全选和全不选的切换
今天,复看了一下JS的菜鸟教程,发现评论里面都是精华呀!! 看到函数这一节,发现就复选框的全选和全不选功能展开了讨论。我感觉挺有意思的,尝试实现了一下。 1. 全选、全不选,两个按钮ÿ…...

React hooks之useState用法(一)
系列文章目录 学习React已经有很长的一段时间了,今天决定重新回顾一下跟React相关的一些知识点 文章目录系列文章目录结构如下一、hooks是什么?useState可以能做什么二、如何使用useState()第一步:创建【函数组件&…...

spring的简单理解
目录 1 .ioc容器(控制反转) 2. Aop面向切面编程 3. 事务申明 4. 注解的方式启动 5. spring是什么与他的优势 6. 代理设计模式(比如aop) 7. springmvc中相应json数据 8. 使用lombok来进行对代码的简化 9. 使用logback记录…...

Docker调用Intel集显实现FFmpeg硬解码
文章目录Docker调用Intel集显实现FFmpeg硬解码参考FFmpeg 集成qsv方式一 容器完成所有步骤方式二 容器完成部分步骤方式三 dockerfile部署Docker调用Intel集显实现FFmpeg硬解码 参考 ffmpeg_qsv_docker拉取该镜像可以实现FFmpeg集成vaapi的硬加速,通过dockerfile文…...

端到端模型(end-to-end)与非端到端模型
一、端到端(end to end) 从输入端到输出端会得到一个预测结果,将预测结果和真实结果进行比较得到误差,将误差反向传播到网络的各个层之中,调整网络的权重和参数直到模型收敛或者达到预期的效果为止,中间所…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...

持续交付的进化:从DevOps到AI驱动的IT新动能
文章目录 一、持续交付的本质:从手动到自动的交付飞跃关键特性案例:电商平台的高效部署 二、持续交付的演进:从CI到AI驱动的未来发展历程 中国…...
Python打卡训练营学习记录Day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...