推荐答案
测试一下
题目
画出可以检测 10010串的状态图 ,并verilog实现之。(威盛)
参考答案与知识点
参考答案
状态图采用 Mealy 型有限状态机,状态定义为 S0(初始状态,未匹配任何位)、S1(匹配 '1')、S2(匹配 '10')、S3(匹配 '100')、S4(匹配 '1001')。当处于 S4 且输入为 '0' 时,输出序列检测成功信号 (flag=1),否则 flag=0。状态转移:
- S0:输入 0→S0,1→S1;
- S1:输入 0→S2,1→S1(因为已匹配 '1',后续输入 '1' 视为新序列开始);
- S2:输入 0→S3,1→S1(因为 '10' 后输入 '1',可视为新序列开始);
- S3:输入 0→S0('100' 后输入 '0',无匹配),1→S4;
- S4:输入 0→S0 且 flag=1(检测到 '10010'),输入 1→S1('1001' 后输入 '1',可视为新序列开始)。
Verilog 实现采用三段式状态机,代码如下:
module seq_detector (
input wire clk,
input wire rst_n,
input wire din,
output reg dout
);
parameter S0 = 3'd0, S1 = 3'd1, S2 = 3'd2, S3 = 3'd3, S4 = 3'd4;
reg [2:0] state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) state <= S0;
else state <= next_state;
end
always @(*) begin
next_state = state;
case (state)
S0: next_state = din ? S1 : S0;
S1: next_state = din ? S1 : S2;
S2: next_state = din ? S1 : S3;
S3: next_state = din ? S4 : S0;
S4: next_state = din ? S1 : S0;
default: next_state = S0;
endcase
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) dout <= 1'b0;
else if ((state == S4) && (din == 1'b0)) dout <= 1'b1;
else dout <= 1'b0;
end
endmodule
注意点:输出逻辑在检测到序列的最后一个时钟沿输出,即当 state==S4 且 din==0 时,在下一个时钟沿将 dout 拉高。也可采用 Moore 型,需增加状态 S5 表示匹配成功并保持输出直到复位。代码采用同步复位,状态位宽足够。易错点:状态转移需正确处理重叠情况,例如 '10010' 中检测到 '10010' 后,若后续输入 '1',应从 S0 或 S1 开始重叠。
涉及知识点
- 序列检测器状态图设计
- Mealy/Moore状态机区别
- 三段式状态机编码风格
- Verilog 时序逻辑与组合逻辑分离
- 重叠与非重叠检测处理
- 复位电路与状态初始值设定