Lチカ入門!ソフトウェア屋のためのHDL事はじめ
回路は怖くない!どう接続するかではなく,どう動かすか
- 著者・講師:森岡 澄夫(Sumio Morioka) / インターステラテクノロジズ
- 企画編集・主催:ZEPエンジニアリング株式会社
- 関連製品:[Webinar/KIT]Tiny FPGA実習!高校生から始めるHDLプログラミング
- 関連製品:[VOD/KIT]一緒に動かそう!Lチカから始めるFPGA開発【基礎編&実践編】
- 関連製品:[VOD/KIT]Xilinx製FPGAで始めるHDL回路設計入門
- 関連記事:USBカメラの動画キャプチャ&描画用 Pythonプログラム
- 関連記事:ライブラリ完備!組立式ラズパイI/O増設ボード MCC DAQ HATSファミリ誕生
- 関連記事:FPGA/Zynqで作るカスタム・コンピュータ・チップ
回路図をそのまま言語で書くのではない
FPGAやLSIに搭載するディジタル回路が,ハードウェア記述言語(以下HDL; Hardware Description Language.具体的には,Verilog HDL,System Verilog,VHDLなど)を用いて設計されるようになってから,20年以上が経ちました.
しかし,業界標準の設計手法として十分に定着はしているものの,初心者でも気軽に回路を設計できるようになったわけではありません.
HDLは文字どおり,ハードウェアを記述することを目的としているのですが,論理素子(ANDやORといったゲートや,フリップフロップなど)を使った回路図をそのまま一対一対応で表現することを目的とした言語ではありません.また,HDLを使った回路設計をする際,回路図を作成する能力が要るわけでもありません(あったほうがベターですが,必須ではない).これらの点が正しく理解されていない場合もあるようです.
ソフトウェア用言語のような逐次処理でもない
それならばHDLが,PythonやCといった組み込み用途で利用されているプログラミング言語と同じなのかというと,まったく違います.一見プログラミング言語風のキーワードが使われているにも関わらず,プログラミング言語と同じ考え方でコーディングするわけではありません.
手続き型言語のように処理を上から下へ順番に書いていくわけではありませんし,ブロッキング代入やノンブロッキング代入など,少し聞きかじった程度では真意のわからない用語や概念も出てきます.こうした事項が,実態以上にわかりにくい印象をHDLに与えています.
回路の動きを組み立ててそれを書くのが基本
HDLでディジタル回路(正確にはRTLだが,本記事の範囲では理解しなくてよいので説明は割愛)を書くときには,回路を「どう接続するか」ではなく「どう動かすか」を最初に考えます.
回路図設計からHDL設計への転換期の頃に頻繁に言われていたことですが,これは今でも変わりません.
ソフトウェアをコーディングするときには変数を用意し,そこにデータを置いて演算や制御処理を進めますが,これはディジタル回路も同じです(図1).ただし,回路では変数ではなく「レジスタ」と呼び(実体はDフリップフロップ),次の大きな違いがあります.
値が代入されるタイミング
特別なクロック信号が来た瞬間です(図2).クロックが来るたびに,必ず代入されます.このため,値を変えたくないときは,自分自身を代入します.
値が代入されるレジスタ
クロックが来るたび,すべてのレジスタに同時に代入されます(図2).ソフトウェアのように代入文が置かれた時点で代入されるわけではありません.
値のビット数や型
任意のビット数にでき,たとえば1024ビットというようなレジスタも設置できます.型の概念も薄く,単なるビット列というだけであって,それを整数とみなすのも浮動小数点数とみなすのも自由です.
厳密にはソフトにおけるメモリ(配列)を使うことなどもできますが,まずは上記の動きを明確に理解することが,HDLを使えるようになるための最低ラインです.
Lチカでのレジスタ動作の検討例
マイコンでもよく作るLチカを例に考えてみましょう.
LEDの値(0か1の1ビット値.LowかHighかの電圧に対応)をレジスタに置き,0→1→0→1→…と繰り返し反転させるのが処理の最も基礎的な部分です(図1).それにより,クロックに合わせてLEDが点滅します(周波数はクロックの1/2).
一般に,クロック信号は数M~200MHzと非常に速く,この速度でLEDを点滅させると目に見えません.そこで,クロックが来るたびに,値が 1 増えるカウンタとして使うレジスタを用意し,たとえば0.5秒経つまで待ってから,LEDレジスタを反転させます.
この動きを表で書くと,図3左のようになります.
レジスタは2つあり,クロックが来るたびに両方のレジスタに同時に代入されます.こうしたレジスタ変化のさせ方を考えることが,そのまま「回路の動きを考える」ことになります.
HDLには,クロックが来たときに各レジスタに何を代入するかを書きます(図3右).代入値をif文やcase文を使って指定するわけです.繰り返しですが,それらの代入文は並列実行されます(全レジスタが同時に代入されることに対応).さらにビット数の指定などを適宜加えれば,HDLとしてのコードはできあがりです(図4).
以上の考え方は,Verilog HDLであってもVHDLであっても同一ですから,1つの言語をマスターすれば他も使えるようになります.
実用設計のために追加で必要になる知識
このようにして書いたHDLコードは,すべてのレジスタ(フリップフロップ)のクロック入力がクロック信号に直結された,単相同期式順序回路というものを表しています.FPGAやLSIを設計するときには,回路をこの単相同期式で組むことが最も原則的なルールの1つです.回路図設計の時代にはなかなかマスタできない難しいルールだと言われていたのですが,HDLを使うとあっさりできます.
むしろHDLを使う場合,速度や位相の異なる複数種類のクロックを使う設計(本記事よりももっと大規模な設計でしばしば登場する)のほうが不慣れになりやすいです.CDC(Clock Domain Crossing)と呼ばれる設計知識を,次のステップで身に付けてください.〈森岡 澄夫〉