源表达式求值为null

时间:2018-04-14 14:40:54

标签: system-verilog

我注意到,当源表达式求值为null时,不同的模拟器(甚至同一模拟器的不同版本)显示有关动态强制转换的不同行为。以下是LRM(IEEE 1800-2012)所述的内容:

  

8.16施法

     

...   当$ cast应用于类句柄时,它仅在三种情况下成功:

     

1)源表达式和目标类型是赋值兼容的,即目标是源表达式的相同类型或超类。

     

2)源表达式的类型与目标类型转换兼容,即:

     
      
  • 源表达式的类型是目标类型的超类,或
  •   
  • 源表达式的类型是接口类(见8.26)
  •   
     

,源是与目标类型兼容的对象。这种类型的赋值需要由$ cast提供的运行时检查。

     

3)源表达式是文字常量null。

     

在所有其他情况下,$ cast将失败,特别是当源和目标类型不兼容时,即使源表达式求值为null。 ...

这是一个简单的测试案例,可以解决所有可能的情况:

interface class ifc;
  pure virtual function void test();
endclass : ifc

class typeA implements ifc;
  bit    A;
  string s = "typeA";
  function new();
    A = 1'b1;
  endfunction : new
  virtual function void test();
    $display("%t: %s", $time, s);
  endfunction : test
  static function void null_test(string s);
    $display("%t: %s - $cast succeeded", $time, s);
  endfunction : null_test
endclass: typeA

class typeA_ext extends typeA;
  function new();
    super.new();
    A = 1'b0;
    s = "typeA_ext";
  endfunction : new
endclass: typeA_ext


class typeB;
  int    B;
  function new();
    B = 69;
  endfunction : new
endclass: typeB


module test_case;
  ifc        i, i_null;
  typeA      A0, A1, A_null;
  typeA_ext  A0_ext, A1_ext;
  typeB      B, B_null;

  // Case 1
  initial begin
    #1;
    $display("Case 1");
    A1     = new();
    A1_ext = new();

    $cast(A0, A1);              // It succeeds according to case 1 (same as A0 = A1     - the destination is same type as the source expression)
    A0.test();
    $cast(A0, A1_ext);          // It succeeds according to case 1 (same as A0 = A1_ext - the destination is a superclass of the source expression)
    A0.test();
  end

  // Case 2
  initial begin
    #2;
    $display("Case 2");
    A1     = new();
    A1_ext = new();

    A0     = A1_ext;
    i      = A1;

    $cast(A0_ext, A0);          // It succeeds according to case 2a - in fact, A0 (typeA) is holding an object (A1_ext) of type typeA_ext
    A0.test();
    $cast(A0, i);               // It succeeds according to case 2b - in fact, i (interface class) is holding A1 (typeA)
    A0.test();
  end

  // Case 3
  initial begin
    #3;
    $display("Case 3");
    $cast(A0, null);            // It succeeds according to case 3
    A0.null_test("$cast(A0, null)");
  end

  // In all other cases $cast shall fail - Let's use $cast as a function to catch the run-time error
  initial begin
    #4;
    $display("All other cases");
    B      = new();
    B_null = null;

    if ($cast(A0, B))           // source and destination types are not cast compatible
      $display("%t: $cast(A0, B) - Not expected to succeed", $time);
    else if ($cast(A0, B_null)) // even if the source expression evaluates to null
      $display("%t: $cast(A0, B_null) - Not expected to succeed", $time);
    else
      $display("%t: $cast fails as expected", $time);
  end

  // Debatable? Do they fall in "all other cases"? Shall $cast fail?
  initial begin
    #5;
    $display("Debatable?");
    A_null = null;
    i_null = A_null;

    $cast(A0, A_null);          // Shouldn't it match case 1  and/or 3?
    A0.null_test("$cast(A0, A_null)");
    $cast(A0, i_null);          // Shouldn't it match case 2b and/or 3?
    A0.null_test("$cast(A0, i_null)");
  end
endmodule

以下是EDA游乐场中相同测试用例的链接:

Dynamic cast when source expression is null

我想知道当源表达式在每种可能的" flavor"中评估为null时,哪个模拟器正确解释LRM。

有没有"步行LRM"在那里? ; - )

0 个答案:

没有答案