Sunday, 8 December 2013

Using Clocking Blocks: Guidelines to follow

Clocking Blocks: Guidelines to follow

1.    When using a clocking block, the testbench must access only its clockvars and should never access the clocking signals directly.(CB_name.Clock_var_name)

clocking wr_cb@(posedge clock);
        default input #1 output #1;
  ============Clocking Var’s==============
        output wr_address;        
        output data_in;                  
        output write;             
endclocking: wr_cb

2.    Testbench code should synchronize itself to a clocking block’s clock event by waiting for the clocking block’s own named event, NOT by waiting for the raw clock event.

·         Testbench code that uses a clocking block should never synchronize itself to the raw clock event such as @(posedge clock). This would give rise to unexpected behavior of input sampling.

// GOOD testbench procedural code – Wait on clocking block event
@ (IF_name.CB_name) //Do this
valid_result = IF_name.CB_name.Clock_var;
...
...
// BAD testbench procedural code – Wait on raw event
@(posedge clock) // DON’T DO THIS
unreliable_result = IF_name.CB_name.Clock_var;

·         REASON 1: The name of a clocking block (and, therefore, of its named event) can be chosen to reflect the testbench-facing effect of the clock.
Eg. clocking video_pixel_clk @(negedge vClk);
·         The clocking block hides the clock’s edge polarity from the testbench. If the testbench carefully uses @video_pixel_clock everywhere, instead of @(negedge vClk), then future changes to the clock’s name or polarity can be accommodated simply by changing our clocking block’s definition.

3.    Write to output clockvars using the clocking drive operator <=. Never try to write an output clockvar using simple assignment =

·         Testbench obtains the values of the input clocking signals as they were at a time before the clock event, with the actual time specified by the clocking skew(input #1). The testbench can then use those “pre-clock” values to compute appropriate stimulus for the DUT.
·         After the clock event has already happened, we do not wish to risk hold time violations by applying new stimulus immediately. Instead, we apply our new stimulus some time after the clock event, so that it is stable and ready for the next clock.
·         simple_CB.to_DUT <= new_stimulus; // Clocking drive
·         Driving the output clocking var’s with use of NBA as actually known as clocking drive.
·         According to the SystemVerilog LRM, it is illegal to write to an output clockvar using the regular assignment operator =
·         The clocking block’s timing skews do not affect what happens if you access the original signals directly. Timing skews are relevant only when the testbench makes access through the clocking block’s clockvars.

4.    Use input#1step unless you have a special reason to do otherwise. It guarantees that your testbench sees sampled values that are consistent with the values observed by your SystemVerilog assertions, properties and sequences.

·         The default skew for clocking block input sampling, if no skew is explicitly specified, is input #1step.
·         Delay specification indicates that the signal’s value is to be sampled just before the simulation time at which the clock event occurs. “just before” means that the signal is sampled before any activity at the time of the clock event, but after any earlier simulation activity. For example, clock event occurs at time 15ns. Suppose, too, that there was some simulation activity (code execution, signal value changes, etc) at time 14.5ns, and nothing happened between those two times. input#1step sampling requires the simulator to report the value of our clocking block input signal as it was during that idle time between 14.5ns and 15.0ns.
·         input#1step yields exactly the same value as you would obtain by using the $sampled system function at the moment of the clock event. This is the same value that is sampled for the signal if it appears in a SVA property or sequence.

5.    Use non-zero output skew values in your clocking blocks to make waveform displays clearer, and to avoid problems caused by clock network delays in gate level simulation.

·       The default output skew for a clocking block is output#0.
·     This skew specification causes the driven signal to be updated during execution of the Re-NBA scheduling region of the same simulation timestep in which the clock event occurred.
·   This behavior is closely similar to the effect of an ordinary non-blocking assignment (NBA) executed on the clock event, but it will happen after all such NBAs have completed.

6.    Never use input#0 in your clocking blocks.

·    input#0 sampling delay specification causes the clocking block to sample an input signal in the Observed region of the SystemVerilog scheduler.
·     The Observed region occurs very late in the events queue, even later than the NBA region, and therefore input#0 sampling can see the new values of register outputs after they have been updated by NBA assignments executed at the clock edge.
·         input#0 sampling allows our testbench a “sneak preview” of the value of a signal after the effects of the current clock. Normally your testbench would not be able to see that new value until the next clock.

Notes:
·         If a clocking block output or inout drives a net, the driven value will automatically initialize to 'z (all high-impedance).
·         When a signal is driven by more than one clocking block output, that signal should be a variable.
·         Testbench code can read an input clockvar, but cannot write to it. Perhaps more surprisingly, testbench code can drive (write to) an output clockvar, but cannot read that clockvar to inspect its value.
·         When user code reads an inout clockvar it is in fact reading a corresponding input clockvar; by contrast, when user code drives an inout clockvar it is in fact driving a corresponding output clockvar.
·         Declare your clocking block in an interface. Expose the clocking block, and any asynchronous signals that are directly related to it, through a modport of the interface. In your verification code, declare a virtual interface data type that can reference that modport.
·         Use your clocking block to establish signal directions with respect to the testbench. Do not add the raw signals to a testbench-facing interface's modport.

modport master_mp(clocking master_cb, input RESET_async_n,
input READY, output VALID, DATA);               // WRONG – exposes raw signals

·         Clocking blocks should usually be accessed through a virtual interface variable pointing to a modport of the clocking block’s enclosing interface.
·         In that situation, each clockvar must be accessed using the three-part dotted name virtual_interface.clocking_block.clockvar

·         the class-based testbench code has no access to the interface's default clocking, and cannot safely use ##N procedural delays.


      
          View Maulik Suthar's profile on LinkedIn
        

   

------------------------------------------------------------------------------------------------

Reference: SNUG Austin 2012 "Taming Testbench Timing":
http://www.verilab.com/resources/papers-and-presentations/


   
         
     
   

Wednesday, 5 June 2013

Systemverilog important questions and answers

Q. What are different integer data types in System verilog (SV)?
A. int 32-bit signed, longint 64-bit signed, shortint 16-bit signed.
                                                       
Q. What is difference between between int and integer in system verilog?
A. int is 2-state variable, while integer is 4-state.
Q. What are different data types in system verilog?
A. 2-state, queues, dynamic and associative array, classes and structs, unions and packed array, strings, enum.

Q. What is default data type of byte, shortint, int, integer and longint?
A. 2-state for byte,shortint, int, longint and 4-state for integer.

Q. What is callback ?
Callback is mechanism of changing to behavior of a verification component such as driver or generator or monitor without actually changing to code of the component. It's used for functional coverage, inject error and output transaction in a scoreboard.

Q. What is the need of virtual interfaces ?
Virtual Interfaces basically used to connect the dynamic environment of the SV testbench to the static nature of the DUV. Also provides the mechanism to separate the abstract models and test programs form the actual signals that make up the design. Instead of using the actual signals we can manipulate the virtual signals.

Q. Explain the difference between data types logic and reg and wire.
A. Logic is a data-type which can be used both as a wire or a reg.
A  reg is data type which can hold certain valu and can be used inside procedural blocks only, while wire is just like a wire in real time which can be only driven, and cannot be declared inside any procedural block but can only be assigned using assign keyword.

Q. Explain about the virtual task and methods.
They primarily promote polymorphism in SV.  Virtual task and functions helps the derived class to gain control of the function. It overrides the method in all the base classes and its decedents

Q. What is factory pattern?
UVM provides a built-in factory to allow components to create objects without specifying the exact class of the object being creating. The factory provides this capability with a static allocation function that you can use instead of the built-in new function.

Q. What is the use of the abstract class?
Sometimes it make sense to only describe the properties of a set of objects without knowing the actual behaviour beforehand. The need for abstract classes is that you can generalize the super class from which child classes can share its methods.

Q. What is the need of clocking blocks?
A clocking block assembles signals that are synchronous to a particular clock, and makes their timing explicit. The clocking block is a key element in a cycle-based methodology, which enables users to write testbenches at a higher level of abstraction. Rather than focusing on signals and transitions in time, the test can be defined in terms of cycles and transactions. The clocking block separates the timing and synchronization details from the structural, functional, and procedural elements of a testbench.

Q. What is the difference between mailbox and queue?
A mailbox is a communication mechanism that allows messages to be exchanged between processes. Data can be sent to a mailbox by one process and retrieved by another.
A queue is a variable-size, ordered collection of homogeneous elements. A queue supports constant time access to all its elements as well as constant time insertion and removal at the beginning or the end of the queue.
Mailbox are FIFO queue, which allows only atomic operations. They can be bounded/unbounded. A bounded mailbox can suspend the thread (while writing if full, while reading if empty) via get/put task. Thats why mailbox is well suited for communication between threads.

Q. What are the ways to avoid race condition between testbench and RTL using SystemVerilog?
Program  block
Clocking block
Enforcement of design signals being driven in non-blocking fashion from program block

Q. What data structure you used to build scoreboard?
  mailboxes                  

Q. What are the advantages of linkedlist over the queue?
Queue has a certain order. It's hard to insert the data within the queue. But
Linkedlist can easily insert the data in any location.


Q.How to check weather a handles is holding object or not?
It is basically checking if the object is initialized or not. In SystemVerilog all uninitialized object handles have a special value of null, and therefore whether it is holding an object or not can be found out by comparing the object handle to null. So the code will look like

if(My_usb_packet == null) begin.// This loop will get exited if the handle is not holding any object
end else begin// Hurray ... the handle is holding an object
end

Q. What is the use of packages?
In Verilog declaration of data/task/function within modules are specific to the module only. They can't be shared between two modules. Agreed, we can achieve the same via cross module referencing or by including the files, both of which are known to be not a great solution.
The package construct of SystemVerilog aims in solving the above issue. It allows having global data/task/function declaration which can be used across modules. It can contain module/class/function/task/constraints/covergroup and many more declarations (for complete list please refer section 18.2 of 
SV LRM 3.1a)
The content inside the package can be accessed using either scope resolution operator (::), or using import (with option of referencing particular or all content of the package).

Q. What are bi-directional constraints?
Constraints by-default in SystemVerilog are bi-directional. That implies that the constraint solver doesn't follow the sequence in which the constraints are specified. All the variables are looked simultaneously. Even the procedural looking constrains like if ... else ... and -> constrains, both if and else part are tried to solve concurrently. For example (a==0) -> (b==1) shall be solved as all the possible solution of (!(a==0) || (b==1)).

Q. What is solve…before constraint?
in the case where the user want to specify the order in which the constraints solver shall solve the constraints, the user can specify the order via solve before construct.

Q. Without using randomize method or rand,generate an array of unique values?

int UniqVal[10];
foreach(UniqVal[i]) UniqVal[i] = i;
UniqVal.shuffle();

Q. Explain about pass by ref and pass by value?
Pass by value is the default method through which arguments are passed into functions and tasks. Each subroutine retains a local copy of the argument. If the arguments are changed within the subroutine declaration, the changes do not affect the caller. In pass by reference functions and tasks directly access the specified variables passed as arguments.Its like passing pointer of the variable.

Q. What is the difference between bit[7:0] sig_1; byte sig_2;
byte is signed whereas bit [7:0] is unsigned.

Q. What is the difference between program block and module
Program block is newly added in SystemVerilog. It serves these purposes
·         It separates testbench from DUT
·         It helps in ensuring that testbench doesn't have any race condition with DUT
·         It provides an entry point for execution of testbench
·         It provides syntactic context (via program ... endprogram) that specifies scheduling in the Reactive Region.
·         Having said this the major difference between module and program blocks are
·         Program blocks can't have always block inside them, modules can have.
·         Program blocks can't contain UDP, modules, or other instance of program block inside them. Modules don't have any such restrictions.
·         Inside a program block, program variable can only be assigned using blocking assignment and non-program variables can only be assigned using non-blocking assignments. No such restrictions on module

·         Program blocks get executed in the re-active region of scheduling queue, module blocks get executed in the active region
·         A program can call a task or function in modules or other programs. But a module can not call a task or function in a program.

Q. How to implement always block logic in class ?

class Base;
integer a,b;

task always_task();
fork
forever
begin
@(a,b);
$display(" a is %d : b is %d at %t ",a,b,$time);
end
join_none
endtask
endclass 

& In program block

forever begin
   fork
   begin : reset_logic
       @ (negedge reset_);
       data <= '0;
   end : reset_logic
   begin : clk_logic
       @ (posedge clk);
       if(!reset_)    data <= '0;
       else           data <= data_next;
   end : clk_logic
   join_any
   disable fork
end

Q. Write a clock generator without using always block.
Use forever within an initial block.

Q. What is cross coverage?
Cross allows keeping track of information which is received simultaneous on
more than one cover point. Cross coverage is specified using the cross
construct.




Q. Describe the difference between Code Coverage and Functional Coverage Which is more important and Why we need them?
Code Coverage indicates the how much of RTL has been exercised. The Functional Coverage indicates which features or functions has been executed. Both of them are very important. With only Code Coverage, it may not present the real features coverage. On the other hand, the functional coverage may miss some unused RTL coverage.

Q. How to kill a process in fork/join?
The kill() task terminates the given process and all its sub-processes, that is, processes spawned using fork statements by the process being killed. If the process to be terminated is not blocked waiting on some other condition, such as an event, wait expression, or a delay then the process shall be terminated at some unspecified time in the current time step.

Q. Difference between Associative array and Dynamic array?
Dynamic arrays are useful for dealing with contiguous collections of variables whose number changes dynamically. e.g. int array[];
When the size of the collection is unknown or the data space is sparse, an associative array is a better option. In associative array, it uses the transaction names as the keys in associative array.
e.g. int array[string];

Q.What is coverage driven verification?
Coverage Driven Verification is a result oriented approach to functional verification. The manager and verification terms define functional coverage points, and then work on the detail of process. Used effectively coverage driven verification focuses the Verification team on measurable progress toward an agreed and comprehensive goal.

Q. how to randomize dynamic arrays of objects?
class ABC;
// Dynamic array
rand bit [7:0] data [];
// Constraints
constraint cc {
// Constraining size
data.size inside {[1:10]};
// Constraining individual entry
data[0] > 5;
// All elements
foreach(data[i])
if(i > 0)
data[i] > data[i-1];
}
endclass : ABC

Q. What is scope randomization?
Scope randomization ins SystemVerilog allows assignment of unconstrained or constrained random value to the variable within current scope by passing the variable as an argument to the randomize function.

Q. What is polymorphism?
                      Polymorphism allows an entity to take a variety of representations. Polymorphism means the ability to request that the same Operations be performed by a wide range of different types of things. Effectively, this means that you can ask many different objects to perform the same action. Override polymorphism is an override of existing code. Subclasses of existing classes are given a "replacement method" for methods in the superclass. Superclass objects may also use the  replacement methods when dealing with objects of the subtype. The replacement method that a subclass provides has exactly the same signature as the original method in the superclass.
                      Polymorphism allows the redefining of methods for derived classes while enforcing a common interface.To achieve polymorphism the 'virtual' identifier must be used when defining the base class and method(s) within that class.

Q. What are the simulation phases in your verification environment?
Prepone (sample) : Sampling signals before design activity. For testbench input.
Active (design) : Simulation of design code in modules
Observed (assertions) : Evaluation of System Verilog Assertions
Reactive(testbench) : Execution of testbench code in programs

Q. What are the types of coverages available in SV ?
Using covergroup : variables, expression, and their cross
Using cover keyword : properties
Q. List the predefined randomization method: pre_randomize, randomize & post_randomize
Q. What is randsequence and what is its use?
The random sequence generator is useful for randomly generating sequences of stimulus.

Q. How SV is more random stable then Verilog?
In Systemverilog seeding will be done  in hierarchal form. Every module instance, interface instance, program instance and package has initialization RNG. Every thread and object has independent RNG . Whenever dynamic thread is created its RNG is initialized with the next random value from its parent thread. RNG initialization and RNG generation are different process. During RNG initialization, only seed is set to RNG. Whenever static thread is created its RNG is initialized with the next random value from the initialization RNG of module instance, interface instance, program interface or package containing thread declaration. RNG initialization and RNG generation are different process. During RNG initialization, only seed is set to RNG. The random number generator is deterministic. Each time the program executes, it cycles through the same random sequence. This sequence can be made nondeterministic by seeding the $urandom function with an extrinsic random variable, such as the time of day
SystemVerilog system functions $urandom and $urandom_range are thread stable. Calls to RNG using these system function, uses the RNG of that thread. So next time while using $random in SystemVerilog, think twice. 

Q. What is bin?
A coverage-point bin associates a name and a count with a set of values or a sequence of value transitions. If the bin designates a set of values, the count is incremented every time the coverage point matches one of the values in the set. If the bin designates a sequence of value transitions, the count is incremented every time the coverage point matches the entire sequence of value transitions.

Q. Is it possible for functions to return a array( memory) ?
Yes we can return an array in SV functions following these steps
1.       Define a type for an array using typedef (typedef int f_arry[]; f_arry arry1;)
2.       Use it in function.(function f_arry func1  (input int xyz);)
3.       Then return the value of the function into array(arry1 = func1).

Q. How to check weather randomization is successful or not?
Put the randomize function into an if..else condition checking as the randomize func will return 0 if randomization fails else will return 1, another way is to use it with assert.

Q. Do we need to call super.new() when extending a class ? What happens if we don’t call?
The new constructor is by default called by the extended class while creating, but if the parent class constructor needs some arguments then we should pass the arguments from the extended class constructor, which is mandatory and should always be on the first line of the function new() of extended class.

Q. What is the need to implement explicitly a copy() method inside a transaction , when we can simple assign one object to other ?
Assigning an object handle to another will simply make both of the handles to point to a same object, and will share same resource of memory, so as to separate both the objects according to its handle name we need to have a copy method to create a replica of the object.

Q. What is “scope resolution operator”?
The class scope resolution operator enables the following:
·         Access to static public members (methods and class properties) from outside the class hierarchy.
·         Access to public or protected class members of a superclass from within the derived classes.
·         Access to type declarations and enumeration named constants declared inside the class from outside the class hierarchy or from within derived classes.


Q. What is the difference between Verilog Parameterized Macros and SystemVerilog Parameterized Macros?
Verilog provides the `define text substitution macro compiler directive. A macro can contain arguments, whose values can be set for each instance of the macro. SystemVerilog enhances the capabilities of the `define compiler directive to support the construction of string literals and identifiers.

Q. Explain how the timescale unit and precision are taken when a module does not have any timescalerdeclaration in RTL?

If a timeunit is not specified in the module, program, package, or interface definition, then the time unit shall be determined using the following rules of precedence:
a) If the module or interface definition is nested, then the time unit shall be inherited from the enclosing module or interface (programs and packages cannot be nested).
b) Else, if a ‘timescale directive has been previously specified (within the compilation unit), then the time unit shall be set to the units of the last ‘timescale directive.
c) Else, if the compilation-unit scope specifies a time unit (outside all other declarations), then the time unit shall be set to the time units of the compilation unit.
d) Else, the default time unit shall be used.


   
          View Maulik Suthar's profile on LinkedIn