virtual class Component;
local string instance_name;
local Component parent;
protected Component children[$];
function new (string _instance_name, Component _parent);
instance_name = _instance_name;
parent = _parent;
if (parent != null) parent.children.push_back(this);
endfunction
function Component get_parent();
return parent;
endfunction
protected task m_do_run();
foreach ( children[i] )
children[i].m_do_run();
$display("%p",children);
fork
run();
join_none
endtask
virtual task run();
// run() becomes a dynamic process
endtask
//does nothing
endclass : Component
class environment extends Component;
function new(string name, Component parent);
super.new(name,parent);
endfunction
task run();
$display("environment run");
endtask
endclass
class test extends Component;
environment env_h=new("env",this);
function new(string name, Component parent);
super.new(name,parent);
endfunction
task run_test();
fork
$display("in test run_test");
$display("%p",children[0]);
children[0].m_do_run();
//env_h.m_do_run();
join_none
endtask
endclass
`include "Component.sv"
`include "environment.sv"
`include "test.sv"
module top_dptb();
test test_h;
int T=10;
initial
begin
test_h =new("test",null);
test_h.run_test();
#100 $finish;
end
endmodule
The access type of m_do_run task in the component class is protected.
I’m having trouble understanding why children[0].m_do_run() in the test class can enable m_do_run() without errors. When attempting to call m_do_run using the environment object (env_h), it results in an “Illegal access to protected member m_do_run” error. However, utilizing children[0].m_do_run() doesn’t trigger any errors, even though children[0] represents the environment in the test class.
Are you saying that the below sentence of the LRM is allowing the access of protected member of environment from the test class ?
Here in this case, I interpreted the phrase “within a class” as “component” class. And modified the access type of the method “m_do_run” from protected to “local” . and observed that the access to “children[0].m_do_run()” is working!!!.
virtual class Component;
local string instance_name;
local Component parent;
protected Component children[$];
function new (string _instance_name, Component _parent);
instance_name = _instance_name;
parent = _parent;
if (parent != null) parent.children.push_back(this);
endfunction
function Component get_parent();
return parent;
endfunction
/* Modified access type from protected to local*/
local task m_do_run();
foreach ( children[i] )
children[i].m_do_run();
$display("%p",children);
fork
run();
join_none
endtask
virtual task run();
// run() becomes a dynamic process
endtask
//does nothing
endclass : Component
My follow up question is, how do we hide(restrict the access) any member (property/method) without compromising on creating and re-using the base classes?
I am trying to understand the language features. I could not conclude on the below
How to achieve data hiding
Concept of accessing members of an object. Does it depend on the type of the handle? If so, how do we achieve data hiding, would you like to give any guidelines on achieving data hiding ?
virtual class Component;
local string instance_name;
local Component parent;
protected Component children[$];
function new (string _instance_name, Component _parent);
instance_name = _instance_name;
parent = _parent;
if (parent != null) parent.children.push_back(this);
endfunction
function Component get_parent();
return parent;
endfunction
protected task m_do_run();
foreach ( children[i] )
children[i].m_do_run();
$display("%p",children);
fork
run();
join_none
endtask
virtual task run();
// run() becomes a dynamic process
endtask
endclass : Component
class environment extends Component;
function new(string name, Component parent);
super.new(name,parent);
endfunction
task run();
$display("environment run");
endtask
endclass
class test extends Component;
environment env_h=new("env",this);
Component comp_h;
function new(string name, Component parent);
super.new(name,parent);
endfunction
task run_test();
fork
$display("in test run_test");
$display("%p",children[0]);
// This is working protected/local access type m_do_run()
// And your previous answer says that it works
children[0].m_do_run();
// This is resulting error, I am not surprised.
//env_h.m_do_run();
// I am trying the following to check if the handle type is the deciding factor
// My observation on *comp_h.m_do_run();* is the below
// Working when the access type of the method is protected
// *protected task m_do_run();*
//
// Facing error when the access type of the method is local
// *local task m_do_run();*
//
comp_h = env_h;
comp_h.m_do_run();
join_none
endtask
endclass
`include "Component.sv"
`include "environment.sv"
`include "test.sv"
module top_dptb();
test test_h;
initial begin
test_h =new("test",null);
test_h.run_test();
#100 $finish;
end
endmodule
Question :
3) Why there is a change in behavior for " comp_h.m_do_run(); " based on the access type of m_do_run method of Component class ? ( as mentioned above access is successfull when the access type is protected and unsuccessful when the access type is local)
4) Why and how is comp_h.m_do_run() different (successful) than children[0].m_do_run() ?
Help me to get the concepts right.
NOTE: I run the simulation using Questsim 2023.3 version on EDA playground.