牛客网Verilog刷题——VL27

牛客网Verilog刷题——VL27

题目

  请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
  模块的接口信号图如下:

在这里插入图片描述
  模块的时序图如下:

在这里插入图片描述

  请使用Verilog HDL实现以上功能,要求使用状态机实现,画出状态转化图。

信号类型输入/输出位宽描述
clkwireIntput1系统时钟信号
rst_nwireIntput1异步复位信号,低电平有效
awireIntput1单比特信号,待检测的数据
matchregOutput1当输入信号a满足目标序列,该信号为1,其余时刻该信号为0
not_matchregOutput1当输入信号a不满足目标序列,该信号为1,其余时刻该信号为0

答案

  题目中要求使用状态机实现,可以画出其状态转换图。

  根据状态转换图,编写Verilog代码,如下。

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);

//状态机实现
reg [2:0] curr_state;
reg [2:0] next_state;
reg [5:0] r_data;

always @(posedge clk or negedge rst_n)
  if(!rst_n)
    curr_state <= 3'd0;
  else
    curr_state <= next_state;

always @(*) begin
  next_state = 3'd0;
  case(curr_state)
    3'd0: next_state = 3'd1;
	3'd1: next_state = 3'd2;
	3'd2: next_state = 3'd3;
	3'd3: next_state = 3'd4;
	3'd4: next_state = 3'd5;
	3'd5: next_state = 3'd0;
	default: next_state = 3'd0;
  endcase
end
  
always @(posedge clk or negedge rst_n)
  if(!rst_n) begin
	r_data <= 6'd0;
    match <= 1'b0;
	not_match <= 1'b0;
  end
  else 
    case(curr_state)
      3'd0,3'd1,3'd2,3'd3,3'd4: 
	    begin 
		  r_data[curr_state] <= data;
		  match <= 1'b0;
		  not_match <= 1'b0;
		end

	  3'd5:
	    begin
		  r_data[curr_state] <= data;
		  if(r_data[4:0] == 5'b01110 && data == 1'b0)
		    match <= 1'b1;
		  else
		    match <= 1'b0;

		  if(r_data[4:0] != 5'b01110 && data != 1'b0)
		    not_match <= 1'b1;
		  else
		    not_match <= 1'b0;			

		end

	  default: 
	    begin
          r_data <= 6'd0;
		  match <= 1'b0;
		  not_match <= 1'b0;
		end
	endcase
    
endmodule

  另外,我们还可以用计数器+移位寄存器的方式进行实现,如下。

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);
	
//采用移位寄存器+计数器实现
reg [2:0] r_cnt;
reg [5:0] r_data;

always @(posedge clk or negedge rst_n)
  if(!rst_n)
    r_cnt <= 3'd0;
  else if(r_cnt == 3'd5)
    r_cnt <= 3'd0;
  else
    r_cnt <= r_cnt + 1'b1;

always @(posedge clk or negedge rst_n)
  if(!rst_n)
    r_data <= 6'd0;
  else
    r_data <= {r_data,data};

always @(posedge clk or negedge rst_n)
  if(!rst_n) begin
    match <= 1'b0;
	not_match <= 1'b0;
  end
  else if(r_cnt == 3'd5)
    if(data == 1'b0 && r_data[4:0] == 4'b01110) begin
	  match <= 1'b1;
	  not_match <= 1'b0;
	end
	else begin
      match <= 1'b0;
	  not_match <= 1'b1;
	end
  else begin
    match <= 1'b0;
	not_match <= 1'b0;
  end
  
endmodule
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值