1.1 简介
为了比较Mealy 状态机和Moore状态机的异同和许多书写上的注意事项,参考相关书籍,设计了一个111序列检测器,并用verilog代码实现。本文将介绍设计思路、一些小细节。并且比较了NRZ码和RZ(曼彻斯特编码)码的在Mealy 状态机和Moore状态机中的检测结果,发现Mealy 状态机在检测RZ码时候时会产生一定的毛刺。
1.2 原理介绍
用状态机书写序列检测器,可分为Mealy 状态机和Moore状态机,Mealy 状态机的输出取决于当前状态和和输入,但是Moore状态机的输出只取决于当前状态,所以这就导致了Mealy 状态机对输入响应快,Moore状态机对输入响应慢的特点,因此Mealy 状态机比Moore状态机的速度要快,并且状态更少,不过综合后的电路比较复杂,而Moore状态机的电路简单。还有一个需要注意的是Mealy 状态机的输出不是特别的稳定,由于输出可以直接被输入影响,所以不是特别的稳定。一旦输入改变,输出很可能会改变。
针对这个状态机的设计,增加了同步复位功能(高电位服务)、同步使能(高电位使能),设计了一个初始状态,
对于Mealy 状态机大致状态转换图:
对于Moore状态机大致状态转换图:
1.3 verilog代码
1.3.1 Mealy 状态机
// 设计一个mealy型111序列检测器。
// 有同步复位功能和使能信号端口
// 采用三段式写法
module detector_1111_mealy(bit_in,clk,rest,en,cout);
// ports define
input bit_in,clk,rest,en;
output cout;
reg cout;
reg [1:0] state,next_state;
// state define
parameter Idele = 2'b00;//启动和初始化状态
parameter state1 = 2'b01;//检测到0
parameter state2 = 2'b10;// 检测到1
parameter state3 = 2'b11;// 检测到11
// state transform
always @(negedge clk)begin
if(rest)
state <= Idele;
else
state <= next_state;
end
// state change
always @(*)begin
next_state = Idele;
case (state)
Idele : if((en==1)&&(bit_in==1))
next_state = state2;
else if((en ==1 )&&(bit_in==0))
next_state = state1;
else
next_state = Idele;
state1 : if(bit_in==1)
next_state = state2;
else
next_state = state1;
state2 : if(bit_in==1)
next_state = state3;
else
next_state = state1;
state3 : if(bit_in==1) // 这里可以写带复位的还是不带复位的序列检测器。
next_state = state3;
else
next_state = state1;
default: next_state = Idele;
endcase
end
// ouput
assign cout = (state==state3&&bit_in==1)? 1'b1 :1'b0;
endmodule
1.3.2 Moore 状态机
//设计一个mealy型111序列检测器。
// 有同步复位功能和使能信号端口
// 采用三段式写法
module detector_1111_moore(bit_in,clk,rest,en,cout);
// ports define
input bit_in,clk,rest,en;
output cout;
reg cout;
reg [2:0] state,next_state;
// state define
parameter Idele = 3'b000;
parameter state1 = 3'b001;
parameter state2 = 3'b010;
parameter state3 = 3'b011;
parameter state4 = 3'b100;
// state transform
always @(negedge clk)begin
if(rest)
state <= Idele;
else
state <= next_state;
end
// state change
always @(*)begin
next_state = Idele;
case(state)
Idele : if((en==1)&&(bit_in==1))
next_state = state2;
else if((en==1)&&(bit_in==0))
next_state = state1;
else
next_state = Idele;
state1: if(bit_in==1)
next_state = state2;
else
next_state = state1;
state2: if(bit_in==1)
next_state = state3;
else
next_state = state1;
state3: if(bit_in==1)
next_state = state4;
else
next_state = state1;
state4: if(bit_in==1)
next_state = state4;
else
next_state = state1;
default: next_state = Idele;
endcase
end
// ouput
assign cout = (state==state4)? 1'b1 :1'b0;
endmodule
1.3.3 testbench
// 测试模块
// NRZ码RZ码联合方针和
module detector_1111_tb();
reg D_in_NRZ,D_in_RZ,rest,clk,en;
wire Mealy_NRZ;
wire Moore_NRZ;
wire Mealy_RZ;
wire Moore_RZ;
// module
detector_1111_mealy M1_NRZ(.bit_in(D_in_NRZ),.clk(clk),.rest(rest),.en(en),.cout(Mealy_NRZ));
detector_1111_mealy M2_RZ(.bit_in(D_in_RZ),.clk(clk),.rest(rest),.en(en),.cout(Mealy_RZ));
detector_1111_moore M3_NRZ(.bit_in(D_in_NRZ),.clk(clk),.rest(rest),.en(en),.cout(Moore_NRZ));
detector_1111_moore M4_NRZ(.bit_in(D_in_RZ),.clk(clk),.rest(rest),.en(en),.cout(Moore_RZ));
initial #275 $finish;
initial begin
clk=0;
forever #10 clk= ~clk;
end
initial begin
#5 en =1;
#50 en =0;
end
initial begin
#5 rest=1;
#22 rest=0;
end
initial fork
begin
#10 D_in_NRZ =0;
#25 D_in_NRZ =1;
#80 D_in_NRZ =0;
end
begin
#135 D_in_NRZ =1;
#40 D_in_NRZ =0;
end
begin
#195 D_in_NRZ = 1'bx;
#60 D_in_NRZ = 0;
end
join
initial fork
#10 D_in_RZ =0;
#35 D_in_RZ =1;#45 D_in_RZ =0;
#55 D_in_RZ =1;#65 D_in_RZ =0;
#75 D_in_RZ =1;#85 D_in_RZ =0;
#95 D_in_RZ =1;#105 D_in_RZ =0;
#135 D_in_RZ =1;#145 D_in_RZ =0;
#155 D_in_RZ =1;#165 D_in_RZ =0;
#195 D_in_RZ =1;#250 D_in_RZ =0;
join
initial begin
`ifdef DUMP_VPD
$vcdpluson();
`endif
end
endmodule
1.4 编译结果
编译工具 VCS2016
可以看出在mealy_RZ状态机出会出现毛刺,这是由于输出跟随输入变换产生的。