• 备战秋招-手撕代码篇


    欢迎关注个人公众号摸鱼范式

    序列模三(整除3)检测器

    授权转发
    作者:love小酒窝
    链接:https://www.cnblogs.com/lyc-seu/p/12768321.html

    描述:输入口是1bit,每次进来一位数据,检查当前序列是否能整除3,能则输出1,否则输出0.

    例如

    • 序列=1,out=0;
    • 序列=11,out=1;
    • 序列=110,out=1;
    • 序列=1101,out=0;

    首先需要找一下规律,一个数被三除,只可能会有三种情况:

    • 余数为0;
    • 余数为1;
    • 余数为2;

    假设当前序列表示的数是x,商为a,余数为b, 则有:3a+b=x

    需要注意的是:当新进来1bit数据时,实际上隐含了一个条件就是序列将被左移,也就是说如果当前序列为x,输入数据为0,则此时序列表示的数是2x,如果输入是1,则此时序列表示2x+1.
    下面分类讨论:

    1. 余数为0的情况,也就是3a=x:
    • 输入为0,因为之前余数为0表示已经能整除3,这时输入为0相当于序列乘上个2,仍然能被3整除,输出为1;
    • 输入为1,则有6a+1=2x,可见此时余数为1;
    1. 余数为1的情况,也就是3a+1=x:
    • 输入为0,则有6a+2=2x,可见此时余数为2;
    • 输入为1,则有6a+3=2x+1,此时序列可以被三整除,可见此时余数为0,输出为1;
    1. 余数为2的情况,也就是3a+2=x:
    • 输入为0,则有6a+4=2x,可见此时余数为4 mod 3 = 1;
    • 输入为1,则有6a+5=2x+1,可见此时余数为5 mod 3 = 2;

    也可以用下面的表来描述:

    last_Remainder Input Remainder Output
    0 1 1 0
    0 0 0 1
    1 0 2 0
    1 1 0 1
    2 0 1 0
    2 1 2 0

    通过上面的分析可以发现,余数的三种情况可以作为状态机的三种状态,当前的状态以及输出只跟之前的状态和当前的输入有关,因此可以使用Mearly型状态机描述。
    状态转换表

    StateInput 0 1
    0 0/1 1/0
    1 2/0 0/1
    2 1/0 2/0

    表中的值表示next_state/output

    Verilog代码:

    `timescale 1ns/1ps
    
    module seq_mod3_detector
    (
    input                                   clk,
    input                                   rst_n,
    
    input                                   data,
    output  reg                             success
    );
    
    reg [1:0] current_state;
    reg [1:0] next_state;
     
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) current_state <= 0;
        else current_state <= next_state;
      end
    
    always@(*)begin
        next_state = 0;
        case(current_state)
        2'd0: if(data) next_state = 2'd1;
              else next_state = 2'd0;
        2'd1: if(data) next_state = 2'd0;
              else next_state = 2'd2;
        2'd2: if(data) next_state = 2'd2;
              else next_state = 2'd1;
        default: next_state = 0;
        endcase
      end
    
    always@(posedge clk or negedge rst_n) begin
      if(!rst_n) success <= 0;
      else begin
        case(next_state)
        2'd0: if(data) success <= 0;
              else success <= 1;
        2'd1: if(data) success <= 1;
              else success <= 0;
        2'd2: if(data) success <= 0;
              else success <= 0;
        default: success <= 0;
        endcase
      end 
    end
    
    endmodule
    

    testbench:

    `timescale 1ns/1ps
    
    module seq_mod3_detector_tb();
    
    reg clk;
    reg rst_n;
    reg data;
    wire success;
    
    reg [127:0] seq;
    always #1 clk = ~clk;
    
    initial begin
      clk = 1;
      rst_n = 1;
      data = 0;
      #2 rst_n <= 0;
      #2 rst_n <= 1;
      seq = 0;
      while(1) begin
        @(posedge clk) begin 
          data = $random%2;
          seq = (seq<<1) + data;
        end
      end
    
    end
    
    
    seq_mod3_detector U_SEQ_MOD3_DETECTOR_0(
        .clk          ( clk          ),
        .rst_n        ( rst_n        ),
        .data         ( data         ),
        .success      ( success      )
    );
    
    initial begin
        $fsdbDumpvars();
        $fsdbDumpMDA();
        $dumpvars();
        #200 $finish;
     end
    endmodule
    

    波形图:

    可以看到,功能正确。

  • 相关阅读:
    ECharts之类型bar(堆积条形图)
    ECharts之类型bar
    ECharts之类型pie
    ECharts入门一
    ECharts第一个实例
    html树形菜单控件
    【JavaScript】Javascript中document.execCommand()的用法
    【JavaScript】dhtmlXTree 中文API
    【javascript】addEventListener事件方法
    java判断集合是否重复的一种便捷方法
  • 原文地址:https://www.cnblogs.com/icparadigm/p/12864411.html
Copyright © 2020-2023  润新知