Thursday, May 2, 2013

Randomization methods in SV : Part 1


Randomization Methods

(i)randomize()
  a) Variables in an object are randomized using the randomize() class method.
  b) Every class has a built-in randomize() virtual method, declared as:
virtual function int randomize();
c) The randomize() method is a virtual function that generates random values for all the active random variables in the object, subject to the active constraints.
d) The randomize() method returns 1 if it successfully sets all the random variables and objects to valid values, otherwise it returns 0.
Example: class SimpleSum;
rand bit [7:0] x, y, z;
constraint c {z == x + y;}
endclass
(ii)pre_randomize() and post_randomize():
Every class contains built-in pre_randomize() and post_randomize() functions, that are automatically called by randomize() before and after computing new random values.
The built-in definition for pre_randomize() is:
function void pre_randomize;
if (super) super.pre_randomize(); // test super to see if the
// object handle exists
// Optional programming before randomization goes here
endfunction

The built-in definition for post_randomize() is:

function void post_randomize;
if (super) super.post_randomize(); // test super to see if the
// object handle exists
// Optional programming after randomization goes here
endfunction
//example for pre post randomization 

program pre_post_rand;
class eth_pkt ; 
rand integer length ; endclass 
class my_pkt extends eth_pkt ;
function void pre_randomize() ;
super.pre_randomize() ;
$display("before randomize length = %h" , length ) ;
endfunction 
function void post_randomize() ;
super.post_randomize() ;
$display("After randomization length =%h", length ) ;
endfunction
endclass 
my_pkt m_pkt ; 
initial begin 
m_pkt = new() ;
m_pkt.randomize() ;
end
endprogram 
(iii)Disabling random variables with rand_mode():
The rand_mode() method can be used to control whether a random variable is active or inactive. When a random variable is inactive, it is treated the same as if it had not been declared rand or randc. Inactive variables are not randomized by the randomize() method, and their values are treated as state variables by the solver.
All random variables are initially active.
The syntax for the rand_mode() method is:
task object[.random_variable]::rand_mode( bit on_off );
// example to explain rand mode operation 

program rand_mod ;
class eth_pkt ; 
rand integer length ; 
rand bit [47:0] dst_addr ; 
constraint valid_len 
{
length >=; length <= 10 ; 

task print () ; 
$display("the length is %h" , length) ; endtask 
endclass 
eth_pkt pkt ; 
initial begin 
pkt = new () ; 
pkt.length.rand_mode(1) ; // rand mode is on u can make it 1 or 0 
ifpkt.randomize() == 1 
begin 
$display("randomization success") ; 
pkt.print (); 
end 
else 
$display("randomization fail") ; 
end 
endprogram 
(iv)Controlling constraints with constraint_mode():
The constraint_mode() method can be used to control whether a constraint is active or inactive. When a constraint is inactive, it is not considered by the randomize() method. All constraints are initially active.
The syntax for the constraint_mode() method is:
task object[.constraint_identifier]::constraint_modebit on_off );
// example to explain constraint mode operation 

program cnst_mod ;
class Eth_pkt ;
rand integer length ;
constraint valid_len 
{
length >=5 ; length <= 10 ; 

task print () ;
$display("the length is %h" , length) ;endtask 
endclass 
Eth_pkt pkt ;
initial begin 
pkt = new () ;
pkt.valid_len.constraint_mode (0) ; // constraint mode is off u can make it 1 or 0 
if( pkt.randomize() == 1 
begin
$display("randomization success") ;
pkt.print () ;
end 
else 
$display("randomization fail") ;
end
endprogram 

Friday, April 19, 2013

Virtual Sequence and Virtual sequencer in UVM


Virtual Sequence:
When you want to select the sequence from testcase, use virtual sequence.



Virtual Sequencer:
If you need to coordinate the activity between your two sequences (bus_master_seq & other_seq1), it is sometimes easier to do it using a virtual sequence.


If you don't need to coordinate activity between them, then what you have will work fine and you don't need a virtual sequencer.


If the two sequences are independent, but you need one to run before the other, you can use the phasing mechanism in UVM. For example, if your two sequences are independent, but you need to run the bus_master_seq before other_seq1 starts, you can set them to run in different phases.


E.g.


//running bus_master sequence on sequencer1

uvm_config_db#(uvm_object_wrapper)::set(this,"sqr1.configure_phase","default_sequence",bus_master_seq::type_id::get());


//running other_seq1 on sequencer2

uvm_config_db#(uvm_object_wrapper)::set(this,"sqr2.main_phase","default_sequence",other_seq1::type_id::get());

Thursday, December 6, 2012

Difference between data types logic and reg and wire

Wire:-
  1. Wires are used for connecting different elements
  2. They can be treated as a physical wire
  3. They can be read or assigned
  4. No values get stored in them
  5. They need to be driven by either continuous assign statement or from a port of a module
Reg:-
  1. Contrary to their name, regs doesn't necessarily corresponds to physical registers
  2. They represents data storage elements in Verilog/SystemVerilog
  3. They retain their value till next value is assigned to them (not through assign statement)
  4. They can be synthesized to FF, latch or combinational circuit (They might not be synthesizable !!!)
Wires and Regs are present from Verilog timeframe. SystemVerilog added a new data type called logic to them. So the next question is what is this logic data type and how it is different from our good old wire/reg.

Logic:-
  1. As we have seen, reg data type is bit mis-leading in Verilog. SystemVerilog's logic data type addition is to remove the above confusion. The idea behind having a new data type called logic which at least doesn't give an impression that it is hardware synthesizable
  2. Logic data type doesn't permit multiple driver. It has a last assignment wins behavior in case of multiple assignment (which implies it has no hardware equivalence). Reg/Wire data type give X if multiple driver try to drive them with different value. Logic data type simply assign the last assignment value.
  3. The next difference between reg/wire and logic is that logic can be both driven by assign block, output of a port and inside a procedural block like this
    logic a;
    assign a = b ^ c;                   // wire style 
    always (c or d) a = c + d;          // reg style
    MyModule module(.out(a), .in(xyz)); // wire style
source : internet

Friday, November 30, 2012

UVM video lactures link

http://videos.accellera.org/uvmreadysetdeploy/uvm38mtR57B/index.html

Virtual Interface

1. We cannot pass a port (interface) directly in a class, so we use the concept of the virtual interface that points to the actual interface and can be passed in a class as a class is a dynamic entity.

2. The interface is used for connection of two modules.

3. The virtual interface is used to connect a class (dynamic entity) to a module (static entity)

4. Virtual interfaces provide a mechanism for separating abstract models and test programs from the actual signals that make up the design.

5. A virtual interface allows the same subprogram to operate on different portions of a design and to dynamically control the set of signals associated with the subprogram.

6. Instead of referring to the actual set of signals directly, users are able to manipulate a set of virtual signals. Changes to the underlying design do not require the code using virtual interfaces to be rewritten.

7. By abstracting the connectivity and functionality of a set of blocks, virtual interfaces promote code reuse.

8. Virtual interfaces can be declared as class properties, which can be initialized procedurally or by an argument to new(). This allows the same virtual interface to be used in different classes.

8. In UVM based environment we can set the virtual interface using config_db in the tb_top and then it will be available down the hierarchy.


9. The following example shows how the same transactor class can be used to interact with various different devices:

01.interface SBus; // A Simple bus interface
02.logic req, grant;
03.logic [7:0] addr, data;
04.endinterface

05.class SBusTransctor; // SBus transactor class
06.virtual SBus bus; // virtual interface of type Sbus

07 function new( virtual SBus s );
08.bus = s; // initialize the virtual interface
09.endfunction

10.task request(); // request the bus
11.bus.req <= 1'b1;
12.endtask

13.task wait_for_bus(); // wait for the bus to be granted
14.@(posedge bus.grant);
15.endtask

16.endclass

17.module devA( Sbus s ) ... endmodule // devices that use SBus
18.module devB( Sbus s ) ... endmodule

19.module top;
20.SBus s[1:4] (); // instantiate 4 interfaces
21.devA a1( s[1] ); // instantiate 4 devices
22.devB b1( s[2] );
23.devA a2( s[3] );
24.devB b2( s[4] );

25.initial begin
26.SbusTransactor t[1:4]; // create 4 bus-transactors and bind
27.t[1] = new( s[1] );
28.t[2] = new( s[2] );
29.t[3] = new( s[3] );
30.t[4] = new( s[4] );
31. end

32.endmodule


In the preceding example, the transaction class SbusTransctor is a simple reusable component. It is written without any global or hierarchical references and is unaware of the particular device with which it will interact. Nevertheless, the class can interact with any number of devices (four in the example) that adhere to the interface’s protocol.



Notes :
1. virtual i/f is just a handle (like pointers) when a virtual i/f is declared, it only creates handles, doesn't create a local interface.

2. Virtual interface variables can be passed as arguments to tasks, functions, or methods. A single virtual interface variable can thus represent different interface instances at different times throughout the simulation. 

3. A virtual interface must be initialized before it can be used; it has the value null before it is initialized.


Benefits of using interface :
1. can contain protocol checking using assertions and functional coverage blocks. 
2. maintainability and reusability. 
3. can contain tasks and functions.








Friday, November 23, 2012

Post 16: Why virtual class

http://www.systemverilog.in/forum/showthread.php?tid=143

Post 14 : Introduction to OOPs

OOP Can be described with following concepts : 

  • Follows bottom up approach.
  • Emphasis is on data.  //need to search explanation 
  • Programs are divided into objects.
  • Functions and data are bound together.
  • Communication is done through objects.
  • Data is hidden.
The following are the basic concepts of OOPs:
Classes, Objects, Data abstraction and encapsulation, Polymorphism, Inheritance, Message Passing, and Dynamic Binding.

1. What is a class?
Class is an entity which consists of member data and member functions which operate on the member data bound together.

2. What is an object?
i)Objects are instances of classes.
ii) Class is a collection of similar kind of objects.
iii) When a class is created it doesn’t occupy any memory
iv) but when instances of class is created i.e., when objects are created they occupy memory space.

3. What is encapsulation?
Encapsulation is welding of code and data together into objects.

4. What is inheritance?
Inheritance is a mechanism through which a subclass inherits the properties and behavior of its superclass.
The derived class inherits the properties and method implementations of the base class and extends it by overriding methods and adding additional properties and methods.

5. What is polymorphism?
i) In Greek this means "many shapes."
ii) As a consequence of inheritance and virtual functions, a single task (for example, drawing a geometrical shape) can be implemented using the same name (like draw()) and implemented differently (via virtual functions) as each type in object hierarchy requires(circle.draw() or rectangle.draw()).
iii) Later, when a polymorphic object (whose type is not known at compile time) executes the draw() virtual function, the correct implementation is chosen and executed at run time.

6. What is the difference between function overloading and function overriding?
i) Overloading is a method that allows defining multiple member functions with the same name but different signatures.
The compiler will pick the correct function based on the signature.

ii) Overriding is a method that allows the derived class to redefine the behavior of member functions which the derived class inherits from a base class.
The signatures of both base class member function and derived class member function are the same; however, the implementation and, therefore, the behavior will differ.

7. What are the advantages of OOP?
  • Data hiding helps create secure programs.
  • Redundant code can be avoided by using inheritance.
  • Multiple instances of objects can be created.
  • Work can be divided easily based on objects.
  • Inheritance helps to save time and cost.
  • Easy upgrading of systems is possible using object oriented systems.
8. Explain about the virtual task and methods .
#important : Virtual tasks and functions are the ways to achieve the polymorphism in system verilog.

Example :
01.class base ;
03.virtual function int print;
04.$display("INSIDE BASE \n");
05.endfunction : print
06. 
07.endclass : base
08. 
09.class derived extends base;
10. 
11.function int print;
12.$display("INSIDE DERIVED \n");
13.endfunction : print
14. 
15.endclass : derived
16. 
17. 
18. 
19.program test ;
20. 
21.derived d1;
22.initial
23.begin
24.d1 = new();
25.d1.print();
26.callPrint (d1);
27.end
28. 
29.task callPrint (base b1);
30.$display("Inside callPrint \n");
31.b1.print;
32.endtask : callPrint
33. 
34.endprogram
35. 
36.Output :
37.========
38. 
39.VSIM 1> run
40.# INSIDE DERIVED
41.#
42.# Inside callPrint
43.#
44.# INSIDE BASE
45.#

Ethernet and more

Ethernet is a protocol under IEEE 802.33 standard User Datagram Protocol (UDP) UDP is a connectionless transport protocol. I...