第14章 状态机设计(state machine design)
状态机、状态模式

状态机、状态模式什么是状态机?有限状态机,英⽂翻译是 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 }状态机实现⽅法⼆:查表法状态机除了⽤状态转移图表⽰外,还可以⽤⼆维表表⽰。
状态机图(状态活动)汇总课件

已发货
收到货物[缺部分商品]
检查完[缺部分商品]
等待
收到货物[商品齐全]
取消
取消 取消
取消订单
状态图(订单处理3)
检查 do/检查商品
订单处理
收到货物[缺部分商品]
检查完[缺部分商品]
等待
检查完[商品齐全]
办理发货 do/启动发货
收到货物[商品齐全]
已发货
发货
取消 取消订单
状态图(航班预订1)
无预定
预定/已预订数+=预订数
部分预定
event 预 定 [ 预 订 数 < 空 位 数 ] event退 订 [ 退 定 数 < 已 预 订 数 ] /
取消航班
关闭
预定关闭
关闭 关闭
退订/已预订数-=退定数
预定完
预定[无空位]
状态图(航班预订3)
使用复合状态
预定中 退订[已预订人数==0]/已预订数=退定数
action)
Action 可执行的原子计算。 不可中断,其执行时间可忽略不计。
两种特殊动作:
进入动作 (entry action) 进入状态时执行的动作;Entry/ setMode(onTrack)
退出动作 (exit action)
退出状态时执行的动作;Exit /setMode(offTrack)
●例如:在烧水器的状态图中, turnOn 就是一种调用事 件,用来将开关置于“0n” 状态。
触发事件的四种类型
改变事件
● 某个指定属性值为真时,事件得到触发。 ●在对象生命周期内, 一直在计算改变事件中的属性值。
当属性值为真时,事件触发,计算停止 ●例如: when(temperature>100)/alerm()
有限状态机

可综合的设计中应注意
不使用初始化语句;不使用带有延时的描述; 不使用循环次数不确定的循环语句。
应尽量采用同步方式设计电路。
用always过程块描述组合逻辑,应在敏感 信号列表中列出块中出现的所有输入信号。
基于状态机的设计要点
3.状态编码的定义
在Verilog语言中,有两种方式可用于定义状态编码,分别用
parameter和'define语句实现,比如要为state0、state1、state2
、state3四个状态定义码字为:00、01、11、10,可采用下面
两种方式。
方式1:用parameter参数定义
采用一个always模块描述,状态编码用二进制编码:
• module fsm(clk,ina,out); input clk,ina; output out; reg out; parameter s0 = 3'b00,s1 =3'b01,s2 =3'b10,s3=3'b11; reg[0:1]state; always @ (posedge clk) begin state<=s0;out =0; case(state) s0: begin state<=(ina)?s1:s0;out=0; end s1:begin state<=(ina)?s2:s0;out=0; end s2:begin state<=(ina)?s3:s0;out=0; end s3:begin state<=(ina)?s3:s0;out=1; end endcase end endmodule
1、有限状态机
有限状态机的设计
什么是有限状态机( FSM ) FSM的种类和不同点 设计举例
图书管理系统-动态设计-状态图

提交
新办借阅证 信息显示
显示图书 信息 返回 增加
重填 新增图书
登录成功
点击新办借阅证
重填
补办借阅 点击补办借阅证 证 图书管理系 统主界面
查询
重填 旧借阅证 补办
信息
新借阅证信息 ,未还书信息
返回
点击新增图书 点击修改图书
点击图书借阅 点击图书归还
重填 图书借阅 借阅
返回 所借图书
信息
重填 提交修改
阅证信息
阅证信息
点击图书借阅
返回
点击图书归还
重填 图书借阅
借阅
所借图书 信息
返回
重填 图书归还
查询
显示借阅 信息
归还
返回 归还成功
阅读“注销”用例描述
• 用例名称:注销 • 用例描述:图书管理员离开系统 • 参与者:图书馆工作人员。 • 前置条件:已经进入系统 • 基本路径: 1. 点击“注销” 2. 提示“确认退出” 3. 点击确认,退出系统 • 备选流程: 1. 点击取消不退出系统
统主界面
证
返回 显示新办借
阅证信息
显示旧借 补办 显示新借
阅证信息
阅证信息
返回
软件工程实践
阅读“图书借阅”用例描述
• 用例名称:图书借阅 • 用例描述:图书馆工作人员输入借阅证编号和图书登
录号来完成图书借阅。 • 参与者:图书馆工作人员。 • 前置条件:图书馆工作人员点击“图书借阅” • 基本路径: • 输入借阅证编号。 • 输入图书登录号。 • 点击“借阅” • 显示当前借阅信息(书名,ISBN,借阅时间,应归还时
• 活动图:显示动作及其结果。着重描述操作(方法)实 现中所完成的工作以及用例实例或对象中的活动,它是 状态图的一个变种。
简述软件设计的两种分类方法

简述软件设计的两种分类方法介绍在软件开发过程中,软件设计是非常重要的一环。
良好的软件设计能够提高软件的可维护性、可扩展性和可重用性。
软件设计可以按照不同的角度和目标进行分类。
本文将介绍两种常见的软件设计分类方法:结构性设计和行为性设计。
结构性设计结构性设计侧重于软件的组织架构和模块划分。
它将软件系统划分为一系列相互独立的模块,每个模块负责特定的功能或任务。
结构性设计可以通过以下几个方面进行分类: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状态机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功能会被触发,状态机模块会根据预设的逻辑条件和行为来切换到相应的预警状态,并触发声音或振动等警示措施。
状态机模块的设计需要考虑各个功能之间的优先级、依赖关系和冲突情况。
它需要具备灵活性和可扩展性,以应对不同的道路情况和交通场景。
14 UML简介
界面(Interface)(第14章第1讲)
界面(Interface)就是 “操作”的集合。使用界面可 以定义出类(Class)或组件 (Component)能提供的各种服 务。利用界面能清晰地描述出 类中所有让外界看到的行为。
在UML的模型中的是用“圆 圈” 来表示“界面”的,圆圈 下方标注界面的名称,界面的 图形表示法如图。
节点(Nodes)(第14章第1讲)
节点(Nodes)就是系统运算资源的 表示元素,也视为是一种实体元素。
在UML的模型中,节点的图形表示方 法是一个立方体,节点的图形表示法如图。
行为事物(Behavioral Things)(第14章第1讲)
行为事物主要用来反映事物之 间的交互过程和状态变化。行为 事物分为交互(Interaction)和 状态机(State Machine)两种。 ① 交互(Interaction)是指对象之 间相互沟通的动作信息。交互的 图形表示法如图。
静态视图(Static Views)(第14章第1讲)
静态视图包括类图、对象图、组件图、用例图和 部署图。
类图是主要用来描述系统的静态结构的。学校信息 系统的一个类图如下。
对象图(Object Diagram)(第14章第1讲)
对象图(Object Diagram)是类图的实例,它主要 描述在某特定时刻的系统中对象与对象之间的关系。作 者和图书类图的对象图如下。
状态图(State Chat)(第14章第1讲)
状态图(State Chat)描述对象在其生 存周期中所具有的各种状态,以及根据事件 激励各种状态变化的相互关系。
状态图里面一般包括:状态和转换(动 作、事件)要素。下图是反映书店中图书的 各种状态的变化图。
顺序图(Sequence Diagram)(第14章第1讲)
状态机讲义
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)转移:指两个状态之间的关系,表示当发生指定事件且满足指定条件时,第一个状态中的对象将执行某些操作并进入第二个状态,即“触发”了转移。
将触发转移之前的状态定义为“源”状态(初始状态),而触发转移之后的状态定义为“目标”状态(次态)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第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的内部缓存器中。