SystemVerilog Interview Questions with Answers
Basic Level Questions
1. Difference between byte a and bit [7:0] a
Both bit and byte are 2-state data types and can store 8-bit or 1-byte data. The difference between them is that ‘bit’ is unsigned whereas ‘byte’ is a signed integer.
2. What is the difference between bit and logic?
A bit is a 2-state data type having values as 0 or 1 whereas logic is 4 state data type having values as 0, 1, x, z.
3. Why logic is introduced in SV? Or Why reg and wires are not sufficient?
Refer logic data type
4. Difference between reg and logic?
Both are 4 state variables. Reg can be only used in procedural assignments whereas logic can be used in both procedural and continuous assignments
5. What are 2 state and 4 state variables? Provide some examples.
2 state data type can store two values 0 and 1 4 state data type can store two values 0, 1, X, and Z
Refer examples: data type
6. Difference between integer and int
Both can hold 32-bit signed integer values. The main difference between them is
integer – 4 state data type
int – 2 state data type
7. Difference between packed and unpacked arrays
8. Difference between dynamic and associative arrays
Dynamic Array |
Associative array |
Need to allocate memory before using it. |
Memory can be allocated when it is used |
Elements of an array have particular data types. |
Elements of an array can be of any type. We can store the concatenation of various data types or class structures as well. |
9. Difference between dynamic array and queue
Dynamic Array |
Associative array |
Memory needs to be allocated before using it i.e. array size is required to be allocated first. |
For bounded queues, the size needs to be allocated. For unbounded queue can store unlimited entries. |
Memory allocation is contiguous. |
Memory allocation may not be contiguous and accessing intermediate variables needs to traverse like a linked list traversal. |
new[ ] is used to create array memory. |
Queue [<size>] for bounded queue size. |
Similar to the fixed array, any array element can be accessed. |
Usually, head or tail elements are accessed. But queues also offer functionality to access any element of the queue. |
The size can be increased using a new [ ] method to find out larger contiguous memory space and existing array elements get copied in new space. |
For unbounded queues, the size of the queue expands using push_back or push_front methods. The new data elements get added similar to linked list node addition. |
10. Difference between structure and union
Unions are similar to structures that can contain different data types members except they share the same memory location. Hence, it is a memory-efficient data structure. But it also restricts the user to use one member at a time.
11. How do you write a power b in sv code?
module arithmetic_op;
reg [1:0] a, b;
reg [3:0]out;
initial begin
a = 2'd3;
b = 2'd2;
out = a**b;
$display("a = %0d and b = %0d", a, b);
$display("pow: out = %0d", out);
end
endmodule
12. What are pass-by-value and pass-by-reference methods?
A pass-by-value argument passing mechanism does copy arguments locally and operates on those variables. Any changes in variables in the function will not be visible outside of the function.
function int fn_multiply(int a, b);
A pass-by-reference argument passing mechanism does not copy arguments locally but reference to the original arguments is passed. This also means that any change in values for the argument inside the subroutine will affect the original values of the variables,
function int fn_multiply(ref int a, b);
13. Why do we need randomization in SystemVerilog?
Refer Need for randomization
14. Difference between module and program block?
15. How do program block avoid the race condition?
16. Difference between === and == operators?
The output of “==” can be 1, 0, or X. The output would be ‘x’, if you compare two variables if one or both the variables have one or more bits as X.
The output of “===” can only be 0 or 1. It is used to compare ‘x’ or ‘z’, whereas ambiguous values can not be compared using the ‘==’ operator.
out = (A == B) and out = (A === B) results in tabular format.
A |
B |
Using == |
Using === |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0/1 |
x/z |
x |
0 |
x |
x |
x |
1 |
z |
z |
x |
1 |
x |
z |
x |
0 |
17. What are SystemVerilog interfaces and why are they introduced?
System Verilog provides an interface construct that simply contains a bundle of sets of signals to communicate with design and testbench components.
Why are they introduced?
In Verilog for the addition of new signals, it has to be manually changed everywhere that module has been instantiated. System Verilog made it easier to add new signals in the interface block for existing connections.
Advantages:
- It has increased re-usability across the projects.
- A set of signals can be easily shared across the components bypassing its handle.
- It provides directional information (mod ports) and timing information (clocking blocks).
- Interfaces can contain parameters, variables, functional coverage, assertions, tasks, and functions.
- Interfaces can contain procedural initial and always blocks and continuous assign statements.
18. What is modport and clocking block?
Within an interface to declare port directions for signals modport is used
To specify synchronization scheme and timing requirements for an interface, a clocking block is used.
Refer systemverilog modport and clocking block
19. Difference between initial and final block.
Initial Block |
Final Block |
The initial block executes at the start of a simulation at zero time units. |
final block executes at the end of the simulation without any delays |
Usage: Initial configuration set-up |
Usage: To display statistical information about the simulation |
20. What is cross-coverage?
Refer cross coverage
21. Difference between code and functional coverage
Code coverage
Code coverage deals with covering design code metrics. It tells how many lines of code have been exercised w.r.t. block, expression, FSM, signal toggling.
Functional coverage
Functional coverage deals with covering design functionality or feature metrics. It is a user-defined metric that tells about how much design specification or functionality has been exercised.
Read more about coverage and covergroup
22. Different types of code coverage.
Code coverage deals with covering design code metrics. It tells how many lines of code have been exercised w.r.t. block, expression, FSM, signal toggling.
The code coverage is further divided as
- Block coverage – To check how many lines of code have been covered.
- Expression coverage – To check whether all combinations of inputs have been driven to cover expression completely.
- FSM coverage – To check whether all state transitions are covered.
- Toggle coverage – To check whether all bits in variables have changed their states.
23. Write rand constraint on a 3 bit variable with distribution 60% for 0 to 5 and 40% for 6,7. Write coverpoint for the same.
class rand_class;
rand bit [2:0] value;
constraint value_c {value dist {[0:5]:= 60, [6:7] := 40}; }
covergroup c_group;
cp1: coverpoint value {bins b1= {[0:5]};
bins b2 = {[6:7]};
}
endgroup
endclass
24. How many types of arrays are there? Explain
- Fixed-size array in SystemVerilog: Array size is fixed throughout the simulation. Its value will be initialized with a ‘0’ value.
The fixed size array can be further classified as a single-dimensional, multidimensional array, packed, and unpacked array - Dynamic array in SystemVerilog: An array whose size can be changed during run time simulation, is called dynamic array.
- Associative array in SystemVerilog: An associate array is used where the size of a collection is not known or data space is sparse.
Intermediate level questions
1. How to find indexes associated with associative array items?
An array manipulation method find_index can be used for the indices of an associative array.
Refer to an example: find index method
2. Difference between fork-join, fork-join_any, and fork-join_none
In fork-join, all processes start simultaneously and join will wait for all processes to be completed.
In fork-join_any, all processes start simultaneously and join_any will wait for any one process to be completed.
In fork-join_none, all processes start simultaneously and join_none will not wait for any process to be completed.
So, we can say that fork-join and fork-join_any is blocked due to process execution time, whereas fork-join_none is not blocked due to any process.
Refer SystemVerilog processes for more details and examples.
3. Difference Between always_comb and always@(*)?
always_comb |
always@(*) |
always_comb is automatically triggered once at time zero but only after all procedural blocks (initial and always blocks) have been started. |
always @ (*) will be triggered for any change in the sensitivity list. |
always_comb is sensitive to changes within the contents of a function. |
always @* is only sensitive to changes to the arguments of a function. |
Time constructs or delays are not allowed |
Time constructs or delays are not allowed |
4. Difference between structure and class
Structure |
Class |
A structure can contain different members of different data types. |
Classes allow objects to create and delete dynamically. |
Does not supports inheritance, polymorphism |
Supports inheritance, polymorphism |
Data members of structure are visible to everyone |
Data members of class can be protected and will not be visible outside of class. |
Supports data abstraction |
Supports only grouping of data. |
5. Difference between static and automatic functions
- By default, functions declared are static except they are declared inside a class scope. If the function is declared within class scope, they behave as an automatic function by default unless they are specifically mentioned as static functions.
- All variables declared in a static function are static variables unless they are specifically mentioned as an automatic variable.
- All variables declared in an automatic function are automatic variables unless they are specifically mentioned as a static variable.
6. Difference between new[ ] and new()
new[ ] – To create a memory. It can also be used to resize or copy a dynamic array.
Example:
int array [];
array = new[5]; // create an array of size = 5
array = new[8] (array); // Resizing of an array and copy old array content
new() – To create an object for the class, commonly known as ‘class constructor’.
class transaction;
// class properties and methods
endclass
transaction tr; // variable of class data_type transaction or class handle
tr = new(); // memory is allotted for a variable or object.
7. Difference between shallow and deep copy
Shallow Copy:
The shallow copy is used to copy
- Class properties like integers, strings, instance handle, etc
- Nested objects are not copied, only instance handles are copied which means any changes are done in ‘nested copied object’ will also reflect in the ‘nested original object’ or vice-versa.
Refer for an example: Shallow copy example
Deep Copy:
The deep copy is the same as shallow copy except nested created objects are also copied by writing a custom method. Unlike shallow copy, full or deep copy performs a complete copy of an object.
Refer for an example: Deep copy example
8. How does the OOP concept add benefit in Verification?
Object Oriented Programming concept introduce concept of class and object in SystemVerilog similar to other programming language like C++, Java, Python, etc that provides following benefits
- Inheritance: An Inheritance allows users to create an extended class from the existing class. This promotes code reuse and can lead to more efficient verification by having common functionality in the base class.
- Polymorphism: Polymorphism means having many forms. A base class handle can invoke methods of its child class which has the same name. Hence, an object can take many forms.It uses virtual methods tha helps to override base class attributes and methods.
- Data Encapsulation and Hiding: Data encapsulation is a mechanism that combines class properties and methods. Data hiding is a mechanism to hide class members within the class. They are not accessible outside of class scope. This avoids class member modification outside the class scope and its misuse. By default, all class members are accessible with class handles in SystemVerilog. To restrict access, access qualifiers are used.
- Code Readability and Maintainability: The organized way of coding in OOPs provides readable and maintainable code which allows verification engineers to write tests and also build hierarchical verification testbench.
9. What is inheritance?
An Inheritance allows users to create an extended class from the existing class. The existing class is commonly known as base class or parent class and the newly created extended class is known as a derived class or child class or subclass. This promotes code reuse and can lead to more efficient verification by having common functionality in the base class.
Refer to an example: Inheritance example
10. What are the ‘super’ and ‘this’ keywords in SystemVerilog?
‘super’ keyword
The ‘super’ keyword is used in a child or derived class to refer to class members of its immediate base class.
Refer to an example: super keyword example
‘this’ keyword:
To refer to class properties or methods of the current class instance, this keyword is used. In simple terms, this keyword is a handle of the current class object. It shall be used only in non-static class methods. The ‘this’ keyword resolves the ambiguity of a compiler when class properties and arguments passed to class methods are the same.
Refer to an example: this keyword example
11. What is polymorphism and its advantages?
Polymorphism means having many forms. A base class handle can invoke methods of its child class which has the same name. Hence, an object can take many forms.
Advantages
- It makes code more reusable. The common functionality can be kept in the base class and derived class-based functionality will be alone in its inherited or child class. Thus it helps to write the code more modular.
- Improves code readability and easy for code maintenance as common logic can be placed in the base class itself.
- Provides an encapsulation that allows objects to expose only required functionality.
- A new class can be added easily instead of modifying existing class functionality. Thus it enablesflexibility.
12. What is a virtual function?
A virtual function or task from the base class can be overridden by a method of its child class having the same signature (same method name and arguments).
In simple words, When a child class handle is assigned to its base class. On calling a method using a base class handle, the base class method will be executed. On declaring a method as a virtual method, a base class handle can call the method of its child class.
Usage:
- Widely used in verification methodologies like UVM
- Helps to reuse code
- Helps to customize the behavior of verification components
Refer for more details and example: virtual function example
13. What is the use of a scope resolution operator?
The scope resolution operator is used to
- Access to static members (methods and class properties)
Example: static members example - Class method declaration outside the class.
Example: class method using extern keyword - Importing a package and also accessing package items.
Example: Accessing a package
14. Difference between virtual and pure virtual function
Virtual function |
Pure virtual function |
A virtual function from the base class can be overridden by a method of its child class having the same signature (same function name and arguments). |
A pure virtual function is a method that makes it mandatory for methods to be implemented in derived classes whose prototypes have been specified in an abstract class. |
If there is no implementation in the derived class, the base class’s implementation is executed. |
If a derived class doesn’t overwrite the pure virtual function, it will remain abstract and cannot be instantiated. |
Declared by using the keyword ‘virtual’ in the base class. |
Declared by using the keyword ‘pure virtual’ in the base class. |
Example: virtual function example |
Example: pure virtual function example |
15. What is a virtual interface and its need?
An interface represents signals that are used to connect design modules or testbench to the DUT and is commonly known as a physical interface. The design and physical interface are static in nature. Hence, they can not be used dynamically. In modern testbench, randomized class objects are used and connect to the design dynamically. Hence, to bridge the gap between the static world of modules and the dynamic world of objects, a virtual interface is used as a pointer or handle for an actual interface.
16. What is a virtual class?
Refer to abstract class
17. What are parameterized classes?
Parameterized classes are useful when the same class needs to be instantiated differently. The default parameter can be set in the class definition. These parameters can be overridden when it is instantiated.
Refer to an example: parameterized classes
18. What are rand and randc methods?
Refer rand and randc keywords
19. What are pre_randomize and post_randomize methods?
Refer randomization methods
20. Explain bidirectional constraints
Bidirectional constraints are used to specify a relationship between two or more variables or signals where one variable value has a dependency on other variables.
Refer to an example of bidirectional constraint
21. Is it possible to override existing constraints?
Yes, there are two ways to do so
- Inline constraint: Refer to inline constraints
- Inheritance: Refer to inheritance in constraint
22. Difference between :/ and := operators in randomization
Both are used to assign weightage to different values in the distribution constraints.
:/ Operator
- For specific value: Assign mentioned weight to that value
- For range of values ([<range1>: <range2>]): Assigns weight/(number of value) to each value in that range
:= operator
For a specific value or range of value, the mentioned weight is assigned.
Refer to an example: dist keyword in constraints
23. What is std::randomize?
It is one of the methods provided by SystemVerilog to randomize local variable without declaring it as rand or randc. The inline constraint also can be written using the ‘with’ clause.
Example:
int value;
std::randomize(value) with {
value inside {5, 10, 15, 20};
};
24. Is it possible to call a function from constraint? If yes, explain with an example.
Yes, a function can be called inside a constraint which can take input arguments and also return a value.
Refer to an example: function in constraint example
25. Write a constraint - divisible by 5.
class constraint_example;
rand bit[3:0] val;
constraint value_c { val % 5 == 0; }
function void post_randomize();
$display("Randomized value = %0d", val);
endfunction
endclass
26. How to disable constraints?
Refer: disable constraint
27. How to disable randomization?
Yes, it can be disabled using rand_mode. To disable randomization, rand_mode(0) is used. By default, randomization is enabled i.e. rand_mode(1)
Example: using rand_mode
28. Difference between static and dynamic casting
Casting is a process of converting from one data type into another data type for compatibility.
Static Casting |
Dynamic Casting |
static casting is only applicable to fixed data types. |
Dynamic casting is used to cast the assigned values to the variables that might not be ordinarily valid. |
It is a compile-time operation |
It is a run-time operation |
It is a simple and efficient process |
It is more complex and less efficient than static casting |
Compile failure will be seen for casting failure. |
It can detect and handle errors during runtime. |
29. Difference between mailbox and queue
A queue is a variable size and ordered collection of elements whereas a mailbox is a communication mechanism that is used to establish the connection between testbench components. One component can put data into a mailbox that stores data internally and can be retrieved by another component. The mailbox can be a parameterized mailbox that can be put or get data of a particular data_type.
The queue has push_front/push_back/pop_front/ pop_back to operate over data elements, whereas a mailbox has get/ put methods as commonly used methods to exchange the data or objects.
30. What is semaphore and in what scenario is it used?
Semaphore is a built-in class in SystemVerilog used for synchronization which is a container that contains a fixed number of keys. It is used to control the access to shared resources.
Example: The same memory location is accessed by two different cores. To avoid unexpected results when cores try to write or read from the same memory location, a semaphore can be used.
Refer semaphores for explanation of methods in semaphores and examples.
31. What is input and output skew in clocking block?
To specify the synchronization scheme and timing requirements for an interface, a clocking block is used.
Clocking Skew:
The input or output clocking block signals can be sampled before or after some time unit delay known as clocking skew. It is declared as:
default input #2 output #3;
Where, Input clocking skew: #2 and Output clocking skew: #3
This means input signals is sampled #2 time unit before the clocking event and output signals are driven after #3 time units after the clocking event.
Refer for more information: clocking-block
32. What are the types of assertions?
Assertions are used to check design rules or specifications and generate warnings or errors in case of assertion failures.
Types of assertions:
- Immediate assertions – An assertion that checks a condition at the current simulation time is called immediate assertions.
- Concurrent assertions – An assertion that checks the sequence of events spread over multiple clock cycles is called a concurrent assertion.
33. Difference between $strobe, $monitor and $display
System tasks |
Description |
$display |
To display strings, variables, and expressions immediately in the active region. |
$monitor |
To monitor signal values upon its changes and executes in the postpone region. |
$write |
To display strings, variables, and expressions without appending the newline at the end of the message and executing in the active region. |
$strobe |
To display strings, variables, and expressions at the end of the current time slot i.e. in the postpone region. |
Refer system-tasks to understand more.
34. What is ignore bins?
Refer Ignore_bins
35. Difference between ignore and illegal bins.
The ignore bins are used to specify a set of values or transitions that can be excluded from coverage whereas the illegal bins are used to specify a set of values or transitions that can be marked as illegal and a run-time error is reported for the same.
Example:
covergroup c_group;
cp1: coverpoint addr {ignore_bins b1 = {1, 10, 12};
ignore_bins b2 = {2=>3=>9};
}
cp2: coverpoint data {illegal_bins b3 = {1, 10, 12};
illegal_bins b4 = {2=>3=>9};
}
endgroup
36. How do you define callback?
Refer systemverilog-callback
37. What is DPI? Explain DPI export and import.
Refer systemverilog-dpi
38. What is the implication operator in SVA? Explain its type?
Refer implication-operator
39. What all bins are generated by the following code
coverpoint addr {bins b1 = {1, 10, 12};
bins b2[] = {[2:9], 11};
bins b3[4] = {0:8};
Difficult level questions
1. What are the default values of variables in the SystemVerilog classes?
SystemVerilog class has a built-in new method which is commonly known as constructor.
Default values for
2 state variables – 0
4 state variables – X
2. What are local and protected access qualifiers?
Local access qualifiers: If a class member is declared as a local, they will be available to that class alone. The child classes will not have access to a local class member of their parent class.
Protected access qualifiers: A protected class member can not be accessed outside class scope except access by their child classes.
3. How do you implement the randc function in SystemVerilog?
4. Is it possible to generate random numbers without using rand or randc keywords?
Yes, it is possible to generate random numbers using std::randomize() method provided by SystemVerilog to randomize local variable without declaring it as a rand or randc. The inline constraint also can be written using ‘with’ clause.
Example:
int value;
std::randomize(value) with {
value inside {5, 10, 15, 20};
};
5. Difference between @posedge and $rose?
@(posedge <signal>) is true when its value changes from 0 to 1.
$rose(<signal>) is evaluated to be true for value changes happening across two clocking events from 0 or x or z to 1.
6. Talk about basic testbench components.
Refer Testbench_components
7. Explain the cycle of verification and its closure.
Refer asic-verification-flow
8. How will you test the functionality of interrupts using functional coverage?
The functionality of interrupt getting raised and being serviced by the testbench can be verified by writing ‘Sequence of transitions’ coverpoint as follows
covergroup c_group;
cp1: coverpoint intr {bins b1 = (0 => 1 => 0);
}
endgroup
This allows testing interrupt is generated due to the stimulus and testbench is calling an appropriate ISR to service the interrupt.
9. What is layered architecture in Verification?
Layered architecture involves structuring the verification environment into various layers or levels that help to provide abstraction, scalability, reusability, etc.
Testbench Top and Test Layer: The testbench top is a top-level component that includes interface and DUT instances. It connects the design with the test bench. The reset, clock generation, and its connection with DUT is also done in testbench top.
The test is at the top of the hierarchy that initiates the environment component construction and connection between them. It is also responsible for the testbench configuration and stimulus generation process.
Based on the design feature verification, a directed or constrained random test is written. The test case generates stimulus based on configurations or
Verification components Layer:
The Verification Components Layer serves as an abstraction that encapsulates the behavior of the Design Under Test (DUT) while focusing on verifying the functionality of the design using various verification components.
Coverage Layer: Coverage collection mechanisms track different aspects of the DUT that have been exercised during simulation. This includes functional coverage, code coverage, and assertion coverage, providing insights into the verification completeness and identifying any areas that require additional testing.
Advantages of the layered approach:
- Improved Verification Efficiency: Abstraction and modularity accelerate the verification process.
- Enhanced Reusability: Verification components can be reused across multiple projects.
- Better Test Coverage: A modular approach facilitates comprehensive testing.
- Improved Maintainability: Focused components make verification code easier to maintain and update.
10. How can you establish communication between monitor and scoreboard in SystemVerilog?
The monitor observes pin-level activity on the connected interface at the input and output of the design. This pin-level activity is converted into a transaction packet and sent to the scoreboard for checking purposes.
The scoreboard receives the transaction packet from the monitor and compares it with the reference model. The reference module is written based on design specification understanding and design behavior.
Both are used to verify the correctness of the design in the verification environment component. They are connected using a mailbox in a SystemVerilog-based verification environment.
11. Difference between class-based testbench and module-based testbench.
class-based testbench |
module-based testbench |
Testbench is developed around multiple blocks of connected design modules |
Testbench is developed around individual design modules. |
The class-based stimulus is generated and driven to the design. |
The physical interface is driven to the design |
Provide more flexibility in terms of configuring testbench in various modes as needed. |
Configuring a testbench needs modification in the parameter used for the corresponding module that does not give the flexibility to change it during run time. |
Useful for complex design verifications |
Useful for smaller and simpler design verification. |
12. How will be your approach if code coverage is 100% but functional coverage is too low?
This can be possible when
- Functional coverage bins (may be auto bins) generated for wide variable range which is not supported by design.
- Cross check if code coverage exclusions are valid so that it should not give false interpretation of 100% code coverage.
- Functional coverage implemented for feature (were planned during initial project phasing), but those are not supported by the design now.
13. How will be your approach if functional coverage is 100% but code coverage is too low?
This can be possible when
- RTL code is not covered, so new stimulus or existing stimulus improvement is required (assuming dead code is not a reason for low code coverage).
- Another part is that 100% functional coverage suspects that covergroup for some features might be missing. A detailed analysis is required to root cause of the same. If the functional coverage is properly implemented, then code coverage can be improved by new stimulus addition, and updating existing stimulus which might include constraint-based testing.
14. Write an assertion for glitch detection.
realtime duration=50ns;
property glitch_detection;
realtime first_change;
@(signal) // Change in signal value (posedge and negedge)
(1, first_change = $realtime) |=> (($realtime - first_change) >= duration); // It saves current time and also check the delay from previous edge
endproperty
ap_glitch_p: assert property(glitch_detection);
Interview Questions