【问题标题】:How to update the class object in system verilog after constructing?构建后如何更新系统verilog中的类对象?
【发布时间】:2021-08-03 11:59:52
【问题描述】:

这是我关于系统 verilog (Null Object Access error in system verilog) 中的 NOA 错误的问题的后续问题。我正在尝试构建二叉树并按顺序遍历插入的元素。首先我为节点创建了一个类

class node;
  byte data;
  node left;
  node right;
  function new();
    this.data = data;
    this.left = null;
    this.right = null;
  endfunction
endclass

然后我创建了一个包含以下变量的扩展类

class bin_search extends node;
  node newNode;
  node nd,root,current,parent;
  byte in_data;

  function new();
    super.new();
    this.in_data = in_data;
  endfunction

下面是插入数字的完整函数。简单解释一下,如果当前数小于root,我们将它添加到左节点,如果它大于root,我们将它添加到右节点。

 function insert(in_data);
    newNode.data = nd.data;
    if(root.data == null) begin
      root = newNode;
      return;
    end
    else begin
      current = root;
      parent = null;
    end
    forever begin
      parent = current;
      if(in_data < current.data) begin
        current = current.left;
        if(current.left == null) begin
          parent.left = newNode;
        return;
        end
      end
      else begin
        current = current.right;
        if(current.right == null) begin
          parent.right = newNode;
          return;
        end
      end
    end
  endfunction

按序遍历的函数如下。

  function automatic inorder_traverse(node node_tr);
    if(root.data == null) begin
      $display("Empty tree");
      return;
    end
    else begin
      if(node_tr.left!=null) begin
        inorder_traverse(node_tr.left);
      end
        $display("traverse data = %0d\t", node_tr.data);
      if(node_tr.right != null) begin
        inorder_traverse(node_tr.right);
      end
    end
  endfunction

在此之后 bin_search 类结束并在模块内部构造每个对象并使用插入函数插入数据。

module binary;
  bin_search bs;
  initial begin
    bs = new;
    bs.newNode = new();
    bs.nd = new();
    bs.root = new();
    bs.current = new();
    bs.parent = new();
    bs.insert(50);  
    bs.insert(30);  
    bs.insert(70);  
    bs.insert(60);  
    bs.insert(10);  
    bs.insert(90);  
            
    $display("Binary search tree after insertion:"); 
    bs.inorder_traverse(bs.root);
  end
endmodule

我得到的输出如下: 插入后的二叉搜索树:空树 但是,我希望看到 10 30 50 60 70 90 作为输出。 我认为这意味着在使用 bs.insert 语句后根值没有得到更新。谁能帮我解决这里出了什么问题?

【问题讨论】:

  • 看起来您只为所有插入分配了一个“newNode”。相反,您应该在需要时在“插入”函数中执行此操作。
  • @Serge,您能否详细说明如何做到这一点。
  • @srij 我添加了一个详细说明作为答案。

标签: class oop binary-search-tree system-verilog


【解决方案1】:

详细说明我的评论。这是您的代码:

 initial begin
    bs = new;
    bs.newNode = new();
    ...
    bs.insert(50);  
    bs.insert(30);  
    ...

function insert(in_data);
    newNode.data = nd.data;
    if(root.data == null) begin
      root = newNode;
      return;
    end
    ...
          parent.left = newNode;
    ...

因此,您在初始块中分配了一个 newNode。然后你发出几个插入函数。每个插入函数一遍又一遍地重用同一个节点,只需更新其data 成员。结果,树将完全损坏,因为您不仅会破坏数据,还会破坏左/右指针。

此外,类变量中的构造函数没有意义:

class node;
  byte data;
  node left;
  node right;
  function new();
    this.data = data; <<< what does it mean? it assigns node.data to node.data
    this.left = null;
    this.right = null;
  endfunction
endclass

您应该做的是每次在 insert 函数中需要它时分配 newNode。类似于以下内容。

class node;
  byte data;
  node left;
  node right;
  function new(byte in_data); << pass arg to the constructor
    this.data = in_data;
    this.left = null;
    this.right = null;
  endfunction
endclass
...
function insert(in_data);
    // newNode.data = nd.data;
    if(root.data == null) begin
      root = new(in_data);
      return;
    end
   
 ...

是的,去掉 bs 结构中的 newNode。

【讨论】:

  • 我尝试使用您的输入来编辑我的代码。在使用 new() 时,我遇到了一些错误。我认为这是因为我们将参数传递给了新的构造函数,所以我在子类 new 函数中传递了 super.new(in_data),在主模块中传递了 new(0)。现在我又遇到了同样的错误。你觉得我应该通过什么?
  • 是因为super.new();吗?你也需要修改bin_search中的构造函数。
【解决方案2】:

问题解决了:

/*if(current.left == null) begin
parent.left = newNode;
return;
end*/
instead of this use 
if(!current.left ) begin
      parent.left = newNode;
    return;
    end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多