描述
请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
模块的接口信号图如下:
模块的时序图如下:
请使用Verilog HDL实现以上功能,要求使用状态机实现,画出状态转化图。并编写testbench验证模块的功能。
输入描述:
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
输出描述:
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
not_match:当输入信号a不满足目标序列,该信号为1,其余时刻该信号为0
解题分析
状态机
波形图
状态转移图
本程序的状态机在基本的三段式状态机上加入了计数器cnt
,并使用cnt
对状态转移进行约束,以确保正常工作时,状态机每6个周期循环一次。其中FAIL
状态仅在计数器cnt==6
时才会切换到别的状态,match
和not_match
也仅在cnt==6
时才进行更新; ZERO
为启动态,系统复位时,处于该状态。
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
parameter ZERO=0, ONE=1, TWO=2, THREE=3, FOUR=4, FIVE=5, SIX=6, FAIL=7;
reg [2:0] state, nstate;
reg [2:0] cnt;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
cnt <= 0;
else
cnt <= cnt==6? 1: cnt+1;
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
state <= ZERO;
else
state <= nstate;
end
always@(*) begin
if(~rst_n)
nstate = ZERO;
else
case(state)
ZERO : nstate = data? FAIL : ONE;
ONE : nstate = data? TWO : FAIL;
TWO : nstate = data? THREE: FAIL;
THREE: nstate = data? FOUR : FAIL;
FOUR : nstate = data? FAIL : FIVE;
FIVE : nstate = data? FAIL : SIX;
SIX : nstate = data? FAIL : ONE;
FAIL : nstate = cnt==6&&data==0? ONE: FAIL;
default: nstate = ZERO;
endcase
end
always@(*) begin
if(~rst_n) begin
match = 0;
not_match = 0;
end
else begin
match = cnt==6&&state==SIX;
not_match = cnt==6&&state==FAIL;
end
end
endmodule
移位寄存器
本题要求每6个不重叠的数为一组判断是否符合要求,所以需要在移位寄存器的基础上添加一个计数器。当计数器计数到序列长度时,再判断是否match。
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
reg [2:0] cnt;
reg [5:0] data_r;
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
cnt <= 0;
else
cnt <= cnt==5? 0: cnt+1;
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n)
data_r <= 6'b0;
else
data_r <= {data_r[4:0], data};
end
always@(posedge clk or negedge rst_n) begin
if(~rst_n) begin
match <= 1'b0;
not_match <= 1'b0;
end
else begin
match <= (cnt==5) && ({data_r[4:0], data}==6'b011100);
not_match <= (cnt==5) && ({data_r[4:0], data}!=6'b011100);
end
end
endmodule
另外参考
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
reg [3:0] state;
reg [2:0] cnt;
reg [5:0] datareg;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
datareg <= 0;
cnt <= 0;
end
else
begin
if(cnt == 6)
begin
cnt <= 0;
end
else
begin
cnt <= cnt + 1;
datareg <= {datareg[4:0],data};
end
end
end
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
state <= 0;
match <= 0;
not_match <= 0;
end
else
begin
if(match)
match <= 0;
if(not_match)
not_match <= 0;
case(state)
'd0:
begin
if(cnt == 1)
begin
if(datareg[0] == 0)
state <= 1;
else
begin
state <= 0;
not_match <= 1;
end
end
end
'd1:begin
if(datareg[1]==1)
state <= 2;
else
begin
state <= 0;
not_match <= 1;
end
end
'd2:
begin
if(datareg[2]==1)
state <= 3;
else
begin
state <= 0;
not_match <= 1;
end
end
'd3:
begin
if(datareg[3]==1)
state <= 4;
else
begin
state <= 0;
not_match <= 1;
end
end
'd4:
begin
if(datareg[4]==0)
state <= 5;
else
begin
state <= 0;
not_match <= 1;
end
end
'd5:
begin
state <= 0;
if(datareg[5]==0)
match <= 1;
else
begin
state <= 0;
not_match <= 1;
end
end
endcase
end
end
endmodule
注:解题分析来源于网友,如有侵权,请告删之。