UVM factory sequence generation strange behavior - verification

I have read 'seven separate sequence styles speed stimulus scenarios' and want to try out the hierarchical sequence. Here, I have two atomic sequences FifoPush and FifoPop both extending from FifoSeqBase. Also, I wanted to create higher level abstraction sequence called FifoPushPop20 performing FifoPush followed by FifoPop. However, the testbench did not work the way I wanted and it took me while to figure out the errors --- two typos!
class FifoSeqBase extends uvm_sequence #(FifoTransact);
`uvm_object_utils(FifoSeqBase)
...
endclass
class FifoPush extends FifoSeqBase;
`uvm_object_utils(FifoPush)
...
endclass
class FifoPop extends FifoSeqBase;
`uvm_object_utils(FifoPush) <- typo #1
...
endclass
In my FifoPushPop20 sequence, two sequences are started, but made the second typo, as shown below:
class FifoPushPop20 extends FifoSeqBase;
...
task body();
FifoPush push = FifoPush::type_id::create("push");
FifoPush pop = FifoPop::type_id::create("pop"); <- typo #2
push.start(m_sequencer);
pop.start(m_sequencer);
...
endtask
endclass
When I had two typos as shown above, there was no compile or run time errors. Can I have an explanation why this error was not detected during compile time or run time? What happened was that the "typo #2" actually created FifoPush type object, not FifoPop object, even though I used FifoPop::type_id::create("pop").

You were just lucky/unlucky* that you made both typos. Correct either and the code doesn't compile. With both typos, the first macro has expanded to a bunch of stuff related to the FifoPush class instead of the FifoPop class, which just happens to (a) still be legal and (b) is called by the second typo.
*delete as appropriate
It's always good to provide an MCVE:
`include "uvm_macros.svh"
module M;
import uvm_pkg::*;
class FifoTransact extends uvm_sequence_item;
`uvm_object_utils(FifoTransact)
function new (string name = "");
super.new(name);
endfunction
endclass
class FifoSeqBase extends uvm_sequence #(FifoTransact);
`uvm_object_utils(FifoSeqBase)
function new (string name = "");
super.new(name);
endfunction
task body; endtask
endclass
class FifoPush extends FifoSeqBase;
`uvm_object_utils(FifoPush)
function new (string name = "");
super.new(name);
endfunction
endclass
class FifoPop extends FifoSeqBase;
`uvm_object_utils(FifoPush) // <- typo #1
function new (string name = "");
super.new(name);
endfunction
endclass
class FifoPushPop20 extends FifoSeqBase;
`uvm_object_utils(FifoPushPop20)
function new (string name = "");
super.new(name);
endfunction
task body;
FifoPush push = FifoPush::type_id::create("push");
FifoPush pop = FifoPop::type_id::create("pop"); // <- typo #2
push.start(m_sequencer);
pop.start(m_sequencer);
endtask
endclass
endmodule
https://www.edaplayground.com/x/4c7V

Related

Is it reasonable to use a static member function within another static member function contained within the same class?

I am attempting to reorganize some code such that it is self-documenting. If I have a class that I don't intend to instantiate, but rather want to call to perform various tasks all related to the same idea, can I create simple static member functions that are then called by later static member functions (Or tasks in my case)?
class foo;
static protected bit [7:0] Data_A;
static protected bit [7:0] Data_B;
static task bar();
/* Use to print out info. in Data_A and Data_B. */
endtask : bar
static task FooBar();
/* Perform some manipulations on Data_A and Data_B. */
bar();
endtask : FooBar
endclass : foo
Then in my program I would do something like:
program automatic main();
initial
begin
foo::FooBar();
$finish;
end
endprogram
Does this seem sound? Thank you for your time. I have been reading the IEEE System-Verilog standard, but this situation does not seem to come up.
Edit: Do I need to use the "this" keyword, or is that reserved for instantiated classes to refer to the self?
It is perfectly appropriate to be able to call one static method of a class from another. You do not use the this prefix to call a static method. You could prefix your call with foo::bar() just to make it clearer to the reader that you are calling a static method, but the language does not need it.
Any class you do not want constructed should be declared as
virtual class foo;
You can even go further by declaring the constructor as
local function new; endfunction
That keeps people from extended it and constructing, but that might be an overkill.
And finally a suggestion: what you are doing might be better suited for a package
package automatic foo;
bit [7:0] Data_A;
bit [7:0] Data_B;
task bar();
/* Use to print out info. in Data_A and Data_B. */
endtask : bar
task FooBar();
/* Perform some manipulations on Data_A and Data_B. */
bar();
endtask : FooBar
endpackage : foo
module automatic main();
initial
begin
foo::FooBar();
$finish;
end
endmodule

Does fragile base class issue exist in Go?

Despite using composition over inheritance?
If so, is there any solution for it at the language level?
As VonC wrote, but I'd like to point out something.
The fragile base class problem is often blamed on virtual methods (dynamic dispatch of methods – this means if methods can be overridden, the actual implementation that has to be called in case of such an overridden method can only be decided at runtime).
Why is this a problem? You have a class, you add some methods to it, and if MethodA() calls MethodB(), you can't have any guarantee that the MethodB() you wrote will be called and not some other method of a subclass that overrides your MethodB().
In Go there is embedding, but there is no polymorphism. If you embed a type in a struct, all the methods of the embedded type get promoted and will be in the method set of the wrapper struct type. But you can't "override" the promoted methods. Sure, you can add your own method with the same name, and calling a method by that name on the wrapper struct will invoke your method, but if this method is called from the embedded type, that will not be dispatched to your method, it will still call the "original" method that was defined to the embedded type.
So because of this, I'd say the fragile base class problem is only present in a quite mitigated form in Go.
Example
Demonstrating the problem in Java
Let's see an example. First in Java, because Java "suffers" from this kind of problem. Let's create a simple Counter class and a MyCounter subclass:
class Counter {
int value;
void inc() {
value++;
}
void incBy(int n) {
value += n;
}
}
class MyCounter extends Counter {
void inc() {
incBy(1);
}
}
Instantiating and using MyCounter:
MyCounter m = new MyCounter();
m.inc();
System.out.println(m.value);
m.incBy(2);
System.out.println(m.value);
The output is as expected:
1
3
So far so good. Now if the base class, Counter.incBy() would be changed to this:
void incBy(int n) {
for (; n > 0; n--) {
inc();
}
}
The base class Counter still remains flawless and operational. But the MyCounter becomes malfunctioning: MyCounter.inc() calls Counter.incBy(), which calls inc() but due to dynamic dispatch, it will call MyCounter.inc()... yes... endless loop. Stack overflow error.
Demonstrating the lack of the problem in Go
Now let's see the same example, this time written in Go:
type Counter struct {
value int
}
func (c *Counter) Inc() {
c.value++
}
func (c *Counter) IncBy(n int) {
c.value += n
}
type MyCounter struct {
Counter
}
func (m *MyCounter) Inc() {
m.IncBy(1)
}
Testing it:
m := &MyCounter{}
m.Inc()
fmt.Println(m.value)
m.IncBy(2)
fmt.Println(m.value)
Output is as expected (try it on the Go Playground):
1
3
Now let's change Counter.Inc() the same way we did in the Java example:
func (c *Counter) IncBy(n int) {
for ; n > 0; n-- {
c.Inc()
}
}
It runs perfectly, the output is the same. Try it on the Go Playground.
What happens here is that MyCounter.Inc() will call Counter.IncBy() which will call Inc(), but this Inc() will be Counter.Inc(), so no endless loop here. Counter doesn't even know about MyCounter, it does not have any reference to the embedder MyCounter value.
The Fragile base class problem is when a seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction.
As mentioned in this tutorial:
For all intents and purposes, composition by embedding an anonymous type is equivalent to implementation inheritance. An embedded struct is just as fragile as a base class.

How are overridden properties handled in init blocks?

I'm trying to understand why the following code throws:
open class Base(open val input: String) {
lateinit var derived: String
init {
derived = input.toUpperCase() // throws!
}
}
class Sub(override val input: String) : Base(input)
When invoking this code like this:
println(Sub("test").derived)
it throws an exception, because at the time toUpperCase is called, input resolves to null. I find this counter intuitive: I pass a non-null value to the primary constructor, yet in the init block of the super class it resolves to null?
I think I have a vague idea of what might be going on: since input serves both as a constructor argument as well as a property, the assignment internally calls this.input, but this isn't fully initialized yet. It's really odd: in the IntelliJ debugger, input resolves normally (to the value "test"), but as soon as I invoke the expression evaluation window and inspect input manually, it's suddenly null.
Assuming this is expected behavior, what do you recommend to do instead, i.e. when one needs to initialize fields derived from properties of the same class?
UPDATE:
I've posted two even more concise code snippets that illustrate where the confusion stems from:
https://gist.github.com/mttkay/9fbb0ddf72f471465afc
https://gist.github.com/mttkay/5dc9bde1006b70e1e8ba
The original example is equivalent to the following Java program:
class Base {
private String input;
private String derived;
Base(String input) {
this.input = input;
this.derived = getInput().toUpperCase(); // Initializes derived by calling an overridden method
}
public String getInput() {
return input;
}
}
class Derived extends Base {
private String input;
public Derived(String input) {
super(input); // Calls the superclass constructor, which tries to initialize derived
this.input = input; // Initializes the subclass field
}
#Override
public String getInput() {
return input; // Returns the value of the subclass field
}
}
The getInput() method is overridden in the Sub class, so the code calls Sub.getInput(). At this time, the constructor of the Sub class has not executed, so the backing field holding the value of Sub.input is still null. This is not a bug in Kotlin; you can easily run into the same problem in pure Java code.
The fix is to not override the property. (I've seen your comment, but this doesn't really explain why you think you need to override it.)
The confusion comes from the fact that you created two storages for the input value (fields in JVM). One is in base class, one in derived. When you are reading input value in base class, it calls virtual getInput method under the hood. getInput is overridden in derived class to return its own stored value, which is not initialised before base constructor is called. This is typical "virtual call in constructor" problem.
If you change derived class to actually use property of super type, everything is fine again.
class Sub(input: String) : Base(input) {
override val input : String
get() = super.input
}

Why do I get a compilation error when calling println method in the class body? #Java

class Test {
int a = 100;
System.out.println(a);
}
class Demo {
public static void main(String args[]) {
Test t = new Test();
}
}
I'm new to programming. I found this code when I'm practicing. I don't understand why I'm getting this error.
Here is the error I'm getting.
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
2 errors
Compilation failed.
Can you guys explain why I'm getting this error?
You can't call a method directly from the java class body.
Create a constructor in your Test class, and put the print in it :
class Test {
int a = 100;
public Test() {
System.out.println(a);
}
}
Note that if for some reason you really want a statement to be executed when the class is loaded without using a constructor, you can define a static block, here an example :
class Test {
static int a = 100;
static {
System.out.println(a);
}
}
However, this is just for reference and really not needed in your case.
From Declaring Classes in the Java tutorial:
In general, class declarations can include these components, in order:
Modifiers such as public, private, and a number of others that you will encounter later.
The class name, with the initial letter capitalized by convention.
The name of the class's parent (superclass), if any, preceded by the keyword extends. A class can only extend (subclass) one parent.
A comma-separated list of interfaces implemented by the class, if any, preceded by the keyword implements. A class can implement more than one interface.
The class body, surrounded by braces, {}.
You can't make any function calls outside of a method declaration.

SCJP v6 (Sierra,Bates) Chapter 2, Question 12 Interpretations of constructor calls

Could I have some feedback on this
Given "new House("x ")" sends a string I had expected that the "House(String name)" constructor would have called the Building super class constructor "Building(String name)". In which case the answer would have been "bn x h hn x". However the answer is "b h hn x" (and yes it does run with that output).
Questions
1. Other than a call "new Building("string_value")" would there be a situation when House would call the "Building(String name)" constructor? (ie other than additional code in the House constructors?
2.Why is it that the no argument Building constructor is called, rather than the overloaded Building (String name) constructor? What I am looking is a possibility there could be many Building constructors and there could be a need to call specific super constructors from subclasses. How do you ensure which constructor (given two or more choices) is called?
Code included for ease of reference.
The answer is "b h hn x"
class Building {
Building() {System.out.print("b ");}
Building(String name) {this(); System.out.print("bn "+name);}
}
public class House extends Building {
House() {System.out.print("h ");}
House(String name) { this();System.out.print("hn "+name);}
public static void main(String a[]) {
new House("x "); }
}
Regards
Scott
If no explicit superclass constructor call is provided, and no call to a constructor in the same class is provided either, the no-args superclass constructor is always called. That's how Java is designed, and it would be too complicated and inefficient for the JVM to record which was the first constructor called and try and match it up with a superclass constructor.
If you needed to call a different superclass constructor, you would just call it explicitly, like this:
super(foo,bar);
When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.
The superclass constructors are called because otherwise the object would be left in an uninitialized state.
Your program execution order is given below:
new House("x "); // call in main this will call same class default constructor because of this(), as you knew already that first statement must be either this() or super() if any
Call to this() in above constructor executes House() constructor. Now in House() there is no this() call so compiler puts default super() which will call base class default constructor and
hence the output is b h hn x