==note:==状态机里面要么所有选择都有赋值,要么最开始赋初值(nstate =cstate),否则会产生组合逻辑环。并且不能使用非阻塞赋值,否则会产生意想不到的错误,一定要规范使用阻塞和非阻塞。
FSM序列机
根据输入信号,检测序列1011;
IDLE:00001
S1:00010(1)
S2:00100(10)
S3:01000(101)
S4:10000(1011)
`timescale 1ns/1ns
//check 1011
module FSM_check
(
input clk ,
input rst_n ,
input din ,
output check_vld
);
parameter IDLE = 5'b00001;
parameter S1 = 5'b00010;
parameter S2 = 5'b00100;
parameter S3 = 5'b01000;
parameter S4 = 5'b10000;
reg [4:0] c_state ;
reg [4:0] n_state ;
//第一段:状态切换
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
c_state <= IDLE;
else
c_state <= n_state;
end
//第二段:状态切换
//组合逻辑
always @(*)
begin
if(rst_n == 1'b0)
n_state <= IDLE;
else
begin
case(c_state)
IDLE:
begin
if(din==1'b1)
n_state <= S1;
else
n_state <= IDLE;
end
S1:
begin
if(din==1'b0)
n_state <= S2;
else
n_state <= S1;
end
S2:
begin
if(din==1'b1)
n_state <= S3;
else
n_state <= IDLE;
end
S3:
begin
if(din==1'b1)
n_state <= S4;
else
n_state <= S2;
end
S4:
begin
if(din==1'b1)
n_state <= S1;
else
n_state <= S2;
end
default:
n_state <= IDLE;
endcase
end
end
//第三段:结果输出
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
check_vld <= 1'b0;
else if(n_state==S4)
check_vld <= 1'b1;
else
check_vld <= 1'b0;
end