Polyphony でチャタリング除去
polyphony
2019-3-12 16:14 JST

こんな時便利 Polyphony の高位合成

ちょっとしたモジュールをシステムに入れ込みたい。IP-XACT(IP Core) をつくるほどでもないし、かといってちょっとした調整は必要だから Verilog で書いてもいいけど結構手間。ソフトでやるよりハードの方がいいし。HLS のツールがあるけど、プロジェクトを立ち上げるほどでもない。こういう時こそ Polyphony の出番です。

チャタリング除去 + αの機能

今回はソフトで実現すると複雑になりがちな長押しの機能を付けてみます。ターゲットは Zybo-Z7-20 です。

待ち時間調整のためのループ

まずは待ち時間を調整するために for 文をつかいます。待ち時間は self.wait_n です。class を使うので注意が必要です(ソース自身はgistに置きました。)

fix_bounce.py
    def loop_wait(self):
        for i in range(self.wait_n):
            pass

worker で待ち時間を調整しながら押し/長押し検知

これはちょっと複雑ですね。worker は Polyphony の機能でスレッドのような役目をします。self.button_id.rd()が 1 bit のリードで入力情報を得ています。場外が変わると (v0 != v1で判断) 一旦ループを抜けて出力(self.button_out.wr(v1) の部分)しています。長押しだと判断すると( max_count を超えてもまだ押し続けていた場合) long_press_button_out にも 1 を出します。

fix_bounce.py
    def main(self):
        while is_worker_running():
            count:bit32 = 0
            v0:bit = 0
            v1:bit = 0
            while True:
                max_count:bit32 = self.long_press_count_n
                count = 0
                while True:
                    self.loop_wait()
                    v0 = v1
                    v1 = self.button_in.rd()
                    count += 1
                    if v0 != v1:
                        break

                    if (v1 == 1) and ( count > max_count ):
                        self.long_press_button_out.wr(1)

                self.long_press_button_out.wr(0)
                self.button_out.wr(v1)

テストベンチでチェック

コードを書いたら(class の初期化ルーチン __init__ でポートの宣言などをしていますがここでは説明略)今度は @testbench のキーワード(デコレータを使って)テストルーチンを書きます。Python でまず、うまく動きました。高位合成での勝利の方程式は事前に「ソフト的にシミュレーションをする」です。

ソースを gist に

だいぶ舌足らずの記事になってしまいましたが、最後にソース全部を gist にあげておきます。
Enjoy Your FPGA Life!!

Polyphony によるチャタリング除去プログラム(fix_bounce.py)