本記事では Tang NanoでuartのIPコアを動かした件 という記事に登場する Verilog コードの理解を目指します。
概要
理解対象の記事は、Tang Nano という FPGA デバイスに UART 通信を行うための IP コアを組み込み、エコーバック処理を実現しています。記事に登場する Verilog コードが全然分からなかったので、タイミングチャートを用いて理解をしようというのが、本記事のゴールです。
理解が難しい原因は、Gowin の UART IP コアのリファレンス文書の記述が不十分なことと、Verilog コードに登場する各種信号線が相互に依存しあっていることでした。UART IP コアの動作がばっちり分かっている前提で Verilog コードを読めば理解できたのかもしれませんが、どちらも分からない状態で読解しようとして苦労しました。最終的には理解できた(気がする)ので、解説を試みます。
1 バイト受信時
まずは 1 バイトだけ受信した際のタイミングチャートを示します。黄色で示したタイミングで 1 バイトを読み出しています。
radr は UART IP コアのレジスタアドレスを示しており、0 なら RBR、5 なら LSR を読み取ります。RBR は受信バッファレジスタで、受信した 1 バイトを読み出せます。LSR はラインステータスレジスタで、各種のステータスフラグを集めたレジスタです。ビット 0 は RxRDY という名前で、1 なら RBR に受信データが格納されていることを示します。
上記のタイミングチャートは、3 クロック目の後付近(rdata[0] が 1 になる少し前)に 1 バイトの受信が行われたという想定で描いています。1 バイト受信されると LSR.RxRDY が 1 になるため、rdata[0] が 0→1 に変化します。すると、その後 rdd が 1 になり、その影響で radr が 0 になるため、RBR からデータが読み出される、という仕組みです。RBR からデータが読み出されると LSR.RxRDY は 0 に戻ります(と理解しているのですが、間違っていたらご指摘ください)。
このタイミングチャートには載せていませんが、読み出されたデータは直後に THR(送信保持レジスタ)に書かれ、UART から送信されます。つまり、エコーバックですね。
2 バイト受信時
次に連続で 2 バイトを受信した際のタイミングチャートを示します。
現実に連続して 2 バイトを受信することはあり得るでしょうか?UART IP コアは 50MHz で動作する一方、UART の通信速度はそこまで速くありません。せいぜい 115.2kbps 程度ですから、バイトとバイトの間隔は 4340 クロックほど空くことになります。ですので、このタイミングチャートは単なる思考実験のように見えるかもしれませんね。
しかし、複数のバイトが UART IP コア内の FIFO に貯まっているケースはあり得ます。受信データの有無をポーリングにより調べる設計では、ポーリング間隔が長ければ、RBR を読み出してもまだ LSR.RxRDY が 1 のまま、というケースはあるでしょう。
上記のタイミングチャートで考える限り、このように連続して受信するケースも上手く動きそうです。
エコーバックが遅れる理由
理解対象の記事に書かれていますが「適当にキーボードを打つと一つ遅れてエコーバックしてくる」のです。手元で検証し、記事の著者と議論の結果、原因が推測できましたのでここに記します。
端的に言えば Gowin の UART IP コアの仕様(あるいはバグ)によって、LSR.RxRDY が 1 になった後に RBR を読み出すと、1 回目は必ず前回受信したデータが読み出される、ということです。RBR をもう一度読むと、今受信したデータ(LSR.RxRDY を 1 にした要因となった受信データ)が読めます。
ということで、LSR.RxRDY が 1 になった後に 1 バイトを空読みすることで、受信データを正しく読めます。
投稿者の人気記事
-
uchan
さんが
2021/08/17
に
編集
をしました。
(メッセージ: 初版)
-
uchan
さんが
2021/08/18
に
編集
をしました。
(メッセージ: タイミングチャートの微修正)
-
uchan
さんが
2021/08/18
に
編集
をしました。
(メッセージ: エコーバックが遅れる理由と対策を追記)
ログインしてコメントを投稿する