1第10章有限状态机设计2有限状态机(FiniteStateMachine)又称有限状态自动机或简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。有限状态机在数字电路系统中,有限状态机是一种十分重要的时序逻辑电路模块,它对数字系统的设计具有十分重要的作用。有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。一般来说,除了输入部分和输出部分外,有限状态机还含有一组具有“记忆”功能的寄存器,这些寄存器的功能是记忆有限状态机的内部状态,它们常被称为状态寄存器。在有限状态机中,状态寄存器的的下一个状态不仅与输入信号有关,而且还与该寄存器的当前状态有关,因此有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。其中,寄存器逻辑的功能是存储有限状态机的内部状态;而组合逻辑有可以分为次态逻辑和输出逻辑两部分,次态逻辑的功能是确定有限状态机的下一个状态,输出逻辑的功能是确定有限状态机的输出。3有限状态机结构模式相对简单,设计方案相对固定,有利于综合器优化。容易构成性能良好的同步时序逻辑模块,有利于解决竞争冒险现象。在高速运算和控制方面,状态机有其巨大优势。一个结构体可包含多个状态机,类似于并行运行的多CPU系统。运行速度远远高于CPU。状态机状态变换周期只有一个时钟周期,而且每一状态可以完成许多并行运算和控制操作。在可靠性方面,状态机优势明显。状态机可以使用容错技术;状态机进入非法状态并从中跳出所耗时间极短,通常只需2个时钟周期,约10个ns。CPU一般数十ms。有限状态机的优点4状态机分类Melay型:输出是当前状态和所有输入信号的函数。Moore型:输出仅是当前状态的函数。Melay型状态机的输出是输入变化后立即发生变化;而Moore型状态机在输入发生变化后,还需等到时钟到来,时钟使状态发生变化才导致输出变化。因此要多等待一个时钟周期。5设计实例例1Moore状态机状态s0时,输入为0维持s0,输入为1时,下一状态改为s1,不论输入是什么,输出均为0。0101110S1/1S3/0S2/0S0/06modulemoore_ex1(clk,din,op);inputclk,din;outputop;regop;parameters0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;reg[1:0]presentstate;reg[1:0]nextstate;always@(posedgeclk)presentstate=nextstate;7always@(din,presentstate)begincase(presentstate)s0:beginif(din==0)nextstate=s0;elsenextstate=s1;op=0;ends1:beginif(din==1)nextstate=s1;elsenextstate=s2;op=1;ends2:beginif(din==1)nextstate=s2;elsenextstate=s3;op=0;ends3:beginif(din==1)nextstate=s0;elsenextstate=s1;op=0;enddefault:beginnextstate=s0;op=0;endendcaseendendmodule8modulet_moore_ex1;regclk,din;wireop;always#20clk=~clk;initialbeginclk=0;din=0;#80din=1;#160din=0;#200din=1;#160din=0;endmoore_ex1u1(.clk(clk),.din(din),.op(op));endmodule91/1S1S3S2S01/01/10/00/00/01/10/1例2Mealy状态机若当前是S3,若输入是0,则输出0且下一个状态是s1,而输入为1则输出为1且下一个状态更换成s0输入/输出10modulemealy_ex1(clk,din,op);inputclk,din;outputop;regop;parameters0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;reg[1:0]presentstate;reg[1:0]nextstate;always@(posedgeclk)presentstate=nextstate;11always@(din,presentstate)begincase(presentstate)s0:beginif(din==0)beginnextstate=s0;op=0;endelsebeginnextstate=s1;op=1;endends1:beginif(din==1)beginnextstate=s1;op=1;endelsebeginnextstate=s2;op=0;endend12s2:beginif(din==1)beginnextstate=s2;op=0;endelsebeginnextstate=s3;op=1;endends3:beginif(din==1)beginnextstate=s0;op=1;endelsebeginnextstate=s1;op=0;endend13default:beginnextstate=s0;op=0;endendcaseendendmodule14modulet_mealy_ex1;regclk,din;wireop;always#20clk=~clk;initialbeginclk=0;din=0;#80din=1;#160din=0;#200din=1;#160din=0;endmealy_ex1u1(.clk(clk),.din(din),.op(op));endmodule15A/K1=0!Reset/K2=0,K1=0!Reset/K2=0,K1=0!Reset|!A/K2=0,K1=1A/K2=1!AStartIdleClear!Reset/K2=0,K1=0Stop状态转移图16modulefsm(Clock,Reset,A,K2,K1,state);inputClock,Reset,A;outputK2,K1;output[1:0]state;regK2,K1;reg[1:0]state;parameterIdle=2'b00,Start=2'b01,Stop=2'b10,Clear=2'b11;17always@(posedgeClock)if(!Reset)beginstate=Idle;K2=0;K1=0;endelsecase(state)Idle:if(A)beginstate=Start;K1=0;endelsebeginstate=Idle;K2=0;K1=0;endStart:if(!A)state=Stop;elsestate=Start;Stop:if(A)beginstate=Clear;K2=1;endelsebeginstate=Stop;K2=0;K1=0;end18Clear:if(!A)beginstate=Idle;K2=0;K1=1;endelsebeginstate=Clear;K2=0;K1=0;enddefault:state=Idle;endcaseendmodule19对串行输入的数据流进行检测,只要发现10010码型会立即输出一个高位的电平20`timescale1ns/1nsmoduleseqdet2(x,z,clk,rst);inputx,clk,rst;outputz;reg[2:0]state;//状态寄存器wirez;parameterIDLE=3'd0,A=3'd1,B=3'd2,C=3'd3,D=3'd4,E=3'd5,F=3'd6,G=3'd7;assignz=(state==D&&x==0)?1:0;21always@(posedgeclkornegedgerst)if(!rst)beginstate=IDLE;endelsecasex(state)IDLE:if(x==1)state=A;elsestate=IDLE;A:if(x==0)state=B;elsestate=A;B:if(x==0)state=C;elsestate=F;C:if(x==1)state=D;elsestate=G;D:if(x==0)state=E;elsestate=A;E:if(x==0)state=C;elsestate=A;22F:if(x==1)state=A;elsestate=B;G:if(x==1)state=F;elsestate=G;default:state=IDLE;endcaseendmodule23`timescale1ns/1ns`definehalfperiod20modulet_seqdet2;regclk,rst;reg[23:0]data;wirez,x;assignx=data[23];always#(`halfperiod)clk=~clk;always@(posedgeclk)#2data={data[22:0],data[23]};seqdet2m(.x(x),.z(z),.clk(clk),.rst(rst));24initialbeginclk=0;rst=1;#2rst=0;#30rst=1;data=20'b1100_1001_0000_1001_0100;//data=20'b1100_0010_0000_1001_0100;//data=20'b1100_1001_0000_1001_0100;//码流数据#(`halfperiod*1000)$stop;endendmodule25`timescale1ns/1nsmoduleseqdet3(x,z,clk,rst);inputx,clk,rst;outputz;reg[2:0]state;//状态寄存器wirez;parameterIDLE=3'd0,A=3'd1,B=3'd2,C=3'd3,D=3'd4,E=3'd5;assignz=(state==D&&x==0)?1:0;26always@(posedgeclkornegedgerst)if(!rst)beginstate=IDLE;endelsecasex(state)IDLE:if(x==1)state=A;elsestate=IDLE;A:if(x==0)state=B;elsestate=A;B:if(x==0)state=C;elsestate=A;C:if(x==1)state=D;elsestate=IDLE;D:if(x==0)state=E;elsestate=A;E:if(x==0)state=C;elsestate=A;default:state=IDLE;endcaseendmodule27控制A/D变换器的几种方法使用单片机使用高性能嵌入式CPU(如ARM)使用DSP使用FPGA使用ASIC28ADC0809时序START是转换启动信号,高电平有效;ALE是3位通道选择地址(ADDC、ADDB、ADDA)信号的锁存信号。当模拟量送至某一输入端(如IN1或IN2等),由3位地址信号选择,而地址信号由ALE锁存;EOC是转换情况状态信号(类似于AD574的STATUS),当启动转换约100us后,EOC产生一个负脉冲,以示转换结束;在EOC的上升沿后,若使输出使能信号OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。至此ADC0809的一次转换结束。29moduleadcint(reset,d,clk,eoc,lock1,ale,start,oe,adda,q);input[7:0]d;inputreset,clk,eoc;o