本文设计了一个“101101”序列检测器,分别采用mealy型状态机和moore型状态机进行了设计。
Moore型状态机:输出只由当前状态决定,即次态=f(现状,输入),输出=f(现状);
Mealy型状态机:输出不但与当前状态有关,还与当前输入值有关,即次态=f(现状,输入),输出=f(现状,输入);
本文引用自:https://blog.csdn.net/llxxyy507/article/details/83751999
Mealy型状态机设计
“101101”序列检测器的状态输出表如下:
左边的表为mealy型的状态输出表,但含有冗余状态,从右边的表的灰色部分可以看出,这几个状态可以合并为一个状态,从而完成状态化简。
化简后的状态输出表如上表所示,对6个状态分别进行命名。然后根据状态输出表可以写出“101101”序列检测器的的HDL代码(verilog)。也可以再画出状态图然后在写HDL代码。
module seq_detector_mealy #(parameter IDLE = 6'b00_0001,
S1 = 6'b00_0010,
S10 = 6'b00_0100,
S101 = 6'b00_1000,
S1011 = 6'b01_0000,
S10110 = 6'b10_0000)
(
input clk,
input rst_n,
input seq,
output reg out
);
reg [5:0] state;
always @(posedge clk ,negedge rst_n)
if ( !rst_n ) begin
state <= IDLE;
out <= 0;
end
else
case (state)
IDLE : if (seq == 0) begin
state <= IDLE;
out <= 0;
end
else begin
state <= S1;
out <= 0;
end
S1 : if (seq == 0) begin
state <= S10;
out <= 0;
end
else begin
state <= S1;
out <= 0;
end
S10 : if (seq == 0) begin
state <= IDLE;
out <= 0;
end
else begin
state <= S101;
out <= 0;
end
S101 : if (seq == 0) begin
state <= S10;
out <= 0;
end
else begin
state <= S1011;
out <= 0;
end
S1011 : if (seq == 0) begin
state <= S10110;
out <= 0;
end
else begin
state <= S1;
out <= 0;
end
S10110 : if (seq == 0) begin
state <= IDLE;
out <= 0;
end
else begin
state <= IDLE;
out <= 1;
end
default : begin
state <= IDLE;
out <= 0;
end
endcase
endmodule
timescale.v与testbench.v如下:
`timescale 1ns/1ns
`define halfperiod 20
module t;
reg clk;
reg rst_n;
reg [31:0] data;
reg seq;
wire out;
initial begin
clk = 0;
rst_n = 1;
data = 32'b1010_1100_1011_0101_1010_1001_1011_0011;
#5 rst_n = 0;
#16 rst_n = 1;
#(`halfperiod * 100) $finish;
end
always #(`halfperiod) clk = ~clk;
always @(posedge clk)
#2 data <= {data[30:0],data[31]};
assign seq = data[31];
seq_detector_mealy U(.clk(clk), .rst_n(rst_n), .seq(seq), .out(out) );
initial begin
$vcdpluson;
end
endmodule
采用VCS进行仿真,结果如下:
由上图的结果可以看出,mealy型状态机当检测到“101101”序列时,立马输出一个“1”。
Moore型状态机设计
状态输出表如下:
左边表为初始状态输出表,右边灰色区域表示可以合并的冗余状态。状态合并并进行状态命名后的表如下:
根据状态输出表写出的HDL(verilog)代码如下,也可以画出状态输出图再写verilog代码。
module seq_detector_moore #(parameter IDLE = 7'b000_0001,
S1 = 7'b000_0010,
S10 = 7'b000_0100,
S101 = 7'b000_1000,
S1011 = 7'b001_0000,
S10110 = 7'b010_0000,
S101101 = 7'b100_0000)
(input clk,
input rst_n,
input seq,
output reg out
);
reg [6:0] state;
always @(posedge clk, negedge rst_n)
if (!rst_n) begin
state <= IDLE;
out <= 0;
end
else
case (state)
IDLE : begin
if(seq == 0)
state <= IDLE;
else
state <= S1;
out <= 0;
end
S1 : begin
if(seq == 0)
state <= S10;
else
state <= S1;
out <= 0;
end
S10 : begin
if(seq == 0)
state <= IDLE;
else
state <= S101;
out <= 0;
end
S101 : begin
if(seq == 0)
state <= S10;
else
state <= S1011;
out <= 0;
end
S1011 : begin
if(seq == 0)
state <= S10110;
else
state <= S1;
out <= 0;
end
S10110 : begin
if(seq == 0)
state <= IDLE;
else
state <= S101101;
out <= 0;
end
S101101 : begin
if(seq == 0)
state <= IDLE;
else
state <= S1;
out <= 1;
end
default : begin
state <= IDLE;
out <= 0;
end
endcase
endmodule
timescale.v与testbench.v如下:
`timescale 1ns/1ns
`define halfperiod 20
module t;
reg clk;
reg rst_n;
reg [31:0] data;
reg seq;
wire out;
initial begin
clk = 0;
rst_n = 1;
data = 32'b1010_1100_1011_0101_1010_1001_1011_0011;
#5 rst_n = 0;
#16 rst_n = 1;
#(`halfperiod * 100) $finish;
end
always #(`halfperiod) clk = ~clk;
always @(posedge clk)
#2 data <= {data[30:0],data[31]};
assign seq = data[31];
seq_detector_moore U(.clk(clk), .rst_n(rst_n), .seq(seq), .out(out) );
initial begin
$vcdpluson;
end
endmodule
采用VCS进行仿真,结果如下:
由仿真结果可以看出,当检测到“101101”序列后,moore型状态机没有立刻输出“1”,而是在下一个周期输出“1”。