Upcasting in SystemVerilog - system-verilog

I'm trying to understand Upcasting and Downcasting in SystemVerilog.
Upcasting is casting to a supertype, while downcasting is casting to a subtype.
Upcasting is always allowed, but Downcasting involves a type check.
So I made a simple test code for upcasting and downcasting.
1.Test for upcasting.
class animal;
function void eat();
$display("eat");
endfunction
endclass
class dog extends animal;
function void bark();
$display("woof");
endfunction
endclass
class cat extends animal;
function void meow();
$display("meow");
endfunction
endclass
module test;
animal a1,a2;
dog d1, d2;
cat c1, c2;
initial begin
a1=new();
d1=new();
c1=new();
d1.eat();
c1.eat();
d1.bark();
c1.meow();
c1 = d1;
c1.bark(); //bark is not a class item.
d1 = c1;
d1.meow(); //meow is not a class item.
a1 = d1;
a1.bark(); //bark is not a class item.
a1 = c1;
a1.meow(); //meow is not a class item.
end
endmodule
In the class animal, dog and cat, I need to use bark and meow function from a derived dog and meow class. So I declared as the below But I got the compile error
c1 = d1;
c1.bark(); //bark is not a class item.
d1 = c1;
d1.meow(); //meow is not a class item.
a1 = d1;
a1.bark(); //bark is not a class item.
a1 = c1;
a1.meow(); //meow is not a class item.
As I know, the base class want/need to a properties from a derived class then we do upcasting. How do I get c1's bark(), d1's meow(), a1's bark(), a1.meow()?

If you comment out all the lines after c1 = d1;, you get a more helpful error message:
c1 = d1;
|
xmvlog: *E,TYCMPAT: assignment operator type check failed
(expecting datatype compatible with 'class $unit::cat' but found
'class $unit::dog' instead).
This gives you the reason why bark is not a class item: the assignment failed because c1 is not the same type as d1.
The VCS simulator behaves the same way, and produces a similar compile error.

Related

Why do I need an abstract class in systemverilog?

I came across about abstract class in systemverilog when I googling.
But I didn't get it exactly why do we need about abstract class in systemverilog.
So Would you please help me to understand about abstract class in system verilog? Why do we need it, when do we need it.
An abstract class is designed to be extended and cannot be instantiated. Abstract classes are useful to define a contract for extended classes (i.e. extended classes must implement specific functions) in addition to providing existing functionality that can be reused or overridden. pure virtual functions are un-implemented in an abstract class, but must be implemented in extended classes (forming a contract).
Example:
virtual class animal;
// Implemented functionality that can be overridden in extended classes or used as-is
virtual function int get_legs();
return 4;
endfunction
// Functions that must be implemented by extended classes
pure virtual function string get_sound();
pure virtual function string get_name();
endclass
class cat extends animal;
virtual function string get_sound();
return "meow";
endfunction
virtual function string get_name();
return "Mog";
endfunction
endclass
class dog extends animal;
virtual function string get_sound();
return "woof";
endfunction
virtual function string get_name();
return "Rover";
endfunction
endclass
class duck extends animal;
// override default functionality
virtual function int get_legs();
return 2;
endfunction
virtual function string get_sound();
return "quack";
endfunction
virtual function string get_name();
return "Feathers";
endfunction
endclass
module my_module;
initial begin
animal animals[$];
cat c;
dog d;
duck du;
c = new();
d = new();
du = new();
animals.push_back(c);
animals.push_back(d);
animals.push_back(du);
foreach(animals[a])
begin
$display("%s has %0d legs and makes the sound %s",
animals[a].get_name(), animals[a].get_legs(), animals[a].get_sound());
end
end
endmodule
If you are using UVM, uvm_subscriber is a SystemVerilog example of an abstract class (where the write function must be implemented in extended classes).

Inheritance Polymorphism In Matlab

I was trying to read the matlab docs for a while, and either this doesn't exist or they named it something that did not occur to me.
In mainstream languages such as Java for example, I can implement the Strategy pattern with simple polymorphism like so:
class A{
void foo(){
System.out.println("A");
}
}
class B : A{
void foo(){
System.out.println("B");
}
}
A ab = new B();
ab.foo();//prints B, although static type is A.
the same concept is also available in interpreter languages such as python.
Is there something like this in Matlab (I'm using 2016a).
What is it called? what is the syntax?
classdef A < handle
%UNTITLED Summary of this class goes here
% Detailed explanation goes here
methods
function obj = A ()
end
function printSomething (obj)
disp ('Object of class A') ;
end
end
end
classdef B < A
%UNTITLED2 Summary of this class goes here
% Detailed explanation goes here
methods
function obj = B ()
end
function printSomething (obj)
disp ('Object of class B');
end
end
end
creation of instance of class A:
a = A () ;
a.printSomething ();
By executing above line of code, you will see:
Object of class A
creation of instance of class B:
b = B () ;
b.printSomething()
By executing above line of code, you will see:
Object of class B
Type checking:
isa (b,'A')
1
isa (b,'B')
1

MATLAB method overriding behaviour: choose method from this class and not from the subclass

Here are two example classes A and B. The class B is a subclass of A and overrides the method "myMethod":
classdef A
methods
function this = A()
this.myMethod();
end
function myMethod(this)
fprintf('A:myMethod\n');
end
end
end
classdef B < A
methods
function this = B()
this#A();
this.myMethod();
end
% Overrides 'myMethod' in A
function myMethod(this)
fprintf('B:myMethod\n');
end
end
end
Now, when I create an object of class B, the output is:
>> B();
B:myMethod
B:myMethod
My question is: How can I modify the constructor of class A such that the method from class A is called instead of the method from the subclass. The output should become:
>> B();
A:myMethod
B:myMethod
I have tried to do
this.myMethod#A();
in the constructor of A but it gives me an error saying that it only works for super class calls.
Thank you for the help,
Adrian
Your syntax is correct but you cannot call superclass methods from the subclass constructor. If you use the same syntax in a different method in B() it will work fine. E.g., if we redefine class B() to look like this:
classdef B < A
methods
function this = B()
this = this#A();
end
% Overrides 'myMethod' in A
function myMethod(this)
fprintf('B:myMethod\n');
this.myMethod#A() ;
end
end
end
we get
>> B()
B:myMethod
A:myMethod
ans =
B with no properties.
The only superclass method you can call from a subclass constructor is the superclass constructor.

How to understand `C.super[P]` in scala?

I'm reading the book of "The depth of scala", and on chapter 6 "types", page 123:
The path C.super or C.super[P] where C refers to a class and P refers to a par- ent type of class C. Using the super keyword directly is shorthand for C.super. Use this path to disambiguate between identifiers defined on a class and a par- ent class.
I can't understand the C.super[P], why we can specify the type P after super?
I tried this scala code:
class P {
def hello = "hello from P"
}
class C extends P {
override def hello = "hello from C"
}
class D extends C {
override def hello = super[P].hello
}
val d = new D
d.hello
Which is unable to compile on this line:
override def hello = super[P].hello
Note that P must be a parent type, not any supertype. I.e. if you have class D extends C with T1 with T2, and there is a hello method in class C and traits T1 and T2, just writing super.hello wouldn't tell the compiler which hello method you want. So you can write super[C].hello, super[T1].hello or super[T2].hello.

why self-type class can declare class

I know Scala can only mixin traits, it makes sense for dependency injection and cake pattern. My question is why I can still declare a class which need another "class" but not trait.
Code:
class C
class D { self : C =>}
This is still complied successfully. I thought it should failed compiled, because at this point how can new instance D (C is class not trait).
Edit:
when try to instantiate D:
new D with C //compilation fail class C needs to be a trait to be mixed in.
You should explicitly make class D to extends C as follows:
class C
class D extends C { self: C => }
Furthermore, you can refer to the post Does a class with a self type of another class make sense?, which explains this problem clearly.