2013-12-12 12 views
5

SystemVerilog supporta il downcasting (la trasmissione di un oggetto di base a un oggetto derivato)? Se é cosi, come?SystemVerilog supporta il downcasting?

L'esempio seguente abbattuto non funziona:

class base; 
    int a = 5; 
endclass 

class extend extends base; 
    int b = 1; 
endclass 

module test; 

    initial begin 
    base m_base; 
    extend m_extend; 

    m_base = new(); 
    m_extend = new(); 
    $cast(m_extend, m_base); 
    $display(m_extend.a); 
    end 
endmodule 

Modifica ed eseguire nuovamente l'esempio a EDA Playground: http://www.edaplayground.com/s/4/581

risposta

7

Sì, è possibile abbattuto. Il tuo esempio è la sintassi corretta e in realtà viene compilato. Tuttavia stai ricevendo un errore di runtime perché il cast fallisce.

Il cast nell'esempio non riesce perché è possibile eseguire correttamente il downcast solo se l'handle per l'oggetto di base è effettivamente riferimento a un oggetto del tipo derivato. Puoi chiamare $cast come una funzione e restituirà un valore booleano che indica se il cast ha avuto successo o meno.

Ecco un esempio:

class animal; 
    function void eat(); 
    endfunction 
endclass 

class dog extends animal; 
    function void bark(); 
    $display("woof"); 
    endfunction 
endclass 

class cat extends animal; 
    function void meow(); 
    $display("meow"); 
    endfunction 
endclass 

module test; 

    initial begin 
    dog a_dog = new(); 
    cat a_cat = new(); 

    animal animals[$]; 
    animals.push_back(a_dog); 
    animals.push_back(a_cat); 

    foreach (animals[i]) begin 
     dog another_dog; 
     animals[i].eat(); 
     if ($cast(another_dog, animals[i])) begin 
     $display("Found a dog!"); 
     another_dog.bark(); 
     end 
    end 

    end 
endmodule 

Uscite:

# Found a dog! 
# woof 

Vedi http://www.edaplayground.com/s/474/586

+0

Così le opere bassi solo se il l'oggetto di origine è stato trasmesso per primo. –

+1

Sì per la maggior parte. Non è necessario che sia il risultato di un upcast esplicito, ma è necessario che il riferimento di tipo base indichi un oggetto del tipo derivato. – dwikle

3

IEEE Std 1800-2012 § 8,16 "Casting", afferma:

E ' è sempre legale assegnare una espressione di tipo sottoclasse a una variabile di un tipo di classe più alta nell'albero di eredità (una superclasse o antenato del tipo di espressione). È illegale assegnare direttamente una variabile di un tipo di superclasse a una variabile di uno dei suoi tipi di sottoclasse. Tuttavia, è possibile utilizzare $cast per assegnare un handle di superclasse a una variabile di un tipo di sottoclasse a condizione che l'handle della superclasse faccia riferimento a un oggetto compatibile con la variabile di sottoclasse.

Il cast seguente non funziona perché un oggetto superclasse non può essere letto come un childclass.

m_base = new(); 
$cast(m_extend, m_base); // destination type != source object type 

di lanciare correttamente l'oggetto della maniglia sorgente deve essere compatibile con le typetypes destinazione devono essere comparabili:

m_extend = new(); 
m_base = m_extend; 
$cast(m_extend, m_base); // destination type == source object type 

downcasting può lavorare attraverso livelli di ereditarietà. L'esempio seguente mostra una maniglia classe base indicando un oggetto nipotino essere casted alla classe di estendere (classe genitore dell'oggetto nipote):

class ext_more extends extend; 
    int c; 
endclass 
initial begin 
    base m_base; 
    extend m_extend; 
    ext_more m_ext_more; 

    m_ext_more = new(); 
    m_base = m_ext_more; 
    $cast(m_extend, m_base); // legal, casting a subclass object to a parent handle 
    $display(m_extend.a); 
end 

Ecco alcuni esempio di lavoro: http://www.edaplayground.com/s/6/587

Problemi correlati