HDL コードを実装する際に守るべきベスト プラクティスは何ですか?
より一般的なソフトウェア開発分野と比較した場合の共通点と相違点は何ですか?
古いスレッドのようなものですが、0.02 ドルを入れたかったのです。これは、Verilog/VHDL に固有のものではありません。一般的なハードウェア設計について詳しく説明します。特に、カスタム ASIC の合成可能な設計です。
これは、デザインに関する(学問的ではなく)長年の業界経験に基づく私の意見です。それらは特定の順序ではありません
私の包括的な声明は、検証の実行を設計することです。ハードウェア設計では、検証が最も重要です。バグは、実際のシリコンで見つかった場合、はるかに高価です。再コンパイルすることはできません。そのため、プリシリコンにはより多くの焦点が当てられています。
制御パスとデータ パスの違いを理解する。これにより、よりエレガントで保守しやすいコードを作成できます。また、ゲートを保存して X 伝播を最小限に抑えることもできます。たとえば、データ パスにはリセッタブル フロップが必要ではなく、制御パスには常に必要です。
検証前に機能を証明します。正式なアプローチまたは波形のいずれかを使用します。これには多くの利点があります。2 について説明します。まず、タマネギの皮を剥くのに無駄な時間を節約できます。多くのアプリケーション レベルの設計 (特に学習中) やほとんどのコース作業とは異なり、コード変更のターンアラウンド タイムは非常に長くなります (複雑さに応じて、10 分から数日)。コードを変更するたびに、エラボレーション、lint チェック、コンパイル、波形の立ち上げ、そして最後に実際のシミュレーションを行う必要があり、それ自体に何時間もかかる場合があります。第 2 に、コーナー ケースにヒットするのが困難になる可能性がはるかに低くなります。これはプレシリコン検証に関するものであることに注意してください。これらは確かにポストシリコンにヒットし、多くの$$$の費用がかかります. 私を信じて、機能を証明するための初期費用は、リスクを大幅に最小限に抑え、努力する価値があります。これは、最近の大学卒業生を納得させるのが難しい場合があります。
「チキンビッツ」をどうぞ。チキン ビットは、シリコンの機能を無効にするためにドライバーを介して設定される MMIO のビットです。これは、信頼度が高くない変更を元に戻すことを目的としています (信頼度は検証作業に正比例します)。プレシリコンで考えられるすべての状態に到達することはほぼ不可能です。ポストシリコンで証明されるまで、設計に対する信頼は真に満たすことはできません。バグを露呈する 0.000005% の確率でヒットする状態が 1 つしかない場合でも、ポストシリコンではヒットしますが、プレシリコンでは必ずしもヒットしません。
制御パスでの例外は、何としても回避してください。新しい例外が発生するたびに、検証作業が 2 倍になります。これは説明が難しいです。別のブロックが使用するメモリにデータを保存する DMA ブロックがあるとします。保存されたデータ構造が、実行中の機能に依存しているとしましょう。保存されるデータ構造が関数ごとに異なるように設計することにした場合は、検証作業に DMA 関数の数を掛けるだけです。このルールに従うと、保存されるデータ構造は、コンテンツの場所がハードコーディングされているすべての関数で使用できるすべてのデータのスーパーセットになります。DMA 保存ロジックが 1 つの関数に対して検証されると、すべての関数に対して検証されます。
インターフェイスを最小化します (制御パスの最小化を参照)。これは、例外の最小化に関連しています。まず、すべての新しいインターフェースには検証が必要です。これには、新しいチェッカー/トラッカー、アサーション、カバレッジ ポイント、およびテストベンチのバス機能モデルが含まれます。第二に、検証作業を指数関数的に増やすことができます! キャッシュ内のデータを読み取るためのインターフェイスが 1 つあるとします。ここで、(なんらかの奇妙な理由で) メイン メモリを読み取るための別のインターフェイスが必要であると判断したとします。検証作業が 4 倍になりました。これらの組み合わせを任意の時点で検証する必要がありますn :
仮定を理解し、伝達する。これが欠けていることが、通信の問題をブロックするためのブロックの主な理由です。完全に検証された完璧なブロックを持つことができます..しかし、すべての仮定を理解していないと、ブロックが接続されたときに失敗します。
潜在的な状態を最小限に抑えます。設計の状態 (意図的または非意図的) が少ないほど、検証に必要な労力が少なくなります。同様の関数を 1 つの最上位関数 (シーケンサーやアービターなど) にグループ化することをお勧めします。この高レベルの関数を識別して、可能な限り多くの小さな関数を包含するように定義することは非常に困難ですが、そうすることで、状態を大幅に排除し、バグの可能性を大幅に排除できます。
ブロックを離れるときは、常に強い合図を出してください。ほとんどの場合、それをフロップすることが解決策です。エンドポイント ブロックがそれに対して何をするかはわかりません。完全な実装に直接影響するタイミングの問題が発生する可能性があります。
パフォーマンスに悪影響が及ばない限り、食事タイプの FSM は避けてください。Mealy FSM は、Moore よりもタイミングの問題が発生する可能性が高くなります。
.. そして最後に、私が最も嫌いなもの: 「壊れていない場合は、修正しないでください」関連するリスクとバグのコストが高いため、多くの場合、ハッキングは問題を解決するためのより実用的なソリューションです。他の人は、既存のコンポーネントの利用について言及することで、これを回避しています。
従来のソフトウェア設計との比較については、次のとおりです。
離散イベント駆動型プログラミングは、まったく異なるパラダイムです。Verilog 構文を見て、「ああ、C のようだ」と考える人もいますが、これは真実からかけ離れたものではありません。構文は似ていますが、考え方が異なる必要があります。たとえば、従来のデバッガーは、合成可能な RTL ではほとんど意味がありません (テストベンチの設計は異なります)。紙上の波形は、利用できる最良のツールです。ただし、そうは言っても、FSM 設計は手続き型プログラミングを模倣する場合があります。ソフトウェアのバックグラウンドを持つ人は、FSM に夢中になる傾向があります (最初はそうだったと思います)。
System Verilog には、テストベンチ固有の機能がたくさんあります。完全にオブジェクト指向です。テストベンチの設計に関する限り、従来のソフトウェア設計と非常によく似ています。ただし、それにはもう 1 つの次元、時間の次元が関連付けられています。競合状態とプロトコルの遅延を考慮する必要があります
検証に関しては、それも異なります(そして同じです)。主なアプローチは 3 つあります。
...完全を期すために、テストベンチ設計のベスト プラクティスについても説明する必要があります...しかし、それはまた別の機会にします
長々とすみません..私は「ゾーン」にいました:)
このトピックに関する最良の本はReuse Methodology Manualです。VHDL と Verilog の両方をカバーしています。
特に、ソフトウェアで完全に一致しないいくつかの問題:
同じものもあります
Verilog や VHDL などの HDL は、実際にスパゲッティ コードを助長しているようです。ほとんどのモジュールは、任意の順序で配置できる複数の「always」(Verilog) または「process」(VHDL) ブロックで構成されます。モジュールの全体的なアルゴリズムまたは機能は、多くの場合、完全にわかりにくくなっています。コードがどのように機能するかを理解することは (自分で書いていない場合)、骨の折れるプロセスです。
数年前、VHDL 設計のより構造化された方法を概説しているこの論文に出くわしました。基本的な考え方は、各モジュールには 2 つのプロセス ブロックしかないということです。1 つは組み合わせコード用で、もう 1 つは同期 (レジスター) 用です。読みやすく保守しやすいコードを生成するのに最適です。
FPGA については、ザイリンクスにこのページがあります。ほとんどすべてが他の FPGA ベンダーに適用されるか、または同等のルールがあります。ASIC 設計には多くのことが適用できます。
インテルは、このページの下に、推奨される HDL コーディング スタイルと設計の推奨事項 (PDF)を用意しています。