カミは死んだ

Paper Is Dead ... osz

UVM Cookbook 眺めてみた - The Test Is The Starting Point For The Build Process

はじめに

UVM Cookbookを眺めてみた、の続きです。今日はTestbenchのThe Test Is The Starting Point For The Build Processです。

The Test Is The Starting Point For The Build Process

  • UVMテストベンチのbuildプロセスはテストのクラスからトップダウンで始まるよ。
  • テストクラスのbuildメソッドはbuild phaseの中で一番最初にコールされてテストメソッドの設定でUVMテストベンチのビルドが決まるよ。
  • テストのbuildメソッドの機能はこんなだよ。
  • 検証環境において、buildメソッドではテストによらず全部同じことをするよ。
  • テストのbuildがどう実行されるかを説明するのに、ブロックレベルの検証環境を見てみるよ。
  • この例ではSPIマスターがDUTと接続されていて、2つのagentを持つよ。一つはAPBバスインタフェースで、もう一つがSPIインタフェースだよ。

Block Level UVM Test Bench - Hierarchical Layers

test---------------------------------------------
  env--------------------------------------------          -------------
     |Score|◇---◇|APB agent(monitor/SQR-Driver) <- IF -> | DUT
     |Board|◇---◇|SPI agent(monitor/SQR-Driver) <- IF -> |(SPI w/ APB)
     Configuration(apb config/spi config)

Factory Overrides

  • UVM factoryはあるUVMクラスを構成時に他の派生クラスで置き換えるよ。
  • この機能はコンポーネントの振る舞いの変更やアップデート、また、コンフィギュレーションオブジェクトを拡張するのに使えるよ。
  • factoryのオーバーライドはターゲットオブジェクトが構成されるまえに指定する必要があるよ。
  • なのでbuildプロセスの最初でやると便利だよ。

Sub-Component Configuration Objects

はてなMarkdown記法でverilogがSyntax Hilightingされるようですね。

タイトルのとおりですが、

```

で囲いつつ、最初の```の後にverilogをつければOKのようです。

```verilog

verilogコードをここに書きます)

```

systemverilogには対応していないので、SVコードもひとまずverilogと指定すればよいですね。 てきとうなSVコードを張ってみます。 ⇒ classなどはHilightingされませんが十分見やすいと思いますた。

module bench #(
    parameter CONSTRAINT_ENABLE  = 0,
    parameter CONSTRAINT_DISABLE = 1
);

    // Randomization Example
    class packet_base;
        rand bit [7:0] header;
        rand bit [2:0] length;
        rand bit [7:0] payload_dynamic_array[];  // 8bit-wide dynamic array
        rand bit [7:0] payload; 

        // dist   : Control Generation Rate. Specify in Decimal (NOT hex)
        //                                  16:1 = 10:1
        // Generate header in 0, 1, 15 in the rate of 1:2:5.
        constraint const_header {header dist {[0:0]:=1
                                              , [1:1]:=2
                                              , [15:15]:=3 };
                                };
        // if, -> : Use condition based on the other value.
        //          Place ";" at each if/else if/else
        constraint const_length { if      (header==16) length==2;
                                  else if (header==2)  length==3;
                                  else    length==4;
                                };

        // Override new function
        function new;
            if (this.randomize()==1) begin
                // Generate dynamic array according to the length
                this.payload_dynamic_array = new[this.length];
                foreach (this.payload_dynamic_array[i])
                    this.payload_dynamic_array[i] = this.payload;

            end
            else
                $display("Randomization Failed.\n");
        endfunction

        function void set_all_constraint_mode(int mode);
            string temp_str;
            // mode=0 : DISABLE 
            // mode=1 : ENABLE 
            const_header.constraint_mode(mode);
            const_length.constraint_mode(mode);
            case (mode)
                // %m shows hierarchial class name
                0 : temp_str="disable";
                default : temp_str="enable";
            endcase
            $display("[%m] set_all_constraint %s", temp_str);

        endfunction

        function void display;
            $display("header:0x%02x, lendth:0x%02x, payload_dynamic_array.size:%1d"
                      , i_pkt.header, i_pkt.length
                      , i_pkt.payload_dynamic_array.size
                    );
            foreach (i_pkt.payload_dynamic_array[i])
                $display("  payload[%1d]=%02x", i, i_pkt.payload_dynamic_array[i]);
        endfunction
    endclass

    // Generate packet statiscally
    int num_of_list_of_pkt = 5;
    packet_base i_pkt;
    packet_base i_list_of_pkt[] = new[num_of_list_of_pkt];

    initial begin
        // Generate Packet w/ constraints
        $display("--- Generate w/ Constraints ---");
        foreach (i_list_of_pkt[i]) begin
            $display("----- i_pkt[%1d]", i);
            i_pkt = new;
            i_pkt.display();
            i_list_of_pkt[i] = i_pkt;
        end

        // Generate Packet w/o constraints
        $display("\n--- Generate w/o Constraints ---");
        i_pkt.set_all_constraint_mode(CONSTRAINT_DISABLE);

        foreach (i_list_of_pkt[i]) begin
            void'(i_pkt.randomize());  // Implicit void casting
            $display("--- i_pkt[%1d]", i);
            i_pkt.display();
            i_list_of_pkt[i] = i_pkt;
        end
    end 

    /*
   if (i_pkt.randomize() == 1) begin
       $display("Randomization Succeeded.\n");
   else
       $display("Randomization Failed.\n");
   */

endmodule

UVM Cookbook 眺めてみた - TestBench/Build

はじめに

UVM Cookbookを眺めてみた、の続きです。今日はTestbenchのTestBench/Buildです。

TestBench/Build

  • UVMテストベンチの最初のフェーズはbuildだよ。
  • テストベンチを構成するuvm_componentはbuildフェーズでオブジェクトになるよ。
  • buildフェーズは階層をトップダウンで作るよ(順番はちゃんと制御されるよ)。
  • こういうのをdeferredにテストベンチを作るといいます(繰越の・・・日本語だと意味不明です。前がちゃんと終わったら次をやる制御に使う言葉のようです。例えばjQuery.Deferredとか) 。

The UVM Build flow in the context of the test bench

テスト実行のイメージはこんなです。

module tb_top
  initila begin
    run_test() -----> (指定されたテストを呼び出し) -----> test = new();
                                                   テストベンチクラスをトップ階層(test)からトップダウンでビルド。
                                                   env -- agent -- drivers -- monitors 等々
                                                   テスト実行
                                                   UVM phaseの制御が全て終了してUVM$finishをコールしたら
                                                   テストベンチモジュールのinitialブロックに戻る。
    <---------------------------------------------- $finish
  end
end module: tb_top
  • UVMテストベンチはトップ階層module(テスト)のinitialブロックでrun_test()が呼ばれたときに活性化されるよ。
  • run_test()はUVMのstaticなメソッドでstringの引数でテストを定義してfactoryを通じてテストを構成するよ。
  • その後、テストクラスが持つbuildメソッドをコールしてbuild phaseを開始するよ。
  • テストのbuild phase実行中に、テストベンチコンポーネントコンフィギュレーションオブジェクトが準備されてテストベンチモジュールのinterfaceがコンフィギュレーションオブジェクトにあるvirtual interfaceにアサインされるよ。
  • 次にコンフィギュレーションオブジェクトがテストのコンフィギュレーションテーブルに渡されるよ。
  • 最後に次の階層がビルドされるよ。

  • 次の階層ではテストで準備したコンフィギュレーションオブジェクトを取得して更なるコンフィギュレーションをするよ。

  • コンフィギュレーションオブジェクトは次の階層を設定する前に、(その階層の設定によって)修正されることがあるよ。
  • 条件に応じてベンチを構成することでテストベンチのトポロジーや階層構造や変更できるよ。
  • build phaseはトップダウンで動作するので、ビルドはは階層ツリーの一番下にいくまで繰り返されるよ。

  • build phaseが完了したらconnect phaseでコンポーネント間の接続をするよ。

  • connect phaseはボトムアップで実行するよ。
  • connect phaseが終わるよ、残りのUVMフェーズを実行して、それらが全部終わるとテストベンチのmoduleに戻るよ。

UVM Cookbook 眺めてみた - The Env

はじめに

UVM Cookbookを眺めてみた、の続きです。今日はTestbenchのEnvの話です。

The Env

Env(Environment)は、サブコンポーネントのブロックを集めたコンテナコンポーネントだよ。

Block Level Env

  • ブロックレベルのUVMテストベンチでは、envはDUTのインタフェースとやりとりするagentをまとめるのに使うよ。
  • envもagentみたいにSystemVerilogのパッケージにまとめるよ。
  • envはagentの他にも以下のcomponentsを持つよ。
    • Configuration object ・・・ envが持つどのコンポーネントをビルドするかを制御するconfiguration object。 envのconfiguration objectはenvのagentが持つconfiguration objectを制御するハンドルも持つよ。 これらはset_config_objectで設定するよ。
    • Scoreboards ・・・ スコアボードはanalysis componentでDUTの動作が正しいか確認するよ。UVM scoreboardsはagentのモニタからのanalysis transactionを使うよ。たいてい2つのtransactionを比較するよ。
    • Predictors ・・・ プレディクターは入力に対する期待値を作るよ。たいていスコアボードなんかと一緒に使われるよ。
    • Functional Cverage Monitors ・・・ 機能カバレッジモニタになるanalysis componentはcovergroupsをもって機能カバレッジ(テストで何が発生したかの情報)を集めるよ。たいてい機能カバレッジモニタはDUT毎に異なる作りだよ。
  • 例えば、ブロックレベルのテストベンチはagentとanalysis componentsを持つenvをビルドするテストで構成されるよ。

Integration Level Env

  • ブロックを統合してサブシステムを作るには、垂直統合的な再利用、つまり、ブロックレベルのテストベンチで使われるenvをマージして上位レベルのenvの作成、をするよ。
  • ブロックレベルのenvは各ブロックをテストするのに必要な構成を提供するけど、envを統合するとブロックのつなぎ目のインタフェースはDUT内部になって表に出てこなくなるから、統合するとenvには無駄な部分が出てくるよ。
  • だから上位レベルで統合したenvはDUT内部の出てこないインタフェースをパッシブにしたり、そんなagenetを読み込まないようにする必要があるよ。
  • テストでこういうconfigurationをできるようにするために、下位階層の各envはひとつ上位階層のenvのconfiguration objectの内包されて上の階層から制御できる必要があるよ。
  • こんな風にenvをマルチレイヤー化して作るよ。

The UVM Testbench Build and Connection Process

  • UVMテストベンチが入力データ送信する前に、テストベンチ階層をビルドして検証コンポーネント間を接続する必要があるよ。

UVM Cookbook 眺めてみた - The Agent

はじめに

UVM Cookbookを眺めてみた、の続きです。今日はTestbenchのAgentの話です。

The Agent

  • UVMのagentはピンレベルのインタフェースを扱うuvm_componentsを集めたものだよ。
  • ピンレベルのトランザクションを生成したりモニタしたりするよ。
  • agentに関連するクラスはpackageを使って一つの名前空間で扱うよ。

  • agentは下記で構成するよ。

    • sequence_item ・・・ シーケンスアイテムを使ってピンレベルの動作を生成したりモニタで監視したりするよ。
    • driver ・・・ sequence_items をピンレベルに変換するよ。
    • monitor ・・・ ピンレベルの動作をsequence_itemsに変換してスコアボードとかに送るよ。
    • configuration object ・・・ agentのビルドや接続をどうするかを設定するコンテナオブジェクトだよ。
  • agentはdriverやmonitorがピンレベルにアクセスするvirtual interfaceのリファレンスとなるconfiguration objectを持つべきだよ。
  • configuration objectでagentのサブコンポーネントのビルド情報や、動作切り替え(エラー挿入、プロトコル変更)に対応すりょ。
  • configuration objectでdriverやmonitor、カバレッジやスコアボードのON/OFFをするよ。
  • agentが持つ他のクラスは、
    • Functional Coverage Monitor ・・・ プロトコル特有のカバレッジ情報を集めるよ
    • Scoreboard ・・・ スコアボード
    • A responder ・・・ 応答用のドライバ、というか、driverのスレーブバージョン。
    • Sequences ・・・ ユーティリティ的なSequence。というか、ドライバのAPI層。

UVM Cookbook 眺めてみた - Introduction, Testbench Architecture

はじめに

EDAの世界では検証手法からリンターまでメソドロジーが流行っているのでしょうか。そんなメソドロジーの代表格といえばUVM。少しUVMを体系的に理解してみたいと思い立ちメンターさんのCookbookを読み始めたいと思いました。これを選ぶ理由は、昔現実逃避のために読んだOVM Cookbookが好印象だったからであります。
ということでCookbookを眺めたときのメモを残してみたいと思います。とはいえ500ページもある内容の都合、各章(?)のTopic Overviewを拾っていきたいと思います。
何日続くかな...osz

UVM Cookbook

メンターさんのVerification Academyから入手できると思います。会員登録などは必要に応じてどうぞ。
こちらのサイトAWSで動いているようですね。

Introduction

UVM Cookbookは500ページもあるのですが、それを最初から目を通す残念なIDがこちらとなります...osz。ですが最初から目を通さずにはいられないのでIntroductionから行ってみます。

Cookbook/Introduction

  • OVMがコアで、それにResource、TLM2、Phasingなどを追加したそうです。
  • 結構、痔が爺さん。

Testbench Architecture

Testbench

  • UVMスタイルのテストベンチ、build()、ブロックレベル/システムレベルのベンチ、Agent、Phase、Factoryの説明をするよ。

Topic Overview

How an UVM testbench differs from a traditional module based testbench

  • 古いスタイルのVerilogテストベンチはシミュレータが全てをstatic objectで扱うので常にメモリを使っているよ。
  • SVはclassを使ってメモリ生存期間が終わるとGBされるよ。
  • メソッドはNON-TCMなfunctionとTCMなtaskがあるよ。
  • シミュレーションの最初でmoduleがstatic objectで作られて、その後classが作られるよ。
  • なので、classはmoduleを持てないよ。
  • classはnew()したときにインスタンス化されてメモリ確保されるよ。
  • インスタンスにnullを入れるとGBするよ。

The UVM Package

  • UVMパッケージには主に3つの基底クラスがあるよ。
    • uvm_component ・・・ テストベンチ構成用
    • uvm_objects ・・・ データオブジェクト用
    • uvm_transactions ・・・ 入出力データ生成、分析用
  • 最上位のmoduleはDUTを持ってベンチと接続するよ。
  • 最上位のmoduleはinitialブロックでrun_test()を呼んでUVMのフェーズを開始するよ。

UVM Testbench Hierarchy

  • UVMテストベンチはuvm_componentのクラスで構成されるよ。
  • UVMの最上位クラスはtestだよ。ベンチのコンフィギュレーションと下階層方向へのビルド、シーケンスを開始してテストするよ。
  • envとagentの2つのコンテナクラスがあるよ。

今日はここまで

なんだかTopic Overviewだけだと内容薄いなぁ、と思いますが、まずはこんな感じで進めてみたいと思います。

リジューム

はじめに

更新ほったらかしにして何年たったでしょうか。0.3年くらいでしょうか、あーそーですか。夏時間になって無い仕事を更にする必要がなくなりました!。他にすることも無い残念な人なのでボッチでもできるはてブを再開しみたいと思います。

アクセス解析

更新しない間も僅か9個の記事にも毎日誰彼彼女が見に来てくれるようです。今日のアクセス解析を貼っておきます。

  • 今日 ... 5
  • 週間 ... 51
  • 月間 ... 121
  • 合計 ... 1869

はてブで普通に活動されている方々とはfar from beingなアクセス数ですがそれでも元気をもらえます。ありがとうございます。

何で更新止まっていたか、何で再開するのか

正直、何の技術を追えばよいか分からなかったからです。 いい年したおっさんになって会社の文化なら仕事を回せる。しかし、よそ様のはてブなど、一歩外の世界を見たら、俺氏なにやってんだろこの時代遅れなお仕事...osz。自分は見た目が9割だと思っているので世の中の進歩が気がかりでなりません。焦っても手遅れですが自己満足のために雰囲気だけでも味わいたい。だから暇が続く限りはもう少しだけ技術の世界に、世の中の流れについて行ってみたい。 そんなわけで勉強して得たものは誰得メモとして残してここに残してみます。

今日はここまで

もうすぐ電車が着くので!今日は終わりです。次回以降はSystemVerilogネタで行こうと思います。UVM cookbookを読み始めた内容のメモとかコードのメモとか何とかを書きたいなぁ...。