Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Puzzle Bank
  • SystemVerilog Language Puzzles25
    • Datatype and Bit Puzzles
    • Fork Join Puzzles
    • Queue and Array Puzzles
    • String and Casting Puzzles
      • String Substr with Runtime Class Cast
      • putc/getc Index Semantics
      • Case-Sensitive vs Case-Insensitive Compare
      • Enum Safety with $cast
      • Upcast, Virtual Dispatch and Downcast
      • String Number Parsing Stops Early
    • SystemVerilog Language Puzzles: Tricky Q&A
  • Difficulty Guide
  • Full Topic Map
  • Interview-Day Tips
  • Study Route: One Week Before the Interview
  • Study Route: Two Weeks
  • Study Route: Four Weeks (Full Course)4
  • OOP & Testbench Puzzles25
  • Concurrency & Timing Puzzles25
  • Randomization & Constraint Puzzles25
  • SVA Assertion Puzzles25
  • Functional Coverage Puzzles25
  • Logic & Aptitude Puzzles25
  • Scenario & Debug Puzzles25
  • UVM Testbench Puzzles25
  • Clock, Reset & CDC Puzzles25
  • Bus and Interface Protocol Puzzles25
  • Interview Prep: Puzzle Rounds7
  • DV Puzzle Cheatsheet
Loading lesson

←String and Casting Puzzles
  1. Topics
  2. DV Interview Puzzles
  3. SystemVerilog Language Puzzles
  4. String and Casting Puzzles
  5. Upcast, Virtual Dispatch and Downcast
On this page

    VLSI DV Interview PuzzlesAll levels

    Upcast, Virtual Dispatch and Downcast

    Predict every line this prints, and say why the two method calls through the base handle differ.

    Puzzle

    Difficulty: Medium · Puzzle 5 of 6 · Topic: String and Casting Puzzles

    Predict every line this prints, and say why the two method calls through the base handle differ.

    Code

    p5.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class B;
      function string who();  return "B.who";  endfunction
      virtual function string kind(); return "B.kind"; endfunction
    endclass
    class D extends B;
      function string who();  return "D.who";  endfunction
      virtual function string kind(); return "D.kind"; endfunction
      function string only_d(); return "D.only"; endfunction
    endclass
    
    module p5;
      B b;
      D d, d2;
      initial begin
        d = D::new();
        b = d;
        $display("%s %s", b.who(), b.kind());
        if ($cast(d2, b))
          $display("%s %s %s", d2.who(), d2.kind(), d2.only_d());
        b = B::new();
        $display("cast_base=%0d", $cast(d2, b));
      end
    endmodule

    Hint

    A call resolves by the handle type unless the method is virtual, in which case it resolves by the object type. `$cast` checks the object type.

    Step-by-step solution

    Diagram
    1) `b = d` is an implicit upcast; `b` still points to the D object.
    2) `b.who()` is non-virtual, so it is bound at compile time to the handle type B and prints `B.who`.
    3) `b.kind()` is virtual, so it dispatches on the object type D and prints `D.kind`.
    4) `$cast(d2, b)` succeeds because the object is a D; through `d2` all three calls use D, giving `D.who D.kind D.only`.
    5) `b = B::new()` makes the object a plain B, so the downcast fails and the function returns 0.

    Answer

    Answer: B.who D.kind D.who D.kind D.only cast_base=0

    How this was checked

    Checked by running the code in Verilator 5; the printed output supports the answer above. Non-virtual calls follow the handle type, virtual calls the object type; Icarus 13 does not implement $cast.

    Why candidates get it wrong

    Non-virtual methods are chosen by the handle type, virtual ones by the object type; `only_d()` is not callable through `b` at all, so a downcast with `$cast` is needed first.

    Interviewer follow-up

    Why can you assign `d2 = b` only with `$cast` but `b = d` without one? Model answer: an upcast is always legal because every D is a B; a downcast might point at a plain B (or another subclass), so the compiler requires `$cast`, which checks the object type at run time and returns 0 on failure.

    Say it out loud

    I would split the calls into virtual and non-virtual, because a non-virtual call uses the handle type and a virtual call uses the object type. So through the base handle, who prints B and kind prints D, since the object is a D. After a successful downcast with cast, all three calls use D. Once the base handle points to a plain B object, the downcast fails and returns 0. The trap is expecting non-virtual calls to follow the object, and I would check the cast result before using the derived handle.

    Related topics

    • Virtual dispatch

    • Casting with $cast

    • Back to String and Casting Puzzles

    • SystemVerilog Language Puzzles section

    Previous

    33 / 293

    Next: String Number Parsing Stops Early

    Up next

    Up nextString Number Parsing Stops Early

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • String Substr with Runtime Class Cast
    • putc/getc Index Semantics
    • Case-Sensitive vs Case-Insensitive Compare