序列检测
序列检测:要求检测输入码流中的“10010”,检测到则data_out输出1,。同时需要排除重叠检测,例如:
输入:1-0-0-1-0_0-1-0-0-1-0-XXXXX
输出:0-0-0-0-1_0-0-1-0-0-1-XXXXX
输出码流中的第二个1,就是重叠输出,需要排除。
代码如下:
/*检测10010序列*/
module seqdet
(
input wire clk,
input wire rst,
input wire data_in,
output wire data_out
);
reg [2:0]state;
parameter IDLE=0;
parameter A=3'd1;
parameter B=3'd2;
parameter C=3'd3;
parameter D=3'd4;
parameter E=3'd5;
parameter F=3'd6;
parameter G=3'd7;
/*为了防止10010_010出现重叠影响输出,可以多检测几位,
当多检测出来的那几位,如果不会造成重叠影响,
则让状态按正常状态继续运行,否则引导状态进入正途*/
assign data_out=(state==D && data_in==0)?1:0;
always @(posedge clk or negedge rst) begin
if (!rst) begin
state<=IDLE;
end
else begin
case (state)
IDLE:
if (data_in==1) state<=A;/*此时检测到1,进入状态A*/
else state<=IDLE;/*此时检测到0,留在状态IDLE*/
A:
if (data_in==0) state<=B;/*此时检测到10,进入状态B*/
else state<=A;/*此时检测到状态11,相当于只检测到1,状态为A*/
B:
if (data_in==0) state<=C;/*此时检测到100,进入状态C*/
else state<=A;/*此时检测到101,相当于检测到1,状态回到A*/
C:
if (data_in==1) state<=D;/*此时检测到1001,进入状态D*/
else state<=IDLE;/*此时检测到1000,状态进入IDLE*/
D:
if (data_in==0) state<=E;/*此时检测到10010,进入状态E*/
else state<=A; /*此时检测的到了10011,状态回到A*/
E:
if (data_in==0) state<=C;/*此时检测到了100100,相当于检测到100,状态跳转到C*/
else state<=F;/*此时检测到了100101,状态可以回到A*/
F:
if (data_in==0) state<=B;/*此时检测到了1001010,相当于检测到10,可以回到B*/
else state<=G; /*此时检测到1001011,不可以进入状态A,否则引起重叠,所以进入新定义的G状态*/
G:
if (data_in==0) state<=B;/*此时检测到10010110,相当于检测到了10,可以进入B*/
else state<=A;/*此时检测到10010111,相当于检测到了111,可以进入A*/
default :state<=IDLE;
endcase
end
end
endmodule //seqdet```