题目来源于牛客网,完整工程源码:https://github.com/ningbo99128/verilog
目录
1、VL25 输入序列连续的序列检测
题目介绍
思路分析
代码实现
仿真文件
2、VL26 含有无关项的序列检测
题目介绍
思路分析
代码实现
仿真文件
3、VL27 不重叠序列检测
题目介绍
思路分析
代码实现
仿真文件
4、VL28 输入序列不连续的序列检测
题目介绍
思路分析
代码实现
仿真文件
请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。模块的接口信号图如下:
请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
由状态图可以看出,在s5、s6状态为1时,其状态分别为011101、0111001,不满足序列条件,从而跳转到s2状态继续执行检测;其余状态均为跳转到s2状态;最后在s8状态时,满足序列01110001条件,输出信号match为1。
//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
curr_state <= s0;
else
curr_state <= next_state;
end
//第二段 转移状况
always @(*)begin
case(curr_state)
s0: begin
if(a==0) next_state = s1;
else next_state = s0;
end
s1: begin
if(a==1) next_state = s2;
else next_state = s0;
end
s2: begin
if(a==1) next_state = s3;
else next_state = s0;
end
s3: begin
if(a==1) next_state = s4;
else next_state = s0;
end
s4: begin
if(a==0) next_state = s5;
else next_state = s0;
end
s5: begin
if(a==0) next_state = s6;
else next_state = s2;
end
s6: begin
if(a==0) next_state = s7;
else next_state = s2;
end
s7: begin
if(a==1) next_state = s8;
else next_state = s0;
end
s8: begin next_state = s0; end
default: begin next_state = s0;end
endcase
end
/********* 第三段 状态输出 moore FSM ************/
//标志信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
match <= 1'b0;
else if(curr_state == s8) //注意此处是curr_state
match <= 1'b1;
else
match <= 1'b0;
end
注意match的变化,是在a序列结束后的1个时钟周期,而不是在a序列最后一位刚开始就产生变化。
请编写一个序列检测模块,检测输入信号a是否满足011XXX110序列(长度为9位数据,前三位是011,后三位是110,中间三位不做要求),当信号满足该序列,给出指示信号match。
程序的接口信号图如下:
时序图如下:
请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能。 要求代码简洁,功能完整。
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
状态转移图如下:
有一个疑惑是,在s6状态时,011xxx后面有2个状态分别为011xxx0、011xxx1;如果是011xxx1那没问题,继续跳转下一个状态,那如果是011xxx0,应该返回哪个状态呢?要不要识别一下x的值,如果前3个x恰好是011,那应该返回到s3状态,而不是s0状态。这样好像把题目想的太复杂了。最后按照最简单的思路来,就好了。
//第二段 转移状况
always @(*)begin
case(curr_state)
s0: begin
if(a==0) next_state = s1;
else next_state = s0;
end
s1: begin
if(a==1) next_state = s2;
else next_state = s0;
end
s2: begin
if(a==1) next_state = s3;
else next_state = s0;
end
s3: begin next_state = s4; end
s4: begin next_state = s5; end
s5: begin next_state = s6; end
s6: begin
if(a==1) next_state = s7;
else next_state = s0;
end
s7: begin
if(a==1) next_state = s8;
else next_state = s0;
end
s8: begin
if(a==0) next_state = s9;
else next_state = s0;
end
s9: begin next_state = s0; end
default: begin next_state = s0;end
endcase
end
直接运行成功了,就没用vivado仿真。
请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
模块的接口信号图如下:
模块的时序图如下:
请使用Verilog HDL实现以上功能,要求使用状态机实现,画出状态转化图。并编写testbench验证模块的功能。
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
a:单比特信号,待检测的数据
match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
not_match:当输入信号a不满足目标序列,该信号为1,其余时刻该信号为0
自己仿真没啥问题,但是牛客网的提交总是通过不了。有大佬不怕麻烦的话,帮我看看提出问题。
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
//*************code***********//
parameter [2:0] s0 = 3'b000,
s1 = 3'b001,
s2 = 3'b010,
s3 = 3'b011,
s4 = 3'b100,
s5 = 3'b101,
s6 = 3'b110,
s7 = 3'b111;
reg [2:0] curr_state;
reg [2:0] next_state;
reg [2:0] cnt;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 3'd0;
else if(cnt == 3'd6)
cnt <= 3'd1;
else
cnt <= cnt + 1'b1;
end
//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
curr_state <= s0;
else if(cnt == 3'd6)
curr_state <= s1;
else
curr_state <= next_state;
end
//第二段 转移状况
always @(*)begin
case(curr_state)
s0: begin next_state = s1;end
s1: begin
if(data==0) next_state = s2;
else next_state = s1;
end
s2: begin
if(data==1) next_state = s3;
else next_state = s1;
end
s3: begin
if(data==1) next_state = s4;
else next_state = s1;
end
s4: begin
if(data==1) next_state = s5;
else next_state = s1;
end
s5: begin
if(data==0) next_state = s6;
else next_state = s1;
end
s6: begin
if(data==0) next_state = s7;
else next_state = s1;
end
s7: begin next_state = s1;end
default: begin next_state = s1;end
endcase
end
/********* 第三段 状态输出 moore FSM ************/
//标志信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
match <= 1'b0;
not_match <= 1'b0;
end
else if(next_state == s7 && cnt == 3'd6)begin
match <= 1'b1;
not_match <= 1'b0;
end
else if(next_state != s7 && cnt == 3'd6)begin
match <= 1'b0;
not_match <= 1'b1;
end
else begin
match <= 1'b0;
not_match <= 1'b0;
end
end
//*************code***********//
endmodule
仿真代码
//2、产生激励
always #5 clk = ~clk;
initial begin
#15;
rst_n = 1'b1;
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#60;
@(posedge clk); data=1'b0; //0
#60;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
#60;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b1; //1
#10;
@(posedge clk); data=1'b0; //0
#10;
@(posedge clk); data=1'b0; //0
end
波形图
请编写一个序列检测模块,输入信号端口为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
本题和其他序列检测没有本质区别,还是使用3段式状态机,在序列检测的状态跳转部分加一个控制条件。如下:if(data==0 && data_valid) next_state = s1;
//*************code***********//
parameter [2:0] s0 = 3'b000,
s1 = 3'b001,
s2 = 3'b010,
s3 = 3'b011,
s4 = 3'b100;
reg [2:0] curr_state;
reg [2:0] next_state;
//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
curr_state <= s0;
else
curr_state <= next_state;
end
//第二段 转移状况
always @(*)begin
case(curr_state )
s0: begin
if(data==0 && data_valid)
next_state = s1;
else
next_state = s0;
end
s1: begin
if(data==1 && data_valid)
next_state = s2;
else
next_state = s0;
end
s2: begin
if(data==1 && data_valid)
next_state = s3;
else
next_state = s0;
end
s3: begin
if(data==0 && data_valid)
next_state = s4;
else
next_state = s0;
end
s4: begin next_state = s0;end
default: begin next_state = s0;end
endcase
end
/********* 第三段 状态输出 moore FSM ************/
//标志信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
match <= 1'b0;
else if(next_state == s4)
match <= 1'b1;
else
match <= 1'b0;
end
//*************code***********//
有发现的错误,欢迎交流奥~