moore&mealy状态机区分(附例子&代码)&三段式描述方式

您所在的位置:网站首页 蜗牛的画画法 moore&mealy状态机区分(附例子&代码)&三段式描述方式

moore&mealy状态机区分(附例子&代码)&三段式描述方式

2023-12-10 00:19| 来源: 网络整理| 查看: 265

在状态机部分,moore和mealy也算是老生常谈了吧。

什么是状态?

在这里插入图片描述 说白了就是通过时钟信号不断改变当前的状态,可能是根据输入的数据,也可能是自身发生改变(比如一些计时器),所以少不了触发器,虽然我们有功能十分多的JK,有RS,但是我们一般采用的触发器类型都是D触发器。

状态机的设计

实际电路的设计和verilog设计还不大相同。因为verilog好歹还不是那么底层,不需要自己进行搭线(除非采用结构化描述),也就是我们可以省略一些步骤。 在这里插入图片描述 好了么,基本上省了很多了,只需要将状态找出来,进行分配,然后给出状态转移情况即可。

moore和mealy的区分

在这里插入图片描述 很明显了,mealy的输出不但有当前的Q,还有input的参与,再看看moore就没有这么多事,直接受现态Q的控制。

相互转化?

说是这么说,但是不真正给一个例子分析一下,就这样口嗨很难看懂的,而看不懂就很难明白为什么两者可以相互转换。

例子:从八位拨码开关检测序列01011的存在(别问为什么都是并行输入了还需要使用状态机)

首先,我们先给出一个个的状态: (一般是默认0为S0,1为S1)

状态内容输出S000S110S2010S30100S401010S5010111

我们可以看出来,上面那组输出是只和状态有关,而和输入无关(因为根本就没有给出输入情况) 所以这个的状态分配就是moore型了 状态转换: 在这里插入图片描述 那么mealy是什么样的呢?

状态输入0/输出输入1/输出内容S0S0/0S2/00S1S0/0S1/01S2S3/0S1/001S3S0/0S4/0010S4S3/0S1/10101

可以看出,输出不但和状态有关,也看输入的内容(S4+输入1才能输出Z = 1)

我们可以发现,在Moore和mealy中,状态的个数是不同的,其实在一些情况下,两者的状态种类都是不一样的。(如自动贩卖机中,Moore是投入的总硬币价值,mealy是每次投入硬币的价值) 抓住问题的本质,才能设计出Moore和mealy型的状态。

实现

我们的例子还没完呢,我们现在只是得到了基本的状态,还没有进行分配并实现。 状态分配很简单,Si = i即可。 在实现的过程中,我们就不得不提一下三段式的问题了。 这里声明一下,因为被检测串的第一位是0,所以这里采用001状态(S1)为起始状态。(如果采用0为起始状态,会将1011检测为正确)

三段式

在数字逻辑设计中,我们知道时序电路有三个重要的方程:输入方程、驱动方程和输出方程,不论怎么叫,本质上就是:

确定触发器的输入端内容确定触发器的次态确定整体的输出。这里注意,看的是现态而不是次态!

而这三个方程我们分别使用三个always块来实现,这就是三段式。这种描述方法思路更加清晰、便于维护,并且输出变量由时序逻辑控制,不会产生毛刺现象。

接着叙述我们的题目: 利用拨码开关输入8位数,按下s0进行数据输入,使用状态机判断8位中是否存在01011字串,如果有,led灯亮;没有则熄灭。另外我们还有一个异步复位按键,将状态机状态归零并熄灭led灯。

我们先实现Moore型的

有一说一这个例子不太好,看一下三段式的写法即可,就别cv了。(其实虽然实现了,但代码不是很完美)

细节:

我们在每一个输入只能改变状态一次:我们采用按时钟周期输入的方式来解决问题;在输入结束后,我们需要保持led灯的情况,也就是要保持判断,所以在输出always块中选择如果输出为真则一直为真这样一个分支(除非是有set或者rst信号)我们需要在输入结束将state状态改为001,也就是起始状态,而我们在控制计数器开始时有一个时钟信号(该信号覆盖了整个状态转移的过程),刚好我们可以使用这个信号来实现。

输入:set、rst、时钟信号和8位拨码开关输入 输出:led灯使能信号detect_o 代码:

`timescale 1ns / 1ps module moor_top( input rst_n_i, //异步复位&状态机回到初始状态,高电平有效 input set_i, //同步使能端,高电平有效 input clk_i, input [7:0]data, output reg detect_o ); reg x=1'b0; //输入 reg [7:0]in=8'b0000_0000; //存储八位 reg [3:0]number=4'b0000; //计数器 reg [2:0]state=3'b000; //当前状态 reg if_in=1'b0; //判断是否停止计数 //当前状态的状态寄存器 always @(posedge clk_i) begin if(set_i) //有效输入 begin in


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3