题解 | #输入序列连续的序列检测#
输入序列连续的序列检测
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类型,确实要使用时序逻辑输出才行。