FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (4. IOMMUの特徴)

前回:msyksphinz.hatenablog.com

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。


2. データ構造

デバイス・コンテキスト(DC)は、デバイスとアドレス空間を関連付け、IOMMUがアドレス変換を行うためのパラメータを保持するデータ構造である。DCの位置は、device_idによって基数木データ構造のデバイス・ディレクトリ・テーブル(DDT)を走査して特定する。

デバイスが利用するアドレス空間は、デバイス制御がゲストOSに委ねられる際、第二段階のアドレス変換と保護が必要となる場合がある。ゲストOSは、デバイスが利用するIOVAをGPAに変換するための第一段階のページテーブルをオプションで提供できる。第一段階が不要な場合は、Bare設定によって第一段階を無効化し、第二段階でGPAをSPAに変換する。

デバイス制御がハイパーバイザやホストOSによって行われる場合、第一段階のみで必要なアドレス変換と保護が十分である。第二段階を無効化するには、Bare設定にする。

第二段階がBareでない場合、DCにはルート第二段ページテーブルの物理ページ番号(PPN)、仮想マシン単位でキャッシュの無効化を行うゲストソフトコンテキストID(GSCID)、および第二段アドレス変換スキームが保持される。

デバイスが複数のプロセス・コンテキストをサポートする場合、それぞれ異なる仮想アドレス空間が設定され、メモリアクセス時にprocess_idと共にdevice_idが通知され、アクセスアドレス空間が特定される。例として、プロセスごとに異なる仮想アドレス空間を使い分けるGPUがある。こうした場合、DCはprocess_idを基数木データ構造のルートプロセス・ディレクトリ・テーブル(PDT)でインデックス化して関連するプロセス・コンテキスト(PC)を特定する。

PDTが有効な場合、第一段階のアドレス変換はPCによって管理され、無効時はDCが制御を持つ。第一段階のアドレス変換制御にはルート第一段ページテーブルのPPN、プロセス単位でキャッシュ無効化を行うプロセスソフトコンテキストID(PSCID)、および第一段変換スキームが含まれる。

ゲストOSが制御するデバイスのMSIを処理するために、IOMMUはIMSIC内のゲスト割り込みファイルへのリダイレクト機能を持つ必要がある。MSIは通常のメモリ書き込みであるため、IOMMUは他のメモリ書き込みと同様のアドレス変換を適用する。ただし、ソフトウェアの簡素化とメモリ常駐割り込みファイルのサポートのため、IOMMUは仮想マシン向けのMSIを特別に扱うことが可能である。

この機能のため、IOMMUはDCにMSIアドレスマスクとアドレスパタンを追加し、MSIの送信先ページを特定する。IOMMUのこのMSI対応機能は、Advanced Interrupt Architecture仕様で規定されている。

また、DCはデバイスが許可されるトランザクションの種類を制御し、PCIeで定義されるアドレス変換サービス(ATS)などの使用許可も含まれる。

デバイス・コンテキストの形式

DCには2つの形式がある:

  • ベース・フォーマット:32バイトで、MSIの特別処理をサポートしない。
  • 拡張フォーマット:64バイトで、MSI変換用の追加フィールドを含む。capabilities.MSI_FLATが1の場合、拡張フォーマットが使用され、そうでなければベースフォーマットが使用される。

DDTとPDTの構成

DDTは、device_idの最大幅に応じて1~3レベルの基数木となるよう構成される。基数木の走査には、device_idを特定の形式でパーティショニングし、デバイス・ディレクトリ・インデックス(DDI)を取得して使用する。PDTもprocess_idの最大幅に応じて1~3レベルの基数木として構成される。PDT基数木の走査にはprocess_idの特定のパーティショニングで得られるプロセス・ディレクトリ・インデックス(PDI)を用いる。

すべてのRISC-V IOMMU実装は、メインメモリ上にDDTとPDTをサポートする必要があるが、I/Oメモリでのデータ構造のサポートは必須ではなく、仕様で禁止されていない。

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (4. IOMMUの特徴)

前回:msyksphinz.hatenablog.com

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。


1.4. IOMMUの特徴

  • RISC-V IOMMU仕様のバージョン1.0は、以下の機能をサポートしている:
  • メモリ・ベースのデバイス・コンテキストで、パラメータとアドレス変換構造を見つける。デバイス・コンテキストは、ハードウェアが提供する一意のdevice_idを使用して配置される。サポートされるdevice_idの幅は24ビットまでである。
  • ハードウェアが提供する一意のprocess_idを使用して、パラメータとアドレス変換構造を見つけるための、メモリベースのプロセスコンテキスト。サポートされるprocess_idは最大20ビットである。
  • 16ビットのGSCIDと20ビットのPSCID。
  • 2段階のアドレス変換。
  • RISC-V Privileged仕様[3]で規定されているページベースの仮想メモリシステムにより、CPU MMUとIOMMUに共通のページテーブルを使用するか、IOMMUに個別のページテーブルを使用するかをソフトウェアが柔軟に選択できる。
  • 最大57ビットの仮想アドレス幅、56ビットのシステム物理アドレス幅、59ビットのゲスト物理アドレス幅。
  • PTE アクセス済みビットとダーティビットのハードウェア更新。
  • RISC-V Advanced Interrupt Architecture [2]で規定されたMSIページテーブルを使用して、仮想割り込みファイルへのメモリアクセスとMSIアドレス変換を識別する。
  • Svnapot と Svpbmt 拡張。
  • PCIe ATS および PRI サービス [1]。翻訳要求に応答して、SPA ではなく GPA に IOVA を翻訳することをサポートする。
  • ハードウェア・パフォーマンス・モニター(HPM)。
  • ソフトウェアにサービスを要求するためのMSIおよびワイヤシグナル割り込み。
  • ソフトウェアがデバッグをサポートするためにアドレス変換を要求するためのレジスタ・インターフェース。
  • IOMMUがサポートする機能は、5.3節のcapabilitiesレジスタを使用して検出することができる。

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (3. 配置とデータの流れ)

前回:msyksphinz.hatenablog.com

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。


1.3 配置とデータの流れ

図5に示されるように、典型的なRISC-V HARTを搭載したSoCは、メモリコントローラ、複数のIOデバイス、そして2つのIOMMUインスタンスを備えている。 このSoCでは、各デバイスがシステムファブリックやインターコネクトに接続され、ルートポートを通じてIOプロトコルトランザクションとシステムインターコネクトトランザクションの変換が行われる。 PCIeの場合、ルートポートは、PCIeトランザクションをシステムインターコネクトトランザクションに変換し、デバイスはPCIeプロトコルでIOMMUにアクセスする。

最初のIOMMUインスタンス(IOMMU 0、図5におけるIO Bridge 0に関連)は、ルートポートをシステムファブリックに接続する。 これにより、複数のエンドポイントデバイスがSoCに接続される。 PCIeの場合、IOMMUはPCIe ATSプロトコルをサポートしており、デバイス側ATC(DevATC)を持つデバイスがIOMMU 0から取得した変換を保持できる。これにより、デバイスのパフォーマンスが最適化される。

二つ目のIOMMUインスタンス(IOMMU 1、図5のIO Bridge 1に接続)は、ルートポートを介さずに、デバイスAおよびデバイスBを直接システムファブリックに接続する構成である。 このような場合、デバイスはシステムの他の部分と直接インターフェースするため、効率的な通信が可能となる。

IOデバイスはIO仮想アドレス(VA、GVA、GPA)を使用してDMAトランザクションを実行する。 IO Bridgeは、関連するIOMMUを呼び出して、これらのIOVAをスーパーバイザ物理アドレス(SPA)に変換する。 このアドレス変換は主にインバウンドトランザクションに対して実行され、IOMMUはIOブリッジに対するルックアサイドIPの役割を果たす。

図6に示すように、IOMMUは以下のインターフェイスを持つ:

  • ホストインターフェイス:IOMMUのメモリマップされたレジスタにアクセスし、グローバルな設定やメンテナンスを行うためのインターフェイス。
  • デバイス変換リクエストインターフェイス:IO Bridgeから変換リクエストを受け取り、必要なデータ(デバイスID、プロセスID、IOVAなど)を基にアドレス変換を実行する。
  • データ構造インターフェイス:IOMMUがメモリにアクセスして必要なデータ構造(コンテキスト情報やページテーブルエントリ)を取得するためのインターフェイス。
  • データ変換完了インターフェイス:アドレス変換の結果をIOブリッジに返し、変換が成功したか、またはフォルトが発生したかを伝える。
  • ATSインターフェイス:PCIe ATS機能をサポートし、エンドポイントデバイスとの通信を行うためのインターフェイス。

IOMMUは、RISC-V HART同様に、物理メモリアトリビュート(PMA)と物理メモリ保護(PMP)チェックを行う必要がある。 IOMMUの暗黙のメモリアクセスもPMAチェックを受け、PMPチェッカはデバイスのハードウェアIDを基に適切なアクセス制御を行う。 IOブリッジやルートポートはハードウェアIDの認証を行い、例えばPCIeでは、アクセス制御サービス(ACS)のソース検証機能が用いられることがある。

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (2. 使用モデル)

前回:msyksphinz.hatenablog.com

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。


1.2 使用モデル

IOMMUは、非仮想化OSにおいて以下の主要なシステムレベルの機能を提供できる:

  • 誤動作するデバイスからの不正なメモリアクセスからOSを保護する。
  • 64ビット環境で32ビットデバイスをサポートする(バウンスバッファの回避)。
  • 断片化された物理アドレスへの連続した仮想アドレスのマッピングをサポートする(スキャッター/ギャザーリストの回避)。
  • 共有仮想アドレッシングのサポート。

IOMMUがない場合、デバイスは特権メモリを含むあらゆるメモリにアクセス可能であり、ハードウェアやデバイスドライバのバグ、または悪意のあるソフトウェアによって意図しない破損を引き起こす可能性がある。 IOMMUは、デバイスがアクセスできるメモリを制限することで、このような問題を防ぐメカニズムを提供する。OSはIOMMUをページテーブルで構成し、IOVAを変換してアクセス可能なアドレスを制御できる。

図は本論文より引用

レガシーな32ビットデバイスは4GiB以上のメモリにアクセスできないが、IOMMUのアドレス再マッピング機能により、デバイスは適切なアクセス許可があればシステム内の任意のアドレスに直接アクセス可能である。 IOMMUがない場合、OSはバウンスバッファを使用してデータをコピーする必要があり、システムパフォーマンスを低下させる。

IOMMUは、連続した仮想アドレス範囲を断片化された物理アドレスにマッピングできるため、スキャッター/ギャザーDMAの実行に便利である。 また、共有仮想アドレッシングをサポートすることで、デバイスとプロセスアドレス空間を共有し、DMAに使用される仮想アドレスをIOMMUがSPAに変換する。

非仮想化OSでIOMMUを使用する場合、必要なアドレス変換と保護機能は第一段階で十分であり、第二段階はBareに設定できる。

1.2.2 ハイパーバイザ

IOMMUは、仮想マシン上で動作するゲストOSが、ハイパーバイザの介入を最小限に抑えてI/Oデバイスを直接制御できるようにする。 ゲストOSが制御するデバイスはゲスト物理アドレスでプログラムされる。 デバイスがメモリアクセスを行うとき、IOMMUはハイパーバイザが提供するアドレス変換データ構造を参照し、ゲスト物理アドレスをスーパーバイザ物理アドレスに変換する責任を負う。

図は本論文より引用

ハイパーバイザは、各デバイスに対して第二段階のページテーブルを設定し、デバイスがアクセスできるメモリを対応するVMのメモリに制限する。 ゲストOSが制御するデバイスからのMSIを処理するため、ハイパーバイザはIOMMUを構成し、それらのMSIをIMSIC内のゲスト割り込みファイルやメモリ常駐割り込みファイルにリダイレクトする。 IOMMUは、ハイパーバイザが提供するMSIアドレス変換データ構造を使用してMSIのリダイレクトを行う。

図は本論文より引用

1.2.3 ゲストOS

ハイパーバイザは、ハードウェアエミュレーションやソフトウェアインターフェース(パラ仮想化)を通じて、ゲストOSに仮想IOMMU機能を提供できる。 ゲストOSは、仮想IOMMUが提供する機能を使用し、非仮想化OSと同様に第一段階のページテーブルを管理して利点を享受できる。 ハイパーバイザは仮想マシンのアドレス空間を仮想化し、デバイスからのメモリアクセスをVMに関連するメモリに制限するために第二段階のページテーブルを確立する。

二段階のアドレス変換が有効な場合、ゲストOSが管理する第一段階のページテーブルでIOVAがGPAに変換され、ハイパーバイザが管理する第二段階のページテーブルでGPAがSPAに変換される。

図は本論文より引用

IOMMUは、デバイスに対して第一段階および第二段階のページテーブルを使用してアドレス変換を実行するよう構成される。第二段階は通常ハイパーバイザによって使用され、GPAをSPAに変換し、デバイスのアクセスを対応するVMのメモリに制限する。第一段階は通常ゲストOSによって構成され、VAをGPAに変換し、デバイスのアクセスをVMメモリのサブセットに含める。

ホストOSやハイパーバイザは、デバイスを保持し、必要なアドレス変換と保護機能を第一段階で提供し、第二段階はBareに設定することもできる。

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (1. 概要)

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。

用語の定義

用語 定義
AIA RISC-V Advanced Interrupt Architecture
ATS / PCIe ATS Address Translation Services: A PCIe protocol to support DevATC
CXL Compute Express Link bus standard
DC / Device Context デバイスと、そのデバイスが割り当てられているVMを識別する、状態をハードウェアで表現したもの
DDT デバイス・ディレクトリ・テーブル: デバイスコンテキスト構造を見つけるために、一意のデバイス識別子を使って走査されるradix-tree構造。
DDI デバイス・ディレクトリ・インデックス: リーフまたはノンリーフDDT構造へのインデックスとして使用される一意のデバイス識別子のサブフィールド。
Device ID DMA または割り込み要求の送信元を識別するための最大 24 ビットの識別番号。PCIeデバイスの場合は、ルーティング識別子(RID)[1]。
DevATC デバイスのアドレス変換キャッシュ
DMA Direct Memory Access
GPA Guest Physical Address: 仮想マシン上の仮想化された物理メモリ空間
GSCID Gust soft-context identifier: 仮想マシンに割り当てられたデバイスの集合を一意に識別するためにソフトウェアが使用する識別番号。IOMMU は IOATC エントリーに GSCID を付けることができる。同じ GSCID でプログラムされたデバイスコンテキストは、同じセカンドステージページテーブルでプログラムされている必要がある。
Guest 仮想マシン上のソフトウェア
HPM Hardware Performance Monitor
Hypervisor 仮想化を司るソフトウェア
ID 識別子
IMSIC Incoming Message-signaled Interrupt Controller
IOATC IOMMU Address Translation Cache: IOMMUないのキャッシュ。アドレス変換に必要な構造をキャッシュする
IOVA I/O Virtual Address。デバイスによるDMAのための仮想アドレス
MSI Message Signaled Interrupts
OS Operating System
PASID Process Address Space Identifier: プロセスのアドレス空間を識別する。PASID値はリクエストのPASID TLPプレフィックスで提供される。
PBMT Page-Based Memory Types
PPN Physical Page Number
PRI Page Request Interface: PCIeによりOSのメモリマネージャに対してデバイスのページを作成するリクエストを可能にするためのプロトコル。
PC Process Context
PCIe Peripheral Component Interconnect Express bus standard
PDI Process-directory-index: 一意なプロセス識別子のサブフィールドで、リーフまたは非リーフPDT構造へのインデックスに使用される。
PDT Process-directory-table: プロセスコンテキスト構造を見つけるために、一意のプロセス識別子を使用して走査されるradix-treeデータ構造。
PMA Physical Memory Attributes
PMP Physical Memory Protection
PPN Physical Page Number
Process ID プロセス・コンテキストを識別するための最大20ビットの識別番号。PCIeデバイスの場合はPASID [1]。
PSCID Process soft-context identifier: ソフトウェアが一意のアドレス空間を識別するために使用する識別番号。IOMMU は IOATC エントリに PSCID を付けることができる。
PT Page Table
PTE Page Table Entry. ページテーブルのリーフまたは非リーフのエントリ
Reserved 将来の使用のために予約されたレジスタまたはデータ構造フィールド。データ構造の予約フィールドは、ソフトウェアによって0に設定されなければならない。ソフトウェアはレジスタの予約フィールドを無視し、同じレジスタの他のフィールドに値を書き込むときは、これらのフィールドに保持されている値を保持しなければならない。
RID / PCIe RID PCIe routing identifier
RO Read-only: レジスタ・ビットは読み取り専用であり、ソフトウェアで変更することはできない。明示的に定義されている場合、これらのビットは変化するハードウェアの状態を反映するために使用され、その結果、実行時にビットの値が変化するのを観測することができる。ビットを設定するオプション機能が実装されていない場合、ビットはゼロにハードワイヤリングされなければならない。
RW Read-Write: レジスタ・ビットはリード・ライトであり、ソフトウェアによって希望する状態にセットまたはクリアされる。ビットに関連するオプション機能が実装されていない場合、ビットはゼロにハードワイヤリングされることが許可されています。
RW1C Write-1-to-clear status: レジスタ・ビットは、読み出されるとステータスを示す。セット・ビットはステータス・イベントを示し、1bを書き込むとクリアされる。RW1Cビットに0bを書き込んでも効果はない。ビットをセットするオプション機能が実装されていない場合、ビットは読み取り専用で、ゼロにハードワイヤリングされなければならない。
RW1S Read-Write-1-to-set:レジスタ・ビットは、読み出されるとステータスを示す。ビットは1bを書き込むことでセットされる。RW1Sビットに0bを書き込んでも効果はない。このビットを導入するオプション機能が実装されていない場合、このビットは読み取り専用で、ゼロにハードワイヤリングされなければならない
SOC System on a chip, system-on-a-chipもしくはsystem-on-chipとも言われる。
SPA Supervisor Physical Address: メモリもしくはメモリにマップされたリソースにアクセスするための物理アドレス
TLP Transaction Layer Packet
VA Virtual Address
VM Virtual Machine: 実際のコンピュータ・システムの効率的で分離された複製。この仕様では、ハイパーバイザー拡張機能をサポートするRISC-Vハートが仮想化モードを1に設定して実行したときにアクセス可能なリソースとステートの集合体を指す。
VMM Virtual Machine Monitor: ハイパーバイザとも呼ばれる
VS Virtual Supervisor: 仮想モードのスーパバイザの権限
WARL Write any values, Read Legal values: ビットエンコーディングのサブセットに対してのみ定義されるレジスタフィールドの属性。
WPRI Write Preserve values, Reads Ignore values: 将来の使用のために予約されているレジスタ・フィールドの属性。

第1章. Introduction

システムMMU(SMMU)とも称される入出力メモリ管理ユニット(IOMMU)は、DMAが可能なI/Oデバイスをシステムメモリに接続するためのシステムレベルのMMUである。

IOMMUは、各デバイスに対してソフトウェアによりデバイスコンテキストを設定し、特定の仮想アドレス空間やデバイス固有のパラメータを関連付けることが可能である。これにより、各デバイスを個別のOS(ゲストOSまたはホストOS)に割り当てることができる。デバイスがメモリアクセスを開始する際、IOMMUは一意のデバイス識別子(例:PCIeのRID)により元のデバイスを識別する。

一部のデバイスは共有仮想アドレッシングをサポートし、プロセスアドレス空間をデバイスと共有可能である。これにより、DMAはコアカーネルのメモリ管理に依存し、アプリケーションやデバイスドライバの複雑さを軽減する。デバイスにバインド後、アプリケーションは割り当てられたバッファに対してDMAを指示可能である。ソフトウェアはプロセスコンテキストをデバイスコンテキストに設定し、IOMMUはデバイス識別子とプロセス識別子を用いて適切なコンテキストを特定する。

IOMMUは、IOVAをSPAに変換し、DMAのメモリ保護を実施するため、二段階のアドレス変換プロセスを採用する。CPUのMMUと同一のページテーブルフォーマットを使用し、同じページテーブルを共有可能である。二段階のアドレス変換を無効にするオプションはないが、各段階をベア(変換なし)に設定することで効果的に無効化可能である。

IOMMUの仮想メモリ方式はデバイスごとに設定可能である。デバイスのIOVAは、設定によりSPA、GPA、またはVAとなる。両段階がベアの場合、IOVAはSPAとなり、アドレス変換や保護は行われない。第一段階がベアで第二段階がベアでない場合、IOVAはGPAとなり、第二段階でGPAをSPAに変換し保護する。第一段階がベアでなく第二段階がベアの場合、IOVAはVAとなり、第一段階でVAをSPAに変換し保護する。両段階がベアでない場合、IOVAはVAとなり、二段階でVAからGPA、GPAからSPAに変換し、各段階で保護を実施する。

DMAアドレス変換は、メモリ常駐データ構造を用いるため、アクセス時間のオーバーヘッドが生じ得る。このオーバーヘッドを軽減するため、IOMMUはIOATC(IOMMUアドレス変換キャッシュ)を採用可能である。ソフトウェアはGSCIDやPSCIDを用いてデバイスやプロセスのコンテキストを管理し、IOATCの無効化操作を簡素化する。

一部のデバイスはDevATCを提供し、自身のメモリアクセス用にアドレス変換キャッシュを持つ。これにより、IOATCの負荷を軽減し、DMAレイテンシを最適化可能である。PCIeではATSプロトコルを使用し、デバイスとIOMMUが協調して変換をキャッシュし、ソフトウェアのデータ構造と同期する。また、デバイスはPRIを実装し、ページが利用不可の場合にメモリマネージャにページの常駐を動的に要求可能である。

IMSICを用いたシステムでは、IOMMUはハイパーバイザにより、デバイスからのMSIをゲスト割り込みファイルに向けるよう設定されることがある。MSIはメモリ書き込みであるため、通常のアドレス変換が適用されるべきだが、RISC-V高度割り込みアーキテクチャではIOMMUがMSIを特別に扱い、ソフトウェアを簡素化し、メモリ常駐割り込みファイルをサポートする。デバイスコンテキストにより、MSIのアドレス変換テーブルを設定し、仮想割り込みファイルへのアクセスを管理する。

Vivado Simulatorを使ってUVMに入門する (9. UVMのデバッグはやりにくい)

デバッグについて考えている。 例えば、今試しているUVMのデザインで、以下のようなエラーが出てしまった。

ERROR: File: /home/msyksphinz/work/sv/uvm_study/bfm/sample_monitor.sv Line: 24 : Accessing null or invalid reference to virtual interface is not allowed.
  • sample_monitor.sv
  task check_trans;
    forever begin
      @(posedge vif.valid) uvm_report_info("MON", $sformatf("addr=%02xh, data=%02xh", vif.addr, vif.data));
    end
  endtask // check_trans                                                                                                                                                                                                                                                                                                                                                                  

ここのどこが問題なのか分からん。要するにここのvifがインスタンス化されていないという話なのだと思うのだが。

--------------------------------------------------------
Name                 Type                    Size  Value
--------------------------------------------------------
sample_driver        sample_driver           -     @377 
  rsp_port           uvm_analysis_port       -     @396 
  seq_item_port      uvm_seq_item_pull_port  -     @386 
sample_monitor       sample_monitor          -     @543 
sample_sequencer     sample_sequencer        -     @406 
  rsp_export         uvm_analysis_export     -     @415 
  seq_item_export    uvm_seq_item_pull_imp   -     @533 
  arbitration_queue  array                   0     -    
  lock_queue         array                   0     -    
  num_last_reqs      integral                32    'd1  
  num_last_rsps      integral                32    'd1  
uvm_test_top         sample_test             -     @341 
  sample_env         sample_env              -     @358 
    sample_agent     sample_agent            -     @367 
--------------------------------------------------------

他のデザインだと、uvm_test_topをトップにして階層化されるはずだから、なんかおかしいなあ。

-----------------------------------------------------------------
Name                         Type                     Size  Value
-----------------------------------------------------------------
uvm_test_top                 sample_test              -     @341 
  env                        tb_env                   -     @359 
    sample_model             sample_env               -     @368 
      master                 sample_master_agent      -     @406 
        driver               sample_master_driver     -     @425 
          rsp_port           uvm_analysis_port        -     @444 
          seq_item_port      uvm_seq_item_pull_port   -     @434 
        monitor              sample_master_monitor    -     @454 
          ap_read            uvm_analysis_port        -     @473 
          ap_write           uvm_analysis_port        -     @463 
        sequencer            sample_master_sequencer  -     @483 

これをもとにいろいろ修正したのだが、今度は以下のエラーだ。

UVM_FATAL sample_driver.sv(12) @ 0: uvm_test_top.sample_env.sample_agent.driver [NOVIF] virtual interface must be set for: uvm_test_top.sample_env.sample_agent.driver.vif

今度は、sample_envをもとに解を導き出す。uvm_config_dbの記述が間違っていた。

  • 修正前
initial begin
  uvm_config_db#(virtual sample_if)::set(uvm_root::get(), "*.env.*", "vif", sif);
  run_test();
end
  • 修正後
initial begin
  uvm_config_db#(virtual sample_if)::set(uvm_root::get(), "*.sample_env.*", "vif", sif);
  run_test();
end

余談:+UVM_CONFIG_DB_TRACEというオプションもあるらしい。

dsim -image image -uvm 1.2 -waves waves.mxd +UVM_NO_RELNOTES +UVM_TESTNAME=$(TESTNAME) +UVM_CONFIG_DB_TRACE

riscv-perf-model を試す (1. Dhrystoneを試す)

github.com

とりあえず olympia の実行方法を試してみようと思う。

./olympia ../traces/dhry_riscv.zstf --report-all dhry_report.out
# Name:     Olympia RISC-V Perf Model 
# Cmdline:  ./olympia ../traces/dhry_riscv.zstf --report-all dhry_report.out
# Exe:      ./olympia
# SimulatorVersion: v0.1.0
# Repro:    
# Start:    Sunday Sun Oct 13 01:36:34 2024
# Elapsed:  0.002231s
# Sparta Version: map_v2.0.18
  [in] Arch Config: ArchCfg Node "" <- file: "/home/msyksphinz/work/riscv/perf/riscv-perf-model/arches/small_core.yaml"

Setting up Simulation Content...
Resources:
  cpu
Building tree...
Configuring tree...
Finalizing tree...
Inst Allocator: 0 Inst objects allocated/created
Inst Allocator: 1238 Inst objects allocated/created
Preparing to run...
Meta-Parameters:
  architecture: small_core
  is_final_config: false
Non-default model parameters: 8
Running...
olympia: STF file input detected
olympia: Retired 1000000 instructions in 2573632 cycles.  Period IPC: 0.388556 overall IPC: 0.388556
olympia: Retired 2000000 instructions in 5146960 cycles.  Period IPC: 0.388602 overall IPC: 0.388579
Running Complete
  Simulation Performance      : wall(14.9350), system(0.0000), user(14.9200)
  Scheduler Tick Rate  (KTPS): 412.231  (1k ticks per second)
  Scheduler Event Rate (KEPS): 6340.28 KEPS (1k events per second)
  Scheduler Events Fired: 94596913
Run Successful!
Saving reports...
  [out] Wrote Final Report Report def "@" on node "_global" -> "dhry_report.out" (format=text) (updated 1 times):
  1 reports written

Inst Allocator: 1238 Inst objects allocated/created
Inst Allocator: 1238 Inst objects allocated/created
Inst Allocator: 284 Inst objects allocated/created
  • dhry_report.out に情報が出力されるようになっている。
  Report "top"
    Report "top.cpu"
      Report "top.cpu.core0"
        Report "top.cpu.core0.decode"
            FetchQueue_utilization_UF = 0
            FetchQueue_utilization_UF_probability = 0
            FetchQueue_utilization_count0 = 82
            FetchQueue_utilization_count0_probability = 1.33323e-05
            FetchQueue_utilization_count1 = 4
            FetchQueue_utilization_count1_probability = 6.50355e-07
            FetchQueue_utilization_count2 = 0
            FetchQueue_utilization_count2_probability = 0
            FetchQueue_utilization_count3 = 22
            FetchQueue_utilization_count3_probability = 3.57695e-06
            FetchQueue_utilization_count4 = 0
            FetchQueue_utilization_count4_probability = 0
            FetchQueue_utilization_count5 = 2