Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

UVMでのC/C++テストシーケンス

UVMでC/C++のテストシーケンスを走らせる場合のアイディアを紹介しておこうと思う。
Dynamic Objectであるclass内ではDPI-CでC/C++ importする事ができない。なので、UVM sequence class内ではC/C++のプログラムを直接importして使う事はできない。ではどうすれば良いのかと言うと、staticな領域であるpackage内でC/C++のfunctionをimportしてそれを呼ぶようにする。その際に直接呼ぶのではなく、そのpackageに別途SVのtaskを用意して、そのtaskからC/C++のfunctionをコールするようにする。そのSVのtaskの引数としてシーケンサーと親シーケンスのハンドルを指定して、それらをそのpackageに渡すようにする。C側から呼ぶSVのレジスタRead/WriteのSVタスクもpackage内に用意し、その中でではAgentのRead/WriteのAPIシーケンスをスタートさせる。その際に、先ほどのpackageに渡ったシーケンサーと親シーケンスのハンドルを引数にして.start()を実行する。

dpi_seq_pkg.sv
package dpi_seq_pkg;
  import "DPI-C" context task C_Program();
  export "DPI-C" task sv_write;
  export "DPI-C" task sv_read ;

  import uvm_pkg::*;

  uvm_sequencer_base m_sequencer;
  uvm_sequence_base  parent_seq;

  // Called by a UVM sequence
  task start(uvm_sequencer_base sequencer, uvm_sequence_base parent_sequence);
    m_sequencer = sequencer;
    parent_seq  = parent_sequence;
    C_Program();  // C/C++ Program Call
  endtask

  // Called from C side
  task sv_write (input int addr, data);
    agent_pkg::write_sequence  api_wr_seq = agent_write_sequence::type_id::create("api_wr_seq");
    api_wr_seq.Val_A = addr;
    api_wr_seq.Val_D = data;
    api_wr_seq.start( .sequencer(m_sequencer), .parent_seuence(parent_seq) );  // API Sequence Start with Sequencer Handle and Parent Sequencer Handle
  endtask : sv_write

  // Called from C side
  task sv_read (input int addr, output int data);
    agent_pkg::read_sequence  api_rd_seq = agent_read_sequence::type_id::create("api_rd_seq");
    api_rd_seq.Val_A = addr;
    api_rd_seq.start( .sequencer(m_sequencer), .parent_sequence(parent_seq) ); // API Sequence Start with Sequencer Handle and Parent Sequencer Handle
    data = api_rd_seq.Val_D;
  endtask : sv_read

endpackage
C_sequence.sv
task C_sequence::body()
    // C Program
    dpi_seq_pkg::start( .sequencer(m_sequencer), .parent_sequence(this) );

package内でDPI-Cを使うことは許されていると思うが、とある商用シミュレータでは以前は実行時にオプションを設定しないとできなかった。うまくできない場合は各ベンダーのサポートに聞いてみよう。
上記の例ではdpi_seq_pkgとして別packageを用意したが、もちろんテストsequenceが入っているpackageや他のテストコンポーネントが入っているpackageに同様の記述をしても良い。Agentのpackageをいじれるならこの記述自体をAgentのpackageに入れてC/C++を走らせるAgent API Sequenceとしてしまっても良いかもしれない。

また、Verification Academyでは以下のようなさらにregister modelを使った方法が提案されているが、殆どの場合ここまで複雑にしなくても上記の方法で事足りるのではないだろうか。特にこの為だけにregister modelを作る事も無いだろう。

Verification Academy UVM C Based Stimulus

更に同じくVerification Academy内に以下の様なpapaerも見つけた。この例ではpackageではなく同じくstaticであるinterfaceを介してDPI-CでC/C++をコールしている。そしてinterface内で、Agent API Sequenceを介してではなく、Agentのsequencerを直接参照してsequenceを流しているようである。"the simplest approach"とは言っているがsequencerをいじったりしなくてはならず、とても"the simplest"には思えない。

UVM and C Tests - Perfect Together

vega77
主にLSIハード設計/検証の人。あとC/C++も。最近は趣味でラズパイやPythonや機械学習やディープラーニングも。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away