题解 | #输入序列连续的序列检测#
输入序列连续的序列检测
https://www.nowcoder.com/practice/d65c2204fae944d2a6d9a3b32aa37b39
`timescale 1ns/1ns
/*一般采用 Moore 型状态机比较好;采用 Meanly 型状态机,其输出会比 Moore 型早一个周期;
因为 Meanly 型状态机的输出直接受输入影响;而 Moore 型状态机的输出只和状态相关*/
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
localparam
s0 = 8'b0000_0000,
s1 = 8'b0000_0001,
s2 = 8'b0000_0010,
s3 = 8'b0000_0100,
s4 = 8'b0000_1000,
s5 = 8'b0001_0000,
s6 = 8'b0010_0000,
s7 = 8'b0100_0000,
s8 = 8'b1000_0000;
reg [7:0] cur_st, nxt_st;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
cur_st <= s0;
else
cur_st <= nxt_st;
end
always @( *) begin
case (cur_st)
s0: begin
nxt_st = a? s0 : s1;
// match = 1'b0;
end
s1: begin
nxt_st = a? s2 : s1;
// match = 1'b0;
end
s2: begin
nxt_st = a? s3 : s1;
// match = 1'b0;
end
s3: begin
nxt_st = a? s4 : s1;
// match = 1'b0;
end
s4: begin
nxt_st = a? s0 : s5;
// match = 1'b0;
end
s5: begin
nxt_st = a? s2 : s6;
// match = 1'b0;
end
s6: begin
nxt_st = a? s2 : s7;
// match = 1'b0;
end
s7: begin
nxt_st = a? s8 : s1;
// match = 1'b0;
end
s8: begin
nxt_st = a? s0 : s1;
// match = 1'b1;
end
default: begin
nxt_st = s0;
// match = 1'b0;
end
endcase
end
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)begin
match <= 1'b0;
end
else if(cur_st==s8) begin
match <= 1'b1;
end
else begin
match <= 1'b0;
end
end
endmodule
两段式状态机不行,三段式可以。
两段式状态机中,输出比输入的变化晚一拍;
三段式状态机中,输出比输入的变化晚两拍。
这样看的话,两段式状态机完成的是Meanly型状态机的功能(我尝试过将以上状态机改为Meanly写法,少一个状态,输出逻辑要早一个周期,和两段式状态机引起的报错一样),三段式状态机则是Moore型。Meanly型输出变化比Moore型早一个周期。
这个确实也得看题目端口类型的要求,这里题目输出端口是reg类型,确实要使用时序逻辑输出才行。
查看12道真题和解析