EDIT : 詳細説明 re: 一番下の 3 番目のコメント。これの長さについてお詫び申し上げます!
VHDL にも、C と同様に関数とプロシージャがあります (OK、C はそのプロシージャを「void 関数」と呼びます!) そして、C と同様に、同じ種類の順次コード構成 (変数、ループ、 if 文、C の switch に似た case 文など)。
これまでのところ、これはすべて合成可能です。その他の一部の VHDL 機能は、シミュレーション専用です (合成可能なコードをテストできるようにするため)。そのため、シミュレーションでは、C のように、ファイルを開いたり、読み書きしたり、ポインター (アクセス型) を使用してメモリを処理したりできます。VHDL のこれらの部分が合成できない理由がわかると思います!)
しかし、VHDL との違いは、この順次コードをプロセスでラップするために数行追加する必要があることです。C では、それが起こります。典型的な C プログラムは単一のプロセスです (複数のプロセスが必要な場合は、ライブラリまたは fork や pthread などの OS 機能に頼る必要があります)。
しかし、VHDL はさらに多くのことを実行できます。複数のプロセスを非常に簡単に作成し、それらをシグナルで相互接続し、再利用可能なコンポーネントとしてラップし、「for ... generate」を使用して複数のプロセスを作成することができます。繰り返しになりますが、すべて合成可能です。たとえば、システムの実行中にハードウェアのサイズ (プロセス数) を変更することはできません!
キー: 変数の代入ではなく、シグナルの代入のルールを理解してください。変数は C とほとんど同じように機能します。信号はありません!代わりに、安全で同期されたプロセス間通信を簡単に提供します。その方法を確認するには、「延期された割り当て」、デルタ サイクル、wait ステートメント、およびプロセスがどのように中断して再び起動するかを理解する必要があります。
ここで2つの質問をしているようです:
(1) - C のように関数を使用できますか? まさにその通り; 有用な型と関連する関数、プロシージャをパッケージにラップし、そのパッケージを複数の設計で再利用することにより、C よりも優れた結果を得ることができます。これは C++ の再利用可能なクラスに少し似ており、いくつかの長所と短所があります。
(2) VHDL でエンティティ、アーキテクチャ、およびコンポーネントを完全に回避できますか? コンポーネントを避けることはできますが (「VHDL ダイレクト エンティティ インスタンス化」を検索してください)、ある時点でエンティティとアーキテクチャが必要になります。
少なくとも回避できるのは、シグナルで入力 (clk、count) を受信し、他のシグナルで LED に送信する、ジョブを実行する単一のプロセスを作成することです。
これらすべての信号をポートとして持つエンティティと、プロセスを含むアーキテクチャを作成し、その信号をポートに接続します。これは簡単です - 定型的なものです。FPGA では、これらのポートと LED が配線されている実際のピンとの間のマッピングも定義する必要があります。合成したら完成ですよね?.. そうではありません。
外部ポートのない別の「テストベンチ」エンティティを作成します。これには、(直接インスタンス化された) エンティティ、そのポートに接続する一連の信号、およびエンティティの入力ポートを駆動し、その出力ポートを監視する新しいプロセスが含まれます。(ベスト プラクティスは、テストベンチの自己チェックを行い、何か問題が発生したときにアサートすることです!) 通常、「clk」は独自のワンライナー プロセスから発生し、テストベンチとエンティティの両方をクロックします。
これで、テストベンチをシミュレートして、必要な詳細レベルで設計が機能する (または機能しない) ことを確認できます。それが機能するとき - 合成。
詳細については EDIT を参照してください: re: コンポーネント、プロシージャ、関数。
エンティティ/コンポーネントは主要なツールです (必要に応じてコンポーネントを無視できます。エンティティについては後で扱います)。
プロシージャと関数は通常、1 つのプロセスで一緒に機能します。それらがパッケージにリファクタリングされた場合、他の同様のプロセスで再利用できます (同じデータ型での操作など)。一般的な抽象化は、データ型に加えて、データ型で動作するすべての関数とプロシージャをパッケージにラップしたものです。これは、C++ クラスに多少似ています。関数は、初期化子 (ソフトウェア用語では「ファクトリー」パターンとも呼ばれます) として、任意の宣言領域でも使用されます。
しかし、主なツールはエンティティです。
C は基本的にプロセスのレベルで停止するため、組み込み C プログラマにはおそらくなじみのないレベルです。
SPI マスターのような物理ブロックをプロセスとして記述した場合は、そのプロセスをエンティティにラップします。これは、ポート (エンティティ内では信号のように動作します) を介して世界の他の地域と通信します。ジェネリックを介してパラメータ化できます(たとえば、メモリの場合はメモリサイズ用)。エンティティは、いくつかのプロセス、他のエンティティ、およびプロセスにうまく適合しなかった他のロジック (たとえば、プロセスがクロックされたクロックされていないロジック) をラップできます。
システムを作成するには、「構造 HDL コード」(便利な検索用語!) でエンティティを相互接続します。おそらくそれらの階層全体をトップ レベルのエンティティにします。通常、これを FPGA に合成します。
シミュレーションを介してシステムをテストするには、外部ポートを持たない別のエンティティ (テストベンチ) に最上位エンティティ (=FPGA) を組み込みます。代わりに、FPGA のポートがテストベンチ内の信号に接続されます。これらの信号は接続します...それらのいくつかは他のエンティティに接続します-おそらくメモリのモデルまたはSPIスレーブ周辺機器に接続するため、SPIトランザクションをシミュレートできます...それらのいくつかは、FPGA刺激を供給するテストベンチのプロセスによって駆動されます応答をチェックし、エラーを検出して報告します。
ベスト プラクティスには、作成する各エンティティのテストベンチ、つまり単体テストが含まれます。SPI マスターは、他の誰かの SPI スレーブおよびテスト プロセスに接続して、SPI トランザクションを開始し、正しい応答を確認する場合があります。このようにして、最上位のテストベンチから問題を診断しようとするのではなく、エンティティ レベルで問題を特定して修正します。
基本的な例を次に示します。
彼は、位置関連と (後で) 名前付き関連の両方によるポート マッピングを示していることに注意してください。Ada のように、関数の引数に両方の形式を使用することもできますが、位置関連のみを許可する C では使用できません。
「vhdlguru」が言っていないことは、名前付きの関連付けが非常に好まれるということです。位置による関連付けは混乱やバグの原因となるからです。
これは役に立ち始めていますか?