动态投放失败问题

时间:2018-10-05 11:59:50

标签: system-verilog

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

我正在尝试在systemverilog中理解上面的代码的$ cast方法,但是我收到了错误消息。

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

为什么会出错?

更新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 :(得分:1)

您的$cast按照LRM的指示正确失败。您已经构造了base类类型对象,并将其句柄存储在base类变量中。 (顺便说一句,在您现在隐藏base类型名称的同时,对两者使用相同的名称是一个坏主意)。现在,您尝试将base句柄分配给类类型为extend的类变量。 $cast之所以失败,是因为您要为extended分配句柄的对象从未构造过extend对象。如果强制转换成功,则extended中的原始句柄将被替换为base对象的句柄,并且对extend.b的引用将是致命的,因为该变量不会存在。

$cast的用途是将句柄存储在基类变量中,并且该句柄引用扩展类对象。 $cast允许您通过在分配之前先检查其引用的对象来将句柄移至扩展类变量。

请参阅我在SystemVerilog OOP上的研讨会以及在class terminology上的简短帖子。

答案 1 :(得分:0)

我建议使用以下示例进行研究。最后一个'printer()'语句将失败,因为您无法将ext的非后代强制转换为'ext'int他的功能

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