状态机实现序列检测
设计目标:检测输入序列10010并标志
状态转移图
代码
序列检测
module FSM (
input wire clk,
input wire rst_n,
input wire data_in,
output reg find_out
);
reg [5:0]state;
parameter
IDLE = 6'b000001,
S0 = 6'b000010,
S1 = 6'b000100,
S2 = 6'b001000,
S3 = 6'b010000,
S4 = 6'b100000;
// //一段式 状态转换和输出
// always @(posedge clk or negedge rst_n) begin
// if (~rst_n) begin
// state <= IDLE;
// find_out <= 1'b0;
// end
// else case (state)
// IDLE:begin
// find_out <= 1'b0;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= IDLE;
// end
// else begin
// state <= S0;
// end
// end
// S0:begin
// find_out <= 1'b0;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S1;
// end
// else begin
// state <= S0;
// end
// end
// S1:begin
// find_out <= 1'b0;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S2;
// end
// else begin
// state <= S0;
// end
// end
// S2:begin
// find_out <= 1'b0;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= IDLE;
// end
// else begin
// state <= S3;
// end
// end
// S3:begin
// find_out <= 1'b0;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S4;
// end
// else begin
// state <= S0;
// end
// end
// S4:begin
// find_out <= 1'b1;
// if (~rst_n) begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S2;
// end
// else begin
// state <= S0;
// end
// end
// endcase
// end
// //二段式
// //状态转化
// always @(posedge clk or negedge rst_n) begin
// if (~rst_n) begin
// state <= IDLE;
// end
// else case (state)
// IDLE:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= IDLE;
// end
// else begin
// state <= S0;
// end
// end
// S0:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S1;
// end
// else begin
// state <= S0;
// end
// end
// S1:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S2;
// end
// else begin
// state <= S0;
// end
// end
// S2:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= IDLE;
// end
// else begin
// state <= S3;
// end
// end
// S3:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S4;
// end
// else begin
// state <= S0;
// end
// end
// S4:begin
// if(~rst_n)begin
// state <= IDLE;
// end
// else if (data_in == 1'b0) begin
// state <= S2;
// end
// else begin
// state <= S0;
// end
// end
// endcase
// end
// //结果输出
// always @(posedge clk or negedge rst_n) begin
// if (~rst_n) begin
// find_out <= 1'b0;
// end
// else case (state)
// IDLE:find_out <= 1'b0;
// S0:find_out <= 1'b0;
// S1:find_out <= 1'b0;
// S2:find_out <= 1'b0;
// S3:find_out <= 1'b0;
// S4:find_out <= 1'b1;
// default:find_out <= 1'b0;
// endcase
// end
//三段式
reg [5:0]current_state;
reg [5:0]next_state;
//第一段时序逻辑
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
current_state <= IDLE;
end
else begin
current_state <= next_state;
end
end
//组合逻辑表示状态转移
always @(*) begin
case (current_state)
IDLE:begin
if (~rst_n) begin
next_state = IDLE;
end
else if (data_in == 1'b0) begin
next_state = IDLE;
end
else begin
next_state = S0;
end
end
S0:begin
if (~rst_n) begin
next_state <= IDLE;
end
else if (data_in == 1'b0) begin
next_state <= S1;
end
else begin
next_state <= S0;
end
end
S1:begin
if (~rst_n) begin
next_state <= IDLE;
end
else if (data_in == 1'b0) begin
next_state <= S2;
end
else begin
next_state <= S0;
end
end
S2:begin
if (~rst_n) begin
next_state <= IDLE;
end
else if (data_in == 1'b0) begin
next_state <= IDLE;
end
else begin
next_state <= S3;
end
end
S3:begin
if (~rst_n) begin
next_state <= IDLE;
end
else if (data_in == 1'b0) begin
next_state <= S4;
end
else begin
next_state <= S0;
end
end
S4:begin
if (~rst_n) begin
next_state <= IDLE;
end
else if (data_in == 1'b0) begin
next_state <= S2;
end
else begin
next_state <= S0;
end
end
// IDLE: next_state = data_in ? S0 : IDLE;
// S0: next_state = data_in ? S0 : S1;
// S1: next_state = data_in ? S0 : S2;
// S2: next_state = data_in ? S3 : IDLE;
// S3: next_state = data_in ? S0 : S4;
// S4: next_state = data_in ? S0 : S2;
// default: next_state = IDLE;
endcase
end
//结果输出
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
find_out <= 1'b0;
end
else case (current_state)
IDLE:find_out <= 1'b0;
S0:find_out <= 1'b0;
S1:find_out <= 1'b0;
S2:find_out <= 1'b0;
S3:find_out <= 1'b0;
S4:find_out <= 1'b1;
default:find_out <= 1'b0;
endcase
end
endmodule
tb文件
`timescale 1ns/1ps
module FSM_tb ();
reg clk;
reg rst_n;
reg data_in;
wire find_out;
initial begin
clk = 1'b0;
rst_n = 1'b0;
data_in = 1'b0;
#10
rst_n = 1'b1;
end
always #10 clk = ~clk;
always #20 data_in = {$random} % 2;
FSM FSM_1(
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.find_out(find_out)
);
endmodule