题解 | #状态机-重叠序列检测#
状态机-重叠序列检测
https://www.nowcoder.com/practice/10be91c03f5a412cb26f67dbd24020a9
`timescale 1ns/1ns
module sequence_test2(
input wire clk,
input wire rst,
input wire data,
output reg flag
);
reg [2:0] current_state, next_state;
parameter IDLE = 3'd0,
S1 = 3'd1,
S10 = 3'd2,
S101 = 3'd3,
S1011 = 3'd4;
// 状态转换逻辑
always @(posedge clk or negedge rst) begin
if (!rst)
current_state <= IDLE;
else
current_state <= next_state;
end
// 状态机
always @(*) begin
next_state = current_state;
case (current_state)
IDLE: begin
if (data)
next_state = S1;
else
next_state = IDLE;
end
S1: begin
if (data)
next_state = S1;
else
next_state = S10;
end
S10: begin
if (data)
next_state = S101;
else
next_state = IDLE;
end
S101: begin
if (data)
next_state = S1011;
else
next_state = S10;
end
S1011: begin
if (data)
next_state = S1; // 重叠检测
else
next_state = S10; // 重叠检测
end
default: begin
next_state = IDLE;
end
endcase
end
// 输出逻辑
always @(posedge clk or negedge rst) begin
if (!rst) begin
flag <= 1'b0;
end else begin
if (current_state == S1011) begin
flag <= 1'b1; // 在检测到1011的下一拍输出检测有效信号
end else begin
flag <= 1'b0;
end
end
end
endmodule
状态定义和转移关系:
- IDLE:初始状态,等待第一个 1。输入 1:转移到 S1。输入 0:保持在 IDLE。
- S1:检测到第一个 1。输入 1:保持在 S1(因为可能是多个连续的 1)。输入 0:转移到 S10。
- S10:检测到 10。输入 1:转移到 S101。输入 0:转移回 IDLE(因为 00 不匹配序列)。
- S101:检测到 101。输入 1:转移到 S1011。输入 0:转移到 S10(因为 1010 可以继续匹配 10)。
- S1011:检测到 1011,在下一拍输出检测有效信号。输入 1:转移到 S1(因为 1011 后的 1 可以是下一个序列的开始)。输入 0:转移到 S10(因为 10110 可以继续匹配 10)。
