题解 | #输入序列不连续的序列检测#
输入序列不连续的序列检测
https://www.nowcoder.com/practice/f96d0e94ec604592b502b0f1800ed8aa
本题目要求使用状态机。
注意以下几点:
1、题目中要求的match标志是0110中最后一位满足的下一个时钟,因此需要用时序逻辑(如下面注释的部分),测试案例中是同一个周期;所以使用下面的组合逻辑输出(没有注释的部分);
2、“当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。”关于这一点。有两种方式,一种是data_valid为低时,data无效,此时状态返回idle,另一种是返回当前状态。经过提交测试,两种都能够通过。
下面是输入无效直接返回IDLE状态:
always@(cur_state or data or data_valid)begin case(cur_state) IDLE: next_state = data_valid==0? IDLE: data? IDLE:S1; S1: next_state = data_valid==0? IDLE: data? S2: S1; S2: next_state = data_valid==0? IDLE: data? S3: S1; S3: next_state = data_valid==0? IDLE: data? IDLE: S4; S4: next_state = data_valid==0? IDLE: data? S2: S1; default:next_state = IDLE; endcase end
下面是返回当前状态:
always@(cur_state or data or data_valid)begin case(cur_state) IDLE: next_state = data_valid==0? IDLE: data? IDLE:S1; S1: next_state = data_valid==0? S1: data? S2: S1; S2: next_state = data_valid==0? S2: data? S3: S1; S3: next_state = data_valid==0? S3: data? IDLE: S4; S4: next_state = data_valid==0? IDLE: data? S2: S1; default:next_state = IDLE; endcase end
经过学习题解发现,可以使用data_valid以来控制状态的改变过程。如下:
always@(posedge clk or negedge rst_n)begin if(~rst_n) cur_state <= IDLE; else if (data_valid==0) cur_state <= IDLE; else cur_state <= next_state; end
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input data, input data_valid, output reg match ); parameter IDLE=0, S1=1, S2=2, S3=3, S4=4; reg [3:0] cur_state, next_state; always@(posedge clk or negedge rst_n)begin if(~rst_n) cur_state <= IDLE; else cur_state <= next_state; end always@(cur_state or data or data_valid)begin case(cur_state) IDLE: next_state = data_valid==0? IDLE: data? IDLE:S1; S1: next_state = data_valid==0? IDLE: data? S2: S1; S2: next_state = data_valid==0? IDLE: data? S3: S1; S3: next_state = data_valid==0? IDLE: data? IDLE: S4; S4: next_state = data_valid==0? IDLE: data? S2: S1; default:next_state = IDLE; endcase end always@(*)begin match <= cur_state==S4? 1:0; end // always@(posedge clk or negedge rst_n)begin // if(~rst_n) // match <= 0; // else // match <= cur_state==S4? 1:0; // end endmodule