SystemVerilog & Verilog Tricky Interview Questions – Part 3

Expert-Level Coding Snippets with Detailed Answers

📌 Question 51: Race Condition with NBA

reg clk = 0;
always #5 clk = ~clk;

reg [3:0] a = 0, b = 0, c = 0;

always @(posedge clk) a <= a + 1;
always @(posedge clk) b <= a;
always @(posedge clk) c <= b;

initial begin
    #25;
    $display("a=%0d, b=%0d, c=%0d", a, b, c);
end

Question: What are the values at time 25?

Answer:

  • a = 2
  • b = 1
  • c = 0

Explanation:

  • Non-blocking assignments create pipeline effect
  • At each clock edge (time 10, 20):
    • All blocks read current values
    • All blocks write in NBA region
  • Time 10: a reads 0, b reads 0, c reads 0 → a=1, b=0, c=0
  • Time 20: a reads 1, b reads 1, c reads 0 → a=2, b=1, c=0
  • At time 25: between clocks
  • Pipeline delay: c is 2 cycles behind a

📌 Question 52: Foreach with Associative Array

int aa[int];

initial begin
    aa[5] = 50;
    aa[2] = 20;
    aa[8] = 80;
    aa[1] = 10;
    
    foreach(aa[i]) begin
        $display("aa[%0d] = %0d", i, aa[i]);
    end
end

Question: In what order are elements displayed?

Answer: Sorted by key (ascending)

  • aa[1] = 10
  • aa[2] = 20
  • aa[5] = 50
  • aa[8] = 80

Explanation:

  • Associative arrays with int keys are sorted
  • foreach iterates in key order (ascending)
  • Insert order doesn’t matter
  • Keys: 5, 2, 8, 1 → sorted to: 1, 2, 5, 8

📌 Question 53: Typedef Enum Range

typedef enum bit [2:0] {
    RED   = 3'b000,
    GREEN = 3'b001,
    BLUE  = 3'b100,
    YELLOW = 3'b111
} color_t;

color_t c1, c2;

initial begin
    c1 = color_t'(3'b010);  // Not in enum
    c2 = color_t'(3'b100);  // BLUE
    
    $display("c1 = %0d, name = %s", c1, c1.name());
    $display("c2 = %0d, name = %s", c2, c2.name());
end

Question: What will be displayed?

Answer:

  • c1 = 2, name = “” (empty string)
  • c2 = 4, name = “BLUE”

Explanation:

  • Casting to enum with undefined value is allowed
  • c1 gets value 2 (not in enum list)
  • c1.name() returns empty string (not a named value)
  • c2 = BLUE (valid enum value)
  • c2.name() returns “BLUE”
  • Can cast any value in base type range

📌 Question 54: Parameter vs Localparam

module test #(parameter P = 10, localparam L = 20);
    initial $display("P=%0d, L=%0d", P, L);
endmodule

module top;
    test #(.P(100), .L(200)) t1();  // Try to override both
endmodule

Question: What happens?

Answer: Compilation ERROR

Explanation:

  • parameter can be overridden at instantiation
  • localparam cannot be overridden (local only)
  • Attempting to override L causes compile error
  • Correct usage:
test #(.P(100)) t1();  // Only override P
  • L remains 20 (cannot be changed externally)

📌 Question 55: Package Variable Scope

package pkg;
    int shared_var = 100;
endpackage

module m1;
    import pkg::*;
    initial begin
        shared_var = 200;
        $display("m1: shared_var = %0d", shared_var);
    end
endmodule

module m2;
    import pkg::*;
    initial begin
        #1 $display("m2: shared_var = %0d", shared_var);
    end
endmodule

Question: What does m2 display?

Answer: m2: shared_var = 200

Explanation:

  • Package variables are globally shared
  • m1 modifies shared_var to 200
  • m2 sees the modified value
  • All modules importing the package share same variable
  • Not a copy – actual shared storage
  • Be careful with package variables in concurrent modules!

📌 Question 56: Array Reduction Methods

int arr[] = '{1, 2, 3, 4, 5};

initial begin
    $display("sum = %0d", arr.sum());
    $display("product = %0d", arr.product());
    $display("and = %0d", arr.and());
    $display("or = %0d", arr.or());
    $display("xor = %0d", arr.xor());
end

Question: What are the results?

Answer:

  • sum = 15 (1+2+3+4+5)
  • product = 120 (1×2×3×4×5)
  • and = 0 (1&2&3&4&5 = 0)
  • or = 7 (1|2|3|4|5 = 7)
  • xor = 1 (12345 = 1)

Explanation:

  • Array methods perform reduction operations
  • sum(): adds all elements
  • product(): multiplies all elements
  • and(): bitwise AND of all elements (1&2=0)
  • or(): bitwise OR (sets all used bits)
  • xor(): XOR chain (1^2=3, 3^3=0, 0^4=4, 4^5=1)

📌 Question 57: Wait Fork with Timing

initial begin
    fork
        #10 $display("Task A at %0t", $time);
        #20 $display("Task B at %0t", $time);
        begin
            #5 $display("Task C.1 at %0t", $time);
            #10 $display("Task C.2 at %0t", $time);
        end
    join_any
    
    $display("After join_any at %0t", $time);
    wait fork;
    $display("After wait fork at %0t", $time);
end

Question: What is displayed and when?

Answer:

  • Task C.1 at 5
  • Task A at 10
  • After join_any at 10 (first task completes)
  • Task C.2 at 15
  • Task B at 20
  • After wait fork at 20 (all tasks complete)

Explanation:

  • join_any returns when first task completes
  • First to complete: Task C.1 (5ns) – no, it’s nested
  • Actually Task A completes at 10ns (first standalone task)
  • Main thread continues at 10ns
  • wait fork waits for all remaining tasks
  • All complete by 20ns

📌 Question 58: Streaming Operator Unpack

bit [31:0] word = 32'hDEADBEEF;
byte unsigned bytes[];

initial begin
    bytes = {>>byte{word}};
    
    foreach(bytes[i])
        $display("bytes[%0d] = %h", i, bytes[i]);
    
    $display("Size: %0d", bytes.size());
end

Question: What will be displayed?

Answer:

  • bytes[0] = DE
  • bytes[1] = AD
  • bytes[2] = BE
  • bytes[3] = EF
  • Size: 4

Explanation:

  • Streaming operator {>>byte{word}} unpacks word into bytes
  • Direction >> means right-to-left streaming
  • Creates dynamic array of 4 bytes
  • Byte order: MSB first (DE, AD, BE, EF)
  • Very useful for packing/unpacking structures

📌 Question 59: Constraint Distribution Weights

class Packet;
    rand bit [3:0] priority;
    
    constraint c_dist {
        priority dist {0 := 50, [1:3] := 30, [4:15] :/ 20};
    }
endclass

initial begin
    Packet p = new();
    int count[16];
    
    repeat(1000) begin
        p.randomize();
        count[p.priority]++;
    end
    
    // What's the approximate distribution?
end

Question: What’s the expected distribution?

Answer:

  • 0: ~50% (500 times)
  • 1,2,3: ~10% each (~100 times each, 30% total)
  • 4-15: ~1.67% each (~17 times each, 20% total)

Explanation:

  • := assigns exact weight to each value
    • 0 gets weight 50
    • 1,2,3 each get weight 30 (total 90)
  • :/divides weight among range
    • 4-15 (12 values) share weight 20
    • Each gets 20/12 ≈ 1.67
  • Total weight: 50 + 90 + 20 = 160
  • Probability of 0: 50/160 ≈ 31.25%… wait, let me recalculate

Correction:

  • Total weight: 50 + (3×30) + 20 = 160
  • 0: 50/160 = 31.25%
  • 1,2,3: 30/160 each = 18.75% each
  • 4-15: (20/12)/160 each ≈ 1.04% each

📌 Question 60: Bit Select vs Part Select

logic [7:0] data = 8'b10110010;
int idx = 3;

initial begin
    $display("data[3] = %b", data[3]);
    $display("data[idx] = %b", data[idx]);
    $display("data[3:3] = %b", data[3:3]);
    $display("data[idx:idx] = %b", data[idx:idx]);
    $display("data[idx+:2] = %b", data[idx+:2]);
end

Question: What will be displayed?

Answer:

  • data[3] = 1
  • data[idx] = 1
  • data[3:3] = 1
  • data[idx:idx] = 1
  • data[idx+:2] = 10

Explanation:

  • data[3] – bit select (single bit 3)
  • data[idx] – bit select with variable
  • data[3:3] – part select (1-bit wide)
  • data[idx:idx] – variable part select
  • data[idx+:2] – indexed part select (bits 3 and 4)
    • From idx=3, width=2 → data[4:3] = 2’b10

📌 Question 61: Class Handle Null Check

class Packet;
    int data = 100;
endclass

Packet p1;
Packet p2 = null;
Packet p3 = new();

initial begin
    if (p1 == null)
        $display("p1 is null");
    if (p2 == null)
        $display("p2 is null");
    if (p3 == null)
        $display("p3 is null");
    
    $display("p3.data = %0d", p3.data);
end

Question: What will be displayed?

Answer:

  • p1 is null
  • p2 is null
  • p3.data = 100

Explanation:

  • Uninitialized class handle (p1) is null by default
  • Explicitly null (p2) is also null
  • Only p3 is constructed with new()
  • Accessing p1.data or p2.data would cause runtime error
  • Always check if (handle != null) before dereferencing!

📌 Question 62: Multiple Inheritance (Not Supported!)

class Base1;
    int val1 = 10;
endclass

class Base2;
    int val2 = 20;
endclass

class Derived extends Base1, Base2;  // Try multiple inheritance
    int val3 = 30;
endclass

Question: What happens?

Answer: Compilation ERROR

Explanation:

  • SystemVerilog does NOT support multiple inheritance
  • Can only extend one base class
  • Use composition instead:
class Derived extends Base1;
    Base2 obj2 = new();  // Compose instead
    int val3 = 30;
endclass
  • Inheritance is single-chain only

📌 Question 63: Casting Between Incompatible Types

class Base;
    int base_val = 10;
endclass

class Extended extends Base;
    int ext_val = 20;
endclass

Base b = new();
Extended e;

initial begin
    e = Extended'(b);  // Downcast
    $display("ext_val = %0d", e.ext_val);
end

Question: What happens?

Answer: Runtime ERROR (or crash)

Explanation:

  • Downcasting base to derived is dangerous
  • b is Base object (doesn’t have ext_val)
  • Cast forces type but object is still Base
  • Accessing e.ext_val accesses non-existent field
  • Use $cast for safe casting:
if (!$cast(e, b))
    $display("Cast failed!");
  • $cast returns 0 if incompatible

📌 Question 64: Randomization with Pre/Post Randomize

class Packet;
    rand bit [7:0] len;
    rand bit [7:0] data[];
    
    function void pre_randomize();
        $display("pre_randomize: len = %0d", len);
    endfunction
    
    function void post_randomize();
        data = new[len];
        foreach(data[i]) data[i] = i;
        $display("post_randomize: len = %0d, size = %0d", len, data.size());
    endfunction
    
    constraint c { len inside {[3:5]}; }
endclass

Packet p = new();

initial begin
    p.len = 100;
    p.randomize();
end

Question: What will be displayed?

Answer:

  • pre_randomize: len = 100
  • post_randomize: len = 3 (or 4 or 5), size = 3 (or 4 or 5)

Explanation:

  • pre_randomize() called before randomization
    • Sees old value (100)
  • Randomization changes len to 3-5
  • post_randomize() called after randomization
    • Sees new randomized value
    • Can perform post-processing
  • Use pre/post for setup and cleanup

📌 Question 65: Generate with Conditional

module test #(parameter MODE = 0);
    generate
        if (MODE == 0) begin : mode0
            initial $display("Mode 0 selected");
        end else if (MODE == 1) begin : mode1
            initial $display("Mode 1 selected");
        end else begin : mode_other
            initial $display("Mode %0d selected", MODE);
        end
    endgenerate
endmodule

module top;
    test #(0) t0();
    test #(1) t1();
    test #(5) t5();
endmodule

Question: What will be displayed?

Answer:

  • Mode 0 selected
  • Mode 1 selected
  • Mode 5 selected

Explanation:

  • Generate if evaluated at elaboration time
  • Each instance uses its parameter value
  • Different code generated for each instance
  • t0 generates mode0 block
  • t1 generates mode1 block
  • t5 generates mode_other block

📌 Question 66: Bidirectional Port Connection

module bidirectional(inout [7:0] bus);
    reg [7:0] data_out;
    reg enable;
    
    assign bus = enable ? data_out : 8'bz;
    
    initial begin
        enable = 1;
        data_out = 8'hAA;
        #10 enable = 0;
        #10 $display("bus = %h", bus);
    end
endmodule

Question: What is bus at time 20?

Answer: bus = zz (high-impedance)

Explanation:

  • When enable=1: bus = data_out = 0xAA
  • At time 10: enable=0
  • 8'bz drives bus (high-Z)
  • At time 20: bus is floating (zz)
  • No other driver, so remains high-Z
  • Inout ports need external pullup/pulldown or another driver

📌 Question 67: Bit Concatenation with Unsized

bit [15:0] result;

initial begin
    result = {8'hAB, 4'h5, 4'h3};
    $display("result = %h", result);
    
    result = {'1, 4'h5, '0};
    $display("result = %h", result);
end

Question: What are the results?

Answer:

  • result = AB53
  • result = compilation depends on tool (could be error or specific behavior)

Explanation:

  • First: {8’hAB, 4’h5, 4’h3} = 16’hAB53 ✓
  • Second: '1 and '0 are unsized literals
    • Size depends on context
    • Inside concatenation, must be sized explicitly
    • Most tools will error or use default size
  • Best practice: Always use sized literals in concatenation

Correct:

result = {8'hFF, 4'h5, 4'h0};  // Explicitly sized

📌 Question 68: Property with Implication

bit clk = 0;
always #5 clk = ~clk;

bit req = 0, ack = 0;

property p_req_ack;
    @(posedge clk) req |-> ##[1:3] ack;
endproperty

assert property (p_req_ack);

initial begin
    @(posedge clk) req = 1;
    @(posedge clk) req = 0;
    repeat(2) @(posedge clk);
    ack = 1;
    @(posedge clk) ack = 0;
end

Question: Does the assertion pass or fail?

Answer: FAIL

Explanation:

  • req goes high at first clock
  • Property requires ack within 1-3 cycles
  • ack goes high at 4th cycle (too late!)
  • ##[1:3] means 1, 2, or 3 cycles later
  • ack at cycle 4 violates the property
  • Assertion fails at cycle 4

📌 Question 69: Semaphore Key Count

semaphore sem = new(3);  // 3 keys

initial begin
    sem.get(2);
    $display("Got 2 keys at %0t", $time);
    
    if (sem.try_get(2))
        $display("Got 2 more keys");
    else
        $display("Failed to get 2 more keys");
        
    if (sem.try_get(1))
        $display("Got 1 key at %0t", $time);
end

initial begin
    #10 sem.put(1);
    $display("Put 1 key at %0t", $time);
end

Question: What will be displayed?

Answer:

  • Got 2 keys at 0
  • Failed to get 2 more keys
  • Got 1 key at 0
  • Put 1 key at 10

Explanation:

  • Initial keys: 3
  • First get(2): success, remaining = 1
  • try_get(2): fails (only 1 key left)
  • try_get(1): success, remaining = 0
  • At time 10: put(1), remaining = 1
  • Semaphore tracks available keys

📌 Question 70: Assertion with Disable Iff

bit clk = 0, rst = 0;
always #5 clk = ~clk;

bit [3:0] cnt = 0;

always @(posedge clk or posedge rst)
    if (rst) cnt <= 0;
    else cnt <= cnt + 1;

property p_count;
    @(posedge clk) disable iff (rst)
    cnt == $past(cnt) + 1;
endproperty

assert property (p_count);

initial begin
    #12 rst = 1;
    #10 rst = 0;
    #50 $finish;
end

Question: Does the assertion ever fail?

Answer: NO, assertion never fails

Explanation:

  • disable iff (rst) disables checking when rst=1
  • During reset: assertion not checked
  • After reset: cnt increments correctly
  • $past(cnt) gives previous clock value
  • cnt always equals $past(cnt) + 1 when not in reset
  • Property holds throughout simulation

📌 Question 71: Extern Method Declaration

class Packet;
    int data;
    
    extern function void init(int val);
    extern task send();
endclass

function void Packet::init(int val);
    data = val;
    $display("Initialized with %0d", val);
endfunction

// Forget to implement send() task!

Packet p = new();

initial begin
    p.init(100);
    p.send();  // Call unimplemented method
end

Question: What happens?

Answer: Compilation ERROR

Explanation:

  • extern declares method defined outside class
  • Must provide implementation (Packet::send)
  • Missing implementation → link error
  • Compiler/elaborator catches this
  • Must implement all extern methods

Fix:

task Packet::send();
    $display("Sending data: %0d", data);
endtask

📌 Question 72: Parameterized Class Specialization

class Stack #(type T = int, int SIZE = 10);
    T data[SIZE];
    int ptr = 0;
    
    function void push(T item);
        if (ptr < SIZE)
            data[ptr++] = item;
    endfunction
endclass

Stack #(bit [7:0], 5) byte_stack;
Stack #(string) str_stack;  // Uses defaults

initial begin
    byte_stack = new();
    str_stack = new();
    
    byte_stack.push(8'hAA);
    str_stack.push("Hello");
    
    $display("byte_stack SIZE = %0d", byte_stack.SIZE);
    $display("str_stack SIZE = %0d", str_stack.SIZE);
end

Question: What are the SIZE values?

Answer:

  • byte_stack SIZE = 5
  • str_stack SIZE = 10 (default)

Explanation:

  • byte_stack: T=bit[7:0], SIZE=5 (both specified)
  • str_stack: T=string, SIZE=10 (SIZE uses default)
  • Parameterized classes create specialized types
  • Can mix value and type parameters
  • Each specialization is distinct type

📌 Question 73: Covergroup with Bins and Cross

bit [1:0] a, b;

covergroup cg @(posedge clk);
    cp_a: coverpoint a {
        bins low = {0, 1};
        bins high = {2, 3};
    }
    cp_b: coverpoint b;
    cross_ab: cross a, b;
endcovergroup

cg cg_inst = new();

initial begin
    {a, b} = 2'b00; @(posedge clk);
    {a, b} = 2'b01; @(posedge clk);
    {a, b} = 2'b10; @(posedge clk);
    {a, b} = 2'b11; @(posedge clk);
end

Question: How many cross bins are hit?

Answer: 4 cross bins hit

Explanation:

  • a has values: 0, 0, 1, 1
  • b has values: 0, 1, 0, 1
  • Cross creates bins for all a×b combinations
  • Hits: (0,0), (0,1), (1,0), (1,1)
  • Full cross has 4×4 = 16 possible bins
  • Only 4 were sampled/hit
  • Coverage = 4/16 = 25%

📌 Question 74: Initial Block Execution Order

module test;
    initial begin
        $display("Block A at %0t", $time);
    end
    
    initial begin
        $display("Block B at %0t", $time);
    end
    
    initial begin
        $display("Block C at %0t", $time);
    end
endmodule

Question: What order will they execute?

Answer: Undefined order! Could be any permutation

Explanation:

  • Multiple initial blocks at time 0
  • Execution order is non-deterministic
  • Could be: A-B-C or B-A-C or C-B-A, etc.
  • Simulator decides scheduling
  • Never rely on initial block order!
  • Use explicit synchronization (#delays, @events) if order matters

📌 Question 75: Unique0 vs Unique vs Priority

bit [1:0] val = 2'b11;

// Test unique0
initial begin
    unique0 case(val)
        2'b00: $display("Case 00");
        2'b01: $display("Case 01");
    endcase  // val=11 doesn't match - no warning!
end

// Test unique  
initial begin
    unique case(val)
        2'b00: $display("Case 00");
        2'b01: $display("Case 01");
    endcase  // val=11 doesn't match - WARNING!
end

Question: What’s the difference?

Answer:

  • unique0: No warning if no match (0 or 1 match OK)
  • unique: Warning if no match (exactly 1 match required)

Explanation:

  • unique0 case: 0 or 1 match OK, no warning
  • unique case: exactly 1 match required, warns if 0 or 2+
  • priority case: at least 1 match required
  • Use unique0 when default case not needed
  • Use unique when exactly one must match
  • Use priority for precedence order

Summary Statistics – Part 3

Total Questions in Part 3: 25
Grand Total: 75 Questions!

Expert Categories Covered:

  • ✅ NBA pipeline effects
  • ✅ Associative array iteration
  • ✅ Enum edge cases
  • ✅ Package variable sharing
  • ✅ Array reduction methods
  • ✅ Streaming operators
  • ✅ Distribution constraints
  • ✅ Safe casting ($cast)
  • ✅ Pre/post randomize hooks
  • ✅ Generate conditionals
  • ✅ Bidirectional ports
  • ✅ Assertion properties
  • ✅ Semaphore operations
  • ✅ Extern methods
  • ✅ Parameterized classes
  • ✅ Covergroup cross
  • ✅ unique0/unique/priority

Master-Level Takeaways

  1. NBA creates pipelines: Predictable delay chains
  2. Package variables are shared: Global state across modules
  3. Enums allow any value: name() returns “” for undefined
  4. Localparam can’t be overridden: Local constant only
  5. join_any + wait fork: Control parallel processes
  6. Streaming operators: Pack/unpack data structures
  7. Distribution := vs 😕: Exact vs divided weights
  8. $cast for safety: Avoid runtime errors
  9. pre/post randomize: Setup and cleanup hooks
  10. initial block order: Non-deterministic!

Interview Mastery Checklist

To ace SV/Verilog interviews, master:

✅ Data types (2-state vs 4-state, signed vs unsigned)
✅ Blocking vs non-blocking (race conditions)
✅ All array types (packed, unpacked, dynamic, queue, associative)
✅ X/Z propagation rules
✅ OOP concepts (inheritance, polymorphism, virtual)
✅ Constraints (solve-before, distribution, foreach)
✅ Assertions (properties, sequences, disable iff)
✅ Processes (fork/join variants, disable fork)
✅ Interfaces and modports
✅ Generate blocks (for, if, case)
✅ Functional coverage (covergroup, cross)
✅ IPC (mailbox, semaphore, event)
✅ Packages and scope
✅ Parameterization (class and module)
✅ Unique/priority/unique0 semantics

Part 3 completes our comprehensive collection with 75 expert-level questions covering the deepest corners of SystemVerilog and Verilog semantics!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top