Verilog -- 并行2bit输入序列检测器

27 篇文章 18 订阅

Verilog – 并行2bit输入序列检测器

@(verilog)

乐鑫2020笔试题

描述:模块输入口是并行的2bit,实现对 ( 1011001 ) 2 (1011001)_2 (1011001)2的序列检测,输入数据顺序为高位2bit先输入,当检测到序列时输出一拍高电平脉冲,用verilg描述。

方法一:状态机

采用状态机描述,先列出状态转移表,跟单bit输入不同的是,这里的输入是并行的2bit:

state\input00011011
001101
10101101
1001101011
1010101101101
1011101100101101
1011001011001101011
10110001101
10110010101101

以及输出的状态转移表:

state\input00011011
00000
10000
100000
1010000
10110000
101100100
1011000011
10110010000

通过分析可以发现,1011001和1状态是完全等价的,因此可以归并,并且其他状态的转移也有相同的,也可以放到一起:
状态转移表

state\input00011011
0\10110001101
10101101
10\1011001101011
1010101101101
1011101100101101

输出转移表:

state\input00011011
0\1\10\101\10110000
101100100
1011000011

Verilog代码:





`timescale 1ns/1ps

module two_bit_input_seq_detector
(
input                                   clk,
input                                   rst_n,
input        [1:0]                      data,
output reg                              success
);

reg [2:0] current_state;
reg [2:0] next_state;

parameter S0      =  3'b000,
          S1      =  3'b001,
          S10     =  3'b011,
          S101    =  3'b010,
          S1011   =  3'b110,
          S10110  =  3'b111,
          S101100 =  3'b101;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) current_state <= 3'b0;
    else current_state <= next_state;
  end

always @(*) 
  case(current_state)
    S0,S101100: 
            case(data)
              2'b00: next_state = S0;
              2'b01: next_state = S1;
              2'b10: next_state = S10;
              2'b11: next_state = S1;
            endcase
    S1:     case(data)
              2'b00: next_state = S0;
              2'b01: next_state = S101;
              2'b10: next_state = S10;
              2'b11: next_state = S1;
            endcase
    S10,S10110:
            case(data)
              2'b00: next_state = S0;
              2'b01: next_state = S1;
              2'b10: next_state = S10;
              2'b11: next_state = S1011;
            endcase   
    S101:   case(data)
              2'b00: next_state = S0;
              2'b01: next_state = S101;
              2'b10: next_state = S10110;
              2'b11: next_state = S1;
            endcase
    S1011:  case(data)
              2'b00: next_state = S101100;
              2'b01: next_state = S101;
              2'b10: next_state = S10;
              2'b11: next_state = S1;
            endcase
    default:         next_state = S0;
  endcase

  
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      success <= 0;
    end else begin
      case(current_state)
        S0,S1,S10,S101,S1011:        success <= 0;
        S10110 : if(data == 2'b01)   success <= 1;
                 else                success <= 0;
        S101100: if(data[1] == 1'b1) success <= 1;
                 else                success <= 0;
        default:                     success <= 0;
      endcase
    end
  end

endmodule




testbench:


`timescale 1ns/1ps

module two_bit_input_seq_detector_tb();


reg         clk;
reg         rst_n;
reg   [1:0] data;

wire     success;
reg [127:0] seq;


always #1 clk = ~clk;
initial begin
  clk = 0;
  data = 0;
  rst_n = 1;
  #4 rst_n = 0; #2 rst_n = 1;

  seq = 0;
  while(1) begin
    @(posedge clk) begin 
      data <= $random%4;
      seq <= (seq<<2) + data;
    end
  end

end



two_bit_input_seq_detector U_2BIT_INPUT_SEQ_DETECTOR_0
(  .clk     ( clk     ),
   .rst_n   ( rst_n   ),
   .data    ( data    ),
   .success ( success ));


initial begin
  $fsdbDumpvars();
  $fsdbDumpMDA();
  $dumpvars();
  #1000 $finish;
end

endmodule


波形图:

放大来看:

可以看到,功能正确。

方法二:移位寄存器

使用移位寄存器解决序列检测问题是真的简单粗暴,直接上代码:


`timescale 1ns/1ps

module two_bit_input_seq_detector_v2
(
input                                   clk,
input                                   rst_n,
input        [1:0]                      data,
output                                  success
);

parameter DETECTOR = 7'b1011001;
reg [7:0] fifo;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      fifo <= 8'b0;
    end else begin
      fifo <= {fifo[5:0],data};
    end
end

assign success = (fifo[7:1]==DETECTOR || fifo[6:0]==DETECTOR) ? 1:0;

endmodule

testbench:


`timescale 1ns/1ps

module two_bit_input_seq_detector_v2_tb();


reg         clk;
reg         rst_n;
reg   [1:0] data;

wire     success;
reg [127:0] seq;


always #1 clk = ~clk;
initial begin
  clk = 0;
  data = 0;
  rst_n = 1;
  #4 rst_n = 0; #2 rst_n = 1;

  seq = 0;
  while(1) begin
    @(posedge clk) begin 
      data <= $random%4;
      seq <= (seq<<2) + data;
    end
  end

end




two_bit_input_seq_detector_v2 U_TWO_BIT_INPUT_SEQ_DETECTOR_V2_0
(  .clk     ( clk     ),
   .rst_n   ( rst_n   ),
   .data    ( data    ),
   .success ( success ));


initial begin
  $fsdbDumpvars();
  $fsdbDumpMDA();
  $dumpvars();
  #1000 $finish;
end

endmodule

仿真波形:

功能正确!

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

love小酒窝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值