第14章 状态机设计(state machine design)
- 格式:pdf
- 大小:981.29 KB
- 文档页数:16
状态机、状态模式什么是状态机?有限状态机,英⽂翻译是 Finite State Machine,缩写为 FSM,简称为状态机。
状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。
其中,事件也称为转移条件(Transition Condition)。
事件触发状态的转移及动作的执⾏。
不过,动作不是必须的,也可能只转移状态,不执⾏任何动作。
实现状态机的⽅法有多种,⽐较常⽤的有分⽀逻辑法、查表法、状态模式。
我们以⼀个简单的 CD 播放器为例⼦。
这个例⼦⾥⾯只有状态、事件,不包含动作简单CD播放器的按键与按键的功能按键功能[Play/Pause]播放/暂停[Stop]停⽌状态迁移图:状态机实现⽅式⼀:分⽀逻辑法它的核⼼思想是根据状态迁移图,要么先确定状态、要么先确定事件,直译代码。
⽅法分析:对于简单状态机,该法是可以接受的。
但是,对于复杂的状态机,这种实现极易漏写或错写某个状态转移;代码中充斥⼤量if-else或switch-case 分⽀判断逻辑,可读性和可维护性差。
如下就是先确定事件,然后再在事件内根据状态进⾏状态转移。
1 typedef enum {2 ST_IDLE,3 ST_PLAY,4 ST_PAUSE5 } State;67 typedef enum {8 EV_PLAY_PAUSE,9 EV_STOP10 } Event;1112 State state;1314// 初始化15void initialize() {16 state = ST_IDLE;17 }1819// play or pause20void playOrPause() {21if (state == ST_IDLE) {22 state = ST_PLAY;23 } else if (state == ST_PLAY) {24 state = ST_PAUSE;25 } else if (state == ST_PAUSE) {26 state = ST_PLAY;27 }28 }2930// stop31void stop() {32if (state == ST_PLAY || state == ST_PAUSE) {33 state = ST_IDLE;34 }35 }3637// 事件响应38void onEvent(Event ev) {39switch (ev) {40case EV_PLAY_PAUSE:41 playOrPause();42break;43case EV_STOP:44 stop();45break;46default:47break;48 }49 }状态机实现⽅法⼆:查表法状态机除了⽤状态转移图表⽰外,还可以⽤⼆维表表⽰。
简述软件设计的两种分类方法介绍在软件开发过程中,软件设计是非常重要的一环。
良好的软件设计能够提高软件的可维护性、可扩展性和可重用性。
软件设计可以按照不同的角度和目标进行分类。
本文将介绍两种常见的软件设计分类方法:结构性设计和行为性设计。
结构性设计结构性设计侧重于软件的组织架构和模块划分。
它将软件系统划分为一系列相互独立的模块,每个模块负责特定的功能或任务。
结构性设计可以通过以下几个方面进行分类:1. 面向对象设计(Object-Oriented Design)面向对象设计是一种常见的结构性设计方法。
它将软件系统的结构建模为一组对象,并定义了对象之间的关系和行为。
面向对象设计的重要特点包括封装性、继承性和多态性。
在面向对象设计中,常用的设计原则包括单一职责原则、开放封闭原则、里式替换原则等。
2. 模块化设计(Modular Design)模块化设计将软件系统划分为多个模块,每个模块都具有清晰的责任和接口。
模块化设计可以提高代码的可重用性和可维护性,同时也有利于多人协作开发。
常用的模块化设计方法包括单例模块、工厂模块、观察者模块等。
3. 分层设计(Layered Design)分层设计将软件系统划分为不同的层,每一层都负责不同的功能。
分层设计可以提高代码的可维护性和可测试性。
常见的软件分层包括界面层、应用层、服务层和数据层。
行为性设计行为性设计关注软件系统中对象的相互作用和流程控制。
它描述了系统中不同对象之间的消息传递和协作方式。
行为性设计可以通过以下几个方面进行分类:1. 状态机设计(State Machine Design)状态机设计描述了一个对象在不同状态下的行为和相应的状态转换规则。
状态机设计有利于描述复杂的对象行为,并且可以通过状态转换图清晰地表示状态之间的联系。
2. 事件驱动设计(Event-driven Design)事件驱动设计是一种基于事件和消息的编程范式。
在事件驱动设计中,对象通过发送和接收事件来实现协作和响应。
状态机图1.概述状态机图(State Machine Diagram)是用来显示状态机的图,包括简单状态、转换和嵌套的复合状态等,一个典型的状态机图如图1所示:图1. 状态机图2.基本表示符号状态机图的基本元素包括:状态、转移、事件、伪状态和复合状态。
2.1状态(State)状态是对象生命周期中的一个条件或形态。
状态由对象的属性值、与其他对象的关系以及正在执行的活动来确定。
在UML中,状态用圆角矩形和状态名表示,初始状态用实心圆表示,终止状态用牛眼表示,如图2所示:图2. 状态状态可以有一个或多个分栏,这些分栏是可选的,包括名称分栏、嵌套区域、内部转换分栏等,如图3所示:图3. 带分栏的状态状态也可用圆角矩形上带有状态名称标签的方框表示,如图4所示:图4. 带有名称标签符号的状态2.2转移(Transaction)转移表示状态之间可能的路径,可以表示外部转换(用箭头表示),也可以表示内部转换(嵌套在状态内部)。
如图5所示:图5. 转移2.3事件(Event)事件是对,在特定时间和空间上,所发生的有意义的事情。
在状态机中,事件触发转移,事件或者显示在转换之上,或显示在状态以内。
共有四种类型的事件:信号事件、调用事件、时间事件、改变事件。
信号用于对象间异步传递的信息包,它没有任何操作,只有自身携带的信息。
信号事件是通过信号来触发的事件,在UML中,信号如图6所示:图6. 信号调用事件是请求在类语境的实例上调用特定的操作,在UML中,调用事件如图7所示:图7. 调用事件时间事件用关键字after表示,说明事件被触发的临界时间。
改变事件用关键字when表示,说明将事件改变所满足的条件。
如图8所示:图8. 时间事件和改变事件2.4伪状态(Pseudo State)伪状态指在一个状态机中具有状态的形式,同时具有特殊行为的顶点。
它是一个瞬时状态,用于构造转换的细节。
当伪状态处于活动时,状态机还没有完成从运行到完成的步骤,也不会处理事件。
android状态机statemachine 使用方式及实现原理Android中的状态机(State Machine)是一种用于管理应用或系统状态的重要工具。
它可以帮助我们更清晰地组织和管理复杂的逻辑和状态转换,提高代码的可读性和可维护性。
使用方式:定义状态:首先,你需要定义状态。
状态通常是一个枚举(enum),每个枚举值代表一种状态。
定义事件:事件是导致状态转换的因素。
它们通常是一些方法或者函数,用于触发状态的转换。
状态转换:在状态机中,你需要定义不同状态之间的转换逻辑。
这通常通过重写父类的transition方法实现。
处理状态和事件:在每个状态下,你可以定义一些处理逻辑,这些逻辑会在当前状态被激活时执行。
启动状态机:最后,创建状态机的实例并启动它。
实现原理:Android的状态机基于经典的状态机理论,但为了简化开发,它提供了一些关键的抽象和工具。
抽象:Android的状态机提供了一个抽象类StateMachine,开发人员需要继承这个类来创建自己的状态机。
状态和事件:状态和事件都被抽象为类,其中状态是一个类,而事件是一个接口。
这样做的目的是允许开发者在状态和事件中添加更多的逻辑和属性。
转换逻辑:状态的转换逻辑通过重写父类的transition方法实现。
这个方法会在收到事件时被调用,并决定下一个状态是什么。
线程安全:Android的状态机是线程安全的,这意味着你可以在多个线程中同时操作状态机,而不需要担心数据一致性问题。
回调和通知:状态机提供了回调机制,允许开发者在特定状态下注册回调函数,这些函数会在状态被激活或转换时被调用。
注意事项:清晰性:使用状态机可以使复杂的逻辑和状态转换更清晰、更易于理解。
扩展性:由于状态和事件都是类,因此可以很方便地添加更多的属性和方法,提高扩展性。
线程安全:虽然Android的状态机是线程安全的,但在处理事件和回调时仍需注意线程问题。
如何设计自动驾驶系统的状态机状态机模块在(自动驾驶)系统中扮演着关键的角色,它负责管理和控制各个功能的状态转换和行为执行。
今天我们来聊聊如何设计自动驾驶系统的状态机。
0.闲谈作为自动驾驶系统(工程师),从参与项目开始,就必不可少的与状态管理模块打交道,因为状态机在系统运行的全功能周期内起管理作用。
状态机这个模块,从技术实现角度来说,并没有什么难度,在网上有很多关于FSM(Fini(te)-state machine)的介绍文章,有兴趣可以自行了解。
但如何设计得巧妙、周到、精致,却很考验设计者的底蕴与对系统的理解。
大部分的(AD)AS功能都需要状态机进行状态管理,笔者手中就有不下十几份状态机的设计文档,包括FCW/LDW/AEB/(AC)C/LKA/NOP/APA/AVP等等,设计大相径庭,但细细想来内核却大同小异。
其中NOP功能的状态跳转还是比较复杂的,涉及横向、纵向控制与功能降级等逻辑,需要长期的雕琢与迭代才能设计出符合项目要求的效果。
笔者最近也在负责APA功能的状态机设计,虽然比较简单,但还是想借此机会对状态机模块做一点总结,也是对以往工作的回顾。
1.模块概述状态机模块的主要作用是跟踪系统的当前状态,并根据特定的事件和条件进行状态转换。
它可以根据(传感器)数据、车辆状态和系统输入来判断当前功能的可用性和执行条件。
状态机模块还能够监控系统的运行情况,及时响应来自驾驶决策或用户的指令,并根据需要触发相应的功能执行。
状态机模块通过定义和维护一组状态,以及状态之间的转换条件和行为,确保系统在不同的场景和条件下正确地执行相应的功能。
例如,当(检测)到前方车辆与本车距离过近时,FCW功能会被触发,状态机模块会根据预设的逻辑条件和行为来切换到相应的预警状态,并触发声音或振动等警示措施。
状态机模块的设计需要考虑各个功能之间的优先级、依赖关系和冲突情况。
它需要具备灵活性和可扩展性,以应对不同的道路情况和交通场景。
Digital System Design12011/6/21Computer Faculty of Guangdong University of Technology大部分数字系统都可以划分为控制单元和数据单元(存储单元)两个组成部分,通常,控制单元的主体是一个状态机,它接收外部信号以及数据单元产生的状态信息,产生控制信号序列。
Digital System Design22011/6/21Computer Faculty of Guangdong University of Technology有限状态机特别适合描述那些发生有先后顺序或者有逻辑规律的事情(其实这就是状态机的本质)。
状态机的本质就是对具有逻辑顺序或时序规律事件的一种描述方法,即“逻辑顺序”和“时序规律”就是状态机所要描述的核心和强项,换言之,所有具有逻辑顺序和时序规律的事情都适合用状态机来描述。
Digital System Design32011/6/21Computer Faculty of Guangdong University of Technology1、基本概念有限状态机(Finite State Machine ,FSM )是表示实现有限个离散状态及其状态之间的转移等行为动作的数学模型。
(关注Matlab 的Stateflow )(1)状态:也叫状态变量。
在逻辑设计中,使用状态划分逻辑顺序和时序规律。
状态名称、状态编码、进入/退出操作、内部转移、子状态、延迟事件Digital System Design42011/6/21Computer Faculty of Guangdong University of Technology(2)转移:指两个状态之间的关系,表示当发生指定事件且满足指定条件时,第一个状态中的对象将执行某些操作并进入第二个状态,即“触发”了转移。
将触发转移之前的状态定义为“源”状态(初始状态),而触发转移之后的状态定义为“目标”状态(次态)。
状态机编程思路及方法状态机是一种常用的编程思路和方法,用于描述系统或对象在不同状态下的行为和转换。
它可以帮助开发人员更好地理解和设计复杂的系统,并在实际应用中提高代码的可读性和可维护性。
本文将介绍状态机的基本概念、应用场景以及实现方法,并通过示例代码来说明其具体应用。
一、状态机的基本概念状态机,又称有限状态机(Finite State Machine,FSM),是一种计算模型,用于描述系统或对象的状态和状态之间的转换。
它由一组状态、一组转换规则和一个初始状态组成。
1. 状态(State):状态是系统或对象的某种特定情况或属性,可以是一个离散的值或一个更复杂的数据结构。
在状态机中,状态用于描述系统或对象所处的不同状态,例如开机、关机、运行等。
2. 转换(Transition):转换是状态之间的切换过程。
它可以由外部事件触发,也可以由内部条件满足时自动触发。
转换可以是简单的一对一关系,也可以是复杂的多对多关系。
在状态机中,转换规则定义了从一个状态到另一个状态的条件和操作。
3. 初始状态(Initial State):初始状态是系统或对象的初始状态。
在状态机中,初始状态是状态机开始执行时所处的状态。
二、状态机的应用场景状态机广泛应用于各个领域的软件开发中,特别是在需要处理复杂逻辑和状态转换的场景下。
以下是一些常见的应用场景:1. 交通信号灯控制:交通信号灯的状态可以有红灯、黄灯和绿灯,它们之间的转换规则由交通规则和时间控制。
2. 游戏角色行为控制:游戏角色的行为可以有站立、行走、跳跃等,它们之间的转换规则由玩家输入和游戏逻辑控制。
3. 订单状态管理:订单的状态可以有待支付、已支付、待发货、已发货等,它们之间的转换规则由用户行为和系统逻辑控制。
4. 业务流程管理:业务流程的状态可以有开始、进行中、暂停、结束等,它们之间的转换规则由业务规则和用户操作控制。
三、状态机的实现方法状态机的实现方法有多种,可以使用面向对象编程、函数式编程或表驱动等方式来描述和实现状态和转换规则。
状态机的应用原理什么是状态机状态机(State Machine)是一种数学模型,用于描述一个系统中的状态和状态之间的转换。
在计算机科学领域,状态机常被用于模拟和控制复杂的系统行为。
它可以帮助我们理解和设计各种软件和硬件系统,从操作系统到网络协议,从编程语言解析器到游戏逻辑。
状态机的基本概念在状态机中,我们将系统抽象为一个集合的状态,以及在这些状态之间转换的条件和动作。
•状态(State):系统可能处于的不同情况或阶段。
每个状态具有唯一且独立的标识符。
•转换(Transition):状态之间的切换,由触发条件和执行的动作组成。
•初始状态(Initial State):系统启动时的初始状态。
•终止状态(Final State):系统到达该状态时结束。
状态机的应用场景状态机广泛应用于各种领域,例如:1.自动控制系统:状态机可用于描述和控制自动控制系统的行为,如工业自动化、机器人控制等。
2.网络协议:状态机可以描述和模拟网络协议的通信过程,如TCP/IP协议、HTTP协议等。
3.编程语言解析器:状态机可以用于编程语言解析器的词法分析和语法分析过程。
4.游戏开发:状态机常用于游戏中角色和游戏场景的状态管理。
状态机的工作原理状态机由两部分组成:状态转换图和动作。
状态转换图是状态机的核心,它由状态和状态之间的转换组成。
在状态转换图中,每个状态表示一个系统的特定情况或阶段,而状态之间的转换则表示系统在不同情况之间的过渡。
动作是状态机的执行体,它与状态转换相关联。
当系统从一个状态转换到另一个状态时,可能会触发一些动作。
动作可以是一些计算、输出、控制指令等。
动作的目的是使系统在状态转换过程中完成一些特定的操作。
状态机的基本原则设计和应用状态机时,需要遵循以下几个基本原则:1.明确状态集合:清晰定义系统可能的状态及其含义。
2.明确转换条件:确定状态之间的转换条件,即触发状态转换所需的条件。
3.明确动作:为每个状态转换定义相应的动作,确保系统在状态转换时能够执行所需的操作。
简要说明状态机的分类,以及状态机的表达方式状态机是一种抽象的数学模型,用于描述在不同状态下的行为和
转换,常用于计算机科学中控制流程和状态转换的场景。
状态机的分类:
1、有限状态机(Finite State Machine,FSM):是指状态的数
量是有限的,并且每个状态都有明确的转移条件和转移方向的状态机。
FSM通常用状态图或状态表来表示,常用于字符串匹配、语法分析等领域。
2、无限状态机(Infinite State Machine,ISM):是指状态的
数量是无限的,没有明确的转移条件和转移方向的状态机。
ISM通常用状态空间图或状态空间表达式来表示,常用于电路设计、控制系统等领域。
状态机的表达方式:
1、状态图(State Diagram):是一种用于描述状态和状态之间
转移的图形表示方法,通常由状态节点和转移边组成。
状态图可以用于描述有限状态机的行为。
2、状态表(State Table):是一种用于描述状态和转移条件的
表格表示方法,通常由状态、输入、输出和转移条件组成。
状态表可以用于描述有限状态机的行为。
3、状态空间图(State-Space Diagram):是一种用于描述状态空间中状态和状态之间转移的图形表示方法,通常由状态节点和转移边组成。
状态空间图可以用于描述无限状态机的行为。
4、状态空间表达式(State-Space Expression):是一种用于描述状态空间中状态和转移条件的数学表达式,通常由状态变量、输入变量、输出变量和转移方程组成。
状态空间表达式可以用于描述无限状态机的行为。
java statemachine设计原理状态机(StateMachine)是一种基本的设计模式,用于模拟对象的行为,包括描述该对象的所有可能状态,以及状态之间的转移条件和行为响应。
它通过定义状态和状态之间的转换来描述一个系统的行为,并通过触发事件或条件来改变状态。
在Java中,可以使用不同的方式来实现状态机,包括使用面向对象的方法、使用条件语句等。
下面将详细介绍Java状态机的设计原理和实现方式。
一、状态机设计原理1.状态(State):状态是状态机的基本元素,它定义了一个对象可能存在的所有状态。
在Java中,可以通过定义一个状态接口或者一个状态类来表示状态,并在其中定义该状态下的行为。
2.事件(Event):事件是触发状态转换的条件或者动作,它可以是内部事件(例如定时器事件、自定义事件)或者外部事件(例如用户输入)。
3.转换(Transition):转换表示状态之间的转移关系,它定义了从一个状态到另一个状态的条件和行为。
在Java中,可以使用条件语句、状态模式等方式来实现转换。
4.动作(Action):动作是在状态转换过程中执行的一系列操作,它可以包括状态切换、数据处理等。
在Java中,可以通过定义一个动作接口或者一个动作类来表示动作,并在其中实现具体的操作逻辑。
5.触发器(Trigger):触发器是用于触发状态转换的条件或者事件,它可以是一个方法调用、一个信号、一个计时器等。
在Java中,可以使用回调机制、观察者模式等方式来实现触发器。
二、状态机的实现方式在Java中,可以使用面向对象的方法来实现状态机,包括使用接口和类的方式。
下面将分别介绍这两种实现方式。
1.使用接口实现状态机使用接口来实现状态机时,可以定义一个状态接口,其中包含该状态下的行为方法,并在每个状态类中实现对应的行为逻辑。
同时,在状态类中也可以定义一个转换方法,用于根据条件或事件触发状态转换。
```java//定义状态接口public interface State {void behavior();void transition();}//实现状态类public class StateA implements State {public void behavior() {//实现状态A的行为逻辑System.out.println("State A behavior");}public void transition() {//根据条件或事件触发状态转换if (condition) {context.setState(new StateB());}}}public class StateB implements State { public void behavior() {//实现状态B的行为逻辑System.out.println("State B behavior"); }public void transition() {//根据条件或事件触发状态转换if (condition) {context.setState(new StateA());}}}//定义上下文类public class Context {private State state;public void setState(State state) { this.state = state;}public void behavior() {state.behavior();}public void transition() {state.transition();}}```使用接口实现状态机的优点是灵活性高,可以通过定义不同的状态类来扩展状态机的功能。
第14章 状态机设计(State Machine Design)讲到VHDL设计而不讲state machine,感觉上就是不太完整,我们先来看看什么是state machine,它应该是一种流程控制的设计,在有限的状态中,根据判别信号的逻辑值决定后面要进入哪一个状态,这样的讲法似乎有些抽象,我们先来看看下面的状态图。
图14-1所显示的是一个十字路口的红绿灯控制设计,在一开始时信号Reset 会被设为逻辑’0’,此时state machine会在Reset状态,一直等到信号Reset变成逻辑’1’时,state machine才会进入真正的控制状态。
在之后的三个状态中,我们各定义了一个counter,当进入Red或是之后的Green及Yellow状态时,相对的counter值即会开始递减。
当counter值递减到0时,state machine即会改变到下一个状态。
当然state machine的执行就是依照这种方式进行,但是其中仍有许多的细节是设计者所要注意的,在接下来的章节中,我们会依据实际的例子来介绍state machine的设计方式。
14-1State Machine的建立在这一节我们所举的例子是一个类似检查密码的设计,在一般办公室的门口都会有门禁管制,进门前须先输入一组四个数字的密码,当密码确认无误后门才会打开,除此之外还有更改密码的功用。
我们先来看看其状态图。
在图14-2中一共有四个状态,一开始会维持在idle状态,当要更改或是第一次输入密码时,需要按下一个特殊的“密码更改”按键,此时InpinN信号会变成逻辑’0’的状态,状态机即会进入LoadPin的状态,接着再输入四个数字的密码,密码输入完毕按下“输入”按键,状态机即回到原先的idle状态。
在另一方面,当处于平时状态,有人进入门口要输入密码前,他也必需要按下另一个特殊键“密码输入”,表示之后输入的数字是待验证的密码,此时InData 信号会变成逻辑’0’,于是状态机进入InPin的状态。
在输入四个数字之后,一个内部计数器会计数到3,这时状态机会进入CheckPin的状态。
在CheckPin的状态下会将输入值与密码做一比较,当数值相符时会在按下“输入”按键后,信号nMatch会产生一短暂的逻辑’0’,这就能让门锁打开,若数值不符时,则信号nMatch会一直维持在逻辑’1’的状态。
14-1-1程序代码的撰写接着我们来看看设计的声明,首先是使用到的1ibrary和packages的声明。
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;前两行的声明我想已经不用多做解释了。
第三行声明的原因是在后面我们会使用到std_logic_arith package中的一个function----CONV_INTEGER,第四行声明的原因是后面要做输入pin数目的计算,而这种计算只会是正值,所以要声明使用ieee.std_logic_unsigned package。
在1ibrary的声明之后,接下来的是设计接口的声明,我们来看看这个设计的entity声明。
entity PinCheck isport(InD : in std_logic_vector(3 downto 0);InPinN : in std_logic;InData : in std_logic;nMatch : out std_logic;DEnter : in std_logic;Reset : in std_logic;Clk : in std_logic);end PinCheck;在接口的信号中,InD是一4-bit的信号,为输入密码和待测密码所使用,信号InPinN平时是在逻辑’1’的状态,当要更改设计内部的密码时,会先按下“密码更改”的按键,信号InPinN就会产生一逻辑’0’的脉冲,除了产生信号InPinN 外,在按下每一个按键时都会产生一个更短的clk脉冲,提供系统参考。
若是要输入待测的密码,必须先按下“密码输入”按键,此时信号InData会产生逻辑’0’的脉冲,不论是更改密码还是输入密码,在输入四个数值后都要按下“输入”按键,此时信号DEnter会产生逻辑’0’的脉冲,信号Reset是用来重置这个设计内部大部分的计数器,但原先已输入的密码并不会被重置,惟一的输出信号nMatch 会在输入待测密码与原先存储在内部的密码相符时,产生一逻辑’0’的脉冲。
接下来所要看的是architecture声明部分所声明的信号,在此我们先声明了两个数据类型:type MState is ( idle, LoadPin, InPin, CheckPin );type PinArray is array (0 to 3 ) of std_logic_vector ( InD’range );其中MState是以枚举方式将状态机的四种状态都列出来,而PinArray是一个向量型数据类型,可以用来存储一个4组4-bit宽的数值,使用到这两种数据类型的信号有下面三个:signal PinDigit : PinArray;signal InputDigit : PinArray;signal PresentState : MState;其中PinDigit是用来存储修改密码时输入的数值的,而InputDigit则是用来存储待测试的密码,至于PresentState则是用来存储状态机目前的状态值,除了这三个信号使用到自行定义的数据类型外,还有三个使用标准数据类型的信号,分别是:signal PinCnt : integer range 0 to 4;signal InputCnt : integer range 0 to 4;signal nMatchi : std_logic;信号PinCnt及InputCnt所计数的是在修改密码及输入待测密码时,输入数字的数目,信号nMatchi是在输入待测密码时,若是待测密码与实际密码相符,此信号会变成逻辑’0’,否则会一直维持在逻辑’1’。
当内部信号声明完毕后,接下来就是我们的设计内容了,首先要看的是状态机的控制,读者可在分析程序的同时参考图14-2。
process (Reset,Clk)beginif Reset = ‘0’ thenPresentState <= idle;elsif Clk = ‘1’ and Clk’event thenCase PresentState iswhen idle =>if InPinN = ‘0’ thenPresentState <= LoadPin;elsif InData = ‘0’ thenPresentState <= InPin;end if;when LoadPin =>if DEnter = ‘0’ thenPresentState <= idle;end if;when InPin =>if InputCnt = 3 thenPresentState <= CheckPin;end if;when CheckPin =>if DEnter = ‘0’ thenPresentState <= idle;end if;when others =>PresentState <= idle;end case;end if;end process;在上面的程序中,所有的流程受两个信号控制,分别是Reset及Clk。
其中Reset信号有较高的优先权,只要当其active(逻辑’0’)之后,状态机会立刻回到idle状态,所以这是一个异步Reset的设计,当Reset信号为逻辑’1’时,状态机便会等待C1k信号的上升沿出现,我们前面曾经谈过,当每次按下一个按键时会产生两种信号。
第一种是Clk信号,其会在按下任何一个按键时,出现的一个逻辑’0’的脉冲,但其脉冲宽度会比较短。
另一个信号则是按键上所标示的功能,比如说是“密码更改”或是输入的数值,其脉冲宽度会较C1k信号的脉冲宽度来得宽,如此才能使得C1k信号上升沿所读到的一定是正确的逻辑值。
当要更改密码时,必须先要按下“输入密码”的按键,此时除了产生C1k信号的逻辑’0’脉冲外,还会产生一InPinN的信号,当状态机在Idle状态时检测到此信号,便会进入LoadPin状态。
在LoadPin状态时,要等到输入一组四个数字的密码,并且按下“输入”按键后才会再回到Idle状态。
当要输入待测的密码时,要先按下“输入密码”的按键,此时信号InData会产生一逻辑’0’的脉冲。
当状态机检测到这个信号时,会由Idle状态进入InPin状态,在这个状态下,一个内部计数器开始激活,在每次输入数值时计数器会加l,当输入4个数值后,也就是在Clk信号的上升沿检测到计数器的值为3时,状态机便会进入CheckPin状态,在checkPin状态下,状态机会等待“输入”按键被按下,按下后状态机会再回到Idle状态。
接下来我们看看两个计数器的工作方式。
process (Reset,PresentState,Clk)beginif Reset = ‘0’ or PresentState = idle thenPinCnt <= 0;InputCnt <= 0;Elsif Clk = ‘1’ and Clk’event thenif (PresentState = LoadPin and PinCnt < 4) thenPinCnt <= PinCnt+1;PinDigit(CONV_INTEGER(PinCnt)) <= InD;end if;if (PresentState = InPin and InputCnt < 4) thenInputCnt <= InputCnt+1;InputDigit(CONV_INTEGER(InputCnt) <= InD;end if;end if;end process;在Reset信号为逻辑’0’或是PresentState为Idle时,内部计数器PinCnt及InputCnt的值都会被设为0,否则在Clk信号的上升沿时,就会检测PresentState 的状态值,在上面的if语句中,若状态为LoadPin,且PinCnt的值小于4时,表示输入密码的数字还没有达到4个。
此时只要输入一个数字,PinCnt的数值便会加1,并会把输入的数字存到PinDigit数组中,由于成立的条件是计数器PinCnt的值小于4,因此当输入4个数字后,计数器PinCnt的值就已经加到4了,此时即使是再输入其他数字也不会存入PinDigit的内部缓存器中。