Verilog --序列檢測器(采用移位寄存器實現)


轉自:https://www.cnblogs.com/qiweiwang/archive/2011/04/18/2019952.html

Verilog --序列檢測器(采用移位寄存器實現)

序列檢測器就是將一個指定序列從數字碼流中識別出來。本例中將設計一個“10010”序列的檢測器。設X為數字碼流的輸入,Z為檢測出標記輸出,高電平表示發現指定的序列10010.考慮碼流為110010010000100101

之前序列檢測器看到的都是采用狀態機實現,直到偶然看到
https://www.cnblogs.com/qiweiwang/archive/2011/04/18/2019952.html

這篇博客,才發現原來使用移位寄存器可以如此簡單,原理圖如下:

基本思路就是利用移位寄存器作為檢測窗口,每進來一個數就跟目標序列進行比較,簡單粗暴。
下面貼一下原帖的代碼:

module seqdet
(
   input wire x,
   input wire clk,
   input wire rst,
   output wire z,
   output reg [4:0] q
);
 
//reg [4:0] q;
 
assign z = (q == 5'b10010) ? 1'b1:1'b0;
 
always @ (posedge clk,negedge rst)
   if(!rst)
      q <= 5'd0;
   else
      q <= {q[3:0],x};
 
endmodule 

testbench:

`timescale 1ns/1ns
module seqdet_tb;
localparam T =20;
reg clk,rst;
reg [23:0] data;
wire z,x;
wire [4:0] q;
 
assign x = data[23];
 
initial
begin
    clk =0;
    rst =1;
    #2 rst =0;
    #30 rst =1;
    data =20'b1100_1001_0000_1001_0100;
    #(T*1000) $stop;
end
 
always #T clk = ~clk;
 
always @ (posedge clk)
   #2 data = {data[22:0],data[23]};
    
seqdet U1
(
   .x(x),
   .z(z),
   .clk(clk),
   .q(q),
   .rst(rst)
);
 
endmodule

由於移位寄存器的賦值是在always塊中,故而相對實際延遲了一個clk.由上面的方針結果可知,輸出z相對x晚了一個時鍾周期,因為由於移位寄存器的賦值是在always塊中,故而相對實際延遲了一個clk.

Note:

  • 跟用狀態機實現的區別在於,使用移位寄存器需要存儲所有的碼字,因此如果序列長度為N,則該方法需要消耗的寄存器就是N個。而使用狀態機實現時,每個狀態代表部分碼字,如果使用十進制編碼,則只需要使用log2(N)個寄存器即可編碼所有狀態,從寄存器資源的角度來看FSM實現起來代價較小。
  • 此外,寄存器版本每來一個碼元都要比較所有碼字,因此需要消耗N個比較器,而FSM的的狀態寄存器每一位在狀態轉移時都需要不同的譯碼邏輯,如果狀態轉移比較簡單,組合邏輯可能會比移位寄存器少,狀態轉移復雜的化就不好說了。
  • 當然,移位寄存器的版本編碼更加簡潔明了。


免責聲明!

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



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