verilog实现序列检测(状态机和移位寄存器实现)

本文介绍了如何使用Verilog语言设计可综合的序列检测器,分别通过状态机和移位寄存器两种方法实现对输入数据码流中特定序列‘1010’的检测。状态机方法通过状态转移图描述检测过程,而移位寄存器方法利用寄存器作为检测窗口进行比较。文中提供了详细的代码示例及仿真波形,展示两种方法的正确性和有效性。
摘要由CSDN通过智能技术生成

前言

用Verilog描述一个可综合的序列检测器用于检测输入数据码流中的特定序列。本文介绍了使用状态机来直接描述和采用移位寄存器的方式进行检测的两种方法。同时,也给出了tb文件和仿真波形图。

状态机方法

本文实现了对序列“1010”的检测,第一种方法我们采用状态机的写法进行检测。
首先画出状态转移图,如下:
在这里插入图片描述
含义描述如下:A状态相当于idle状态,此刻若输入一个1,则会转移至下一状态,否则保持此状态,同理,当依次输入1010时,状态转移至E,且输出为1,表示检测到序列1010,随后若再次输入1,则会重新跳转至A状态,开始新的序列检测。
下面给出代码:

//check_sequence FSM
`timescale 1ns/1ns
module tb();
  wire out;
  reg clk, rst;
  reg data_in;

  check_sequence dut(.clk(clk), 
                     .rst(rst),
                     .ina(data_in),
                     .out(out)
                    );
  initial begin
    clk <= 0;
    forever begin 
      #5 clk <= ~clk;
    end
  end

  initial begin//给出一段码流数据
    #20 data_in = 1;
    #20 data_in = 0;
    #20 data_in = 1;
    #20 data_in = 0;
    #20 data_in = 0;
    #20 data_in = 0;
    #20 data_in = 1;
    #20 data_in = 0;
    #20 data_in = 1;
    #20 data_in = 0;
    #500 $stop;
    $display("check finished");
  end

  initial begin
    #10 rst <= 0;
    #20 rst <= 1;
  end
endmodule

module check_sequence(input clk, input rst, input ina, output out); 
  reg[1:0] state, next_state;
  reg out;
  
  parameter A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100;

  always @(posedge clk or negedge rst)
    if (!rst)
      state <= A;
    else 
      state <= next_state;

  always @(state or ina)//state transition
    begin
      next_state <= A;
      case(state)
        A: begin
          if (ina == 1)
            next_state <= B;
          else 
            next_state <= A;
            out <= 0;
           end
        B: begin
          if (ina==1)
            next_state <= B;
          else
            next_state <= C;
            out <= 0;
           end
        C: begin
          if (ina==1)
            next_state <= D;
          else
            next_state <= C;
            out <= 0;
           end
        D: begin
          if (ina==1)
            next_state <= D;
          else
            next_state <= E;
            out <= 1;
           end
        E: begin
          if (ina==1)
            next_state <= A;
          else
            next_state <= E;
            out <= 0;
           end
        default: next_state <= A;
      endcase
    end
 endmodule

仿真波形如下:
在这里插入图片描述
可以看到,当检测到1010时,out信号会拉高。

移位寄存器方法

此方法的基本思路就是利用移位寄存器作为检测窗口,每进来一个数就跟目标序列进行比较。
直接给出代码如下:

//shift regeister detection
//test sequence: 1010

`timescale 1ns/1ns
module tb();
  wire check_rst, ina;
  reg clk, rst;
  reg [23:0] data;//give data in sequence

  assign ina = data[23];
  check_sequence1 dut(.clk(clk), 
                      .rst(rst), 
                      .check_rst(check_rst),
                      .ina(ina)
                     );

  initial begin
    clk <= 0;
    forever begin
      #5 clk <= ~clk;
    end
  end

  initial begin
    #10 rst <= 0;
    repeat(2) @(posedge clk);
    rst <= 1;
  end

  initial begin

    data = 24'b1100_1010_0011_1101_1010_1011;
    #500 $stop;
  end
  always @(posedge clk) begin

    #2 data = {data[22:0],data[23]};
  end
endmodule

module check_sequence1 (input ina, input clk, input rst, output check_rst);
  parameter check_sq = 4'b1010;//check_sequence
  reg [3:0] buffer;

  assign check_rst = (buffer == check_sq)? 1:0;
  always @(posedge clk or negedge rst) begin
    if (!rst)
      buffer <= 4'b0000;
    else 
      buffer <= {buffer[2:0],ina};
    end
endmodule

仿真波形如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

借问众神明.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值