描述
题目描述:
请编写一个序列检测模块,输入信号端口为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
解题分析
本质上和输入序列连续的序列检测,当data_valid
信号有效时,移位寄存器data_r
再进行移位即可。
本题的题目要求和Testbench有不相符的地方。题目中要求match
在序列匹配的下一个周期拉高,如上图。而Testbench则是在序列匹配的同周期拉高。下面的代码中,被注释掉的部分是符合题目要求的match
,没有注释的是符合Testbench的match
。
参考代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
reg [3:0] data_r;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
data_r <= 4'b0;
else
data_r <= data_valid? {data_r[2:0], data}: data_r;
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
match <= 0;
else
match <= data_r[2:0]==3'b011 && data==1'b0 && data_valid;
end
// always@(posedge clk or negedge rst_n) begin
// if(~rst_n)
// match <= 0;
// else
// match <= data_r==4'b0110;
// end
endmodule
方法二
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
reg [3:0] datareg;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
datareg <= 0;
end
else
begin
if(data_valid)
datareg <= {datareg[2:0],data};
else
datareg <= datareg;
end
end
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
match <= 0;
end
else
begin
if(datareg == 3'b011 && data ==0 && data_valid)
match <= 1;
else
match <= 0;
end
end
endmodule
注:解题分析来源于网友,如有侵权,请告删之。