チャタリング防止機能付きカウンターを作る


コード

TopModule.v

module TopModule(
	//////////// CLOCK //////////
	input 		          		CLK1,
	input 		          		CLK2,
	//////////// SEG7 //////////
	output		     [7:0]		HEX0,
	output		     [7:0]		HEX1,
	output		     [7:0]		HEX2,
	output		     [7:0]		HEX3,
	output		     [7:0]		HEX4,
	output		     [7:0]		HEX5,
	//////////// Push Button //////////
	input 		     [1:0]		BTN,
	//////////// LED //////////
	output		     [9:0]		LED,
	//////////// SW //////////
	input 		     [9:0]		SW

	);

	wire button;	//チャタリング除去後のスイッチデータ
	wire [3:0] wq;	//10進カウンタの出力データ
	wire clk;		//KEY0は、押された時に0になるので、カウンタ用に論理を反転
	assign clk=~button;
	m_chattering u0(CLK1,BTN[0],button);
	m_dec_counter u1(clk,wq);
	assign LED={6'h0,wq};
	assign HEX0=8'hff;
	assign HEX1=8'hff;
	assign HEX2=8'hff;
	assign HEX3=8'hff;
	assign HEX4=8'hff;
	assign HEX5=8'hff;
	
endmodule

Chattering.v

module m_chattering(input clk,input sw_in,output sw_out);
	reg [15:0] cnt;	//16bit counter
	reg swreg;			//Switch Latch
	wire iclk;			//1/65536 clock
	
	assign sw_out=swreg;
	
	//16bit Counter
	always @(posedge clk) begin
		cnt=cnt+1;
	end
	assign iclk=cnt[15];	//clock for chattering inhibit
	
	//switch latch 
	always @(posedge iclk) begin
		swreg=sw_in;
	end

endmodule

module m_dec_counter(input clk,output [3:0] q);
	reg [3:0] counter;
	
	always @(posedge clk) begin
		if(counter==4'h9) begin
			counter=0;
		end
		else begin
			counter=counter+1;
		end
	end
	
	assign q=counter;
endmodule




動作

1周期が763Hzのカウンター

reg [15:0] cnt;

の部分でcntを16bit確保していることがわかります。つまりcntは0から1111 1111 1111 1111(=10進数で65536)までカウントできます。

そしてalways文を見ると、clkが立ち上がるときにcntを加算していることがわかります。DE10-Liteのクロックは50MHzなので、50x10^6/65536≒763Hzで動作するカウンターになっています。

    always @(posedge clk) begin
		cnt=cnt+1;
	end

ここで763Hzという数字に意味はないのですが、この回路を応用すると音響浮揚装置の超音波素子を操作する40kHzの出力を作ることができます。


カウンターを使ったチャタリング防止回路

assign iclk=cnt[15];	//clock for chattering inhibit	

そして、763Hzで動作するカウンターcntの一番上の位をiclkに渡しています。こうすることで、cntが65536回更新されたときにiclkが0→1に切り替わります。

	//switch latch 
	always @(posedge iclk) begin
		swreg=sw_in;
	end

そして、iclkが立ち上がったときに、always文でsw_inの値がswregに渡されます。

sw_inはTopModule.vでスイッチと接続されているので、ボタンの入力を引き渡していることになります。

上記の動作をまとめると、clkが65536回onしたら(=763Hz)、sw_inの値をswregに渡す、という動作になっています。

こうすることでsw_inにチャタリングが生じても、この時間内に電圧の変動が収まればチャタリングの影響が出ない回路を作ることができるのですね。

ちなみに動作としても、sw0を押すだけでledがカウントアップされていくことがわかります。フリップフロップ回路をチャタリング防止に使用した場合よりも簡単に実装できます。

この記事が気に入ったらサポートをしてみませんか?