2016-05-20 8 views
2

Ich habe eine Elternklasse und viele Unterklassen. Und ich möchte alle untergeordneten Klassen instanziieren und sie in ein übergeordnetes Objekt-Array/eine Warteschlange umwandeln, so dass ich mit dem übergeordneten Array/der Warteschlange etwas Nützliches tun kann.Wie man statischen Konstruktor in SystemVerilog nachahmt?

Der Code ist unten:

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 

Ich frage mich, ob es einen Weg gibt mehr ordentlich machen dies. Also ich meinen Code in das ändern:

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  

Aber der Compiler beschwert sich über direkt statischen Konstruktor "child1 :: neu()" oder "child1.new()" verwendet wird. Unterstützt SystemVerilog solch eine Funktion? (Wenn es eine Unfähigkeit des Simulators ist, können Sie angeben, welcher Simulator es unterstützt?) Wenn nicht, gibt es einen ordentlichen Weg, es zu tun? Zum Beispiel mit Makro?

Das Problem mit Makro ist, dass ich zwei Makros dazu verwenden muss. Ein Makro erklärt die Instanz an der Spitze der Funktion/Programm zuerst:

child1 c1; 

Und dann initialisiert ein anderes Makro die Instanz und itinto Array im Körper der Funktion/Programm setzen:

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

Gibt es eine Möglichkeit, ein Makro anstelle von zwei Makros zu verwenden?

--------------------- BEARBEITEN ------------------------

Vielen Dank @Tudor und @ dave_59 für die Antwort, das Beispiel funktionierte für p = child1 :: new(). Ich erkannte, dass meine Elternklasse eine parametrisierte Klasse ist. Und Syntax funktioniert auch für sie.

Leider muss ich für einen neuen Konstruktor explizit angeben, welchem ​​Objekt der neue zugewiesen ist. Und die folgende Syntax funktioniert nicht.

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

Antwort

2

Die Syntax in der LRM für scoped Konstruktoraufrufe beschrieben ist:

child1::new(); 

Wenn Sie Glück haben, Ihr Simulator unterstützt wird.

Was Sie in Ihrem Code jedoch nicht benötigen, sind die $cast(...) Anweisungen. Da Sie unten Guss (geht von Unterklasse zu übergeordneten Klasse), würde die folgende auch legal sein:

p = child1::new(); 

Wenn Sie noch mehr Glück haben, können Sie sogar verkürzen Sie es an:

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

aber wieder, das hängt davon ab, was Ihr Simulator unterstützt.

+0

Welche Simulator unterstützt? Ich führe es auf QuestaSim und es beschwert sich auch über child1 :: new(). Unterstützt VCS oder Icarus es? – TyL

+0

Siehe meine Antwort hier https://verificationacademy.com/forums/systemverilog/how-mimic-static-constructor-systemverilog#reply-54421 –

2

Das SystemVerilog BNF erfordert, dass new() auf dem RHS einer Zuweisung angezeigt wird. Es ist jedoch nicht notwendig, $ cast zu verwenden, wenn eine Zuweisung von einer erweiterten Klasse zu einer Basisklassenvariablen durchgeführt wird.So können Sie tun:

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 

Sie können auch Dinge wie

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

Vielen Dank! Es hat für mich funktioniert. – TyL