02日目~モデルの構造と実行フェーズ
モデルの基本構造と、実行フェーズについて説明します。
基本構造
基本構造
- すべてclassで定義していきます。以下のようなインスタンス構成をとります。
- class uvm_env
- class uvm_agent
- class uvm_driver
- class uvm_sequencer
- class uvm_monitor
- class uvm_agent
- uvm_agentは、特定の役割毎に用意します。
- ahb_master_agent
- ahb_slave_agent など
- class uvm_env
実行フェーズ
実行フェーズ
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を利用したりして対処すればいいのかなと。