How to update the class object in system verilog after constructing?
This is a follow up question for my question on NOA error in system verilog (Null Object Access error in system verilog). I am trying to build binary tree and do in order traverse for the inserted elements. First I created a class for node
class node;
byte data;
node left;
node right;
function new();
this.data = data;
this.left = null;
this.right = null;
endfunction
endclass
I then created an extended class with the following variables
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
Below is the complete function to insert a number. To simply explain the functioning, if the current number is less than root the we add it to left node and if it is greater than root, we add it to right node.
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
The function for in ordedr transversing is given below.
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
After this the bin_search class is ended and insided the module each object is constructed and data is inserted using insert function.
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
The output I am getting is as follows: Binary search tree after insertion: Empty tree But, I expect to see 10 30 50 60 70 90 as the output. I think this means the root value is not getting updated after bs.insert statement is used. Can anyone help me with what is going wrong here?
Solution 1:
Elaborating my comment. Here is your code:
initial begin
bs = new;
bs.newNode = new();
...
bs.insert(50);
bs.insert(30);
...
and
function insert(in_data);
newNode.data = nd.data;
if(root.data == null) begin
root = newNode;
return;
end
...
parent.left = newNode;
...
So, you allocate a single newNode
in the initial block. Then you issue several insert functions. Every insert function reuses the same node over and over again, just updatint its data
member. As a result, the tree will be completely corrupted because you mangle not only data but also left/right pointers.
Also, constructor in your class variable makes no sense:
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
What you should have done instead, was to allocate newNode every time you need it in the insert
function. Something like the following.
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
...
and yes, get rid of the newNode in the bs
struct.