1.mealy状态机和moore状态机me
状态机是硬件电路设计的常用的描述工具,也是电路设计的重要思想。很早之前我就知道mealy状态机和moore状态机,但是对两者的差别不是非常的清楚,最近在学习系列检测器的设计时对这两种状态机和一段式、三段式状态机有了更深刻的了解,在这里分享自己的见解给大家。有什么理解不准确的地方也希望大家指正。
1.1序列检测器
在介绍两种状态机之前首先先介绍一下序列检测器。
序列检测器:从一串数据流中找到需要检测的序列号。例如如下一串数据流,需要检测的序列为11010,则每一次检测到11010时序列检测器需要输出一次使能。
设计该电路就可以使用状态机来实现。接下来讲解两种状态机区别和用这两种状态机实现该电路的状态图。
1.2.mealy状态机和moore状态机区别
mealy状态机:输出由当前状态机状态和控制信号共同决定。
moore状态机:输出仅仅取决于当前的状态机状态。
下图时两种状态机的状态转移图
首先解释两种状态机的工作:
1.mealy状态机:s0状态表示一个最初状态,该状态检测到1表示序列11010的第一个1被检测到,跳转到s1,此时需要检测11010的第二个1,当在检测到第二个1时,跳转到s2,一次类推到跳转到s4,此时如果下一时刻检测到0,则表示检测到了所需要的序列,输出正确。
具体状态解释:s0:等待检测第一个需要的序列
s1:已经检测到1,等待检测到第二位1
s2:已经检测到11,等待检测第三位0
s3:已经检测到110, 等待检测第四位1
s4:已经检测到1101,等待检测第五位0
检测成功条件:状态机处于s4状态,并且下一个时刻输入的检测信号是0
2.moore状态机:s0表示一个空闲状态,该状态等待第一位1的到来,当检测到第一个1后,跳转到s1,等待检测第二位1,一次类推直到跳转到s5。
具体状态解释:s0:等待检测第一个需要的序列
s1:已经检测到1,等待检测到第二位1
s2:已经检测到11,等待检测第三位0
s3:已经检测到110, 等待检测第四位1
s4:已经检测到1101,等待检测第五位0
s5:已经检测到11010
检测成功条件:状态机处于s5状态。
在该电路中,两种状态机本质上,moore状态机是比mealy多一个s5状态,moore状态机就是通过判定是否处于该状态来判定条件是否正确,而mealy状态机则时通过s4状态以及下一个时刻的条件信号是否有效来判定条件是否正确。
2.序列检测器的verilog代码实现
2.1.mealy状态机verilog实现ssf
module sequence_11010_chack (
input clk ,
input rst_p ,
input sequence_num ,
output num_en
);
localparam s0 = 5'd0 ;
localparam s1 = 5'd1 ;
localparam s2 = 5'd2 ;
localparam s3 = 5'd4 ;
localparam s4 = 5'd8 ;
localparam s5 = 5'd16 ;
reg [ 4 : 0 ] cur_state ;
reg chack_right ;
reg [ 4 : 0 ] next_state ;
//-----------------------------------------------------------------------
//-----mealy状态机
//---三段式实现
//--序列11010检测
//-----------------------------------------------------------------------
//第一段
always @(posedge clk) begin
if(rst_p)
cur_state <= 5'd0 ;
else
cur_state <= next_state ;
end
//第二段
always @( *) begin
case(cur_state)
s0 : next_state = (sequence_num) ? s1 : s0 ;
s1 : next_state = (sequence_num) ? s2 : s0 ;
s2 : next_state = (sequence_num) ? s2 : s3 ;
s3 : next_state = (sequence_num) ? s4 : s0 ;
s4 : next_state = (sequence_num) ? s1 : s0 ;
default : next_state = s0 ;
endcase
end
//第三段
always @(posedge clk) begin
if(rst_p)
chack_right <= 1'b0 ;
else begin
case(cur_state)
s4 : chack_right <= (sequence_num) ? 1'b0 : 1'b1 ;
default : chack_right <= 1'b0 ;
endcase
end
end
assign num_en = chack_right ;
mealy状态机输出与当前状态以及输入信号有关 可以看到代码中chack_right信号是由cur_state和sequence_num共同决定的。
2.2.moore状态机的Verilog代码实现
module sequence_11010_chack (
input clk ,
input rst_p ,
input sequence_num ,
output num_en
);
localparam s0 = 5'd0 ;
localparam s1 = 5'd1 ;
localparam s2 = 5'd2 ;
localparam s3 = 5'd4 ;
localparam s4 = 5'd8 ;
localparam s5 = 5'd16 ;
reg [ 4 : 0 ] cur_state ;
reg chack_right ;
//-----------------------------------------------------------------------------
//----------Moore状态机
//---三段式
//--序列11010检测
//-----------------------------------------------------------------------------
reg [ 4 : 0 ] next_state ;
//第一段
always @(posedge clk) begin
if(rst_p)
cur_state <= 5'd0 ;
else
cur_state <= next_state ;
end
//第二段
always @( *) begin
case(cur_state)
s0 : next_state = (sequence_num) ? s1 : s0 ;
s1 : next_state = (sequence_num) ? s2 : s0 ;
s2 : next_state = (sequence_num) ? s2 : s3 ;
s3 : next_state = (sequence_num) ? s4 : s0 ;
s4 : next_state = (sequence_num) ? s2 : s5 ;
s5 : next_state = (sequence_num) ? s1 : s0 ;
default : next_state = s0 ;
endcase
end
//第三段
always @(*) begin
case(cur_state)
s5 : chack_right = 1'b1 ;
default : chack_right = 1'b0 ;
endcase
end
assign num_en = chack_right ;
moore状态机输出只与当前状态有关,从代码中表示就是输出chack_right信号只要当cur_state处于s5就输出1,反之就输出0。
2.3.仿真代码
`timescale 1ns/1ps
module sequence_11010_chack_tb;
// Parameters
//Ports
reg clk=0;
reg rst_p=1;
reg sequence_num=0;
reg [4:0] tb_data = 5'b11010;
wire num_en;
sequence_11010_chack sequence_11010_chack_inst (
.clk(clk),
.rst_p(rst_p),
.sequence_num(sequence_num),
.num_en(num_en)
);
always #5 clk = ! clk ;
initial begin
#201;
rst_p = 1'b0 ;
//1
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//2
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//3
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//4
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//5
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//6
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//7
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[3:0],tb_data[4]};
end
//移位方向改变
//1
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[0],tb_data[4:1]};
end
//2
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[0],tb_data[4:1]};
end
//3
@(posedge clk)begin
sequence_num <= tb_data[4] ;
end
@(posedge clk)begin
sequence_num <= tb_data[3] ;
end
@(posedge clk)begin
sequence_num <= tb_data[2] ;
end
@(posedge clk)begin
sequence_num <= tb_data[1] ;
end
@(posedge clk)begin
sequence_num <= tb_data[0] ;
tb_data <= {tb_data[0],tb_data[4:1]};
end
#100;
$stop;
end
endmodule
仿真结果如下:
3.Reference
本文参考了csdn、知乎上相关文章。如果存在什么问题请指正!!!文章来源:https://www.toymoban.com/news/detail-754105.html
完成工程和仿真代码如下链接免费下载:【免费】verilog序列检测器,序列11010,(mealy状态机和moore状态机)资源-CSDN文库文章来源地址https://www.toymoban.com/news/detail-754105.html
到了这里,关于【 FPGA 】序列检测器 11010 (mealy状态机,moore状态机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!