Interview Question Bank
Questions asked in RTL design, verification, timing, physical design and post-silicon interviews.
- 337 Questions
- 149 Verilog
- 100 SystemVerilog
- 15 SoC Verification
- 14 Formal Verification
- 15 Static Timing Analysis
- 15 Bus Protocols
- 15 Physical Design
- 14 Post-Silicon Validation
What are the testability implications for derived clocks ?
Derived clocks are created within a chip using clock dividers through Flip-Flops or PLLs. Because these clocks are generated internally, a control signal from the primary pins is necessary to prevent Flip-Flops from capturing data at unintended times.
A multiplexor can be added in the clock path with the select line controlled by a test mode enable signal. The inputs to the mux should be regular clock and derived clock.
What are the testability challenges of gated clocks ?
Gated clocks are typically used to reduce power consumption by disabling the clock signal to specific parts of the chip when they are not in use. However, during testing, it is essential to be able to access and control these signals in order to ensure correct operation of the chip and detect any faults.
The workaround is to logically OR a test mode enable signal to the enabling pin of the AND gate that gates the clock.
What is the implication of a combinatorial feedback loops in design testability?
Combinatorial feedback loops occur when the output of a combinational logic gate is fed back into one of its inputs, potentially creating a feedback loop that can lead to unexpected behavior or cause the design to become stuck in an unstable state. Since the loops are delay-dependent, they cannot be tested with any ATPG algorithm and must be avoided in the logic.
How does the presence of latches affect the testability ?
One of the main issues with latches is that they can cause the propagation of glitches, which are short-lived pulses that can be difficult to observe during testing. These glitches can be especially problematic if they propagate to other parts of the design, potentially causing unintended behavior or creating false positives during testing.
Output of a latch is not controllable directly from a primary input since, the enable to a latch is not the regular clock going to rest of the flops in the design. The enable pin to the latch needs to be OR'd with a test mode enable signal.
What value is sampled by the logic from an input port that is left open (that is, no-connect) during its module instantiation?
An unconnected input port is a floating port, and it may float to an intermediate voltage level due to parasitic capacitance and inductance in the circuit. In simulations, this is indicated by the value 'Z' or high impedance and logic driven by it sees an unknown: gates and most operators treat a 'Z' input as 'X', so 'X' propagates until it is masked, for example by an AND with 0.
To avoid these types of issues, it is generally recommended to tie all unused input ports to a known state, such as ground or VDD, through the use of pull-up or pull-down resistors. This can help to prevent the input signal from floating and ensure that the logic gates are working as intended.
The default value of Z can be changed using compiler directives.
// Causes all unconnected input ports following this to be pulled down to logic 0
`unconnected_drive pull0
module mod_2341( ... );
...
endmodule
// Do not apply for rest of the code
`nounconnected_drive
How is the connectivity established in Verilog when connecting wires of different widths?
Connections are right-justified, which means that the LSB of the RHS is connected to the LSB of the LHS.
wire [7:0] net1;
wire [3:0] net2;
// net2 is narrower than net1, so it is zero-extended and net1[7:4] = 0
assign net1 = net2;
// net2 gets the truncated value of net1[3:0]
assign net2 = net1;
Can I use a Verilog function to define the width of a multi-bit port, wire, or reg type?
Yes, with a constant function. A constant function is called with constant arguments, such as parameters or literals, and is evaluated during elaboration, so its result can size a port, wire or reg. It must be declared in the same module and cannot use hierarchical references.
function integer clog2 (input integer value);
begin
value = value - 1;
for (clog2 = 0; value > 0; clog2 = clog2 + 1)
value = value >> 1;
end
endfunction
parameter DEPTH = 16;
input [clog2(DEPTH)-1:0] addr; // 4-bit address
Verilog-2005 also has a built-in $clog2 system function for this common case.
Summarize the main differences between $strobe and $monitor
$strobe displays values of selected signals at the end of the current simulation time when all simulation events have occurred and just before time advances whereas $monitor displays the value of selected signals whenever its value changes.
Read more on Verilog Display Tasks.
How can I selectively enable or disable monitoring?
This can be done with $monitoron and $monitoroff tasks.
How will you test the functionality of interrupts using functional coverage?
Testing the functionality of interrupts using functional coverage involves the following steps:
- Define functional coverage goals: First, you need to define your functional coverage goals. These goals should be specific to the interrupts you want to test. For example, you might define goals for interrupt latency, interrupt frequency, or interrupt priority handling.
- Create a testbench for interrupts: Next, you need to create a testbench that generates interrupts with different characteristics. This testbench should also monitor the behavior of the design under test (DUT) in response to the interrupts.
- Implement functional coverage: You can then implement functional coverage in your testbench to track how often each of the defined functional goals is achieved. You can use standard SystemVerilog constructs like covergroups, coverpoints, and bins to define and track the functional coverage.
- Analyze the functional coverage results: Finally, you can analyze the functional coverage results to determine how well your testbench tests the desired interrupt functionality. Based on the results, you can make adjustments to your testbench to improve the tests.
What is the use of scope resolution operator?
The scope resolution operator in SystemVerilog is denoted by the double colon '::' symbol. The basic purpose of this operator is to specify the scope in which an identifier is defined or should be searched for.
Here are some common uses of the scope resolution operator:
- Accessing a base class's members from a derived class: The
::operator can reach a superclass's public or protected members directly from a subclass, or reach anything declaredstaticfrom outside the class hierarchy entirely. This is a genuinely different mechanism from the dot operator's hierarchical name referencing (e.g.top.sub.clk), which navigates module/instance hierarchy rather than class or package scope —::only ever resolves against a class type, package, covergroup, or typedef name, never an instance path. - Resolving naming conflicts: When a design has two or more variables or modules with the same name, the scope resolution operator can be used to differentiate the variables or modules by specifying their scope.
- Accessing static variables and functions: The scope resolution operator is also used to access static properties and methods in a class.
- Accessing items in package: Elements in a package can be imported using
importwith scope resolution operator.
package ahb_pkg;
typedef enum {READ, WRITE} e_access;
endpackage
package wishbone_pkg;
typedef enum {WRITE, READ} e_access;
endpackage
ahb_pkg::e_access m_access; // m_access = 1 indicates WRITE
import ahb_pkg::*; // Imports everything in the package called "ahb_pkg"
import enum_pkg::global; // Imports everything under "global" from enum_pkg
Read more on SystemVerilog Scope Resolution Operator.
How do you implement randc in SystemVerilog?
The randc keyword in SystemVerilog will first exhaust all combinations possible before repeating a value. This is different from rand keyword where the same value may repeat even before all combinations are exercised.
Here's an example :
class ABC;
rand bit [1:0] x; // randomization can give x = 3, 1, 1, 0, 3, 0, 2, 2
randc bit [1:0] y; // randomization can give y = 1, 3, 0, 2, 3, 1, 2, 0
endclass
Read more on SystemVerilog rand Variables.
What is inheritance?
Inheritance is a concept in object-oriented programming that allows creating a new class by inheriting or extending the properties and behavior of an existing class. The existing class is called the parent or base class, and the new class is called the child or derived class. The child class inherits all the members of the parent class, such as variables, methods, and constructors, and can also add new members or override the inherited members.
Read more on SystemVerilog Inheritance.
What is DPI? Explain DPI export and import.
DPI stands for Direct Programming Interface, which is a mechanism in SystemVerilog for integrating SystemVerilog design and verification code with external C/C++ code. It enables interoperability between SystemVerilog and other high-level programming languages, which is not possible with traditional Verilog.
DPI import is used to import C/C++ functions into SystemVerilog. This means that a C/C++ function can be used as a task or function in SystemVerilog by creating an import task or import function.
extern "C" void my_function(int arg1, int arg2) {
// Do something here
}
And here's an example of how to import this function in SystemVerilog using DPI import:
import "DPI-C" context function void my_function(int arg1, int arg2);
DPI export works in the other direction: it makes a SystemVerilog function or task callable from that same C code. Declaring a function as exported doesn't change how it behaves on the SystemVerilog side at all — it just makes it reachable from the foreign-language side of a DPI call chain:
// SystemVerilog side: an ordinary function, nothing special about its body
function void sv_callback(int status);
$display("Got status %0d from C", status);
endfunction
// Export it so C code can call it directly
export "DPI-C" function sv_callback;
C code elsewhere in the same simulation can now call sv_callback(...) directly, the same way SystemVerilog called into my_function above — the DPI boundary works in both directions.
Read more on SystemVerilog DPI.
What is semaphore and in what scenario is it used?
Semaphore is a synchronization mechanism used to control access to shared resources. It is a variable or an abstract data type that is used to indicate the status of a shared resource, whether it is free, in use, or unavailable.
In a multi-tasking or multi-threaded environment where multiple processes or threads access shared resources concurrently, semaphores can ensure that only one process or thread can access the shared resource at a time. This helps to avoid conflicts and data inconsistency caused by simultaneous access, which could result in unexpected behavior.
Read more on SystemVerilog Semaphore.
Difference between fork-join, fork-join_any, and fork-join_none
They are all used to spawn processes in parallel.
- fork-join will exit only after all child processes finish.
- fork-join_any will exit after any of the child processes finish.
- fork-join_none will exit immediately without waiting for any child process to finish.
See examples of fork join, fork join_any and fork join_none.
Difference between static and automatic variables
The main difference is that a static variable gets initialized once before time 0 at some memory location and future accesses to this variable from different threads or processes access the same memory location. However, an automatic variable gets initialized every time the scope where it is declared gets executed and stored in a different location every time.
Read more on SystemVerilog Static Variables & Functions.
Difference between module and program block?
A module is the primary container for all RTL design code and allows hierarchical structuring of design intent. A program block, on the other hand, is a verification container introduced in SystemVerilog to avoid race conditions with the testbench: its contents execute in the Reactive region, after all of that time step's Active/Inactive/NBA design activity has already settled.
Read more on Verilog module and SystemVerilog Program Blocks.
Difference between dynamic and associative arrays
A dynamic array is an array whose size can be changed during runtime. Elements of the array are stored in a contiguous block of memory, and the size is determined when the array is created. An associative array, on the other hand, is also known as a dictionary or a map. It is a collection of key-value pairs where each key has a corresponding value.
In a dynamic array, the elements are accessed using an index, which refers to the position of the element in the array. In an associative array, elements are accessed using the key.
Read more on SystemVerilog Dynamic Array and Associative Array.
What is the difference between a deep copy and a shallow copy ?
A deep copy is one where nested class object contents are also entirely copied over into the new class object. A shallow copy is one where nested class objects are not copied but instead handles are simply assigned. So, if the original class object changes its contents, then the copied class also see the same contents.
Read more on SystemVerilog Copying Objects.