FPGA之道(56)状态的编码方式

前言

据我说知,并非在代码设计时,状态编码写成什么样子就会综合成什么样子,还需要对综合属性进行操作,那具体是什么样子呢?一起看看《FPGA之道》对这一问题是怎么描述的。
本文摘选自《FPGA之道》。

状态的编码方式

状态编码是使用特定数量的寄存器,通过特定形式的取值集合,将状态集合表示出来的过程。这一工作通常是由编译器完成的,我们可以通过修改编译选项或者添加综合约束的方式来影响状态编码的结果。下面就以相关的编译选项为线索,对各种不同的状态编码方式做一些介绍。

binary

binary选项表示采用二进制的编码方式来进行状态编码,它的特点是编码简单,非常符合人们通常的计数规则。例如,状态集合为{S0、S1、S2、S3},那么若采用binary的编码方式,结果应该为:
S0 = 00;
S1 = 01;
S2 = 10;
S3 = 11。

one-hot

one-hot选项表示采用one-hot(又叫独热码)的编码方式来进行状态编码,它的特点是状态寄存器在任何状态时的取值都仅有一位有效。例如,状态集合为{S0、S1、S2、S3},那么若采用one-hot的编码方式,结果应该为:
S0 = 0001;
S1 = 0010;
S2 = 0100;
S3 = 1000。
由此可见,one-hot编码方式的结果其实就是二-四译码器的输出,因此在状态选择时需要的译码电路也最简单,译码速度也最快,而且还能够避免译码时引起毛刺,因此对FPGA设计的速度性能和功耗非常有利,在一些大型电路中使用的较多。
不过one-hot编码方式占用的寄存器资源较多,因此适合在寄存器富裕时使用,而且由于任意两个状态之间所对应的寄存器取值都有两位不同,因此在状态切换时会产生不稳定态,而这会对组合形式的输出信号产生不好的影响。

gray

gray选项表示采用格雷码的方式来进行状态编码,它的特点是相邻两个状态的寄存器表示仅有一位变化,更多关于格雷码的概念和具体编码公式请参考【本篇->编程思路->数字电路中的隐患->寄存器输出的不稳定态->特定情况下去除不稳定态的方法】小节。例如,状态集合为{S0、S1、S2、S3},那么若采用binary的编码方式,结果应该为:
S0 = 00;
S1 = 01;
S2 = 11;
S3 = 10。
由于两个状态之间仅有1位不同,因此非常有利于消除当状态机在相邻状态间跳转时所产生的毛刺,不过上述优势的前提是必须保证状态机的状态迁移是顺序或逆序变化的,所以gray编码方式仅适用于分支较少的状态机,而当状态机的规模较为庞大时,gray码的优势便很难得到发挥。

johnson

johnson选项表示采用约翰逊码的方式来进行状态编码,它与gray编码方式的效果类似,仅适用于分支较少的状态机。不过与gray编码方式通常采用N位寄存器可表示个状态不同,johnson编码方式通常采用N位寄存器表示2N个不同的状态。它码字生成原则为:初始时N位寄存器取值均为0;然后取最高位(左边)的寄存器,在对其值取反后将其放在最低位(右边)的寄存器后,形成新的最低位;如此往复2N+1次,便得所有johnson码字。例如,状态集合为{S0、S1、S2、S3、S4、S5},共6个状态,那么若采用johnson的编码方式,寄存器位宽应为3,编码结果应该为:
S0 = 000;
S1 = 001;
S2 = 011;
S3 = 111;
S4 = 110;
S5 = 100。
通过上例可见,johnson编码后的两个相邻状态之间也仅有1位不同。

auto

auto选项表示自动选择的意思,它是编译器在进行状态编码时的默认选项,此时编译器将会根据它的判断选择它认为合适的状态编码方式。

compact

compact选项表示采用最精简、节省的方式来进行状态编码,即采用最少的寄存器来表示整个状态集合。compact选项关注的是资源上面的节省,这点和one-hot恰恰相反,通过前面的介绍,binary等编码方式都可能在compact选项下被使用。

sequential

sequential选项表示采用尽最大努力优化当前状态到下一状态的等式处理,使得产生次态的逻辑最简。

user

user选项表示采用自定义的方式进行编码,它沿用用户在HDL代码中为状态集合所赋予的编码方式,正如我们在【状态机的HDL模板->状态集合的HDL定义->实现层级的定义】小节中所描述的那样 。如果该选项未被使能,那么编译器将无视我们在HDL代码中为状态集合显示赋予的那些编码值。

speed

speed选项表示努力采用令状态机性能达到最高的方式来进行状态编码,即想办法让状态机运转时所能达到的时钟频率上限尽量高。speed选项关注的是时间方面的节省,速度方面的提升,通过前面的介绍,可知道one-hot编码方式最能体现speed选项的要求,也正因为如此,当选中speed选项时,通常会占用较多的寄存器资源。

none

none选项表示不从HDL代码中提取状态机结构,即人脑抽象出来的状态机在经过HDL描述后,并不被编译器所接受,因此编译器也不会将该部分代码看做是状态机,也更不会对状态集合进行识别和提取,进而也不会有状态编码工作。

safe mode

safe mode选项其实并不是一种状态编码方式,但它是对状态编码方式的一种可靠补充,表示采用安全模式来实现状态机。所谓安全模式,指的是一旦状态机进入到一个非法的状态,它能够自己从该非法状态返回到一个正常状态并重新开始工作。这里的非法状态即指的是多余态,很多种编码方式都存在着这种潜在的多余态,例如:
【one-hot】小节中的例子,如果状态寄存器受到某些影响,变为0011、1001……之类的值,那么状态机将无法进入到任何一个状态;
【binary】小节中的例子,如果状态集合中没有S3,那么如果状态寄存器受到某些影响,值变为11,那么状态机也将无法进入到任何一个状态;
诸如此类的情况,如果不加处理,状态机将无法跳出当前的非法状态,永不超生。因此,为了避免这种不幸,我们在使用case描述状态选择代码时,务必一定要加入others或者default语句,以告知编译器当出现非法状态时该如何应对。但是在通常的工作环境下,FPGA芯片还是十分稳定的,因此状态机也不太可能由于干扰而进入非法状态,故而编译器从节省资源的角度出发,通常都会忽视case中的others或者default语句。不过为了保险起见,或者应付一些极端情况(例如太空中的强辐射),必须使能safe mode选项,以使得编译器能够实现出一个具有安全模式的状态机。

发布了806 篇原创文章 · 获赞 1541 · 访问量 151万+

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/104385864