题目描述
编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
上题出自牛客网中,本文简化了题目,即改为检测序列为0110
解题思路:
不同于常见的序列检测,要求检测重复序列,在画状态转移图时要注意,例如第一位不匹配,不应该返回到初始状态去进行第一位的判断,因为此时的输入是第二位数值,题目要求不对该数值做判断,而需要等到4个时钟周期之后,即第5位数据(第二组数值的第一位)再判断是否匹配目标序列的第一位.
状态转移图
dut和tb代码:
`timescale 1ns/1ns
module tb();
wire match, not_match;
reg clk, rst_n;
reg data_in;
sequence_detect dut(.clk(clk),
.rst_n(rst_n),
.data(data_in),
.match(match),
.not_match(not_match)
);
initial begin
clk <= 0;
forever begin
#5 clk <= ~clk;
end
end
initial begin//给出一段码流数据
#10 data_in = 0;
#10 data_in = 1;
#10 data_in = 1;
#10 data_in = 0;
#10 data_in = 0;
#10 data_in = 0;
#10 data_in = 1;
#10 data_in = 0;
#10 data_in = 1;
#10 data_in = 0;
#10 data_in = 1;
#10 data_in = 1;
#500 $stop;
$display("check finished");
end
initial begin
#5 rst_n <= 0;
#5 rst_n <= 1;
end
endmodule
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
reg[3:0] state, next_state;
parameter IDLE = 4'd0, A = 4'd1, B = 4'd2, C = 4'd3, D = 4'd4,
e0 = 4'd5, e1 = 4'd6, e2 = 4'd7, e3 = 4'd8;
always @(posedge clk or negedge rst_n)
if (!rst_n)
state <= IDLE;
else
state <= next_state;
always @(state or data)//state transition
begin
next_state = IDLE;
case(state)
IDLE: begin
if (data == 0)
next_state <= A;
else
next_state <= e0;
end
A: begin
if (data == 1)
next_state <= B;
else
next_state <= e1;
end
B: begin
if (data == 1)
next_state <= C;
else
next_state <= e2;
end
C: begin
if (data==0)
next_state <= D;
else
next_state <= e3;
end
D: begin
if (data == 0)
next_state <= A;
else
next_state <= e0;
end
e0: next_state <= e1;
e1: next_state <= e2;
e2: next_state <= e3;
e3: next_state = data? e1:A;
default: next_state <= IDLE;
endcase
end
always @(state or negedge rst_n or data) begin//logic out
if (!rst_n) begin
match <= 1'b0;
not_match <= 1'b0;
end
else if (state == D) begin
match <= 1'b1;
not_match <= 1'b0;
end
else if (state == e3) begin
not_match <= 1'b1;
match <= 1'b0;
end
else begin
not_match <= 1'b0;
match <= 1'b0;
end
end
endmodule
波形图
根据自己写的tb,得到的仿真波形如下图: