概要
UVM-MSは、Universal Verification Methodology for Mixed-Signalの略で、UVM-MS 1.0としてAccelleraが標準化している。
UVM-MSは、従来のUVMを拡張して、AMS/DMSの検証を効率化するための統一された検証環境を提供する。 SystemVerilogをベースにしつつ、アナログ信号のモデリングと制御が可能になる。
用途例
- ADC/DACのようなデータ変換器の検証
- 電源管理IC(PMIC)やRF回路のテスト
- SoC設計における、アナログ部とデジタル部の統合検証
UVM-MSの構成
UVM-MSは下記3つの要素から構成される。
1. MS-Bridge
UVM環境とDUT(アナログ回路)を接続するためのBridgeモジュール。
2. MS-Proxy
uvm_driverからのトランザクションを変換してBridge-Coreと通信するためのクラス。
3. Bridge-Core
データ型の変換や信号の調整を行い、アナログ/デジタル間のやり取りを制御するモジュール。

AgentはMS-ProxyへのハンドルとSV IFへのvirtual IFをもつ。IFはAgentとMS-Bridge間、もしくはMS-Bridgeの中に持つ。
Bridge-CoreはDUTのネットタイプに基づいてSV/Verilog-AMSでモデリングされる。
MS-Bridgeの中にはBridge-Coreが複数存在可能、MS-Proxyは1つ持つ。
DriverやMonitorはMS-Proxyを駆動するためのメソッドを追加する。ただし、この変更はUVM Factory overridesの対応範囲内なので、通常のUVMテストベンチと同様の手順でMixed-Signalへのエンハンスが可能となっている。
MS-Bridge
MS-BridgeはVerilog-AMSまたはSVで記述された、DUTとAgentをシームレスに接続するためのモジュール。MS-ProxyとBridge-Coreをインスタンスする。

Bridge-CoreはDUTに合わせてSVまたはVerilog-AMSで記述される。MS-Proxyによって、Bridge-Coreの言語を変更しても、APIを維持すればAgentを変更せずに使用が可能となる。
ただし、Verilog-AMSは対応するデータ型が限られているため、MS-ProxyはOOMR(Out of Module Reference)を使用してBridge-Coreと接続する。これにより、Verilog-AMSのデータ型の制限を回避できる。
また、MS-BridgeのI/OはSVのInterconnect型で定義する。Interconnect型は型を持たないため、モデルの抽象化レベル(SV/Verilog-AMS)に応じて接続の型をシミュレータが解決する。しかし、Interconnect型を宣言している階層ではProbeやAssignは許可されていない。したがって、Probe/AssignはBridge-Coreの中で行う。これにより、Probe/Assignの制限を回避する。また、MS-BridgeのI/Oはポータビィリティのためinout で宣言することが推奨されている。
MS-Proxy
MS-Proxyはuvm_agentとアナログモデル(Bridge-Core)を接続するクラス。MS-Proxyを使用することで、Bridge-Coreの抽象化レベルに依らないAPIを定義することが可能となる。MS-Proxyはuvm_agentからBridge-Coreを駆動するためのAPIの提供、アナログ/デジタルのデータ型の変換、メッセージのハンドリングなどを行う。
通常のUVMではSV IFを用いて駆動するが、Mixed-Signalにおいて以下のような問題が発生する。SV IFにBridge-CoreのAPIを定義するとfactory overrideができない。SV IFにVerilog-AMSが対応していない。よって、MS-ProxyによってBridge-Coreを駆動する。
Bridge-Core
SV/Verilog-AMSで記述したアナログモデルを置く。Bridge-CoreはMS-Proxyで制御される。Bridge-CoreがSVの場合は通常通りデータをやり取りする。
Bridge-CoreがVerilog-AMSの場合は、アナログ信号をデジタルで使用する場合はabove(), cross(), absdelta()を使用(ドキュメントではcross()よりabove()が推奨されている)。デジタル信号をアナログで使用する場合はtransition()を使用する。また、Bridge-CoreがVerilog-AMSのときはuvm_ms_includes.vamshをインクルードする。
MS-Bridgeの作成例
sin波を生成するアナログモデルを作成する。sin波は周波数、振幅、位相、DC成分で表現可能。UVM-MSではこれらの値をuvm_sequence_itemで定義する。uvm_driveがトランザクションを発行してMS-Proxyに渡す。MS-Proxyは与えられた設定値をReal型に変換するなどしてBridge-Coreに渡す。Bridge-Coreはその値に基いてSin波を生成する。
複数の生成器を組み合わせることも可能。例えば、Sin波にノイズを付与したい場合、ノイズを生成するBridge-Coreを作成して、Sin波が渡されているnetに接続する。ノイズ用のuvm_sequence_itemの定義や、sequneceによりMS-Proxyを経由してノイズ用のBridge-Coreを駆動する。

UVMテストベンチとの変更点
共通して、uvm_macros.svhと同様にuvm_ms_includes.svhをインクルード、uvm_pkgと同様にuvm_ms_pkgをimportする。
`include "uvm_macros.svh"
`include "uvm_ms_includes.svh"
import uvm_pkg::*;
import uvm_ms_pkg::*;Agent
既存のuvm_agentをExtendしてMS用のuvm_agentを作成する。
Driver
既存のuvm_driverをExtendしてMS-Proxyを駆動させるためのメソッドを追加する
// Example
virtual task drive_transaction(osc_ms_transaction req);
bridge_proxy.push(.ampl(req.ampl),.bias(req.bias),.freq(req.freq));
endtaskMonitor
既存のuvm_monitorをExtendしてMS-Proxyからのデータを受け取るメソッドを追加する。
Sequence_item
既存のuvm_sequnece_itemをExtendしてMS-Proxyで使用するFieldを定義する。
Scoreboard, Coverage
特に変更なし。
メッセージング
UVMは`uvm_{info, warning, error, fatal}など共通的なメッセージマクロを持つ。
しかし Bridge-CoreがVerilog-AMSで作成された場合、Verilog-AMSはUVMをサポートしていないため、UVMメッセージマクロを使用できない。
そこで、Bridge-Coreではuvm_ms_includes.vamshをインクルードする。同時に、MS-Bridgeではuvm_ms_includes.svhをインクルードする。
uvm_ms_includes.svhではuvm_report_*()関数のラッパー関数であるuvm_ms_report_*()が定義されている。また、uvm_ms_includes.vamshでは、アップワードネームリファレンスでuvm_ms_report_*()を使用する`uvm_ms_*メッセージマクロを定義している。
そうすることで、Bridge-Core では`uvm_ms_*マクロを使用することが可能となる。
Bridge-CoreがSVのときは通常のUVM環境同様に`uvm_*メッセージマクロを使用できるが、一貫性のため`uvm_ms_*メッセージマクロを使用することが推奨されている。
サンプルコード
Bridge-CoreがSVのときのサンプルコード
// MS-Proxyのコンフィグをpackageで定義
package pkg;
import uvm_pkg::*, uvm_ms_pkg::*;
`include "uvm_macros.svh"
`include "uvm_ms_includes.svh"
class uvm_config extends uvm_object;
real analog_out, digital_data;
`uvm_object_utils(uvm_config)
function new(string name = "uvm_config");
super.new(name);
endfunction
endclass
endpackage
// MS-Bridge
module ms_bridge #(
parameter init = 255
)(
output real analog_out
);
import uvm_pkg::*, uvm_ms_pkg::*;
`include "uvm_macros.svh"
`include "uvm_ms_includes.svh"
// MS-Proxy
import pkg::*;
class proxy extends uvm_ms_proxy;
function new(string name);
super.new(name);
endfunction
virtual function uvm_config get_parameters();
uvm_config cfg = new();
cfg.analog_out = i_core.analog_out;
cfg.digital_data = i_core.digital_data;
return(cfg);
endfunction
virtual function void set_parameters(uvm_config cfg);
i_core.digital_data = cfg.digital_data;
endfunction
endclass
// Instantiate MS-Proxy class
proxy i_proxy = new("i_proxy");
// instance of Bridge-Core
bridge_core #(
.init(init)
) i_core (
.analog_out(analog_out)
);
endmodule
// Bridge-Core(SV)
module bridge_core #(
parameter init = 255
)(
output real analog_out
);
logic [7:0] digital_data = init;
assign analog_out = digital_data / 256.0;
endmodule
module top;
ms_bridge #(
) i_ms_bridge (
.analog_out()
);
// uvm_testの代わり。
import pkg::*;
initial begin
uvm_config cfg = new;
cfg.digital_data = 128;
i_ms_bridge.i_proxy.set_parameters(cfg);
#5;
cfg = i_ms_bridge.i_proxy.get_parameters();
$display("%d", cfg.digital_data);
$display("%f", cfg.analog_out);
$finish();
end
endmodule
// 出力
// 128
// 0.5


コメント