FPGA上のBK-0010エミュレーター-パート2


前編


既にVivadoでブロックデザインを操作できた場合、多くの標準IPの外観は設定されたパラメーターによって異なることがわかります。 たとえば、AXI-GPIOモジュールは、「デュアルチャネルを有効にする」パラメーターに応じて、シングルチャンネルまたは2チャンネルにすることができます。



BK-0010プロジェクトでは、この技術を使用することも便利であり、今日はその方法を学びます。



また、このパートでは:





アーキテクチャの概要



BK-0010のすべての要素(CPU、RAM、ROM、ポート)は、MPIバスを介して相互接続されています。 MPIは、DECのQバスの簡易バージョンであり、16ビットの組み合わせ(アドレスとデータが同じ導体で送信される)双方向バスです。



元のMPIバスは非同期で、さまざまな信号がナノ秒単位で正規化されたいくつかの遅延で設定されていました。



MPIバスでの交換中に、スレーブデバイスがあまりにも長い間応答しなかった場合、バスエラーが中断されました(たとえば、Z80のような、何もありませんでした)。 このアーキテクチャ機能はBK-0010で使用されるため、エミュレートする必要があります。



同様の内部バスがBK-0010プロジェクトで使用されます。 もちろん、FPGA内で双方向のアドレスバスとデータバスを組み合わせて作成しても意味がないため、ADDR、DATAIN、DATAOUT(16ビットすべて)の3つのバスがあります。 バスは完全に同期し、ナノ秒の遅延はありません。



BK-0010では、MPIバス上にマスターデバイスが1つしかありませんでした-CPUなので、バスキャプチャ、ダイレクトメモリアクセスなどの手順を実装しませんでした。



残りの信号は、最も適切なオリジナルを残しました:



SYNC-マスターがADDRバスにアドレスを設定したことを示す信号。 メモリはバイト単位でアドレス指定されますが、偶数アドレスのバイトデータは常に下位8ビットで送信され、奇数ビットは上位ビットで送信されます。



DIN-マスターが以前に設定されたアドレスで読み取りを要求したことを示す信号。 マスタが1バイトのみを必要とする場合、読み取りは常に2バイトワードで行われ、2番目のバイトは無視されます。



DOUT-マスターがDATAOUTバスにデータを設定し、以前に設定したアドレスにデータを書き込む必要があることを示す信号。



WTBT-バイト操作が実行されていることを示す信号。 記録サイクルでのみ設定されます。 マスターは、DATAOUTバスの下位8ビット(偶数アドレスの場合)または上位(奇数アドレスの場合)のいずれかに書き込むバイトを設定する必要があります。 残りのバイトはスレーブによって無視されます。



RPLY-スレーブがマスターにバスサイクル(読み取りサイクルでデータを設定するか、書き込みサイクルで受信したデータ)を通知する信号。 64サイクル以内に信号が届かない場合、バスエラー割り込みが発生します。



VIRQ-割り込み要求信号。



IAKO-割り込み信号の確認/要求。 この信号は、中断を必要とする可能性のあるすべてのデバイスを順番に通過しました。 現時点でデバイスが中断する必要がない場合、チェーンに沿ってさらに信号を送信しました。 現時点でデバイスが割り込みを必要とする場合、それ以上信号を送信せず、割り込みアドレスの送信サイクルを開始しました。 IAKO信号伝送チェーンにおけるデバイスの位置により、相対的な優先順位が決まりました。



BK-0010の外部デバイスからの割り込みが使用されるため、これらの信号が必要です。











バスとインターフェース



バスとインターフェースでは、対処する必要のある用語の混乱があります。 Verilog / VHDLでは、バス(バス)は同じタイプのデジタル信号の接続セットであり、複数桁の数字を送信するように設計されています。 たとえば、8ビットで構成されるデータバス。



また、バスは一般に、異種信号のセット(データ、アドレス、制御の信号)とも呼ばれます。 たとえば、PCIバス、AXI4バス、この場合はMPIバス。 このデザインは、Xilinx Vivadoの用語ではインターフェイスと呼ばれます。



いくつかの場所でMPIバスを使用する必要があります。 このインターフェイスには、少なくともCPU、RAM、ROM、外部デバイスのポートがあります。 便宜上、説明を単一のエンティティとして作成するため、各信号を毎回手動で接続する必要はありません。



これを行うには、Vivadoで[ツール]-> [インターフェイスツールの作成]を呼び出します。







ここに必要なすべての信号を追加し、それらの方向を示します(スレーブの場合、方向はマスターと比較して自動的に反転します)、どの信号が存在する必要があるか、または存在しない可能性があるかを示します。 別途、クロックとリセット信号に注意してください。



インターフェイスの説明はxml形式で保存されます。 プロジェクトで使用するには、プロジェクトのプロパティでこのファイルのあるフォルダーへのパスを追加する必要があります。







構成可能なIPモジュール



相互接続の例を使用して、このようなモジュールを作成する方法を考えてみましょう。 インターコネクトは、マスターポートとスレーブポートを相互接続するモジュールです。 ポートの数は事前にわからないため、このパラメーターはカスタマイズ可能でなければなりません。 この場合の相互接続モジュール自体は、バス幅やバッファリングを変換する必要がないため、非常に単純です。 組み合わせロジックで実装できます。



この例では、プロセッサは1つしかありませんが、インターコネクトによると、スレーブポートが1つあれば十分です。 マスターポートの数は、MASTER_INTERFACESパラメーターで指定されます。







モジュールの現在のリビジョンは、最大11個のマスターポートをサポートしています。当然、この番号は誰でも実行できます。



それでは、モジュールを作成しましょう



  1. モジュールのヘッドファイルを作成します。このファイルには、このモジュールに到達できるすべての信号が記述されています。 それらの多くがあります-すべての可能なMPIポート(1スレーブ+ 11マスター)+ clkおよびrst信号のすべての信号を記述する必要があります。 これまでのところ、clk信号とrst信号は完全に組み合わせロジックに基づいているため、モジュールでは使用されていませんが、均一性、突然のバッファリングなど、将来必要になるものはすべて残しました。



    module MPI_Interconnect ( input [15:0] S00_ADDR, input [15:0] S00_DATA_W, output [15:0] S00_DATA_R, input S00_SYNC, output S00_RPLY, input S00_DIN, input S00_DOUT, input S00_WTBT, input S00_IAKO, output reg S00_VIRQ, output [15:0] M00_ADDR, output [15:0] M00_DATA_W, input [15:0] M00_DATA_R, output M00_SYNC, input M00_RPLY, output M00_DIN, output M00_DOUT, output M00_WTBT, output M00_IAKO, input reg M00_VIRQ, ...
          
          





  2. モジュールをIPに変換します([ツール]-> [新しいIPの作成とパッケージ化])。 その後、プロジェクトマネージャーに新しいパッケージIPアイテムが表示され、プロジェクト設定を構成できます。



  3. [インターフェイス]タブで、前の手順で作成したインターフェイスの説明を使用して12のMPIインターフェイスを作成します。



  4. 作成されたMPIインターフェイスとモジュール信号の間のマッピングを構成します。 モジュールの信号にインターフェイスのポートと同じ名前が付けられている場合、Vivadoはこのマッピングを自動的に行いますが、この場合、信号M00_ADDRおよびM00_DINがゼロマスターポートに属し、M02_DOUTが2番目のポートに属していると推測できません。手でタッチアップします。







  5. MASTER_INTERFACESパラメーターに可能な値のリストを設定します。 リストに加えて、16進値または10進値、チェックボックス、ラジオボタンも使用できます。







  6. ポートの可視性条件を構成します。 S00_MPIおよびM00_MPIポートは常に表示されます。M01_MPIポートをオプションとしてマークし、$ MASTER_INTERFACES> 1の条件でのみ表示されるようにします。他のマスターポートについても同様です。







  7. Verilogの条件付きコンパイルオプションを使用して、MASTER_INTERFACESパラメーターの値に応じて、モジュールの操作に必要なロジックを作成します。



      if (MASTER_INTERFACES > 1) begin assign M01_ADDR = S00_ADDR; assign M01_DATA_W = S00_DATA_W; assign M01_SYNC = S00_SYNC; assign M01_DIN = S00_DIN; assign M01_DOUT = S00_DOUT; assign M01_WTBT = S00_WTBT; assign M01_IAKO = (M00_VIRQ == 1) ? S00_IAKO : 1; end ...
          
          





これで、150個の信号の代わりに、ブロックデザインで使用できる12個のインターフェイスのきちんとしたリストができました。







この段階では、MPIインターフェースを備えたいくつかのモジュールも作成します。これらはRAMおよびROMモジュールです。 MPIバスのロジック、具体的には読み取りサイクル(ROM)または読み取りと書き込み(RAM)を実装するステートマシンに基づいて、それらの実装は非常に簡単です。 システムモニター用、Fokal言語インタープリター用、テストモジュール用の3つのROMモジュールがあります。 各モジュールのサイズは8 KBで、それらはすべてFPGAブロックメモリに基づいています。 RAMモジュールのサイズは32KBです。



重要な点は、名前空間がサポートされていないため、異なるROMを初期化するための配列には異なる名前を付ける必要があるということです。 同じ名前でも(異なるIPであっても)、1つのROMが別のROMの内容で初期化され、これに関する警告が発行されない場合、診断が困難になります。



プロジェクトの収集を開始します。 これまでのところ、相互接続モジュールとRAMおよびROMモジュールが少しあります。







clk信号とrst信号はまだどこにも接続されていません。クロックドメインを処理したらすぐに接続します。 RAMモジュールには多くの未接続信号があります-ディスプレイコントローラーはそこに接続されます。 相互接続の左側には、MPIスレーブインターフェイスがあります。 CPUモジュールがここに接続されます。



継続する。






参照資料



MPIインターフェースの説明

MPIインターコネクトモジュール

RAMモジュール

システムモニターROMモジュール

Fokal言語インタープリターROMモジュール

テストサブシステムのROMモジュール



All Articles