3.3.1 一般有限状态机的设计
用VHDL可以设计不同表达方式和不同实用功能的状态机,它们都有相对固定语句和程序表达方式,只要把握了这些固定的语句表达部分,就能根据实际需要写出各种不同风格的VHDL状态机。
1.为什么要使用状态机
利用VHDL设计的实用逻辑系统中,有许多是可以利用有限状态机的设计方案来描述和实现的。无论与基于VHDL的其他设计方案相比,还是与可完成相似功能的CPU相比,状态机都有其难以超越的优越性,它主要表现在以下几方面:
(1)有限状态机克服了纯硬件数字系统顺序方式控制不灵活的缺点。状态机的工作方式是根据控制信号按照预先设定的状态进行顺序运行的,状态机是纯硬件数字系统中的顺序控制电路,因此状态机在其运行方式上类似于控制灵活和方便的CPU,而在运行速度和工作可靠性方面都优于CPU。
(2)由于状态机的结构模式相对简单,设计方案相对固定,特别是可以定义符号化枚举类型的状态,这一切都为VHDL综合器尽可能发挥其强大的优化功能提供了有利条件。而且,性能良好的综合器都具备许多可控或自动的专门用于优化状态机的功能。
(3)状态机容易构成性能良好的同步时序逻辑模块,这对于对付大规模逻辑电路设计中令人深感棘手的竞争冒险现象无疑是一个上佳的选择。为了消除电路中的毛刺现象,在状态机设计中有多种设计方案可供选择。
(4)与VHDL的其他描述方式相比,状态机的VHDL表述丰富多样、程序层次分明,结构清晰,易读易懂;在排错、修改和模块移植方面也有其独到的特点。
(5)在高速运算和控制方面,状态机更有其巨大的优势。由于在VHDL中,一个状态机可以由多个进程构成,一个结构体中可以包含多个状态机,而一个单独的状态机(或多个并行运行的状态机)以顺序方式所能完成的运算和控制方面的工作与一个CPU的功能类似。因此,一个设计实体的功能便类似于一个含有并行运行的多CPU的高性能微处理器的功能。事实上,多CPU的微处理器早已在通信、工控和军事等领域有了十分广泛的应用。
(6)就运行速度而言,尽管CPU和状态机都是按照时钟节拍以顺序时序方式工作的,但CPU是按照指令周期,以逐条执行指令的方式运行的;每执行一条指令,通常只能完成一项简单的操作,而一个指令周期须由多个机器周期构成,一个机器周期又由多个时钟节拍构成;一个含有运算和控制的完整设计程序往往需要成百上千条指令。相比之下,状态机状态变换周期只有一个时钟周期,而且,由于在每一状态中,状态机可以完成许多并行的运算和控制操作,所以,一个完整的控制程序,即使由多个并行的状态机构成,其状态数也是十分有限的。一般由状态机构成的硬件系统比CPU所能完成同样功能的软件系统的工作速度要高出三至四个数量级。
(7)就可靠性而言,状态机的优势也是十分明显的。CPU本身的结构特点与执行软件指令的工作方式决定了任何CPU都不可能获得圆满的容错保障,这已是不争的事实了。因此,用于要求高可靠性的特殊环境中的电子系统中,如果以CPU作为主控部件,应是一项错误的决策。而状态机系统就不同了,首先它是由纯硬件电路构成,不存在CPU运行软件过程中许多固有的缺陷;其次是由于状态机的设计中能使用各种完整的容错技术;再次是当状态机进入非法状态并从中跳出,进入正常状态所耗的时间十分短暂,通常只有2、3个时钟周期,约数十个ns,尚不足以对系统的运行构成损害;而CPU通过复位方式从非法运行方式中恢复过来,耗时达数十个ms,这对于高速高可靠系统显然是无法容忍的。
2.用户自定义数据类型定义语句
VHDL有限状态机涉及的相关语句类型和语法表述在此前的VHDL语法介绍中多已涉及,本节将介绍与有限状态机设计有重要联系的其他语法现象,即用户自定义数据类型定义语句及相关的语法现象。
除了上述一些标准的预定义数据类型外,如整数类型、Boolean类型、标准逻辑位类型Std_logic等,VHDL还允许用户自行定义新的数据类型。由用户定义的数据类型可以有多种,如枚举类型(Enumeration Types)、整数类型(Integer Types)、数组类型(Array Types)、记录类型(Record Types)、时间类型(Time Types)、实数类型(Real Types)等。
用户自定义数据类型是用类型定义语句TYPE和子类型定义语句SUBTYPE实现的,以下将介绍这两种语句的使用方法。
(1)类型定义语句TYPE
TYPE语句用法如下:
TYPE 数据类型名 IS 数据类型定义 OF 基本数据类型;
或
TYPE 数据类型名 IS 数据类型定义;
利用TYPE语句进行数据类型自定义有两种不同的格式,但方法是相同的。其中,数据类型名由设计者自定,此名将作为数据类型定义之用,方法与以上提到的预定义数据类型的用法一样;数据类型定义部分用来描述所定义的数据类型的表达方式和表达内容;关键词OF后的基本数据类型是指数据类型定义中所定义的元素的基本数据类型,一般都是取已有的预定义数据类型,如BIT、STD_LOGIC或INTEGER等。
两种不同的定义方式:
·TYPE stl IS ARRAY(0TO 15)OF STD_LOGIC;
·TYPE week IS(sun,mon,tue,wed,thu,fri,sat);
第一句定义的数据类型stl是一个具有16个元素的数组型数据类型,数组中的每一个元素的数据类型都是STD_LOGIC型;第二句定义的数据类型属于枚举类型,是由一组文字符号表示的。
VHDL中的枚举数据类型是一种特殊的数据类型,它们是用文字符号来表示一组实际的二进制数。例如,状态机的每一状态在实际电路中是以一组触发器的当前二进制数位的组合来表示的,但设计者在状态机的设计中,为了更利于阅读、编译和VHDL综合器的优化,往往将表征每一状态的二进制数组用文字符号来代表,即所谓状态符号化。例如:
TYPE m_state IS(st0,stl,st2,st3,st4,st5);
SIGNAL present_state,next_state:m_state;
在这里,信号present_state和next_state的数据类型定义为m_state,它们的取值范围是可枚举的,即从st0~st5共6种,而这些状态代表6组唯一的二进制数值。实际上,在VHDL中的许多十分常用的数据类型,如位(BIT)、布尔量(BOOLEAN)、字符(CHARAC-TER)及STD_LOGIC等都是程序包中已定义的枚举型数据类型。例如布尔数据类型的定义语句是:
TYPE BOOLEAN IS(FALSE,TRUE);其中FALSE和TRUE都是可枚举的符号,综合后它们分别用逻辑值‘0’和‘1’表示。
对于此类枚举数据,在综合过程中,都将转化成二进制代码。当然枚举类型也可以直接用数值来定义,但必须使用单引号,如:
在综合过程中,枚举类型文字元素的编码通常是自动设置的,综合器根据优化情况、优化控制的设置或设计者的特殊设定来确定各元素具体编码的二进制位数、数值及元素间编码顺序。一般情况下,编码顺序是默认的,如一般将第一个枚举量(最左边的量)编码为‘0’或“0000”等,以后的依次加l。综合器在编码过程中自动将每一枚举元素转变成位矢量,位矢量的长度根据实际情况决定。如前例中用于表达6个状态的位矢量长度可以为3,编码默认值为:st0=“000”,stl=“001”,st2=“010”,st3=“011”,st4=“100”,st5=“101”。
一般地,编码方式也会因综合器及综合控制方式不同而不同,为了某些特殊的需要,编码顺序也可以人为设置。
用Type语句来定义符号化的枚举类型,并将状态机中的现态和次态的类型定义为相应的数据类型将有助于综合器对状态机设计程序的优化设计。
(2)子类型定义语句SUBTYPE
子类型SUBTYPE只是由TYPE所定义的原数据类型的一个子集,它满足原数据类型的所有约束条件,原数据类型称为基本数据类型。子类型SUBTYPE的语句格式如下:
SUBTYPE 子类型名 IS 基本数据类型 RANGE 约束范围;
子类型的定义只在基本数据类型上作一些约束,并没有定义新的数据类型,这是与TYPE最大的不同之处。子类型定义中的基本数据类型必须在前面已有过TYPE定义的类型,包括已在VHDL,预定义程序包中用TYPE定义过的类型。如:
SUBTYPE digits IS INTEGER RANGE 0 TO 9 ;
例中,INTEGER是标准程序包中已定义过的数据类型,子类型digits只是把INTEGER约束到只含10个值的数据类型。
事实上,在程序包STANDARD中,已有两个预定义子类型,即自然数类型(Natural type)和正整数类型(Positive type),它们的基本数据类型都是INTEGER。
由于子类型与其基本数据类型属同一数据类型,因此属于子类型的和属于基本数据类型的数据对象间的赋值和被赋值可以直接进行,不必进行数据类型的转换。
利用子类型定义数据对象的好处是,除了使程序提高可读性和易处理外,其实质性的好处还在于有利于提高综合的优化效率,这是因为综合器可以根据子类型所设的约束范围,有效地推出参与综合的寄存器的最合适的数目。
3.有限状态机的描述方式
由于VHDL的灵活性,因此有限状态机可以具有多种不同的描述方式。有限状态机虽然可以具有多种不同的描述方式,但是为了使综合工具可以将一个完整的VHDL源代码识别为有限状态机,必须还要遵循一定的描述规则。描述规则规定,一个有限状态机的VHDL描述应该包括以下内容:
·至少包括一个状态信号,它们用来指定有限状态机的状态。
·状态转移指定和输出指定,它们对应于控制单元中与每个控制步有关的转移条件。
·时钟信号,它是用来进行同步的。
·同步或异步复位信号。
上面的第一条至第三条内容是一个有限状态机的VHDL描述所必须包括的,对于第四条内容有些源代码可以不包括,但对于一个实际应用的有限状态机来说,复位信号是不可缺少的,所以我们将同步或异步复位信号也列在了上面。
只要遵循了上面的描述规则,我们编写的多种不同描述方式的VHDL源代码都是合法的。在描述有限状态机的过程中,常常使用的描述方式有三种:三进程描述、双进程描述和单进程描述。
三进程描述就是指在VHDL源代码的结构体中,用三个进程语句来描述有限状态机的行为:一个进程用来进行有限状态机中的次态逻辑的描述;一个进程用来进行有限状态机中的状态寄存器的描述;还有一个进程用来进行状态机中的输出逻辑的描述。
所谓双进程描述就是指在VHDL源代码的结构体中,用两个进程语句来描述有限状态机的行为:一个进程语句用来描述有限状态机中次态逻辑、状态寄存器和输出逻辑中的任何两个;剩下的一个用另外的一个进程来进行描述。
顾名思义,所谓单进程描述就是将有限状态机中的次态逻辑、状态寄存器和输出逻辑在VHDL源代码的结构体中用一个进程来进行描述。
根据上面有限状态机VHDL源代码的三种描述方式的定义,将它们列成如表3-14所示的表格形式,以此来比较这三种描述方式的不同。
表3-14 有限状态机的描述方式列表
采用三进程描述方式和双进程描述方式中的形式1来描述有限状态机时,可以把有限状态机的组合逻辑部分和时序逻辑部分分开,这样有利于对有限状态机的组合逻辑部分和时序逻辑部分进行测试。不同的描述方式对于综合的结果影响很大,一般来说,三进程描述方式、双进程描述方式中的形式1和单进程描述方式的综合结果是比较好的,而双进程描述方式中的形式2和形式3并不常用。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。