HI,
I’m trying to understand between Down cast functionality and virtual methods.
And I was made simple example for test it as the below.
class base_class;
virtual function void display;
$display("Inside base_class 0\n");
endfunction
virtual function void display2;
$display("Inside base_class 2\n");
endfunction
endclass
class extended_class extends base_class;
function void display;
$display("Inside extended_class 1\n");
endfunction
function void display3;
$display("Inside extended_class 3\n");
endfunction
function void display5;
$display("Inside extended_class 5\n");
endfunction
endclass
class extended_class2 extends extended_class;
function void display;
$display("Inside extended2_class 1\n");
endfunction
function void display3;
$display("Inside extended2_class 3\n");
endfunction
function void display5;
$display("Inside extended2_class 5\n");
endfunction
endclass
module virtual_class;
initial begin
base_class b_c;
extended_class e_c;
extended_class2 e2_c;
b_c = new();
e_c = new();
$cast(e_c, b_c);
b_c.display(); /Error Why?
e_c.display(); /Error Why?
end
endmodule
When I ran this code, I encounter
$cast(e_c, b_c);
|
xmsim: *E,BCLCST (./testbench.sv,61|8): Invalid cast: a value with the class datatype ‘$unit_0x4ccdf83b::base_class’ cannot be assigned to a class variable with the datatype ‘$unit_0x4ccdf83b::extended_class’.
Inside base_class 0
Could you let me know why I can’t down-cast?
I think there is no issue because they are hierarchically same. so I though it will work but this Down-cast make error.
works perfectly, because e_c and b_c are now of the same type.
See an explanation also here:
Thanks SIr, I got it.
In Up-casting, I don’t need to assigning =. just I can casting between them.
But Down Casting, after assigning become same type, I can use $cast.
module test_module ();
`include "uvm_macros.svh"
import uvm_pkg::*;
class A; endclass
class B extends A; endclass
class C extends A; endclass
A a_h;
B b_h;
C c_h;
initial begin
b_h = new;
a_h = b_h; // always legal to go up the inheritance tree
$cast(b_h, a_h); // $cast required - will succeed
c_h = new();
b_h = c_h;
$cast(c_h, b_h);
end
endmodule : test_module
I got xrun: 20.09-s003: (c) Copyright 1995-2020 Cadence Design Systems, Inc.
b_h = c_h;
|
xmvlog: *E,TYCMPAT (testbench.sv,20|12): assignment operator type check failed (expecting datatype compatible with 'class test_module::B' but found 'class test_module::C' instead).
Error message.
I thought b_h and c_h are extended by same class.
But b_h and c_h are not same class type so.
I assign b_h = c_h;
But why does assign make error?
I pass the simulation with only commented out b_c = c_h line
But I still didn’t get it.
Is there any special rule? I can’t find any illegal rule for this b_c = c_h line.
Could you give some guidance?
Can’t assign between different class type ? Only can between Family relationship (parents and child)?
As I said, B and C are 2 different classes. Then the handles b_c and c_h are also different objects you cannot assign. Finally it is limited to the family.
In reply to UVM_LOVE:
As I said, B and C are 2 different classes. Then the handles b_c and c_h are also different objects you cannot assign. Finally it is limited to the family.
Sir,
What if they were registered by UVM Factory not $cast, then Can I override between b_h and c_h?
I think this will be one method for can’t casting class handles situation. what if b_h and c_h each they has the same methods and properties. I think UVM OVERRIDE will be the one way using $cast instead. Does this conceptually make sense?
You are mixing 2 different constructs.
(1) $cast is a SystemVerilog task/function. This is a language feature.
(2) override is a UVM methodology construct using SystemVerilog.
It would be great to know what your intention is to use $cast an override.
In reply to UVM_LOVE:
You are mixing 2 different constructs.
(1) $cast is a SystemVerilog task/function. This is a language feature.
(2) override is a UVM methodology construct using SystemVerilog.
It would be great to know what your intention is to use $cast an override.
For understanding Override, I was made a simple Override example as the below
module test_module ();
`include "uvm_macros.svh"
import uvm_pkg::*;
class agent_a extends uvm_agent;
`uvm_component_utils(agent_a)
function new(string name = "agent_a", uvm_component parent = null);
super.new(name, parent);
endfunction : new
endclass : agent_a
class agent_b extends agent_a;
`uvm_component_utils(agent_b)
string field = "agent_b.field";
function new(string name = "agent_b", uvm_component parent = null);
super.new(name, parent);
endfunction : new
endclass : agent_b
class agent_c extends uvm_env;
`uvm_component_utils(agent_c)
string field = "agent_c.field";
function new(string name = "agent_c", uvm_component parent = null);
super.new(name, parent);
endfunction : new
endclass : agent_c
agent_a agent_a_h;
initial begin
agent_a::type_id::set_type_override(agent_c::get_type());
factory.print();
agent_a_h = agent_a::type_id::create("agent_a_h", null);
$display("field = ", agent_a_h.field);
end
endmodule : test_module
When I ran the above simulation. I encounter below Error message.
$display("field = ", agent_a_h.field);
|
xmvlog: *E,NOTCLM (testbench.sv,46|39): field is not a class item.
it said that override must have the same prototype.
What does prototype mean?
Does prototype mean that they class must have the relationship between parents and child as $cast?
You cannot override objects/components which do not belong together and have a different function.
This is not a limitation. It helps you to do bad things.
See your example here
In reply to UVM_LOVE:
You cannot override objects/components which do not belong together and have a different function.
This is not a limitation. It helps you to do bad things.
See your example here Edit code - EDA Playground
Thanks for Great example Sir, How to change uvm_factory factory; to 1.1d version not 1.2?
Sir, What if I want to override with some class they have the same parents, then can I override between them? such as Serge override(2) - EDA Playground ?
You can see your example fails. What you are doing means you could override an spi_agent with an apb_agent (as an example). And this is useless. Believe me.