10

私は次の擬似コードに似たものを持っています:

for (lets say 10 iterations)
begin
// Do some configuration changes
    fork
        begin
        ///apply input to design
        end
        begin
        while (1)
        /// at particular point update expected status / values
        end
        begin
        while (1)
        /// read status and verify with expected values
        end
    join_any
end

コードから:他の2つのスレッドが動作している間、入力の適用のみがフォークを壊すことができます(1)forの各反復の間、つまり入力のストリームが適用されたら、すべてのスレッドを無効にします-次の反復が始まるまで、生成されたすべてのスレッドを無効にします(新しい構成で)

だから私は上記のコードをに変更しました

 ....
 join_any
 disable_fork
 end

しかし、これはforループも無効にしているようです/または私が理解していない類似のものですが、効果はテストがハングアップしています。誰かが私に理由と解決策を説明できますか?

4

3 に答える 3

29

「disablefork」は、fork ... join_anyによって起動されたプロセスだけでなく、disable-forkを実行する同じプロセスの子孫である他のプロセスもすべて強制終了します。このプロセスの初期段階で他のプロセスを起動した場合(たとえば、fork ... join_noneを使用)、それらの他のプロセスも強制終了されます。

fork ... join_anyとその後のdisable-forkを独自の新しい子プロセスで実行することで、これを簡単に防ぐことができます。これにより、ディセーブルフォークの効果が制限されるため、気になる新しく起動されたプロセスにのみ影響を与えることができ、他の不要な効果がないことが保証されます。

これを行うには、次のように、混乱全体を「fork begin...endjoin」で囲みます。

fork begin // isolate the following code as a single child process
  fork  // launch the processes you wish to manage
    apply_input();
    update_status();
    verify_status();
  join_any // kill off the *_status threads when apply_input terminates
  disable fork;
end join // end of child process isolation

これは、fork...join_anyおよびfork...join_noneでよく知られている問題です。これは最近VerificationGuildフォーラムで議論されており、Sutherland and Millsの本「VerilogとSystemVerilogGotchas」のセクション#79と#80で説明されています。

「forkbegin」と「endjoin」を1行に配置するのは珍しいことですが、1つの子プロセスを同期的にフォークしていることを明確にする方法として気に入っています。通常、それは役に立たないことですが、この状況ではそれが不可欠です。

このイディオムは非常に一般的で、間違えやすいので、マクロのペアにカプセル化することをお勧めします(私はこれが好きではありませんが...):

`define BEGIN_FIRST_OF fork begin fork
`define END_FIRST_OF join_any disable fork; end join

今、あなたは書くことができます...

`BEGIN_FIRST_OF
    apply_input();
    update_status();
    verify_status();
`END_FIRST_OF

ここで、「... FIRST_OF」という名前は、同じことを行うSpecman(e)言語構造との類似性を反映することを目的としています。

于 2013-01-23T13:52:16.610 に答える
2

SystemVerilogで無効にする代わりにプロセスを使用することを検討する必要があります

process process1;
process process2;
fork
  begin
    process1 = process::self();
    # do something in process 1
  end
  begin
    process2 = process::self();
    # do something in process 2
  end
join_any
#1;
if (process1 != null && process1.status != process::FINISHED)
  process1.kill();
if (process2 != null && process2.status != process::FINISHED)
  process2.kill();

無効にするよりも安全であると思われます。

于 2018-01-24T16:41:08.667 に答える
-1

フォークの無効化は正常に機能するはずです。これが小さな例です。

 module top;

      initial
      begin
          $display(" BEFORE fork  time = %0t ",$time );

          for(int i = 0 ; i < 3 ; i++)
          begin
            fork
              automatic int j = i;
              begin
                  $display(" Action thread started time = %0t  j: %0d",$time,j);
                  #(10*j);
                  $display(" Action thread ended time = %0t  j: %0d",$time,j);
              end

              begin
                 $display(" Entered timeout_15 = %0t j: %0d",$time,j);
                 #15;
                 $display(" Ended timeout_15 = %0t j: %0d",$time,j);
              end
            join_any

            disable fork; // it kills all processes
            $display("---------------------------------------------------");
        end

       #100; // This is to make sure if there any threads ..

       $display(" time = %0d Outside the main fork ",$time );
       $display(" time = %0d  After wait fork ",$time );
      end
    endmodule

出力::

BEFORE fork  time = 0
 Action thread started time = 0  j: 0
 Entered timeout_15 = 0 j: 0
 Action thread ended time = 0  j: 0
---------------------------------------------------
 Action thread started time = 0  j: 1
 Entered timeout_15 = 0 j: 1
 Action thread ended time = 10  j: 1
---------------------------------------------------
 Action thread started time = 10  j: 2
 Entered timeout_15 = 10 j: 2
 Ended timeout_15 = 25 j: 2
---------------------------------------------------
 time = 125 Outside the main fork
 time = 125  After wait fork
于 2015-12-26T02:56:08.433 に答える