Monday, 14 January 2008

OVM available on its new site

Open Verification Methodology (OVM) is now available on its new site http://www.ovmworld.org

Tuesday, 8 January 2008

Checker implementation dilema

Ever encountered the checker implementation dilemma? How to implement it? Using temporal expressions or using methods? Once in a lifetime, every verification engineer comes to a stage where they have to take decision about the implementation of a checker. Once, I made a wrong decision and implemented a complex event-based checker in temporal expressions using "expect" statement. After that I was introduced to the hell of debugging temporal expressions in Specman. Event chart is a junk feature in the Specman. Filtering of the events, having full path of the events are not so easy to see in the events chart. Even, when-subtypes' events can not be viewed separately.
After having a lot of trouble debugging temporal expressions, I re-wrote the entire checker in the methods format using "check that" and "if else" construct. Debugging of method based checker is such an easy task in Specman, as Specman has a beautiful and reliable debugger. Lot of features, though might be basic, are quiet useful when it comes to debug the method based checkers. In Specman debugger, one can put conditional and unconditional breakpoints, can see the hierarchy of the threads, can add watch points on e fields and a lot more. I will discuss about debugging in Specman for the beginners in the separate post.
After that experience, I concluded following things for the checker implementation.
  1. Write down the checker in the simple english to understand its complexity.
  2. If checker is simple, I mean, just contains 2 to 3 basic events to check, then go for temporal expressions for the checker implementation.
  3. If checker is even a bit complex having more than 3 events, just go for the method based checker implementation. You will save a hell lot of time which might be lost in the debugging temporal expressions.
Method based checker implementation looks more readable, even though it requires extra codes to implement and it's a bit slower than temporal expressions based checkers. But at the end, you are going to save lot of time having clean checker.

Friday, 4 January 2008

Specman Verification Questions - Part III

Question 1: What will be the output if following code is loaded and test command is issued into Specman ?

<'
struct x
{
y : uint;
keep soft y == 8;
};
extend sys
{
run() is also
{
var x : x;
gen x;
var a : uint = 2;
outf ("a = %d x.y = %d\n", a, x.y);
update_field(a);
update_struct(x);
outf ("a = %d x.y = %d\n", a, x.y);
};
update_field(a: uint) is
{
a = 4;
};
update_struct(x: x) is
{
x.y = 4;
};
};
'>

Answer:

a = 2 x.y = 8

a = 2 x.y = 4

Here, variable uint a is not updated and struct x is updated. Why is so? Because in specman, unlike user defined data types (e.g. structs, units), all variables with standard data types are passed by value in the methods. All user defined data types (like structs) are passed by reference. So, whenever, called methods update the passed structs, it is actually updating the original struct and not its copy.

If one wants user defined data types to be passed by value then he/she can use deep_copy to copy the existing variable and pass it to the method as shown below.

<'
struct x
{
y : uint;
keep soft y == 8;
};
extend sys
{
run() is also
{
var x : x;
gen x;
var a : uint = 2;
outf ("a = %d x.y = %d\n", a, x.y);
update_field(a);
update_struct(deep_copy(x));
outf ("a = %d x.y = %d\n", a, x.y);
};
update_field(a: uint) is
{
a = 4;
};
update_struct(x: x) is
{
x.y = 4;
};
};
'>


Question 2: What is the difference between inheritance implemented by "when" construct and implemented by "like" construct?

Answer:

like inheritance is the concept of the object oriented programming (OOP) where as when inheritance is the concept of aspect oriented programming (AOP). For more detail on AOP, please refer Aspect-Oriented Programming with the e Verification Language book written by David Robinson (Verilab).

like construct is used when someone wants to derive a child object from the already defined struct/unit. This derived child will have new struct/unit name. When someone derive the child object using when construct, the base name of the child will remain the same.

Another difference between like and when construct is that, once the child is derived using like inheritance, one can not add extra fields in the parent struct/unit, wherease, if child is derived using when construct, parent struct/unit can have extra fields.

Take a look at the following example. packet_valid field is added in the parent struct packet_s after the child is derived using like inheritance. This is not allowed and Specman will issue an error during loading phase.

<'
type packet_type_t : [GOOD, BAD, UGLY];
struct packet_s
{
kind : packet_type_t;
};
struct good_packet_s like packet_s
{
packet_size : uint (bits: 5);
};
extend packet_s
{
packet_valid : bool;
ack() is
{
outf ("NOTE :: This is packet %s\n", me);
};
};
extend sys
{
packet : packet_s;
good_packet : good_packet_s;
};
'>

Specman will issue following error.

*** Error: Cannot add new field 'packet_valid' to struct 'packet_s': it has like children (e.g. 'good_packet_s') with fields.

Note that ack() method will be added in the parent struct packet_s even though child is derived using like inheritance.