2013-12-12 6 views
5

Поддерживает ли SystemVerilog downcasting (литье базового объекта в производный объект)? Если да, то как?Поддерживает ли SystemVerilog понижение?

Следующие опущенный пример не работает:

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 

Изменить и снова запустите пример на EDA Playground: http://www.edaplayground.com/s/4/581

ответ

7

Да, вы можете обратное приведения. Ваш пример - правильный синтаксис, и он действительно компилируется. Однако вы получаете ошибку времени выполнения, потому что сбой выполняется.

Приведенный вами пример не срабатывает, потому что вы можете только успешно удалить, если дескриптор базового объекта является фактическим ссылкой на объект производного типа. Вы можете вызвать $cast в качестве функции, и он вернет логическое значение, указывающее, был ли урон успешным или нет.

Вот пример:

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 

Выходы:

# Found a dog! 
# woof 

См http://www.edaplayground.com/s/474/586

+0

Так, в опущенных работает только если исходный объект был сначала опрошен. –

+1

Да по большей части. Это не должно быть результатом явного upcast, но вам нужно, чтобы ссылка базового типа указывала на объект производного типа. – dwikle

3

IEEE Std 1800-2012 § 8,16 "Кастинг" гласит:

It всегда легально назначать выражение типа подкласса переменной типа класса, более высокой в ​​дереве наследования (суперкласс или предок типа выражения). Недопустимо прямое назначение переменной типа суперкласса переменной для одного из ее типов подкласса. Однако $cast может использоваться для назначения дескриптора суперкласса переменной типа подкласса, если дескриптор суперкласса относится к объекту, который является присвоением, совместимым с переменной подкласса.

Следующие действия не выполняются, потому что объект суперкласса не читается как дочерний класс.

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

Чтобы правильно преобразовать объект исходных ручек должна быть совместимы с typetypes назначения должен быть сопоставим:

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

понижающее приведение может работать через уровни наследования. Следующий пример демонстрирует базовый класс дескриптор указывает объект внучат быть отлиты в классе расширения (объекта внучки родительского класса):

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 

Вот некоторые рабочий пример: http://www.edaplayground.com/s/6/587

Смежные вопросы