第七章状态机与IO口.docx
《第七章状态机与IO口.docx》由会员分享,可在线阅读,更多相关《第七章状态机与IO口.docx(17页珍藏版)》请在冰豆网上搜索。
第七章状态机与IO口
第七章状态机与I/O口
7.1有限状态机设计
7.1.1有限状态机引论
1、状态机的概念
在实际逻辑控制系统中,有许多是可以利用状态机的设计方案来实现的。
如AD574转换控制器,AD574的控制逻辑表如下:
表7-1AD574逻辑控制真值表
CE
CS
RC
X12/8
A0
工作状态
0
X
X
X
X
禁止
X
1
X
X
X
禁止
1
0
0
X
0
启动12位转换
1
0
0
X
1
启动8位转换
1
0
1
1
X
12位数据输出
1
0
1
0
0
高8位数据输出
1
0
1
0
1
低4位数据输出
AD574工作时序为:
图7-1AD574工作时序(CE=1,X12/8=1)
图7-2AD574状态转换图
其对应控制器的状态转换图见图7-2。
要求控制器在现场信号作用下自动进行状态转换,并根据当前状态发出相应控制信号以控制现场。
状态机就是完成这一目的。
有限状态机及其设计技术是实用数字系统设计中的重要组成部分,是实现高效率高可靠逻辑控制的重要途径。
2、状态机的优点
无论与基于VHDL的其他设计方案相比,还是与可完成
相似功能的CPU相比,状态机都有其难以超越的优越性,它主要表现在以下几方面:
1、控制灵活、方便:
状态机的工作方式是根据控制信号按照预先设定的状态顺序运行的,因此状态机在其运行方式上类似于控制灵活和方便的CPU。
克服了纯硬件数字系统顺序方式控制不灵活的缺点。
2、结构简单,便于设计:
设计方案相对固定,特别是可以定义符号化枚举类型的状态,这一切都为VHDL综合器尽可能发挥其强大的优化功能提供了有利条件。
而且,性能良好的综合器都具备许多可控或自动的专门用于优化状态机的功能。
3、状态机易构成性能良好的同步时序逻辑模块,这对于对付大规模逻辑电路设计中令人深感棘手的竞争冒险现象无疑是一个上佳的选择。
4、就运行速度而言,一般由状态机构成的硬件系统比CPU所能完成同样功能的软件系统的工作速度要高出三至四个数量级。
如进行AD转换采集数据,传统的方法多数是用CPU或单片机完成的。
编程简单,控制灵活,但缺点是控制周期长,速度慢。
当A/D本身的采样速度比较快时,如用于视频信号采样的TLC5540,采样速率达40MHz,单片机对于此类高速的A/D器件完全无从控制。
如果使用状态机来控制A/D采样,包括将采得的数据存入RAM,整个采样周期需要4至5个状态即可完成.若FPGA的时钟频率为100MHz,则从一个状态向另一状态转移的时间为一个时钟周期,即10ns,那么一个采样周期约50ns。
由此可见利用状态机对A/D进行采样控制是一种行之有效的方法。
5、就可靠性而言,CPU本身的结构特点与执行软件指令的工作方式决定了任何CPU都不可能获得圆满的容错保障。
而状态机系统由纯硬件电路构成,不存在CPU运行软件过程中许多固有的缺陷;其次是当状态机进入非法状态并从中跳出,进入正常状态所耗的时间十分短暂,通常只有2、3个时钟周期,约数十个ns,尚不足以对系统的运行构成损害;而CPU通过复位方式从非法运行方式中恢复过来,耗时达数十ms,这对于高速高可靠系统显然是无法容忍的。
3、状态机的分类
1)从状态机的信号输出方式上分有Mealy型和Moore型两种状态机。
从输出时序上看,Mealy属于异步输出状态机。
其输出是当前状态和所有输入信号的函数,它的输出是在输入变化后立即发生的,不依赖时钟的同步。
Moore属于同步输出状态机,其输出则仅为当前状态的函数,这类状态机在输入发生变化还必须等待时钟的到来,时钟使状态发生变化时才导致输出的变化,所以比Mealy机要多等待一个时钟周期。
2)从结构上分,有单进程状态机和多进程状态机。
3)从编码方式上分有顺序编码状态机、一位热码编码状态机或其他编码方式状态机。
7.1.2典型状态机结构
典型状态机设计由状态信号定义、准备下一状态进程、状态切换进程、输出进程等四部分构成。
下面以AD574为例介绍状态机编程。
【例7-1】用FPGA/CPLD控制AD574进行12位A/D转换,并将转换结果保存在Q0~Q11中。
分析:
12位A/D转换,12位结果输出,X12/8接高电平,A0接低电平;2个片选信号用1个CE,CS接低电平。
连接电路图见图7-3。
图7-3AD574连接图
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYAD574IS
PORT(D:
INSTD_LOGIC_VECTOR(11DOWNTO0);
Q:
OUTSTD_LOGIC_VECTOR(11DOWNTO0);
CLK,STATUS:
INSTD_LOGIC;
CE,RC:
OUTSTD_LOGIC);--AD574控制信号
ENDAD574;
ARCHITECTUREbehavOFAD574IS
TYPEstatesIS(s0,sl,s2,s3,s4,s5);
SIGNALc_st,n_st:
states;
SIGNALLOCK:
STD_LOGIC;
BEGIN
PROCESS(c_st,STATUS)--准备下一状态
BEGIN
CASEc_stIS
WHENs0=>n_st<=sl;
WHENSl=>n_st<=s2;
WHENs2=>IF(STATUS='1')THENn_st<=s3;
ELSEn_st<=s2;
END1F;
WHENs3=>IF(STATUS='1')THENn_st<=s3;
ELSEn_st<=s4;
END1F;
WHENS4=>n_st<=s5;
WHENS5=>n_st<=s0;
WHENOTHERS=>n_st<=s0;
ENDCASE;
ENDPROCESS;
PROCESS(c_st)--输出控制信号的进程
BEGIN
CASEc_stIS
WHENs0=>CE<=‘0’;RC<='0';LOCK<='0';
WHENsl=>CE<=‘1’;RC<=‘0’;LOCK<='0';
WHENs2=>CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
WHENs3=>CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
WHENs4=>CE<=‘1’;RC<=‘1’;LOCK<=‘0’;
WHENs5=>CE<=‘1’;RC<=‘1’;LOCK<=‘1’;
WHENOTHERS=>CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
ENDCASE;
ENDPROCESS;
PROCESS(CLK)--状态切换进程
BEGIN
IF(CLK’EVENTANDCLK=’1’)THEN
c_st<=n_st;
ENDIF;
ENDPROCESS;
PROCESS(LOCK)--数据保存
BEGIN
IFLOCK=‘1’ANDLOCK‘EVENTTHEN
Q12<=D;
ENDIF;
ENDPROCESS;
ENDbehav;
1、状态信号定义:
采用枚举数据类型定义系统中有哪些状态,并定义当前状态信号、下一状态信号。
一般放在结构体的ARCHITECTURE和BEGIN之间。
如图7-2有6个状态,VHDL编程为:
ARCHITECTUREBEHAVOFAD574EIS
TYPEstatesIS(S0,S1,S2,S3,S4,S5);--定义状态的数据类型
SIGNALnextstate,currentstate:
states;--定义下一状态信号、当前状态信号
BEGIN
在数字系统中,每一状态对应一个二进制数,称状态编码。
如AD574控制有5个状态,可用3位二进制表示:
(000、001、010、011、100)。
但设计者在状态机的设计中,为了更利于阅读、编译和VHDL综合器的优化,往往将表征每一状态的二进制数组用文字符号来代表,即所谓状态符号化。
如(s0,sl,s2,s3,s4,s5),或者(READY,START,WAIT,READY,READ,LOCK)等更直观的符号表示。
2、准备下一状态进程:
根据外部输入的控制信号,和当前状态的状态值确定下一状态(nextstate)的取向,即nextstate的取值内容。
相当于用VHDL语言实现状态转换图的连接。
常用CASE语句。
进程敏感表为当前状态和状态机的输入信号。
3、状态切换进程:
负责状态机运转和在时钟驱动下负责状态转换的进程。
此进程只是机械地将代表次态的信号next_state中的内容送入现态的信号current中。
当然此进程中也可以放置一些同步或异步清零或置位方面的控制信号。
4、输出进程:
根据当前状态和输入,送出控制信号。
从例7-1可观察到,准备下一状态进程与输出进程结构类似,可合并为一个进程。
见例7-2。
【例7-2】用FPGA/CPLD控制AD574进行12位A/D转换,并将转换结果保存在Q0~Q11中。
采用二进程状态机。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYAD574IS
PORT(D:
INSTD_LOGIC_VECTOR(11DOWNTO0);
Q:
OUTSTD_LOGIC_VECTOR(11DOWNTO0);
CLK,STATUS:
INSTD_LOGIC;
CE,RC:
OUTSTD_LOGIC);--AD574控制信号
ENDAD574;
ARCHITECTUREbehavOFAD574IS
TYPEstatesIS(s0,sl,s2,s3,s4,s5);
SIGNALc_st,n_st:
states;
SIGNALLOCK:
STD_LOGIC;
BEGIN
PROCESS(c_st,STATUS)--准备下一状态
BEGIN
CASEc_stIS
WHENs0=>n_st<=sl;
CE<=‘0’;RC<='0';LOCK<='0';
WHENSl=>n_st<=s2;
CE<=‘1’;RC<=‘0’;LOCK<='0';
WHENs2=>IF(STATUS='1')THENn_st<=s3;
ELSEn_st<=s2;
END1F;
CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
WHENs3=>IF(STATUS='1')THENn_st<=s3;
ELSEn_st<=s4;
END1F;
CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
WHENS4=>n_st<=s5;
CE<=‘1’;RC<=‘1’;LOCK<=‘0’;
WHENS5=>n_st<=s0;
CE<=‘1’;RC<=‘1’;LOCK<=‘1’;
WHENOTHERS=>n_st<=s0;
CE<=‘0’;RC<=‘0’;LOCK<=‘0’;
ENDCASE;
ENDPROCESS;
PROCESS(CLK)--状态切换进程
BEGIN
IF(CLK’EVENTANDCLK=’1’)THEN
c_st<=n_st;
ENDIF;
ENDPROCESS;
PROCESS(LOCK)--数据保存
BEGIN
IFLOCK=‘1’ANDLOCK‘EVENTTHEN
Q12<=D;
ENDIF;
ENDPROCESS;
ENDbehav;
【例7-3】ADC0809
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYAD0809IS
PORT(D:
INSTD_LOGIC_VECTORY(7DOWNTO0);
ALE,START,OE:
OUTSTD_LOGIC;
CLK,EOC:
INSTD_LOGIC;
LED8:
OUTSTD_LOGIC_VECTORY(7DOWNTO0);
SEL:
BUFFERINTEGERRANGE(7DOWNTO0))
ENDENTITY;
ARCHITECTUREBODYOFAD0809IS
TYPESTATESIS(S0,S1,S2,S3,S4,S5);
SIGNALC_ST,N_ST:
STATES;
SIGNALD8;STD_LOGIC_VECTORY(7DOWNTO0);
SIGNALD4;STD_LOGIC_VECTORY(3DOWNTO0);
SIGNALLOCK;STD_LOGIC;
BEGIN
PROCESS(C_ST,EOC)--N_STATE--OUTCONTRAL
BEGIN
CASEC_STIS
WHENS0=>N_ST<=S1;ALE=’0’;START=’0’;OE=’0’;LOCK=’0’;
WHENS1=>N_ST<=S2;ALE=’1’;START=’0’;OE=’0’;LOCK=’0’;
WHENS2=>N_ST<=S3;ALE=’0’;START=’1’;OE=’0’;LOCK=’0’;
WHENS3=>IFEOC=’1’THENN_ST<=S3;
ELSEN_ST<=S4;
ENDIF;
ALE=’0’;START=’0’;OE=’0’;LOCK=’0’;
WHENS4=>IFEOC=’0’THENN_ST<=S4;
ELSEN_ST<=S5;
ENDIF;
ALE=’0’;START=’0’;OE=’0’;LOCK=’0’;
WHENS5=>N_ST<=S6;ALE=’0’;START=’0’;OE=’1’;LOCK=’0’;
WHENS6=>N_ST<=S0;ALE=’0’;START=’0’;OE=’1’;LOCK=’1’;
WHENOTHERS=>N_ST<=S0;ALE=’0’;START=’0’;OE=’0’;LOCK=’0’;
ENDCASE;
ENDPROCESS;
PROCESS(clk)--STATESWITCH,SEL+1
BEGIN
IF(CLK'EVENTANDCLK='1')THEN
C_ST<=N_ST;
SEL<=SEL+1;
ENDIF;
ENDPROCESS;
PROCESS(SEL)--选择待显示的数据
BEGIN
CASESELIS
WHEN0=>D4<=”1010”;
WHEN1=>D4<=”1101”;
WHEN2=>D4<=”0000”;
WHEN3=>D4<=”1000”;
WHEN4=>D4<=”0000”;
WHEN5=>D4<=”1001”;
WHEN6=>D4<=D8(7DOWNT04);
WHEN7=>D4<=D8(3DOWNT00);
WHENOTHERS=>NULL;
ENDCASE;
ENDPROCESS;
PROCESS(LOCK)--STATESWITCH
BEGIN
IF(LOCK'EVENTANDLOCK='1')THEN
D8<=D;
ENDIF;
ENDPROCESS;
--字型转换进程(略)HEXLEDD4LED8
ENDBODY;
【例7-3】根据状态转换图给出状态机设计,S0~S3为状态号,圈内为输出。
LIBRARY1EEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYs_machineIS
port(clk,reset:
INSTD_LOGIC;
inputs:
INSTD_LOGIC_VECTOR(0TO1);
图7-4例7-3状态转换图
outputs:
OUTINTEGERrange(0to15);
ENDs_machine;
ARCHITECTUREbehavOFs_machineIS
Typestatesis(s0,s1,s2,s3);
SIGNAlcurcent_state,next_state:
states;
BEGIN
REG:
PROCESS(reset,clk)--状态切换
BEGIN
IFreset=‘1’THENcurrent_state<=s0;
ELSIFclk=’l’ANDclk‘EVENTTHEN
Current_state<=next_state;
ENDIF;
ENDPROCESS;
COM:
PROCESS(current_state,inputs)--下一状态、
Begin
CASEcurrent_stateIS
WHENs0=>outputs<=5;
IFinputs=”00”THENnext_state<=s0;
ELSEnext_state<=sl;
ENDIF;
WHENsl=>outputs<=8;
IFinputs=”00”THENnext_state<=sl;
ELSEnext_state<=s2;
ENDIf;
WHENS2=>outputs<=12;
IFinputs=”11”THENnext_state<='s0';
ELSEnext_state<=s3;
ENDIF;
whens3=>OUTPUTS<=14;
Ifinputs=“11”THennext_state<=s3;;
ELSEnextstate<=s0;
ENDIF;
ENDcase;
ENDPROCESS;
ENDbehav;
7.1.3状态机的改进
1、状态机输出毛刺现象的克服
当状态机的输出信号由组合电路发出时,一般情况下难免出现毛刺现象,如果这些输出被用于作为时钟信号,极易产生错误的操作,单进程Moore状态机比较容易构成能避免出现毛刺现象的状态机。
例7-4单进程Moore状态机,其组合进程和时序进程在同一个进程中,在此进程中,CASE语句处于测试时钟上升沿的ELSIF语句中,因此在综合时,对Q的赋值操作必然能引进对Q锁存的锁存器。
【例7-4】例7-3,单进程
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYMOORElIS
PORT(DATAIN:
INSTD_LOGIC_VECTOR(1DOWNTO0);
CLK,RST:
INSTD_LOGIC;
Q:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDMOOREl;
ARCHITECTUREbehavOFMOORElIS
TYPEST_TYPEIS(ST0,STl,ST2,ST3,ST4);
SIGNALC_ST,C;ST_TYPE;
BEGIN
PROCESS(CLK,RES)
BEGIN
IFRST=‘1’THENC_ST<=ST0;Q<=“0000”;
ELSIFCLK’EVENTANDCLK=‘1’THEN
CASEC_STIS
WHENST0=>IFDATAIN=”10”THENC_ST<=STi;
ELSEC_ST<=ST0;
ENDIF;
Q<=”1001”;
WHENSTl=>IFDATAIN=“1l”THENC_ST<=ST2;
ELSEC_ST<=STl;
ENDIF;
Q<=”0101”;
WHENST2=>IFDATAIN=”01”THENC_ST<=ST3;
ELSEC_ST<=ST0;
ENDIF;
Q<=”1100”;
WHENST3=>IFDATAIN=”00”THEHC_ST<=ST4;
ELSEC_ST<=ST2;
ENDIF;
Q<=”0010”;
WHENST4=>IFDATAIN=“11”THENC_ST<=ST0;
ELSEC_ST<=ST3;
ENDIF;
Q<=”1001”;
WHENOTHERS=>C_ST<=ST0;
ENDCASE;
ENDIF;
ENDPROCESS;
ENDbehav;
三、Mealy型有限状态机的设计
与Moore型状态机相比,Memy机的输出变化要领先一个周期.即一旦输入信号发生变化,输出信号即刻发生变化。
MOORE机和Mealy机在设计上基本相同,稍有不同之处是,Mealy机的组合进程中的输出信号是当前状态和当前输入的函数。
[例7-51
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYMEALY1IS
PORT(CLK,DATAIN,RESET;INSTD_LOGIC;
Q:
OUTSTD_LOGIC_VECTOR(4DOWNTO0));
ENDMEALY1;
ARCHITECTUREbehavOFMEALY1IS
TYPEstatesIS(st0,stl,st2.st3,st4);
SIGNALSTX:
states;
BEGIN
COMREG:
PROCESS(CLK,RESET)--决定转换状态的进程
BEGIN
IFRESET=’l’THENSTX<=ST0;
ELSIFCLK‘EVENTANDCLK=‘1’THEN
CASESTXIS
WHENst0=>IFDATAIN=‘1’THENSTX<=stl;ENDIF;
WHENstl=>IFDATAIN=‘0’THENSTX<=st2;END:
IF;
WHENst2=>IFDATAIN=‘l’THENSTX<=st3;ENDIF;
WHENst3=>IFDATAIN=‘0‘TRENSTX<=st4;ENDIF;
WHENst4=>IFDATAIN=‘1’THENSTX<=st0;ENDIF;
WHENOTHERS=>STX<=st0;
ENDCASE;
ENDIF;
ENDPROCESSCOMREG;
COMl:
PROCESS(sTx,DATAIN)BEGIN——输出控制信号的进程
CASESTXIS
WHENst0=>IFDATAIN=’l’THENQ<=”10000”;
ELSEQ<="01010