2016-05-20 5 views
2

私は親クラスとたくさんの子クラスを持っています。そして、すべての子クラスをインスタンス化し、それらを親オブジェクト配列/キューにキャストしたいので、親配列/キューを使って何か有用なことをすることができます。SystemVerilogで静的コンストラクタを模倣する方法は?

コードは以下の通りです:

class parent; 
endclass 

class child1 extends parent; 
endclass 

class child2 extends parent; 
endclass 

program top; 

    child1 c1; 
    child2 c2; 
    parent p, p_arr[$]; 

    initial 
    begin 
     c1 = new; 
     assert ($cast(p,c1)) else $fatal; 
     p_arr.push_back(p); 
     c2 = new; 
     assert ($cast(p,c2)) else $fatal; 
     p_arr.push_back(p); 

     // Doing useful things with p_arr 
     // ....... 
    end 
endprogram 

これはより整頓させる方法がある場合、私は疑問に思います。 だから私はこれに私のコードを変更:

begin 
     assert ($cast(p,child1::new())) else $fatal; <---- QuestaSim compiler complained about "child1::new" 
     p_arr.push_back(p); 

     assert ($cast(p,child2.new())) else $fatal; <---- QuestaSim compiler complained about "child2.new" 
     p_arr.push_back(p); 
    end  

しかし、コンパイラは、およそ直接「)(child1.new」静的コンストラクタ「child1の::新しい()」を使用するか、文句を言います。 SystemVerilogはこのような機能をサポートしていますか? (シミュレータの能力がない場合は、シミュレータがそれをサポートしているかどうかを述べることはできますか?)そうでない場合、それを行うためのきれいな方法がありますか?たとえば、マクロを使用して?

マクロの問題は、2つのマクロを使用しなければならないことです。 つのマクロは、最初の関数/プログラムの先頭にインスタンスを宣言:

child1 c1; 

し、別のマクロは、インスタンスを初期化し、機能/プログラムの本体にitintoアレイを置く:

c1 = new; 
assert ($cast(p,c1)) else $fatal; 
p_arr.push_back(p); 

2つのマクロの代わりに1つのマクロを使用する方法はありますか?

--------------------- EDIT ------------------------

答えが@Tudorと@ dave_59ありがとうございました。この例はp = child1 :: new()のために働いていました。私は親クラスがパラメータ化されたクラスであることを認識しました。構文も同様に機能します。

p = child1_class #(.WIDTH(WIDTH))::new(); 
p_arr.push_back(p); 
p = child2_class #(.WIDTH(WIDTH))::new(); 
p_arr.push_back(p); 

残念ながら、新しいコンストラクタでは、新しいオブジェクトがどのオブジェクトに割り当てられているかを明示的に指定する必要があります。次の構文は機能しません。

p_arr.push_back(child1::new()); 

答えて

2

スコープのコンストラクタの呼び出しのためにLRMに記述構文は次のとおりです。運がよけれ場合

child1::new(); 

、あなたのシミュレータは、それをサポートしています。

あなたのコードには、$cast(...)の文は必要ありません。あなたはダウンキャスト(親クラスにサブクラスから行く)しているので、次のようにも法的次のようになります。

p = child1::new(); 

あなたも幸運であれば、あなたもそれを短縮することができます。

p_arr.push_back(child1::new()); 

ただし、これはシミュレータがサポートしているものによって異なります。

+0

のようなものは何シミュレータのサポートにも行うことができますか?私はQuestaSimでそれを実行し、child1 :: new()についても不平を言います。 VCSかIcarusはそれをサポートしていますか? – TyL

+0

私の答えはこちらを見てくださいhttps://verificationacademy.com/forums/systemverilog/how-mimic-static-constructor-systemverilog#reply-54421 –

2

SystemVerilog BNFでは、割り当てのRHSにnew()が表示されている必要があります。しかし、拡張クラスから基本クラス変数に代入するときに$ castを使う必要はありません。だから、あなたが行うことができます:

module top; 
    parent p, p_arr[$]; 
    initial 
     begin 
    p = child1::new(); 
    p_arr.push_back(p); 
    p = child2::new(); 
    p_arr.push_back(p); 

    // Doing useful things with p_arr 
    // ....... 
    end 
endmodule 

をあなたは

 p_arr = '{3{null}}; 
    p_arr[0] = child1::new(); 
    p_arr[1] = child2::new(); 
    p_arr[2] = child1::new(); 
+0

ありがとう!それは私のために働いた。 – TyL

関連する問題