题目描述:
请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match。
模块的接口信号图如下:
模块的时序图如下:
请使用状态机实现以上功能,画出状态转移图并使用Verilog HDL编写代码实现以上功能,并编写testbench验证模块的功能.
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
data:单比特信号,待检测的数据
data_valid:输入信号有效标志,当该信号为1时,表示输入信号有效
输出描述:
match:当输入信号data满足目标序列,该信号为1,其余时刻该信号为0
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
//parameter define
parameter IDLE = 6'b000_001,
S1 = 6'b000_010,
S2 = 6'b000_100,
S3 = 6'b001_000,
S4 = 6'b010_000;
//reg define
reg [5:0] cur_state ; // 定义现态
reg [5:0] next_state ; //定义次态
always @(posedge clk or negedge rst_n) begin //描述状态转移规律
if (!rst_n) begin
cur_state <= IDLE ;
end
else begin
cur_state <= next_state ;
end
end
always @ (*) begin //data_valid 的作用相当于使能的操作
case (cur_state)
IDLE : begin
if (data_valid ) begin
if (data) begin
next_state = IDLE ;
end
else begin
next_state = S1 ;
end
end
else begin
next_state = IDLE ;
end
end
S1 : begin
if (data_valid ) begin
if (data) begin
next_state = S2 ;
end
else begin
next_state = S1 ;
end
end
else begin
next_state = S1 ;
end
end
S2 : begin
if (data_valid ) begin
if (data) begin
next_state = S3 ;
end
else begin
next_state = S1 ;
end
end
else begin
next_state = S2 ;
end
end
S3 : begin
if (data_valid ) begin
if (data) begin
next_state = IDLE ;
end
else begin
next_state = S4 ;
end
end
else begin
next_state = S3 ;
end
end
S4 : begin
if (data_valid ) begin
if (data) begin
next_state = IDLE;
end
else begin
next_state = S1 ;
end
end
else begin
next_state = IDLE ;
end
end
default : next_state = IDLE ;
endcase
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
match <= 1'b0;
end
else if ( cur_state == S3) begin
match <= 1'b1 ;
end
else begin
match <= 1'b0 ;
end
end
endmodule
题解总结:解题思路是采用三段式状态机进行书写,其中该题目与别的题目不同的地方是在于信号是否有效,在进行判断时候需要考虑信号输入是否有效。所以case段应该有两种情况进行讨论。