Verilog -- 序列模三(整除3)檢測器


Verilog -- 序列模三(整除3)檢測器

描述:輸入口是1bit,每次進來一位數據,檢查當前序列是否能整除3,能則輸出1,否則輸出0.
例如
序列=1,out=0;
序列=11,out=1;
序列=110,out=1;
序列=1101,out=0;

首先需要找一下規律,一個數被三除,只可能會有三種情況:
1.余數為0;
2.余數為1;
3.余數為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;
  2. 余數為1的情況,也就是\(3a+1=x\)
    • 輸入為0,則有\(6a+2=2x\),可見此時余數為2;
    • 輸入為1,則有\(6a+3=2x+1\),此時序列可以被三整除,可見此時余數為0,輸出為1;
  3. 余數為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型狀態機描述。
狀態轉換表

State\Input 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

波形圖:

可以看到,功能正確。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM