有限状态机FSM在PLD中的实现分析
- 格式:pdf
- 大小:667.78 KB
- 文档页数:3
在FPGA设计中,“有限状态机”(Finite State Machine,FSM)的描述方式主要有三种方式:一段式、两段式、三段式。
一段式写法,整个状态机写到一个always块(进程)中。
在该always块中,即描述了状态转移,又描述了状态的输入和输出。
二段式写法,状态机用两个always块描述。
在其中一个always块中,采用同步方式描述状态转移;在另外一个always块中,采用组合逻辑判断状态转移条件、状态转移规律和输出。
三段式写法,状态机用三个always快描述。
第一个always块采用同步方式描述状态转移;第二个always块采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always块,利用组合或者同步逻辑描述状态输出。
‘两段式写法’相比于‘一段式写法’,优点在于将同步逻辑和组合逻辑放入两个always块中,便于理解和维护,利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线;缺点,则是当前状态的输出用组合逻辑实现,用以产生毛刺。
‘三段式写法’则弥补了‘两段式写法’的不足,其根据状态转移规律,在上一状态根据输入条件,判断出当前状态的输出,从而在不插入额外时钟条件的情况下,实现寄存器输出。
例如,编写‘101’序列检测器的状态机程序,当检测到输入序列为101时,输出一个高电平信号。
(1)一段式写法:module seqcheck_101(clk,rst,din,dout);input clk;//clock signalinput rst;//reset signalinput din;//data inoutput reg dout;//data outparameter idle=3'b000,one=3'b001,two=3'b010,three=3'b100;reg [2:0] state;//fsmalways @(posedge clk)beginif(!rst)begindout<=1'b0;state<=idle;endelsebegincase(state)idle:beginif(din)beginstate<=one;dout<=1'b0;endelsebeginstate<=idle;dout<=1'b0;endendone:beginif(din)beginstate<=one;dout<=1'b0;endelsebeginstate<=two;dout<=1'b0;endendtwo:beginif(din)beginstate<=three;dout<=1'b1;endelsebeginstate<=idle;dout<=1'b0;endendthree:beginif(din)beginstate<=one;dout<=1'b0;endelsebeginstate<=two;dout<=1'b0;endenddefault:beginstate<=idle;dout<=1'b0;endendcaseendendendmodule(2)两段式写法module seqcheck_101(clk,rst,din,dout);input clk;//clock signalinput rst;//reset signalinput din;//data inoutput reg dout;//data outparameter idle=3'b000,one=3'b001,two=3'b010,three=3'b100; reg [2:0] c_state;reg [2:0] n_state;//sequential state transitionalways @(posedge clk)beginif(!rst)c_state<=idle;elsec_state<=n_state;end//combinational condition judgmentalways @(c_state or din)beginn_state=3'bx;case(c_state)idle:beginidle_out;//idle state outputif(din)n_state=one;elsen_state=idle;endone:beginone_out;if(din)n_state=one;elseendtwo:begintwo_out;if(din)n_state=three;elsen_state=idle;endthree:beginthree_out;if(din)n_state=one;elsen_state=two;enddefault:n_state=idle;endcaseend//output tasktask idle_out;dout=1'b0;endtasktask one_out;dout=1'b0;endtasktask two_out;dout=1'b0;endtasktask three_out;dout=1'b1;endtaskendmodule(3)三段式写法module seqcheck_101(clk,rst,din,dout);input clk;//clock signalinput rst;//reset signalinput din;//data inoutput reg dout;//data outparameter idle=3'b000,one=3'b001,two=3'b010,three=3'b100; reg [2:0] c_state;//sequential state transitionalways @(posedge clk)beginif(!rst)c_state<=idle;elsec_state<=n_state;end//combinational condition judgment always @(c_state or din)beginn_state=3'bx;case(c_state)idle:beginif(din)n_state=one;elsen_state=idle;endone:beginif(din)n_state=one;elsen_state=two;endtwo:beginif(din)n_state=three;elsen_state=idle;endthree:beginif(din)n_state=one;elsen_state=two;enddefault:n_state=idle;endcaseend//the sequential outputalways @(posedge clk)beginif(!rst)dout<=1'b0;elsebegincase(n_state)idle:dout<=1'b0;one:dout<=1'b0;two:dout<=1'b0;three:dout<=1'b1;default:dout<=1'b0;endcaseendendendmodule推荐使用三段式描述法,即利于维护,又不会产生毛刺。
面向多优化目标的有限状态机状态分配在现代计算机应用中,有限状态机被广泛应用于许多领域,例如系统硬件设计、软件开发等领域。
有限状态机通常会使用状态分配来实现状态机的预期目标。
在这篇文章中,我们将探讨如何在面向多个优化目标的情况下进行状态分配。
有限状态机(Finite State Machine, FSM)是一种非常常见的模型,用于建模和分析计算机系统的行为。
它由有限个状态组成,并且可以通过事件和条件的转换而实现状态之间的切换。
在许多情况下,使用状态机可以比使用传统的编程语言更加简洁明了。
状态机可以描述复杂的系统,并在预定义的状态下执行有限的行为。
状态机的主要优点是其可以被分析和验证,这有助于提高系统的可靠性和可维护性。
在有限状态机的实现过程中,状态分配是一个至关重要的步骤。
状态分配主要是将状态编号分配到有限状态机的状态集合中的每一个状态。
代表系统状态的状态数目是有限的。
因此,状态的分配需要考虑多种约束条件,例如状态的数量、硬件资源的使用、状态转移的效率等。
在本文中,我们将讨论如何在面向多个优化目标的情况下进行状态分配。
首先,我们需要了解状态分配过程中遇到的各种约束条件。
为了实现状态分配的最佳效果,我们必须考虑以下约束条件:1.状态数量:在状态分配过程中,我们需要确定状态的总数。
如果状态的数量过多,可能会占用过多的硬件资源和能耗。
另一方面,状态数量过少可能会限制状态机的功能,导致无法满足预期目标。
2.状态转移的路径数量:在状态分配过程中,我们还需要考虑状态转移路径的数量。
状态转移路径的数量会影响整个系统的执行速度和效率。
因此,如果状态机的状态转移路径数量过多,则可能会导致系统性能下降。
3.状态分配的可行性:状态分配的可行性指的是我们是否可以实现分配的状态。
在实践中,一些状态分配可能会限制可用的资源。
因此,如果我们不能实现特定的状态分配,则我们可能需要重新考虑其他状态分配,以实现所需的系统功能。
4.状态的复杂性:状态的复杂性是指状态机实现过程中所使用的硬件资源和能耗的复杂性。
有限状态机(FSM)设计利用VHDL设计的许多实用逻辑系统中,有许多是可以利用有限状态机的设计方案来描述和实现的。
无论与基于VHDL的其它设计方案相比,还是与可完成相似功能的CPU相比,状态机都有其难以逾越的优越性。
它主要表现在以下几方面:由于状态机的结构模式相对简单,设计方案相对固定,特别是可以定义符号化枚举类型的状态,这一切都为VHDL综合器尽可能发挥其强大的优化功能提供了有利条件。
而且性能良好的综合器都具备许多可控或不可控的专门用于优化状态机的功能。
状态机容易构成性能良好的同步时序逻辑模块,这对于对付大规模逻辑电路设计中令人深感棘手的竞争冒险现象无疑是一个上佳的选择,加之综合器对状态机的特有的优化能,使得状态机解决方案的优越性更为突出。
状态机的VHDL设计程序层次分明,结构清晰,易读易懂,在排错、修改和模块移植方面,初学者特别容易掌握。
在高速运算和控制方面,状态机更有其巨大的优势。
由于在VHDL中,一个状态机可以由多个进程构成,一个结构体中可以包含多个状态机,而一个单独的状态机(或多个并行运行的状态机)以顺序方式的所能完成的运算和控制方面的工作与一个CPU类似。
由此不难理解,一个设计实体的功能便类似于一个含有并行运行的多CPU的高性能微处理器的功能。
事实上这种多CPU的微处理器早已在通信、工控和军事等领域有了十分广泛的应用。
就运行速度而言,尽管CPU和状态机都是按照时钟节拍以顺序时序方式工作的,但CPU 是按照指令周期以逐条执行指令的方式运行的;每执行一条指令通常只能完成一项操作,而一个指令周期须由多个CPU机器周期构成,一个机器周期又由多个时钟周期构成,一个含有运算和控制的完整设计程序往往需要成百上千条指令。
相比之下,状态机状态变换周期只有一个时钟周期,而且由于在每一状态中状态机可以完成许多并行的运算和控制操作,所以一个完整的控制程序,即使由多个并行的状态机构成,其状态数也是十分有限的。
LuaFSM有限状态机的实现最近做项⽬,因为要将游戏的代码基本全部改成lua的,对c#层⾯的东西基本只要unity的⽣命周期就可以了。
刚开始接触lua,⼼痒痒,决定上⽹买了《Lua游戏AI开发指南》看看,决定实现⼀个fsm以便于在项⽬中使⽤。
在这⾥贴出代码,其实代码都是直接抄这本书的。
建议直接买书看,对于不想买书⼜想实现lua的状态机的可以直接拿下⾯的代码使⽤就可以了。
1 Action = {}23 Action.Status = {4 RUNNING = "RUNNING",5 TERMINATED = "TERMINATED",6 UNINIIALIZED = "UNINIIALIZED"7 }89 Action.Type = "Action"101112function Action.new(name,initializeFunction,updateFunction,cleanUpFunction,userData)1314local action = {}1516 action.cleanUpFunction_ = cleanUpFunction17 action.initializeFunction_ = initializeFunction18 action.updateFunction_ = updateFunction19 _ = name or""20 action.status_ = Action.Status.UNINIIALIZED21 action.type_ = Action.Type22 erData_ = userData2324 action.CleanUp = Action.CleanUp25 action.Initialize = Action.Initialize26 action.Update = Action.Update2728return action29end3031function Action.Initialize(self)32if self.status_ == Action.Status.UNINIIALIZED then33if self.initializeFunction_ then34 self.initializeFunction_(erData_)35end36end3738 self.status_ = Action.Status.RUNNING39end404142function Action.Update(self,deltaTimeInMillis)43if self.status_ == Action.Status.TERMINATED then44return Action.Status.TERMINATED45elseif self.status_ == Action.Status.RUNNING then46if self.updateFunction_ then47 self.status_ = self.updateFunction_(deltaTimeInMillis,erData_)4849assert(self.status_)50else51 self.status_ = Action.Status.TERMINATED52end53end5455return self.status_5657end58function Action.CleanUp(self)59if self.status_ == Action.Status.TERMINATED then60if self.cleanUpFunction_ then61 self.cleanUpFunction_(erData_)62end63end6465 self.status_ = Action.Status.UNINIIALIZED66endAction1require"Action"2--require "FiniteState"3require"FiniteStateTransition"45 FiniteState = {}67function FiniteState.new(name,action)8local state = {}9-- 状态的数据10 _ = name11 state.action_ = action1213return state14endFiniteState1 FiniteStateTransition = {}23function FiniteStateTransition.new(toStateName,evaluator)4local transition = {}56-- 状态转换条件的数据7 transition.evaluator_ = evaluator8 transition.toStateName_ = toStateName910return transition11endFiniteStateTransition1require"Action"2require"FiniteState"3require"FiniteStateTransition"45 FiniteStateMachine = {}67function FiniteStateMachine.new(userData)8local fsm = {}910-- 状态机的数据11 fsm.currentState_ = nil12 fsm.states_ = {}13 fsm.transition_ = {}14 erData_ = userData1516 fsm.AddState = FiniteStateMachine.AddState17 fsm.AddTransition = FiniteStateMachine.AddTransition18 fsm.ContainState = FiniteStateMachine.ContainState19 fsm.ContainTransition = FiniteStateMachine.ContainTransition20 fsm.GetCurrentStateName = FiniteStateMachine.GetCurrentStateName21 fsm.GetCurrentStateStatus = FiniteStateMachine.GetCurrentStateStatus22 fsm.SetState = FiniteStateMachine.SetState23 fsm.Update = FiniteStateMachine.Update2425return fsm26end272829function FiniteStateMachine.ContainState(self,stateName)30return self.states_[stateName] ~= nil31end3233function FiniteStateMachine.ContainTransition(self,fromStateName,toStateName) 34return self.transition_[fromStateName] ~= nil and35 self.transition_[fromStateName][toStateName] ~= nil36end3738function FiniteStateMachine.GetCurrentStateName(self)39if self.currentState_ then40return self.currentState_.name_41end42end4344function FiniteStateMachine.GetCurrentStateStatus(self)45if self.currentState_ then46return self.currentState_.action_.status_47end48end495051function FiniteStateMachine.SetState(self,stateName)52if self:ContainState(stateName) then53if self.currentState_ then54 self.currentState_.action_:CleanUp()55end5657 self.currentState_ = self.states_[stateName]58 self.currentState_.action_:Initialize()59end60end61function FiniteStateMachine.AddState(self,name,action)62 self.states_[name] = FiniteState.new(name,action)63end6465function FiniteStateMachine.AddTransition(self,fromStateName,toStateName,evaluator)66if self:ContainState(fromStateName) and67 self:ContainState(toStateName) then6869if self.transition_[fromStateName] == nil then70 self.transition_[fromStateName] = {}71end7273table.insert(74 self.transition_[fromStateName],75 FiniteStateTransition.new(toStateName,evaluator)76 )7778end79end80local function EvaluateTransitions(self,transitions)81for index = 1 , #transitions do82if transitions[index].evaluator_(erData_) then83return transitions[index].toStateName_;84end85end86end87function FiniteStateMachine.Update(self,deltaTimeInMillis)88if self.currentState_ then89local status = self:GetCurrentStateStatus()9091if status == Action.Status.RUNNING then92 self.currentState_.action_:Update(deltaTimeInMillis)93elseif status == Action.Status.TERMINATED then94local toStateName = EvaluateTransitions(self,self.transition_[self.currentState_.name_]) 9596if self.states_[toStateName] ~= nil then97 self.currentState_.action_:CleanUp()98 self.currentState_ = self.states_[toStateName]99 self.currentState_.action_:Initialize()100end101end102end103endFiniteStateMachine下⾯是测试代码1 timer = 023function SoldierActions_IdleCleanUp(userData)4print("SoldierActions_IdleCleanUp data is "erData)5 timer = 06end78function SoldierActions_IdleInitialize(userData)9print("SoldierActions_IdleInitialize data is "erData)10 timer = 011end1213function SoldierActions_IdleUpdate(deltaTimeInMillis,userData)14print("SoldierActions_IdleUpdate data is "erData)15 timer = (timer + 1)16if timer > 3then17return Action.Status.TERMINATED18end1920return Action.Status.RUNNING21end222324function SoldierActions_DieCleanUp(userData)25print("SoldierActions_DieCleanUp data is "erData)26 timer = 027end2829function SoldierActions_DieInitialize(userData)30print("SoldierActions_DieInitialize data is "erData)31 timer = 032end3334function SoldierActions_DieUpdate(deltaTimeInMillis,userData)35print("SoldierActions_DieUpdate data is "erData)36 timer = (timer + 1)37if timer > 3then38return Action.Status.TERMINATED39end4041return Action.Status.RUNNING42endSoldierActions1function SoldierEvaluators_True(userData)2print("SoldierEvaluators_True data is "erData)3return true4end56function SoldierEvaluators_False(userData)7print("SoldierEvaluators_True data is "erData)8return false9endSoldierEvaluators1require"SoldierActions"2require"FiniteStateMachine"3require"SoldierEvaluators"45local function IdleAction(userData)6return Action.new(7"idle",8 SoldierActions_IdleInitialize,9 SoldierActions_IdleUpdate,10 SoldierActions_IdleCleanUp,11 userData12 )13end141516local function DieAction(userData)17return Action.new(18"die",19 SoldierActions_DieInitialize,20 SoldierActions_DieUpdate,21 SoldierActions_DieCleanUp,22 userData23 )24end2526function SoldierLogic_FiniteStateMachine(userData)27local fsm = FiniteStateMachine.new(userData)28 fsm:AddState("idle",IdleAction(userData))29 fsm:AddState("die", DieAction(userData))3031 fsm:AddTransition("idle","die",SoldierEvaluators_True)32 fsm:AddTransition("die","idle",SoldierEvaluators_True)3334 fsm:SetState('idle')3536return fsm37endSoldierLogic基本就是这样,挺喜欢这个状态机的。
一填空题:1.解释英文含义:HDL(硬件描述语言)、ASCⅡ(基于拉丁字母的一套电脑编码系统)、EDA(电子设计自动化)、FSM(有限状态机)、CPLD(复杂的可编程逻辑器件)、FPGA(现场可编程门阵列)2.一个模块的组成部分:模块名、端口设置、内部结点信息、功能说明3.实验:a.了解后缀名:sof“.sof”配置文件是由下载电缆将其下载到FPGA中的pof “.pof”配置文件是存放在配置器件里的gdf 地理数据文件vpdf 图文多媒体文件另注:仿真文件:vwf,图形文件:bdf,文本文件:VHD,工程文件:qpfb.设计步骤:1新建文件夹,新建工程2文本输入、编译、仿真3管脚设定4全编译5下载c .2个可编程芯片:CPLD(基于逻辑门)FDGA(基于查找表)d.HDL的数据类型:二进制、八进制、十进制、十六进制e.状体机分类:Moore状态机(异步):输出只和状态有关而与输入无关,即输入变量改变,输出变量不会立即改变。
Mealy状态机(同步):输出不仅和状态有关而且和输入有关系f.循环语句(4种):repeat while for foreverg.块语句:支持顺序块{begin end} 和并列块{fork join}h.变量的位宽;赋值i.过程赋值:阻塞(顺序执行)与非阻塞(非顺序执行)的区别与特点(起点都一样)j.子程序:任务和函数k.分频器的程序:加法计数器的程序的两个ALW AYSl.模块的基本组成:四个部分,并非每个都必须模块名、端口设置、内部结点信息、功能说明二编程1循坏语句的编程(作业中的两道)P11213.使用while循环设计一个时钟信号发生器。
时钟信号的初值为0,周期为10个时间单位。
module clk_gen;integer i;reg clk;initialbegini=0;clk=0;while (i>=0)begin$display ("i=%d",i);#5 clk=~clk;i = i +1;endendendmodule14.使用for循环对一个长度为1024(地址从0到1023)、位宽为4的寄存器类型数组cache_var进行初始化,把所有单元都设置为0。
eda试题及答案verilog1. 请解释Verilog中的阻塞赋值和非阻塞赋值的区别。
答案:在Verilog中,阻塞赋值使用`=`操作符,表示在赋值时会立即执行,并且赋值操作会阻塞后续语句的执行,直到当前赋值完成。
而非阻塞赋值使用`<=`操作符,表示赋值操作会在当前时间单位的末尾执行,不会阻塞后续语句的执行,允许并行执行。
2. 描述Verilog中模块的实例化过程。
答案:在Verilog中,模块的实例化是通过使用模块名后跟实例名和连接端口的列表来完成的。
实例化过程包括指定模块名、实例名以及将端口连接到适当的信号或参数上。
例如:```verilogmodule my_module(a, b, c);output a, c;input b;// ...endmodule// 实例化my_module instance_name(.out1(a), .out2(c), .in(b));```3. 列出Verilog中的基本数据类型。
答案:Verilog中的基本数据类型包括:- 线网类型(wire)- 寄存器类型(reg)- 实数类型(real)- 整型(integer)- 时间类型(time)- 字符串类型(string)4. 说明Verilog中如何使用条件语句。
答案:在Verilog中,可以使用`if`、`case`和`if-else`等条件语句来实现条件控制。
例如,使用`if`语句:```verilogif (condition) begin// 条件为真时执行的代码end else begin// 条件为假时执行的代码end```5. 解释Verilog中的always块的作用。
答案:Verilog中的always块用于描述硬件的时序逻辑和组合逻辑。
always块可以是时序的(使用时钟信号触发),也可以是非时序的(不依赖于时钟信号)。
时序always块通常用于描述寄存器行为,而非时序always块用于描述组合逻辑。
二线制I2C CMOS 串行EEPROM 的FPGA设计姓名:钱大成学号:080230114院系:物理院电子系2011年1月1日一、课程设计摘要:(1)背景知识:A、基本介绍:二线制I2C CMOS 串行EEPROM AT24C02/4/8/16 是一种采用CMOS 工艺制成的串行可用电擦除可编程只读存储器。
B、I2C (Inter Integrated Circuit)总线特征介绍:I2C 双向二线制串行总线协议定义如下:只有在总线处于“非忙”状态时,数据传输才能被初始化。
在数据传输期间,只要时钟线为高电平,数据线都必须保持稳定,否则数据线上的任何变化都被当作“启动”或“停止”信号。
图1 是被定义的总线状态。
①总线非忙状态(A 段)数据线SDA 和时钟线 SCL 都保持高电平。
②启动数据传输(B 段)当时钟线(SCL)为高电平状态时,数据线(SDA)由高电平变为低电平的下降沿被认为是“启动”信号。
只有出现“启动”信号后,其它的命令才有效。
③停止数据传输(C 段)当时钟线(SCL)为高电平状态时,数据线(SDA)由低电平变为高电平的上升沿被认为是“停止”信号。
随着“停在”信号出现,所有的外部操作都结束。
④数据有效(D 段)在出现“启动”信号以后,在时钟线(SCL)为高电平状态时数据线是稳定的,这时数据线的状态就要传送的数据。
数据线(SDA)上的数据的改变必须在时钟线为低电平期间完成,每位数据占用一个时钟脉冲。
每个数传输都是由“启动”信号开始,结束于“停止”信号。
⑤应答信号每个正在接收数据的EEPROM 在接到一个字节的数据后,通常需要发出一个应答信号。
而每个正在发送数据的EEPROM 在发出一个字节的数据后,通常需要接收一个应答信号。
EEPROM 读写控制器必须产生一个与这个应答位相联系的额外的时钟脉冲。
在EEPROM 的读操作中,EEPROM 读写控制器对EEPROM 完成的最后一个字节不产生应答位,但是应该给EEPROM 一个结束信号。
一、选择题:(20分)1.大规模可编程器件主要有FPGA FPGA、、CPLD 两类,下列对CPLD 结构与工作原理的描述中,正确的是:确的是:_________D D __A. CPLD 是基于查找表结构的可编程逻辑器件是基于查找表结构的可编程逻辑器件B. CPLD 即是现场可编程逻辑器件的英文简称即是现场可编程逻辑器件的英文简称C. 早期的CPLD 是从FPGA 的结构扩展而来的结构扩展而来D. 在Xilinx 公司生产的器件中,公司生产的器件中,XC9500XC9500系列属CPLD 结构结构2. 基于VHDL 设计的仿真包括有①门级时序仿真、②行为仿真、③功能仿真和④前端功能仿真这四种,按照自顶向下的设计流程,其先后顺序应该是:__________________DD A .①②③④.①②③④ B.B.②①④③②①④③②①④③ C .④③②①.④③②① D .②④③①.②④③① 3. IP 核在EDA 技术和开发中具有十分重要的地位,技术和开发中具有十分重要的地位,IP IP 分软IP IP、固、固IP IP、硬、硬IP IP;下列所描述;下列所描述的IP 核中,对于固IP 的正确描述为:的正确描述为:______________________________D DA .提供用VHDL 等硬件描述语言描述的功能块,但不涉及实现该功能块的具体电路等硬件描述语言描述的功能块,但不涉及实现该功能块的具体电路B .提供设计的最总产品——模型库.提供设计的最总产品——模型库C .以可执行文件的形式提交用户,完成了综合的功能块.以可执行文件的形式提交用户,完成了综合的功能块D .都不是.都不是4. 下面对利用原理图输入设计方法进行数字电路系统设计,哪一种说法是正确的:____________________B BA .原理图输入设计方法直观便捷,很适合完成较大规模的电路系统设计.原理图输入设计方法直观便捷,很适合完成较大规模的电路系统设计B .原理图输入设计方法一般是一种自底向上的设计方法.原理图输入设计方法一般是一种自底向上的设计方法C .原理图输入设计方法无法对电路进行功能描述.原理图输入设计方法无法对电路进行功能描述D .原理图输入设计方法不适合进行层次化设计.原理图输入设计方法不适合进行层次化设计5. 在VHDL 语言中,下列对进程(语言中,下列对进程(PROCESS PROCESS PROCESS)语句的语句结构及语法规则的描述中,不正确)语句的语句结构及语法规则的描述中,不正确的是:______________DD A .PROCESS 为一无限循环语句为一无限循环语句B .敏感信号发生更新时启动进程,执行完成后,等待下一次进程启动.敏感信号发生更新时启动进程,执行完成后,等待下一次进程启动C .当前进程中声明的变量不可用于其他进程.当前进程中声明的变量不可用于其他进程D .进程由说明语句部分、并行语句部分和敏感信号参数表三部分组成.进程由说明语句部分、并行语句部分和敏感信号参数表三部分组成 6. 对于信号和变量的说法,哪一个是不正确的:__________________A A A .信号用于作为进程中局部数据存储单元.信号用于作为进程中局部数据存储单元 B .变量的赋值是立即完成的.变量的赋值是立即完成的C .信号在整个结构体内的任何地方都能适用.信号在整个结构体内的任何地方都能适用D .变量和信号的赋值符号不一样.变量和信号的赋值符号不一样7. 下列状态机的状态编码,_________方式有“输出速度快、难以有效控制非法状态出现”这个特点。
研究设计 电 子 测 量 技 术 EL ECTRON IC M EASU REM EN T TECHNOLO GY第30卷第10期2007年10月 有限状态机FSM 在PLD 中的实现分析3何永泰(云南楚雄师范学院物理与电子科学系 楚雄 675000)摘 要:随着EDA 技术的发展,利用V HDL 语言描述有限状态机(FSM ),得到广泛应用研究。
本文通过举例,利用V HDL 语言描述了不同模式的有限状态机,分析了有限状态机在PLD 中综合的特点。
同时,本文中对不同描述风格的有限状态机在PLD EMP7032中综合的特性进行了比较分析。
可以看出,不同的模式、不同的描述风格,对有限状态机的特性具有较大的影响。
这一结果,为在实际的设计中,对有限状态机的V HDL 语言设计的优化提供了有效的参考依据。
关键词:有限状态机(FSM );可编程逻辑器件;V HDL 语言中图分类号:TP331.2 文献标识码:AAnalyzed realization of f inite state machine on programmable logic deviceHe Y ongtai(Depart ment of Physics and Electron Science ,Chuxiong Normal University ,Chuxiong 675000)Abstract :With developing of EDA technique ,using V HDL language describes FSM is in broad use.Different pattern of FSM were described through V HDL language in this paper.We also analyzed characteristic of synthesis of FSM on PLD by giving an example in the paper.At the same time ,the different characteristic in different description style of FSM synthesized on the EMP7032was paring results show that different patter ,different description all contributes to the characteristic of FSM ,which provide us a solid reference basis for the V HDL language optimization for FSM.K eyw ords :finite state machine ;programmable logic device (PLD );V HDL language 3基金项目:楚雄师范学院院级自然科学基金项目(05-Y J RC01)0 引 言目前,随着PLD 技术的发展,以可编程逻辑器件为载体,以V HDL 语言为描述方式,以相应的集成开发环境为开发工具的现代数字系统设计方法,正在取代传统的数字系统设计方法。
有限状态机(finite state machine ,FSM )作为时序逻辑电路的主要表示方式,其V HDL 语言的描述风格和在可编程逻辑器件(PLD )综合的特点得到越来越广泛的研究。
本文从有限状态机的模式及V HDL 描述风格两方面入手,分析不同模式不同描述风格状态机对PLD 资源的占用及其运行速度等方面的影响,结果表明PLD 的结构特点非常适合于实现有限状态机FSM ,为利用V HDL 语言设计有限状态机及在PLD 中综合FSM 提供了依据。
1 有限状态机的模式及特点1.1 有限状态机的模式一个限状态机是一个5元函数M =(X ,Y ,S ,f ,g ),其中X 为输入信号变量;Y 为输出信号变量;S 为状态;f 为状态转换函数,表示由输入信号变量X 和当前状态S 决定下一个状态即:X Y →S ;g 为输出函数,表示由输入信号变量X 和状态S 决定状态机的输出变量Y 即:X S →Y 。
根据有限状态机的输出Y 与当前状态和当前输入的关系,可以将有限状态机分为莫尔(Moore )型和米勒(Mealy )型2类。
Moore 状态机的输出只与有限状态机的当前状态有关,与输入信号的当前值无关,输入对输出的影响要到下一个时钟周期才能反映出来。
其行为描述可用式(1)表示:S n +1=f (X n ,S n )Y n =g (S n )(1)Mealy 有限状态机的输出与输入信号的当前值有关,其行为描述可用方程(2)表示:S n +1=f (X n ,S n )Y n =g (X n ,S n )(2)Mealy 有限状态机输入信号可能在一个时钟周期内任・4・ 何永泰:有限状态机FSM 在PLD 中的实现分析第10期意时刻变化,这使得Mealy 有限状态机对输入的影响发生在当前时钟周期,比Moore 有限状态机对输入信号的响应要早一个时钟周期。
例如,一个空调控制系统的状态转换如图1所示,利用V HDL 语言描述的Moore 型有限状态机和Mealy 型空调控制系统,在MAXPL USII 中时序仿真结果如图2(a )、2(b )所示。
图1 空调控制系统的状态转换图图2 空调控制系统状态机时序仿真图同时,根据有限状态机状态编码方式的不同,可将状态机分为二进制编码和一位有效(one 2hot )编码两种。
二进制编码,即将状态依次编码为顺序的二进制数,它是最紧密的编码,优点在于它使用状态向量的位数最少。
例如对于8个状态,只需要3位二进制数来进行编码。
在one 2hot 编码中,对于任何给定状态,状态向量只有1位置为1,所有其他的状态位都为0,one 2hot 编码最长,因为n 个状态就需要n 位的状态向量,one 2hot 编码的状态机最大的优势是它的速度。
莫尔(Moore )型二进制编码与one 2hot 编码的速度随状态数量变化如表1所示。
从表1中可以看出,对于同一类型的状态机,在状态数量相等的情况下,one 2hot 编码状态机的速度总比二进制编码状态机的速度快。
表1 状态编码与状态机的速度比较状态数状态机的时钟二进制编码/M Hz One 2hot 编码/M Hz3142.86172.4896.15112.351.2 有限状态机在PLD 中实现分析可编程逻辑器件(PLD )根据内部基本逻辑单元结构的不同分为两类,基本逻辑单元由与2或阵列为主构成的称为CPLD ,基本逻辑单元由查找表L U T 为主构成的称为FP GA 。
由于基本逻辑单元结构的不同,V HDL 语言设计的数字系统在两类器件中综合有所不同。
CPLD 中逻辑块L AB 的基本结构如图3所示。
主要由与2或阵列、r 个宏单元、和m 个双向口等组成。
若状态机有L 位输入,N 位输出和M 个状态,表示为X ={x 1,x 2,…,x L },Y ={y 1,y 2,…,y N }和S ={s 1,s 2,…,s M },其中,状态码长为R 位。
若状态编码采用一位有效(one 2hot )编码方式,那么,状态数M 与状态码R 相等,即:R =M 。
在CPLD 中实现状态机FSM ,必须考虑满足不等式组(3)的关系:N ≤m ・FR ≤r ・F -NL ≤d l +m ・F -N(3)在不等式组(3)中,F 表示CPLD 中逻辑块L AB 的个数,d l 为CPLD 的专用逻辑控制输入端。
不等式组(3)中,第1式表示设计的输出位数不能超过CPLD 的用户端口,第2式表示在CPLD 中必须有足够的宏单元存储状态变量,第3式表示设计中必须为输入变量留有足够的I/O 口。
对于莫尔(Moore )有限状态机,其在CPLD中的综合可分为状态转换函数的实现和输出函数的实现两步,状态转换函数的实现在于放置FSM 到CPLD 中逻辑块中的存储单元触发器中,目的在于使每一个L AB 有足够的资源实现触发器的激励函数;输出函数的实现在于分配FSM 的输出函数到CPLD 的逻辑块L AB 中,目的在于使L AB 有足够的资源实现输出函数。
图3 CPLD 中逻辑块L AB 的基本结构图・5・ 第30卷电 子 测 量 技 术2 有限状态机的描述风格及特性分析状态机的性能有多方面的因素决定,除了前面提到的状态机的不同模式、状态编码之外,在V HDL 语言描述的状态机中,根据描述风格的不同可将其分为A 、B 、C 、D 、E 5种,其对状态机的性能也会产生较大的影响。
下面以多位输出空调控制系统不同描述风格为例进行比较,其状态图如图4所示。
利用V HDL 语言描述的不同描述风格的状态机,其在MAXPL USII 中编译综合后下载到EMP7032中,对CPLD 资源的占用、运行速度等特点如表2所示。
图4 多位输出空调控制系统的状态转换图表2 不同描述风格的综合特性描述风格逻辑单元乘积项触发器时钟/M HzA19422142B 18321895C 183718142D 17459112E18412172从表2中可以看出,不同的描述风格,其在CPLD 中综合时占用资源的情况及时钟的速度各不相同。
V HDL 语言描述风格A 、E 中,宏单元中的触发器被旁路,状态输出采用组合逻辑工作方式,综合中,乘积项使用较多,触发器使用较少,状态机的时钟速度较快。
描述风格B 状态输出采用触发器工作方式,综合中,乘积项使用最少,触发器使用较多,状态机的时钟速度较低。
描述风格C 状态输出采用触发器工作方式,在V HDL 语言程序设计中状态机用一个进程实现了次态逻辑、状态寄存器及输出逻辑,通过部分加强组合逻辑功能,时钟速度较描述风格B 有了较大提高。
描述风格D 用一个进程实现次态逻辑和状态寄存器,用一个进程实现输出逻辑,在CPLD 中占用的资源最少。
在实际的设计中,选用哪一种描述方式,可根据所选用的器件的结构特点,结合各描述风格在综合时对器件资源占用的特性来选择,例如,器件为CPLD 则选择描述风格A 、E ,若器件为FP GA 则选择描述风格B 、C 。
3 结 论利用V HDL 语言描述的有限状态机,在PLD 中综合时,必须要考虑PLD 的资源(包括I/O 口)与状态机的输入变量、状态变量及输入输出变量的关系。
同时,有限状态机FSM 不同的模式、不同的状态编码及V HDL 语言不同的描述风格对状态机的性能会产生较大的影响。
利用V HDL 语言描述的有限状态机,通过状态编码及描述方式的优化,其对PLD 资源的占用可达到33%。