質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Verilog

Verilogは、デジタル回路設計用の論理シミュレータ。また、ハードウェアの電子回路設計の際に用いるハードウェア記述言語を指すこともあります。両者を見分けるために、言語を「Verilog-HDL」と呼ぶ場合もあります。

FPGA

FPGAは、製造後でも設計者によって書き換えができる論理回路です。即時に書き換えが可能なため、開発期間を短縮することが可能。何度でも書き換えられるといった柔軟性があるため、製造や開発における費用も削減できるといったメリットがあります。

Q&A

解決済

2回答

4472閲覧

【VerilogHDL】チャタリング除去回路

kakuwane

総合スコア7

Verilog

Verilogは、デジタル回路設計用の論理シミュレータ。また、ハードウェアの電子回路設計の際に用いるハードウェア記述言語を指すこともあります。両者を見分けるために、言語を「Verilog-HDL」と呼ぶ場合もあります。

FPGA

FPGAは、製造後でも設計者によって書き換えができる論理回路です。即時に書き換えが可能なため、開発期間を短縮することが可能。何度でも書き換えられるといった柔軟性があるため、製造や開発における費用も削減できるといったメリットがあります。

0グッド

0クリップ

投稿2019/12/09 20:03

前提・実現したいこと

Verilog HDLにて、参考書のチャタリング処理を理解すること。

理解できない問題

下記、ソースの処理が理解できない。
ご教授いただければ助かります。

module debounce ( input CLK, input RST, input BTNIN, output reg BTNOUT ); /* 125MHzを分周し40Hzを作成 */ reg [21:0] cnt22; wire en40hz = (cnt22==22'd3125000-1); always @( posedge CLK ) begin if ( RST ) cnt22 <= 22'h0; else if ( en40hz ) cnt22 <= 22'h0; else cnt22 <= cnt22 + 22'h1; end /* スイッチ入力をFF2個で受ける */ reg ff1, ff2; always @( posedge CLK ) begin if ( RST ) begin ff1 <= 1'b0; ff2 <= 1'b0; end else if ( en40hz ) begin ff2 <= ff1; ff1 <= BTNIN; end end /* 立ち上がり検出し、FFで受ける */ wire temp = ff1 & ~ff2 & en40hz; always @( posedge CLK ) begin if ( RST ) BTNOUT <= 1'b0; else BTNOUT <= temp; end endmodule

該当のソースコード

私の理解は、スイッチ入力をFF2個で受けとり
スイッチの値が前値が0で、現在の値が1であるから立ち上がった値である。
そして、40Hzの間隔でCLK1上がった時のタイミングである。
それのタイミングをANDしている。とソースから推測しました。

40Hz間隔のCLK1周期で、1回分の値でスイッチが押された?ってなんでそれが正しい値なのかが
自分にはわからないです。たとえばノイズだったりとかでも誤動作しないのか?
など考えてしまい。この処理で良いのかがわからないです。

/* スイッチ入力をFF2個で受ける */ reg ff1, ff2; always @( posedge CLK ) begin if ( RST ) begin ff1 <= 1'b0; ff2 <= 1'b0; end else if ( en40hz ) begin ff2 <= ff1; ff1 <= BTNIN; end end /* 立ち上がり検出し、FFで受ける */ wire temp = ff1 & ~ff2 & en40hz;

マイコンでのチャタリング処理

void *func_thread(void* args) { static int last=0; //前回のスイッチの確定値 static int sw1=0; //今回のスイッチの読取り値 static int sw2=0; //前回のスイッチの読取り値 static int sw3=0; //前々回のスイッチの読取り値 static int cnt=0; //スイッチ読取りのタイミング調製用カウンタ printf("thread start\n"); while(1){ if(kill == 1) break; if(cnt==9){ //10ms間隔で読み取る cnt = 0; sw3 = sw2; //前々回のスイッチの読取り値を保存する sw2 = sw1; //前回のスイッチの読取り値を保存する sw1 = get_sw(); //今回のスイッチの読取り値を保存する if((sw3==sw2) && (sw2==sw1)) now = sw1; //今回と前回と前々回のスイッチの読取り値が //等しければ、それを現在のスイッチの確定値とする if(now!=last){ if(now & ~last){ //前回と今回(現在)のスイッチの確定値が異なる場合 up |= switch_on; //立上がり(スイッチの押下)検出 if(up & 0x1){ rew = now; } } last = now; //今回のスイッチの確定値を(最後の値として)保存する } }else{ cnt++; } } return 0; }

三回スイッチの値を取得して、一致したら、立ち上がり処理をしています。
VerilogHDLでは、値を三回取得してから、立ち上がり処理などしなくていいのかが分からないです。

ハザード処理について

always @( posedge CLK ) begin if ( RST ) BTNOUT <= 1'b0; else BTNOUT <= temp; end

これで回避できる理由が理解できなくて、説明が欲しいです。
どうしても納得ができなくて、先に進めなく、ご教授いただけると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

チャタリングで不安定になっている時間はen40hzの間隔より十分短いので
en40hzに同期して値を取ればチャタリングの影響を除去できます。

各種タイミングでの波形(L=_, H=*)

BTNIN _____________*_*_***__**************************************** ff1 ________________________************************************** ff2 _________________________________________********************* en40hz _______*________________*________________*________________*___ temp ________________________*_____________________________________
BTNIN _____________________*_*_**__********************************* ff1 _________________________________________********************* ff2 __________________________________________________________**** en40hz _______*________________*________________*________________*___ temp _________________________________________*____________________
BTNIN ______________________*_*_**__******************************** ff1 ________________________************************************** ff2 _________________________________________********************* en40hz _______*________________*________________*________________*___ temp ________________________*_____________________________________

ハザード

ffの出力からtempへの入力までには配線遅延があって
例えば仮にff2(~ff2)の入力がen40hzより遅れるとtempにヒゲが出ます。
しかし配線遅延は1クロック内(より短い)に収まるように配線されるので
(配線されなかったとき:タイミングエラー)
FFで受ければヒゲが消えます。

CLK / / ff1 *********************** ff2 ___******************** en40hz ___******************__ ff1' *********************** ff2' _____________********** en40hz' ________*************** temp ________*****__________ BTNOUT _______________________

(/は立ち上がりエッジ)

投稿2019/12/09 23:29

編集2019/12/10 00:12
ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakuwane

2019/12/11 01:56

詳細に記載していただき、ありがとうございます。 本を色々読み漁っている段階で、理解がまだいろいろ追いついていってなく 凄く助かりました。 あと一つ質問してもよろしいでしょうか? チャタリング処理の参考書を読んでいるとメタステーブル対策をしているかと書かれていまして。 DFFを複数段入れること不安定な値が伝搬しなくなる。 と書いてあり、同じことなのか?理解できていません。 同じことなのでしょうか?
ozwk

2019/12/11 02:12 編集

フリップフロップへの入力がちょうど読み取りのタイミングで変化してしまうと フリップフロップの出力が不安定になります。(0と1を行ったり来たりしてそのうちどちらかに収束する) 質問文のハザードの話はFFで受けたあとの話ですから別の話です [メタステーブル参考](https://dora.bk.tsukuba.ac.jp/~takeuchi/?%E9%9B%BB%E6%B0%97%E5%9B%9E%E8%B7%AF%2FHDL%2F%E9%9D%9E%E5%90%8C%E6%9C%9F%E4%BF%A1%E5%8F%B7%E3%82%92%E6%89%B1%E3%81%86%E3%81%9F%E3%82%81%E3%81%AE%E5%8D%B1%E3%81%86%E3%81%84Verilog%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA#t82a0ca1)
guest

0

チャタリング処理というのは、ある程度の時間をおいて定期的に状態を読み、2回(あるいはそれ以上の回数)以上の変化がない場合にその値をスイッチの状態として返す、ということを行います
#状態が変化した場合はその値を捨てて前の状態のママにする

それを頭において、動作を追いかけていきましょう

投稿2019/12/09 22:58

編集2019/12/09 22:59
y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問