Динамическая ошибка приведения - PullRequest
0 голосов
/ 05 октября 2018
class base;
  int a = 15;
endclass

class extended extends base;
  int b = 2;
endclass

module top;
  initial begin
    base       base;
    extended  extend;

    extend = new();
    base    = new();
    $cast(extend, base);
    $display(extend.a);
  end
endmodule

Я пытаюсь понять метод $ cast в systemverilog как приведенный выше код, но у меня есть сообщения об ошибках.

ncsim> source /incisiv/15.20/tools/inca/files/ncsimrc
ncsim> run
    $cast(extend, base);
        |
ncsim: *E,BCLCST (./testbench.sv,18|8): Invalid cast: a value with the class datatype '$unit_0x4ccdf83b::base' cannot be assigned to a class variable with the datatype '$unit_0x4ccdf83b::extended'.
         15
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit
Exit code expected: 0, received: 1

Почему возникает ошибка?

update 2

У меня есть еще тестовый код для понимания $ cast ().

тестовый код.1

class base;
  int a = 15;
endclass

class extended extends base;
  int b = 2;
endclass

module top;
  initial begin
    base       b;
    extended  e;

    e = new();
    b    = new();
    $cast(b, e);
    //b=e;
    $display(e.a);
  end
endmodule

тестовый код 2

class base;
  int a = 15;
endclass

class extended extends base;
  int b = 2;
endclass

module top;
  initial begin
    base       b;
    extended  e;

    e = new();
    b    = new();
    //$cast(b, e);
    b=e;
    $display(e.a);
  end
endmodule

Когда я скомпилировал оба тестовых кода.1 и тестовый код.2, результат один и тот же.Поэтому я запутался, почему мы используем методы $ cast ()?

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Предлагаю следующий пример для изучения.последний оператор 'printer ()' потерпит неудачу, потому что вы не можете привести не потомок ext к 'ext' в функции

class base;
  local string a;
  function new();
    a = "I am a";
  endfunction
  function print();
    $display(a);
  endfunction
endclass

class ext extends base;
  local string b;
  function new();
    b = "i am b";
  endfunction
  function print();
    $display(b);
  endfunction
endclass


function printer(base p);
  ext e;
  $cast(e, p);

  e.print();
  p.print();
endfunction

program P;
  base b = new();
  ext e = new();

  initial begin
    printer(e);
    printer(b); // << this will fail
  end
endprogram
0 голосов
/ 05 октября 2018

Ваш $cast работает неправильно, как указано LRM.Вы создали объект класса base и сохранили его дескриптор в переменной класса base.(Кстати, плохая идея использовать одно и то же имя для обоих, поскольку вы теперь скрыли имя типа base).Теперь вы пытаетесь присвоить дескриптор base переменной класса типа extend.$cast терпит неудачу, потому что объект, который вы пытаетесь присвоить дескриптору extended, никогда не создавал extend объект.Если бы приведение было разрешено успешно, исходный дескриптор в extended был бы заменен дескриптором объекта base, а ссылка на extend.b была бы фатальной, поскольку эта переменная не существует.

Цель $cast - это когда у вас есть дескриптор, хранящийся в переменной базового класса, и этот дескриптор ссылается на объект расширенного класса.$cast позволяет вам переместить этот дескриптор в переменную расширенного класса, проверив объект, на который он ссылается, перед выполнением присваивания.

Пожалуйста, смотрите мой семинар по SystemVerilog OOP , а также короткий пост по терминология класса .

...