重迭式三段式状态机序列检测器-检测10110110
要求:序列检测器
clk | input | clock input |
---|---|---|
rst_n | input | asynchronous reset, low active |
data_in | input | serial input signal |
det_out | output | output flag |
1.当输入序列检测到10110110的时候,标志信号拉升
2.要求使用三段式序列状态机
做题第一步 -先画出状态转移图
第二步-写出状态转移表 方便写代码
初态 | 输入X=0 X=1 | 输出 |
---|---|---|
S0 :0 | S0 S1 | 0 |
S1:1 | S2 S1 | 0 |
S2:10 | S0 S3 | 0 |
S3:101 | S2 S4 | 0 |
S4:1011 | S5 S1 | 0 |
S5:10110 | S0 S6 | 0 |
S6:101101 | S2 S7 | 0 |
S7:1011011 | S8 S1 | 1 |
S8:10110110 | S0 S6 | 0 |
第三步-化简状态表
第四部-状态分配
以上两步由于笔者不会,所以没有进行化简与分配。直接写就可以完成本题目要求
注意
当序列到S8时,序列检测为 10110110 如果下一个输入信号时1 那么从我加粗的这个点开始就是101101 就是状态S6
设计文件
module seq_det(
input clk,
input rst_n,
input data_in,
output reg det_out
);
reg [3:0] state; //状态编码使用了0-8 一共9位使用4位的位宽
reg [3:0] next_state;
parameter S0=4'd0;//idle
parameter S1=4'd1;//1
parameter S2=4'd2;//10
parameter S3=4'd3;//101
parameter S4=4'd4;//1011
parameter S5=4'd5;//10110
parameter S6=4'd6;//101101
parameter S7=4'd7;//1011011
parameter S8=4'd8;//10110110
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
state<=S0;
else
state<=next_state;
end
always@(*)
case (state)
S0: if(data_in==1) next_state<=S1; else next_state<=S0;
S1: if(data_in==0) next_state<=S2; else next_state<=S1;
S2: if(data_in==1) next_state<=S3; else next_state<=S0;
S3: if(data_in==1) next_state<=S4; else next_state<=S2;
S4: if(data_in==0) next_state<=S5; else next_state<=S1;
S5: if(data_in==1) next_state<=S6; else next_state<=S0;
S6: if(data_in==1) next_state<=S7; else next_state<=S2;
S7: if(data_in==0) next_state<=S8; else next_state<=S1;
S8: if(data_in==1) next_state<=S6; else next_state<=S0;
default: next_state<=S0;
endcase
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
det_out<=1'b0;
else if(next_state==S8)//摩尔型状态机 输出和当前输入无关
det_out<=1'b1;
else
det_out<=1'b0;
end
endmodule
测试文件
`timescale 1ns/1ps`
module tb_seq_det();`
reg clk;`
reg rst_n;`
reg data_in;`
wire det_out;`
always #10 clk=~clk;`
initial begin`
clk=1;`
rst_n=0;`
data_in=0;`
#21 rst_n=1;
data_in=1;
#20 data_in=0;
#20 data_in=1;
#40 data_in=0;
#20 data_in=1;
#40 data_in=0;
#20 data_in=1;
#40 data_in=0;
#20 data_in=1;
end
seq_det tb_seq_det(
.clk (clk ),
.rst_n (rst_n ),
.data_in (data_in ),
.det_out (det_out )
);//括号里面的时测试文件接口 外面的是设计文件接口
endmodule