VL4 输入序列不连续的序列检测
这里有一个小细节
截止到我写文章时,牛客网上在always 语句块中的赋值只能用=,不能用<=
否则无法通过测试。
首先这里时为了找到信号匹配到0110
状态转换图请自行脑补
我这里设置一个起始参数:start
接下来有四个状态:s1,s2,s3,s4。(本人才疏学浅,实际s4状态是可以优化的)
parameter start = 4'd0;
parameter s1 = 4'd1;
parameter s2 = 4'd2;
parameter s3 = 4'd3;
parameter s4 = 4'd4;
依旧,在状态机中存在两个寄存器,用来存放当前状态和下一个状态
reg [3:0] cur,nex;
这里还有一个小细节,因为start到s1状态需要data为0
所以,当s1状态到s2状态时,如果data为1则成功跳转,否则data为0,就不用从start开始则直接跳到s1。
同理,s2到s3也是这样的
s4不是!!!
rtl代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
reg [3:0] cur,nex;
parameter start = 4'd0;
parameter s1 = 4'd1;
parameter s2 = 4'd2;
parameter s3 = 4'd3;
parameter s4 = 4'd4;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)//0-1
cur = start;
else
cur = nex;
end
always @(*) begin
case(cur)
start:
if(data_valid && !data)//0
nex = s1; //0
else
nex = start;
s1:
if (data_valid)
begin
if (data) //1
nex = s2; //01
else
nex = s1;
end
else
nex = s1;
s2:
if (data_valid)
begin
if (data) //1
nex = s3; //011
else
nex = s1;
end
else
nex = s2;
s3:
if (data_valid)
begin
if (!data) //0
nex = s4; //0110
else
nex = start;
end
else
nex = s3;
s4:
if (data_valid)
begin
if (!data)//0
nex = s1;
//数据有效且为0,即匹配目标序列的第一位0,下一状态为s1
else
nex = start;
//数据有效但为1,不匹配目标序列,下一状态为start
end
else nex = start;
//数据无效,下一状态为start
default:
nex = start;
endcase
end
always @(cur or rst_n)
begin
if(!rst_n == 1)
match = 1'b0;
else if(cur == s4)
//进入状态s4表示四位数据都匹配,把匹配指示信号match拉高
match = 1'b1;
else
match = 1'b0;
end
endmodule
testbench 代码
`timescale 1ns / 1ps
`define clock 20
module sequence_detect_tb( );
reg clk,rst_n;
reg data;
reg data_valid;
wire match;
sequence_detect sequence_detect01(
.data(data),
.clk(clk),
.rst_n(rst_n),
.data_valid(data_valid),
.match(match)
);
real CYCLE_200MHz = 5 ;
always begin
clk = 0 ; #(CYCLE_200MHz/2) ;
clk = 1 ; #(CYCLE_200MHz/2) ;
end
initial begin
rst_n = 0; data_valid = 0; data = 0;
#5 rst_n = 1; data_valid = 0; data = 0;
#5 rst_n = 1; data_valid = 1; data = 0;
#5 rst_n = 1; data_valid = 1; data = 1;
#5 rst_n = 1; data_valid = 1; data = 1;
#5 rst_n = 1; data_valid = 1; data = 0;
#5 rst_n = 1; data_valid = 1; data = 0;
#5 rst_n = 1; data_valid = 1; data = 1;
#5 rst_n = 1; data_valid = 1; data = 1;
#5 rst_n = 1; data_valid = 1; data = 0;
#5 rst_n = 1; data_valid = 1; data = 0;
$stop;
end
endmodule
波形图