2016-09-21 18 views
1

レジスタのステータスを監視する必要があります。私は、レジスタを読み込んでローカルに格納するUVMシーケンスを作成しました。私のテストコードでは、これらの レジスタにアクセスする必要があります。ここでsudoのコードは次のとおりです。UVMシーケンスへの参照

typedef struct { 
    int a; 
} my_regs; 

class my_seq extends uvm_sequence; 
    // register to uvm db 
    reg_map  map; 
    my_regs  regs; 
    uvm_status_e status; 

    task build_phase(uvm_phase phase); 
    endtask 

    task run_phase(uvm_phase phase); 
     map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR) 
    endtask 
endclass 

class test_reg extends uvm_test; 
    // register to uvm db 
    my_seq seq; 
    my_regs regs; 

    task build_phase(uvm_phase phase); 
     seq = my_seq::type_id::create("reg_seq", this); 
     regs = seq.regs; 
    endtask 

    task run_phase(uvm_phase phase); 
     reg_seq.start(null); 
     // read reg values from seq?????? 
     if(rqgs.a>1) 
      //do some thing 

    endtask 
endclass 

あなたが見ることができるように、私はすべての更新プログラムを欠場いけないように、私は常にシーケンスを始めています。 開始タスクが順番に新しいオブジェクト を作成しないので、オブジェクト内の値は開始呼び出しの間に一定のままでなければなりません。

私は毎回seqからregs値を読み込まないと仮定すると、テストクラスのregsはseqからの更新を取得しません。意味は、regs = seq.regs;seq.regsへの実際の参照を作成しません。私はなぜそれが知りたいのですが、どうすればそのオブジェクトへの絶対参照を作成できますか? (そうすることで、テストクラスのregs値を読み込んで更新する際にシミュレーションサイクルを無駄にすることはありません)。また、これを行うより良い方法があるかどうか、私に助言してください。

答えて

2

最初はマイナーな修正です。シーケンスにはビルドフェーズまたは実行フェーズはありません。他のuvm_componentsとは異なり、自動的に[フェーズシステムを使用して]起動されません。 シーケンスには、機能を実装するためにオーバーライドされた本体タスクがあります(この場合はレジスタを読み込みます)。したがって、run_phaseのコードはボディ関数に移動する必要があります。シーケンスは、それが登録RTLから値を読み込み、クラスmy_seqでREGSに「」フィールドを更新する呼び出されると

class my_seq extends uvm_sequence; 
    // register to uvm db 
    reg_map  map; 
    my_regs  regs; 
    uvm_status_e status; 
function new(string name="my_seq"); 
    super.new(name); 
    endfunction 

    task body(); 
     map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR); 
    endtask 
endclass 

。 (試験中)

regs = seq.regs; // 

REGSは配列内REGSフィールドに永久的なリンクを提供します。したがって、シーケンスがレジスタを読み取ってregsフィールドを更新するときはいつでも、test_regの変数regsに変更が表示されますが、それはレジスタがRTLから読み込まれなければならないことを意味します。 test_regは定期的に(シーケンスmy_seqを呼び出すことによって)レジスタを読み込むためのループを実装する必要があります。これは、変数regsまたはレジスタフィールドmap.CORE.reg_aがRTL内のレジスタへの直接リンクではないためです。

uvm_registerは読み取りが発行されたときにのみ更新されるミラー/コピーであるため、シミュレーションサイクルでRTLレジスタを読み取る必要があります。

ファームウェアはどのようにレジスタにアクセスしますか?ポーリング機構を介してレジスタにアクセスすると、テストケースで同じことを模倣するほうが優れています。

task run_phase(uvm_phase phase); 
    task_done = 0; 
    while (!task_done) 
     begin 
     // wait for some delay as backdoor access takes 0 simulation time 
     reg_seq.start(null); // regs is updates 
     // read reg values from seq - done 
     if(regs.a>1) // check for bit to be set 
     begin 
      task_done = 1; 
      //do some thing 
     end 
     // else continue to poll register 
     end 
end task 

代わりに、私たちはああ、あなたが正しいです

task run_phase(uvm_phase phase); 
      wait (RTL.module.reg.CORE.reg_a == 1) ; 
      reg_seq.start(null); // regs file is updates 
      // read reg values from seq - done 
      if(regs.a>1) // check for bit to be set 
       //do some thing 
    endtask 
+0

(我々はテストベンチからRTL信号にアクセスしているとして、この方法は望ましくありません。)変更して、読み取りを発行するRTL信号を待つことができ私が言ったように、それはsudoのコードであり、元のコードではあなたが記述した方法で本体を実装しました。再度、感謝します! – maskarih

+0

:)それを得ました。すべてのことを確認するだけです。どういたしまして 。 –