FPGAの言語の習得で最初からつまづく
行事の連続が終わって、やっと電子工作に専念する時間が出来た。前の記事では勇ましくFPGAのプロジェクト計画をぶちあげたが、その後は一向に進んでいない。モチベーションが下がったわけではない。初っ端のステップであるハードウエア記述言語(以下HDL)の習得にえらく手間取っているのだ。
VHDLも、VerilogHDLも、CやPASCAL(begin endでくくる。;がないところがある)言語にそっくりなので、HDLの習得は簡単だろうと考えていた。雑誌のソースコードを読んでいても何をしているかおおよその見当がつく。ところがいざ、実際にスクラッチからコードを書き始めると、そんな甘いものではないことを思い知らされた。
雑誌や参考書のソースリストをそのまま忠実に書き移せば動くのだろうが、こちらは言語の習得が目的なので、少し欲張って自分でロジックを考え、自前の回路を作って動かそうとしている。7セグLEDを表示装置、UARTを入力にし、キーボードからのリターンキーの回数を数える4桁のカウンターを作ろうというのが、練習問題の課題である。
考えてみれば、今まで順序処理に慣れてきた計算機屋が、形は似ていても同時処理の多いハードを作る回路屋の言語をマスターしようというのだから、一筋縄で行くわけがない。悪戦苦闘の連続で、簡単な回路の論理合成がいまだに通らない。日暮れて道遠しというところである。
7セグLEDを買ってきた(3/14/10)
FPGAの演習問題につかう表示ディバイスは7セグLEDである。名古屋で行われた全国集会の旅行前に既に買ってあった。神田で安売り切符を買ったついでに秋葉に立ち寄って、秋月で緑の7セグLEDを調達した。いまさら7セグLEDなんかと偉そうに言っていたが、恥ずかしながら当研究所では始めてのディバイスである。
カソードコモンかアノードコモンかで迷う。前にLEDマトリックスを使った電光掲示板を作ったとき余分に買ってあったトランジスタアレイ(TD62083)をコモン側につけるつもりなので、これを間違えると別のトランジスタアレイを揃えないといけない。
前の電光掲示板の回路図を探したが見つからない。秋葉原に行く途中で必死に思い出し、うろ覚えでカソードコモンを指定して買ってきた。家に帰り恐る恐るトランジスタアレイ(TD62083)のデータシートを取り出した。良かった。あたっていた。NPNトランジスタなのでシンクドライバーとなりカソードコモンで良いのだ。
旅行から戻って行事も一段落したので、ぼちぼち7セグLEDの基板を作り始めた。久しぶりのUEW線のハンダ付けである。4桁にしたのは特に理由はない。時計あたりにするなら、時分秒で6つ欲しいところだが、演習問題には多すぎるので4つに減らした。それでも、4つのLEDの8つのセグメント(ドット発光に+1)を並列につけるだけでも結構手間がかかる。
コモン側は定石どおりトランジスタアレイでドライブする。ひとつひとつのLEDは数mAだが、まとまれば数十mAになりFPGAの1ピンには過大になることを考慮した。
こいつも最初動かなかった。単独では問題ないのに、トランジスタアレイを通すと動かない。やれやれ何処が悪いのだ。ありゃあー、トランジスタアレイのTopViewとBottmViewを間違えている。ドライブ側と出力がちょうど逆だ。久しぶりにハンダ付けするとこれだ。仕方がない。ICそのものをソケットの印を無視して逆ざしし、帳尻をあわせる(8本×2の16ヶもハンダ付けをしなおすのは大変だ)。
コネクターは前の電光掲示板のケーブルを流用し、ブレッドボードでテストする。うむ、問題なく動いた。しかし少し暗い。考えてみればFPGAのVccは3.3Vだ。5Vを想定した330オームの制限抵抗が大きすぎたようだ。まあ、大勢に影響はない。先に進もう。
へそ曲がりな勉強法(3/17/10)
ハードの準備が出来たので、いよいよHDLの勉強に入る。VHDLかVerilogHDLか最後まで迷ったが、とりあえずコード量の少ないVerilogHDLに決める。これまでにFPGAに関する特集の雑誌が貯まっている。
ざっと挙げて見ると、古いものから、
(イ)デザインウエーブマガジン 2007年7月号 付属FPGA基板を使った回路設計
FPGA基板が付録になった号で、Xilinxの開発環境のインストールと使い方の解説が主で、応用回路も高度なものが多く、HDLの勉強には役に立たない。
(ロ) 同 2007年8月号 FPGA基板で始める画像処理回路入門
画像処理に付録基板を使うときの解説。映像信号を作るときに参考になるが入門にはならない
(ハ) 同 2008年7月号 動画像をメモリーカードに記録する技術
画像処理回路とSDカードアクセスのVHDLの一部の紹介があるがこれも入門レベルでない。
(ニ) 同 2008年10月号 CPLD/FPGA活用回路&サンプル記述集
10以上のアプリケーションのVHDLやVerilogHDLのサンプルソースがある。7セグLEDのドライバーもあり、当面これが役に立ちそう。
(ホ)トランジスタ技術 2009年3月号 手軽にはじめるFPGA
手軽という割にはある程度のレベル以上のハードエンジニア向けの内容で、FPGAの内部の解説や高度な応用の紹介でソースコードは殆どない。
(へ)インターフェース 2009年9月号 ソフトウエア技術者のためのFPGA入門
ソフトウエア技術者向けというだけあって、VHDLとVerilogHDLのコードを並べたサンプルコードがあったり、ステートマシンの解説があったりして有用。
これ以外に、Latticeの基板が付録についた季刊の
(ト)デジタルデザインテクノロジー 1号(2009年春) FPGA超入門
(チ) 同 2号(2009年夏) HDL設計超入門
の2冊もあり、合わせると何と8冊のFPGA特集号が揃った。
これだけ沢山情報があっても、結論から言えば、コーディングに役に立ったのは、(ニ)の7セグLEDをダイナミックドライブするVHDLのソースコードと、(へ)の7セグLEDのVerilogHDLのコードだけであった。
何か適当な入門書を買って来て、最初から素直にやるのが結局は一番早道なのだろうが、このやりかたは昔からである。もともと入門書に書いてある通り何かを習得していくというのが嫌いなのだ。へそ曲がりで人の言うことに唯々諾々とついていくのに我慢できない。マニュアルも最初から読んだことがない。
年をとったのでなおさらその傾向が強まっている。それとこの世界に40年つきあっている。つまみ食いで何とかなるという横着な気持ちもある。さらに今まで一冊の入門書だけでマスターできたものはひとつもないという経験も加勢している。これが吉と出るか、凶と出るか。
論理合成が通らない(3/23/10)
まずブロックダイアグラムを描き、お手本どおり入出力を決める。おお、これは擬似コーディングと同じではないか。典型的なトップダウン設計だ。UARTはサンプルコードがあるし、今度の演習問題では、エコーバックさせるだけなのでバッファーも考える必要がない。7セグLEDも沢山サンプルがあるので、必要な信号線も決めやすい。
順調にブロックダイアグラムが出来た。快調だ。いそいそとXilinxの開発環境ISEを立ち上げて、コーディングを開始する。VerilogHDLでソースを書き始めた。今後のことを考えて、ひとつのモジュールに全部を書き込むのではなく、機能ごとにモジュールを分け、サブモジュールにする。
このあたりから、開発のスピードが落ち始めた。サブモジュールの呼び出しが今までの感覚と違う。何かおかしいのである。まず、サブモジュールを呼び出す順番がわからない。色々調べているうち、はたと気づいた。これは論理回路の記述なのでモジュールにわけても動作は同時なのだ。順番は関係ない。それとwireとregの区別がつかない。functionとmoduleの区別が分からない。assignの意味が分からない。段々不安になってきた。
どうも自信がなくなってきたので、UARTの実装の前に、7セグLEDのところだけ動かしてみることにことにした。UARTのモジュールはダミーにして、とりあえずXSTで論理合成(synthesize、コンパイルと同じ)をしてみる。
予感は当たって、膨大なエラーに見舞われる。単にトップモジュールを作り、4ビットのBCDデータから7セグLEDのエレメントにデコードするサブモジュール、それに入力のバイナリから4つの7セグLEDをダイナミックドライブするサブモジュールだけなのだが、殆どのデータの受け渡しでエラーが出ている。
Webの情報を頼りに少しづつエラーを減らしていく。データの受け渡しはreg変数だと思っていたが、wireでないと通らないところがある。regはフリップフロップ、wireは単なる接続と習った。どちらでも良いような気がするが良く分からない。遅延の関係かもしれないが、今は調べている暇はない。
言われるまま直して行って、データの受け渡しでエラーはなくなった。しかし次のエラーでは参った。
Operator <DIVIDE> must have constant operands or first operand must be power of 2
何い、HDLでは除算は2のべき乗でしか割れないのか。そんなこと聞いたことがないぞ。16ビットのバイナリカウンターを作り、UARTからの入力をカウントアップしていく。7セグLEDに9999まで表示させるため、バイナリーの各桁の10進数をだすのに、1000や100で割り、余りを計算しているところだ。
そんな馬鹿な。あわててWebに助けを求める。ほんとだ。これはHDLの仕様のようだ。対処法を考える。除算ができなければ、引き算を繰り返せばよい。HDLにはwhileもforループもある。気楽にwhileループを作り、回数を商にして回路を組み直した。
おやあ、論理合成(コンパイル)が終わらない。延々と解析を続ける。何がおかしいのだろう。いつまで待っても終わらないので、解析の中止ボタンを押す。それでも終わらない。何回か押して、やっと止まった。しかし、動作が重い。おかしいのでタスクマネージャーを立ち上げてみたらCPUの使用率は100%になったままだ。いけないISEが暴走している。ISEを終了させる。しかし状態は変わらない。結局、Windowsを再起動させられる羽目になった。
何だ、何だ。これはどうしたことだ。原因は分からないが、新しく加えたwhileループで論理合成が暴走したことに間違いはない。とにかく組み合わせ回路でwhileループが使えないことだけは確かだ。whileループの部分をコメントアウトして元へ戻す。
ISEの暴走は止まった。しかし、今度は、別のエラーで論理合成が止まる。何だと、「致命的エラー」(fatal error)だというではないか。
"FATAL_ERROR: SEG7DRVR:Port_Main.h:143:1.13.2.3 - This application has discovered an exceptional condition from which it cannot recover. Process will terminate. ...........
始めは大げさなメッセージなので驚いたが、Web情報によれば、ちょっとした記述ミスでもこの種のエラーは出るらしい。少しづつステートメントを減らして様子を見る。 しかし、なかなかエラーがとれない。
遂に、あるassignステートメントをとると。論理合成(Synthesize)がNo Errorとなることがわかった。別に難しいことをしているわけではない。reg変数を初期化しているだけである。initialブロックの中で、assignは使ってはいけないようだ。よく分からない。変数宣言でも初期化は出来るのでこのステートメントはなくてもかまわない。
やっとのことで最初のHDLの論理合成が終了した。No Errorとなると、FPGA内のリソースの使用状況などの壮大な結果リストが表示される。わからないまま、画面のレポートを見ていくと、ちゃんとした回路図まで出てくる。すごい。何か壮大な仕事をやりとげた気分になる。
しかし、肝腎のバイナリから4桁の10進数になおす部分ははずしたままである。このままではLEDは0しか表示しない。これでは練習にならない。Webをさらに探し回る。すると99までのバイナリーを組み合わせ回路で2桁のBCDに変換するリストが見つかった。100までなら、条件文を20ヶ(10の商と余り)書けばできるようだ。早速使わせてもらう。論理合成する。おお、さすがにこれはNo Errorで入った。
それにしても、自前のソースをコンパイル(論理合成)するだけでこれだけの騒ぎだ。次のピンアサインをやって動かすことを確認するステップに進む勇気が出てこない。恐らくコードは考えたようには動かないに違いない(書いたようにしか動かない)。動いたとしても今のコードではLEDの表示が動かない。
カウンターを動かすサブモジュールがまだ出来ていないのだ。このままでは決め打ちした数字しか表示されない。UARTを雑誌のサンプルから入れても良いが、これ以上コード量を増やして検証範囲を広げたくない気持ちもある。 タクトスイッチの入力回路を作ることにする。ひとまず動くのを確認してからブログに報告しようと思っていたが、いつ動くか見当がつかなくなってきた。とりあえずこのあたりで区切りをつけることにする。次回をお楽しみに。
| 固定リンク
「FPGA」カテゴリの記事
- CQ-STARM基板のCPU換装とDE0の到着(2010.11.09)
- フォトフレーム: SRAMを増設して15ビットカラーに(2010.11.01)
- フォトフレーム:最後まで難航したが遂に成功(2010.10.19)
- フォトフレーム: 画像らしいものが出てあともう一息(2010.10.10)
- フォトフレーム: デジタル液晶インターフェース実装(2010.09.28)
コメント
Lynx-EyEDさん お褒め頂きありがとうございます。たった今やっと、組み込んだテストプログラムが動き出したところです。まだまともな表示ではないですが、とにかく7セグのLEDが点滅しています。いやHDLは難しいですね。
そちらのブログも見せていただきました。リンクを張っていただいてありがとうございました。これからもよろしく。
投稿: がた老 | 2010年3月27日 (土) 00時23分
初めまして。いつも楽しく読ませて頂いております。
割り算ですが、論理合成ツールによってはそのようにエラーを吐くみたいです。自分も論理シフトと足し算で対処させられます。
オリジナル性の高いアプローチもすごく面白いです。
AVRユーザーの方々、スマートな方が多いので期待してます。
投稿: Lynx-EyED | 2010年3月26日 (金) 13時52分
がた老です。みなさん早速のコメントありがとうございました。
->ぶうさん
申し訳ありません。こういうステップを踏む学習が昔から一番の苦手でした(笑)。子供の時から、型にはめられるのがいやで成績は良かったけれど、叱られてばかりいましたね。ちなみに血液型はB型です。
->友水さん
仰るとおり単なるカウンターだけなら10進カウンター(キャリー付き)を並べれば良いのですが、本来はUARTからのデータを表示したりする汎用的なモジュールを考えていたので、こういうことになりました。いや難しいものですね。
投稿: がた老 | 2010年3月26日 (金) 02時45分
いつも楽しく読ませてもらっています。
>7セグLEDに9999まで表示させるため、バイナリーの各桁の10進数をだすため、1000や100で割り、余りを計算しているところだ。
ところで、7セグLEDを点灯させる回路を作る場合、二進化十進数(BCD)を扱うカウンタ(0b0000~0b1001)とデコーダのモジュールを作って、桁数分モジュールを作る方法が簡単な気がするのですが、何か意図があるのでしょうか?四則演算のテストやループ処理のテストを兼ねてるとか…?
投稿: 友水 | 2010年3月25日 (木) 22時33分
「HDL独習ソフトで学ぶCQ Endeavor Verilog HDL」
http://shop.cqpub.co.jp/book_guide/detail/38961/
はどうでしょう? 付録ソフトで自分の理解度に合わせた学習が出来ます。
投稿: ぶぅ | 2010年3月25日 (木) 12時58分