描述
请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。
模块的接口信号图如下:
模块的时序图如下:
请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
输出描述:
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
简析
序列检测问题可以用移位寄存器,也可以使用状态机。
移位寄存器方法比较简单。设置一个和序列等长的寄存器,每个时钟都将输入移入寄存器的最低位,并判断寄存器中的值是否与序列相同。
状态机方法较为麻烦些。设置若干个状态(一般是序列长度+1个状态),然后每个时钟根据新的输入以及当前状态判断下一状态。
移位寄存器
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[7:0] a_r;
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
a_r<='b0;
end
else begin
a_r<={a_r[6:0],a};
end
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
match <= 1'b0;
end
else begin
match <= a_r==8'b01110001;
end
end
endmodule
状态机
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
parameter ZERO=0, ONE=1, TWO=2, THREE=3, FOUR=4, FIVE=5, SIX=6, SEVEN=7, EIGHT=8;
reg [3:0] state, nstate;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
state <= ZERO;
else
state <= nstate;
end
always@(*) begin
case(state)
ZERO : nstate = a? ZERO : ONE;
ONE : nstate = a? TWO : ONE;
TWO : nstate = a? THREE: ONE;
THREE : nstate = a? FOUR : ONE;
FOUR : nstate = a? ZERO : FIVE;
FIVE : nstate = a? TWO : SIX;
SIX : nstate = a? TWO : SEVEN;
SEVEN : nstate = a? EIGHT: ONE;
EIGHT : nstate = a? THREE: ONE ;
default: nstate = ZERO;
endcase
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
match <= 0;
else
match <= state==EIGHT;
end
endmodule