k0b0's record.

Computer Engineering, Arts and Books

SystemVerilogでチャタリング除去回路を記述してみる。

チャタリング除去回路を記述してみる

FPGAボードを使っているとスイッチをよく使う。
スイッチを押すとノイズ(チャタリング)が起こる。
というわけで、色々と参考にしてチャタリング除去回路を書いたのでメモしておく。

チャタリング除去回路(chatter.sv)

/* chatter.sv */
module chatter (input  logic clk,     // クロック 
                input  logic reset,   // リセット
                input  logic sw,      // スイッチ入力(立ち下がり)
                output logic sw_out); // 出力(1パルス)

/* cntの値はクロック周波数をどのくらい分周するかによって調整する */
logic [20:0] cnt;
wire en_N_hz = (cnt == 1200000);

/* クロックをカウントして分周 */
always_ff @(posedge clk) 
begin
    if (reset)
        cnt <= 21'b0;
    else if ( en_N_hz )
        cnt <= 21'b0;
    else
        cnt <= cnt + 21'b1;
end

/* スイッチ入力をシフトレジスタ(2つのFF)に入力 */
logic ff_0, ff_1;
always_ff @( posedge clk ) 
begin
    if (reset) 
    begin
        ff_1 <= 1'b0;
        ff_0 <= 1'b0;
    end
    else if ( en_N_hz ) begin
        ff_1 <= ff_0;
        ff_0 <= sw;
    end
end

/* シフトレジスタの各出力とクロック(分周)のANDをとりノイズを消去 */
wire tmp = ~(ff_0) & ff_1 & en_N_hz;

always_ff @(posedge clk) 
begin
    if (reset)
        sw_out <= 1'b0;
    else
        sw_out <= tmp;
end

endmodule

chatter.svを論理合成した結果(Quartus PrimeのRTL Viewerで確認)

f:id:k0b0:20190526111309j:plain