输出 *E,TRNULLID: NULL 指针解除引用。系统验证

output *E,TRNULLID: NULL pointer dereference. System verilog

class tx;
  pkt p;
  int j;
  function new ( pkt p);
    p = new();
    j =10;
  endfunction
  task copy(pkt p);
    this.p = new p;
  endtask
endclass :tx

initial
  begin  
  tx t1,t2;
  pkt p;

  t1 =new();
  p = new();

  p.i=256;

  t2= new t1;
  t2.j=20;
  t2.copy(p);

  $display(t1.j);
  $display(t2.j);
  $display(p.i);
  $display(t1.p.i);
  $display(t2.p.i);

  t1.p.i=221;
  $display(t1.p.i);
  $display(t2.p.i);
 end
 endprogram

为什么这段代码没有给出输出。当我更改 t1 = new (p) 时。它工作正常 但给出几行错误

ncsim> run 10 20 256 ncsim: *E,TRNULLID: NULL pointer dereference.

虽然它不打印 $显示(t1.p.i); $显示(t2.p.i);

尝试访问不存在的对象时出现空指针错误。

对于t1 = new()的情况,compile/elaboration日志中应该会有警告。类似于缺少输入 p 的内容。将 t1 = new() 更改为 t1 = new(p) 似乎可以解决该行的错误,但 t1.p 仍然为空。这是因为输入变量与成员变量同名。当您 newtxnew 中编辑 p 时,它使用输入变量,因为它的范围更近。由于您将新对象分配给输入句柄,因此原始句柄未指向同一对象。如果您使用将方向性定义为 inoutref 而不是推断输入,它将指向同一个对象。成员 p 仍然为空。

解决方案:

  1. txfunction new ( pkt p); 更改为 function new ();。输入 p 似乎没有做任何事情,所以没有理由拥有它。 p = new() 将被赋值给 tx 的成员变量,因为没有名称冲突。
  2. txnew方法中将p = new()更改为this.p = new()。这明确表示 new 将应用于成员变量,而不是局部变量。
  3. 同时执行解决方案 1 和 2。
  4. 如果您需要两个 p 并且不想执行上述操作,请重命名一个并相应地使用。