2016-09-16 3 views
1

Ich erstelle eine Klasse, die einen Verweis auf das Konfigurationsobjekt des Prüfstands benötigt. Da die Konfiguration während der gesamten Simulation intakt sein muss, übergebe ich sie als const ref-Objekt. Hier ist ein Sudo-Code, den ich ausführen möchte:Systemverilog const ref arg position beim Erstellen eines Objekts

class tb_config; 
    int unsigned rate; 
    int unsigned chnls[]; 
    const int unsigned nb_chnls; 

    function new (int unsigned rate, int unsigned nb_chnls); 
    this.rate  = rate; 
    this.nb_chnls = nb_chnls; 
    chnls   = new[nb_chnls]; 
    endfunction 
endclass 

class tx_phy; 
    static int phy_id; 
    tb_config cfg; 

    function new (int unsigned phy_id, const ref tb_config cfg); 
     this.phy_id = phy_id; 
     this.cfg = cfg; 
    endfunction 

endclass 


module test; 
    tb_config cfg = new(100, 4); 
    tx_phy phy = new(1234, cfg); 

endmodule 

Der obige Code funktioniert einwandfrei und es erfüllt meine Erwartungen. Aber wenn ich die Argumente in tx_phy :: new zu Funktion neu ändere (const ref tb_config cfg, int unsigned phy_id); und die Werte an den Konstruktor übergeben entsprechend ich folgende Fehlermeldung in Cadence Incisive erhalten:

invalid ref argument usage because actual argument is not a variable. 

auch gleiche passiert, wenn ich es mit Aldec in edaplayground testen: https://www.edaplayground.com/x/5PWV

Ich nehme an, das eine Sprachbegrenzung , aber gibt es einen anderen Grund dafür?

Antwort

2

Der Grund dafür ist, dass die Argumentart implizit ist, wenn nicht angegeben. Sie haben für das erste Argument const ref angegeben, aber nichts für das zweite Argument, also ist es auch implizit const ref. Das Hinzufügen von input zur zweiten Argumentdeklaration behebt dies.

function new (const ref tb_config cfg, input int unsigned phy_id); 

Ich möchte auch das Schreiben

function new (tb_config cfg, int unsigned phy_id); 

Beide Argumente sind implizit input Argumente Äquivalent hinzuzufügen, const ref tb_config cfg ist, was bedeutet, sie beim Eintritt kopiert werden.

Eine Klassenvariable ist bereits eine Referenz. Das Übergeben einer Klassenvariablen mit ref bedeutet, dass Sie das Handle, das die Klassenvariable innerhalb der Funktion hat, aktualisieren können. Wenn Sie das Argument auf const ref setzen, bedeutet dies, dass Sie die Klassenvariable nicht aktualisieren können, aber Sie können die Variablenreferenzen immer noch für Mitglieder der Klasse aktualisieren. Es gibt keinen Mechanismus, der verhindert, dass Mitglieder des Klassenobjekts aktualisiert werden, wenn Sie ein Handle dafür haben, indem Sie sie als protected oder local deklarieren.

Die einzige Stelle, an der die Übergabe von Funktionsargumenten durch ref in SystemVerilog sinnvoll ist, ist eine Optimierung, wenn die Argumente große Datenstrukturen wie ein Array sind und Sie nur auf einige wenige Elemente des Arrays zugreifen müssen. Sie können die Aufgabe ref Argumente verwenden, wenn die Argumente während der Lebensdauer der Aufgabe aktualisiert werden müssen (d. H. Eine Uhr als Argument übergeben).

+0

Vielen Dank! Jetzt macht es Sinn. Ich habe nur ref hinzugefügt, weil der Compiler mir einen Fehler gegeben hat, als ich es nicht angegeben habe: Erwartete Token: 'ref'. "" Testbench.sv " – maskarih

Verwandte Themen