02日目~モデルの構造と実行フェーズ

モデルの基本構造と、実行フェーズについて説明します。

基本構造

  • すべてclassで定義していきます。以下のようなインスタンス構成をとります。
    • class uvm_env
      • class uvm_agent
        • class uvm_driver
        • class uvm_sequencer
        • class uvm_monitor
    • uvm_agentは、特定の役割毎に用意します。
      • ahb_master_agent
      • ahb_slave_agent など

実行フェーズ

UVMでは、特定のメソッド(task / function)が順番に呼ばれる仕組みがあります。これを理解することで、特定の処理を意図したタイミングで実施しやすくなります。読んでわからないところは流し読みし、 あとから読み返してください。唯一、run_phaseだけが「task」です。

  • function new
    • これはUVMというより、classに付随する初期化メソッドです。コンストラクタと呼びます。
  • function void build_phase
    • uvm_env, uvm_agent, ...のインスタンスは、この中で生成します。生成の際は、「type_id::create(...)」というUVM独特の文法を使います。newで生成してもダメではないのですが、それをすると UVMファクトリーの機能が使えなくなり、再利用性の上で特に困ったことが起きるかもしれません。
    • virtualインスタンスのinterface情報を get する処理も、ここで行います。ubusのdriverやmonitorのサンプルを見るとわかります。
  • function void connect_phase
    • 接続処理を行います。OVMのときはここでvirtual interfaceの接続を行っていましたが、UVMでは基本手法が変わりました。assign_viを定義してここでつなぐもよし、UVMの新しい手法を使うのもよし、 です。個人的には、新しい手法が出るのには訳があるので、新しい手法を使うようにしています。このへんは慣れの問題かと。
  • function void end_of_elaboration_phase
    • ほとんど使ったことがありませんが、接続してからrunするまでの間にしておきたいことがあれば、記述してください。
  • function void start_of_simulation_phase
    • ほとんど使ったことがありませんが、接続してからrunするまでの間にしておきたいことがあれば、記述してください。
  • task run_phase
    • 唯一、時間を扱えるのがここです。時間を扱う処理をすべてこの中に記述します。
  • function void extract_phase
    • 使ったことがありませんが、runが終わってから「しておきたいこと」があれば記述します。意味としては「引き抜く」「書き出す」なので、期待値をファイルに書き出したいときなどに使うのがいいの かもしれません。
  • function void check_phase
    • あまり使っていませんが、何かチェック処理があれば、ここに記述してください。
  • function void report_phase
    • スコアボードのqueueをチェックして「レポート」するときによく使っています。

UVMには、VMM系の人も使いやすいように、同じ意味を持った違う名前のメソッドで呼び出す機構があります。上記はOVM系列です。

ここで重要な事は、上記メソッドが「順番に実行される」ということです。デルタ遅延の影響が気になって、programブロックで書かないと!ということから解放されるわけです。もちろん、run_phase内で fork-joinしたときの並列処理間のデルタ遅延問題は残りますが、それはeventを利用したりして対処すればいいのかなと。