FPGA開発日記

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

Vivado Simulatorを使ってUVMに入門する (2. sequencer, monitor, driver)

もう何回目になるのかわからないが、そろそろUVMを覚えなければならないのでVivado Simulatorを使ってUVMに入門してみよう。

今回はVivado 2023.2を使っている。

参考にしているのは例によって以下のウェブサイトだ:

sites.google.com

前回に追加して、以下のファイルを追加した:

uvm_driver

デザインに対して制御信号や入力データを与える役割を持つ。

  • sample_driver.sv
class sample_driver extends uvm_driver;
  `uvm_component_utils(sample_driver)

  function new (string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    uvm_report_info("DRIVER", "Hi");
  endtask

endclass // sample_driver

uvm_monitor

デザインの信号を監視し、テストベンチにその情報を報告する。DUT (Device Under Test) に対して信号を駆動せず、単にDUTから出力される信号や内部の動作を観測する。

  • sample_monitor.sv
class sample_monitor extends uvm_monitor;
  `uvm_component_utils(sample_monitor)

  function new (string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    uvm_report_info("MONITOR", "Hi");
  endtask

endclass // sample_monitor

uvm_sequencer

トランザクション(データ、命令、操作など)を生成し、それをドライバに送信する。テストデータや命令の流れを管理し、設計検証のためにDUTに入力される信号を間接的に制御する。

  • sample_sequencer.sv
class sample_sequencer extends uvm_sequencer;
  `uvm_component_utils(sample_sequencer)

  function new (string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    uvm_report_info("SEQR", "Hi");
  endtask

endclass // sample_sequencer

uvm_agent

sequencer, driver, monitor を1つにまとめたコンポーネントで、特定の役割を持ったコンポーネントの集合体として動作する。

  • sample_agent.sv
class sample_agent extends uvm_agent;
  `uvm_component_utils(sample_agent)
  sample_driver    driver;
  sample_monitor   monitor;
  sample_sequencer sequencer;
  function new (string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    driver    = sample_driver::type_id::create("driver", this);
    monitor   = sample_monitor::type_id::create("monitor", this);
    sequencer = sample_sequencer::type_id::create("sequencer", this);
  endfunction
  task run_phase(uvm_phase phase);
    uvm_report_info("AGENT", "Hi");
  endtask
endclass

sample_env をアップデートする。

sample_agent を埋め込む。

`include "uvm_macros.svh"
import uvm_pkg::*;

class sample_env extends uvm_env;
  `uvm_component_utils(sample_env)

  sample_agent agent;

  function new (string name, uvm_component parent);
    super.new(name,parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    agent = sample_agent::type_id::create("agent", this);
  endfunction

  task run_phase(uvm_phase phase);
    uvm_report_info("ENV", "Hello ENV");
  endtask
endclass

実行結果は以下のようになった。

UVM_INFO @ 0: uvm_test_top [TEST] Hello World
UVM_INFO @ 0: uvm_test_top.env [ENV] Hello ENV
UVM_INFO @ 0: uvm_test_top.env.agent [AGENT] Hi
UVM_INFO @ 0: uvm_test_top.env.agent.sequencer [SEQR] Hi
UVM_INFO @ 0: uvm_test_top.env.agent.monitor [MONITOR] Hi
UVM_INFO @ 0: uvm_test_top.env.agent.driver [DRIVER] Hi