摘要 在FPGA/CPLD设计中频繁使用的状态机,常出现一些稳定性问题,本文提出了一些解决方法,实验表明该方法有效地提高了综合效率.

  随着大规模和超大规模FPGA/CPLD器件的诞生和发展,以HDL(硬件描述语言)为工具、FPGA/CPLD器件为载体的EDA技术的应用越来越广泛.从小型电子系统到大规模SOC(Systemonachip)设计,已经无处不在.在FPGA/CPLD设计中,状态机是最典型、应用最广泛的时序电路模块,如何设计一个稳定可靠的状态机是我们必须面对的问题.

1、状态机的特点和常见问题

标准状态机分为摩尔(Moore)状态机和米立(Mealy)状态机两类.Moore状态机的输出仅与当前状态值有关,且只在时钟边沿到来时才会有状态变化.Mealy状态机的输出不仅与当前状态值有关,而且与当前输入值有关,这一特点使其控制和输出更加灵活,但同时也增加了设计复杂程度.其原理如图1所示.

 
  根据图1所示,很容易理解状态机的结构.但是为什么要使用状态机而不使用一般时序电路呢?这是因为它具有一些一般时序电路无法比拟的优点.

  • 用VHDL描述的状态机结构分明,易读,易懂,易排错;
  • 相对其它时序电路而言,状态机更加稳定,运行模式类似于CPU,易于实现顺序控制等.

用VHDL语言描述状态机属于一种高层次建模,结果经常出现一些出乎设计者意外的情况:

  1. 在两个状态转换时,出现过渡状态.
  2. 在运行过程中,进入非法状态.
  3. 在一种器件上综合出理想结果,移植到另一器件上时,不能得到与之相符的结果.
  4. 状态机能够稳定工作,但占用逻辑资源过多.

在针对FPGA器件综合时,这种情况出现的可能性更大.我们必须慎重设计状态机,分析状态机内在结构,在Moore状态机中输出信号是当前状态值的译码,当状态寄存器的状态值稳定时,输出也随之稳定了.经综合器综合后一般生成以触发器为核心的状态寄存电路,其稳定性由此决定.如果CLOCK信号的上升沿到达各触发器的时间严格一致的话,状态值也会严格按照设计要求在规定的状态值之间转换.然而这只是一种理想情况,实际CPLD/FPGA器件一般无法满足这种苛刻的时序要求,特别是在布线后这些触发器相距较远时,CLOCK到达各触发器的延时往往有一些差异.这种差异将直接导致状态机在状态转换时产生过渡状态,当这种延时进一步加大时,将有可能导致状态机进入非法状态.这就是Moore状态机的失效机理.对于Mealy状态机而言,由于其任何时刻的输出与输入有关,这种情况就更常见了.

2 状态机设计方案比较
2.1 采用枚举数据类型定义状态值
      在设计中定义状态机的状态值为枚举数据类型,综合器一般把它表示为二进制数的序列,综合后生成以触发器为核心的状态寄存电路,寄存器用量会减少,其综合效率和电路速度将会在一定程度上得到提高.

例1 定义状态值为枚举类型的状态机VHDL程序.

library ieee;
use ieee.std_logic_1164 all;

entity example is
port(clk:in std_logic;
mach_input:in std_logic;
mach_outputs:out std_logic_vector(0 to 1));

end example;

architecture behave of example is
type states is(st0,st1,st2,st3); --定义states为枚举类型
signal current_state,next_state:states;

begin

state_change:process(clk) --状态改变进程

begin

wait until clk'event and clk='1';
current_state<=next_state;

end process state_change;
combination:process(current_state,mach_input)
……  --输出状态值译码,给"next_state"赋新值.省略

end behave;

 
图2 枚举类型的状态机综合后的波形
  例1是一个四状态全编码状态机,综合后的仿真波形如图2所示.从放大后的局部可以看出输出状态值从“01”到“10”转换过程中出现了过渡状态“11”.从微观上分析中间信号“Current_state”状态转换过程,状态寄存器的高位翻转和低位翻转时间是不一致的,当高位翻转速度快时,会产生过渡状态“11”,当低位翻转速度快时会产生过渡状态“00”.若状态机的状态值更多的话,则产生过渡状态的概率更大.如果在非全编码状态机中,由于这种过渡状态的反馈作用,将直接导致电路进入非法状态,若此时电路不具备自启动功能,那么电路将无法返回正常工作状态.

因为状态机的输出信号常用作重要的控制,如:三态使能,寄存器清零等.所以这种结果是不允许的,如何消除此类过渡状态呢?方法之一是采用格雷码表示状态值.

2.2 用格雷码表示状态值
     格雷码的特点是任意相邻两个数据之间只有一位不同,这一特点使得采用格雷码表示状态值的状态机,可以在很大程度上消除由延时引起的过渡状态.将例1改进之后的程序如例2.
例2 采用格雷码表示状态值的状态机.
library ieee;

use ieee.std_logic_1164 all;

entity example is
port(clk:in std_logic;
mach_input:in std_logic;
mach_outputs:out std_logic_vector(0 to 1));

end example;

architecture behave of example is
constant st0:std_logic_vector(0 to 1):="00";
constant st1 :std_logic_vector(0 to 1):="01";
constant st2:std_logic_vector(0 to 1):="11";
constant st3:std_logic_vector(0 to 1):="10";
signal current_state,next_state:std_logic
vector(0to1);

begin

……

endbebave;
采用该方法,寄存器的状态在相邻状态之间跳转时,只有一位变化,产生过渡状态的概率大大降低.但是当一个状态到下一个状态有多种转换路径时,就不能保证状态跳转时只有一位变化,这样将无法发挥格雷码的特点.

2.3 定义“ONEHOT”风格的状态值编码
   虽然VHDL语言的目标之一是远离硬件,但是到目前为止并没有完全实现,所以VHDL程序在针对不同的器件综合时,仍然会有很大差异.特别是FPGA器件,当我们采用格雷表示状态值,描述一个简单的状态机时,就可能出现不稳定结果.在针对FPGA器件写程序时,我们可以将状态值定义为“ONEHOT”风格的状态码,将上例稍作修改,见例3.

例3 采用“ONEHOT”编码的状态机

library ieee;
use ieee std_logic_1164.all;

entity example is
port(clk:in std_logic;
mach_input:in std_logic;
mach_outputs:out std_logic_vector(0 to 1));

endexample;

architecture behave of example is

constant st0:std_logic_vector(0 to 3):="0001";
constant st1:std_logic_vector(0 to 3):="0010";
constant st2:std_logic_vector(0 to 3):="0100";
constant st3:std_logic_vector(0 to 3):="1000";

signal current_state,next_state:std_logic vector(0 to 3);

begin

……
对FLEX10K系列器件综合后的仿真结果如图3所示.

 
图3 采用“ONEHOT”编码的状态机综合后的波形
 如图3所示,在输入信号稳定以后,状态机的输出信号也稳定下来,定义这种风格的状态码来设计基于FPGA的状态机是一种不错的选择.
    然而在输入信号跳变时,电路还是会出现不稳定现象.此时我们已不能只从状态值编码方式寻找解决方法.回头看看状态机的原理框图不难发现:状态寄存器的输出值是必须符合建立保持时间约束关系的.在上述状态机中虽然采用了各种不同的编码方式但都不能彻底消除这种过渡状态,我们将电路结构稍作改进,一种更好的结构如图4所示.这种结构的状态机可有效抑制过渡状态的出现.这是因为输出寄存器只要求状态值在时钟的边沿稳定.将上述程序改进之后的程序如图4.

……
architecture behave of example1is
type states is(st0,st1,st2,st3); 定义states为枚举类型

signal current_state,next_state:states;
signal temp:std_logic_vector(0 to 1); 定义一个信号用于引入输出寄存器

begin
state_change:process(clk) --状态改变进程

begin

wait until clk'eventandclk='1';

current_state<=next_state;

mach_outputs<=temp;

end process state_change;

……

 
 
图5 改进后的状态机综合后的波形
  显然这种结构的状态机稳定性优于一般结构的状态机,但是它占用的逻辑资源更多,电路的速度可能下降,在设计时应综合考虑.
    另外,为防止电路进入非法状态,可以设计成自启动结构,在VHDL描述的状态机中添加一个“when others”语句是行之有效的
.

3 选择不同编码方式、不同结构的状态机的技巧
3.1 针对不同结构器件选择不同编码风格
   基于乘积项结构的CPLD器件适合于设计全编码状态机,在全编码状态机中采用格雷码表示状态值.这对于逻辑资源较少的器件是一种不错的优化方法.

基于查找表结构的FPGA器件适合于设计成“ONEHOT”方式编码的状态机,这种结构状态机只用一位二进制数表示一个状态,可提高稳定性,但要占用更多的逻辑资源.

3.2 根据逻辑资源大小选择状态机结构
   当设计的状态机状态转换次序出现多路径时,采用格雷码表示状态值不会有任何作用,因为此时有些相邻状态不只是一位不同.在逻辑资源允许的情况下,可以考虑在状态机后级增加一级输出寄存器,可确保输出不产生毛刺,使状态机输出稳定可靠的信号.

感触颇深:

  流水式:格雷码

  复杂:全编码+reg

  FPGA:独热

  CPLD:全编码

转载于:https://www.cnblogs.com/FPGA_DSP/archive/2011/02/09/1950413.html

FPGA/CPLD状态机稳定性研究相关推荐

  1. FPGA中状态机的稳定性

    第一个:状态机输出信号填写问题,下面是我转载的一些能百度的到的东西.好像都比较正常.这里我还要强调的是,每个状态机的输出信号都需要全面. 举例: always @ (posedge clk or ne ...

  2. 特权同学的FPGA/CPLD设计学习笔记

    题记:这个笔记不是特权同学自己整理的,特权同学只是对这个笔记做了一下完善,也忘了是从那DOWNLOAD来的,首先对整理者表示感谢.这些知识点确实都很实用,这些设计思想或者也可以说是经验吧,是很值得每一 ...

  3. FPGA中状态机实现需要注意的地方

    写状态机时需要注意的地方: 1.状态机的状态编码大概有三种:二进制编码,格雷码,独热码.      其中二进制编码就是000.001.010.011.100这类的逐渐加一      格雷码就是相邻两个 ...

  4. SAP QM 稳定性研究功能研习系列1 - 稳定性研究总流程

    SAP QM 稳定性研究功能研习系列1 - 稳定性研究总流程 如下图是SAP系统里标准的Stability Study Processing. 2,QM01创建一个QS类型(StabilStudy w ...

  5. [EDA]FPGA/CPLD 设计流程步骤及步骤概念

    EDA(以 FPGA/CPLD 设计为例)流程步骤 1.设计输入 2.全程编译 3.仿真验证 4.编程下载 5.硬件测试 设计输入 原理图/HDL文本编辑或其他输入方式把电路系统输入到EDA平台中. ...

  6. 从 Spec.到芯片_(数字IC、模拟IC、FPGA/CPLD设计的流程及EDA工具)

    从 Spec.到芯片→ 先来看张图,本图体现出了集成电路产业链:设计业.制造业.封测业. 关于制造.封装测试我们看两张图稍作了解即可: 关于设计,是本文主要内容,主要从下方几个方面了解: 1.IC设计 ...

  7. 51单片机真的过时了吗?单片机、ARM、DSP、FPGA/CPLD

    现在在大学里,51单片机仍是电子类专业必修的课程,然而这几年随着ARM的火爆,很多51的学习者有了专业一个疑问:既然大家都在用ARM,我们为什么还要学51?而且找工作的时候人家也比较关注有过ARM使用 ...

  8. 对于Lattice FPGA/CPLD XO2编程,“Flash erase, program, verify, secure”和“Flash erase, program, verify, secu

    向博主本人提问FPGA相关问题 对于XO2编程,"Flash erase, program, verify, secure"和"Flash erase, program, ...

  9. 【 FPGA 】状态机,FPGA的灵魂

    有关状态机的文章,事实上已经写过很多了,可是即使如此,真的懂了吗?真的能熟练应用吗?未必吧.这篇博文来源是<FPGA之道>,认真下看去收货颇丰! 借这个主题来梳理下状态机: 状态机简介 状 ...

最新文章

  1. 如何在进程间共享数据
  2. 计算机中位运算的一些性质与技巧
  3. 区块链和java哪个更难_java 区块链中设计合理的难度系数
  4. spark教程python案例_Spark实战(四)spark+python快速入门实战小例子(PySpark)
  5. 盘点最重要的7个Python库
  6. HDU5150 Sum Sum Sum
  7. 昨天做的事情和今天需要做的事情
  8. Linux --忘记root密码/su: Authentication failure
  9. volley源代码解析(六)--HurlStack与HttpClientStack之争
  10. 设计模式原则之六:依赖倒置原则
  11. 蓝牙设备一键切换工具ToothFairy for Mac中文
  12. Kotlin的中文文档
  13. 《电磁学》学习笔记4——磁场高斯定理、安培环路定理、电动势
  14. 2021全国大学生电子设计竞赛F题参赛简记
  15. android ndk 如何安装,Android NDK 安装
  16. python cfg文件解析
  17. 网站关键词怎么布局才更合理?
  18. 在线版音乐播放器APP
  19. linux小说编辑,Fade In Pro——剧本小说编辑软件
  20. Linux下chkconfig命令详解

热门文章

  1. metasploitable2渗透测试
  2. NewCode----句子反转
  3. python sep函数_Python中带有print()函数的sep参数
  4. Java——多线程(线程安全问题)
  5. 远控免杀4---Evasion免杀
  6. socket通信需要网线连接吗_socket网络编程基础知识篇
  7. CCPC网络赛前一周的充电计划
  8. 软件工程---2.软件过程
  9. Linux中netstat工具详解
  10. Linux_linux常用工具(git,vim ,gcc ,gdb,权限)超详解