← Design Verification Interviews

Interview Question · Code Reading

Which Byte Is Index Zero?

L0 FresherL1 Juniorsystemverilogarrayspacked

The Question

The interviewer asks

What does this print? Then tell me when you would choose a packed array and when an unpacked one.

systemverilog
module tb;
  logic [3:0][7:0] p;     // four packed bytes: one 32-bit vector
  logic [7:0]      u [4]; // four separate bytes
  initial begin
    p = 32'hAABB_CCDD;
    u[0] = 8'hAA;
    $display("p[0]=%h p[3]=%h $bits(p)=%0d", p[0], p[3], $bits(p));
  end
endmodule
Reveal the Model Answer

It prints p[0]=dd p[3]=aa $bits(p)=32. Packed dimensions form one contiguous vector, and with [3:0] index 0 is the least significant byte. An unpacked array such as u[4] is four separate elements: it cannot take a 32-bit literal or join arithmetic without streaming. Pack fields that travel as one bus or word; unpack collections you index like a memory.

Arrival Order Mapped to SignificanceLeft: the unpacked array rx, one element per byte in arrival order. Right: the packed array lanes, with the most significant byte on top. Arrows show data, each byte copied by lanes[3-i] = rx[i].
Arrival order mapped to significanceLeft: the unpacked array `rx`, one element per byte in arrival order. Right: the packed array `lanes`, with the most significant byte on top. Arrows show data, each byte copied by `lanes[3-i] = rx[i]`. unpacked rx[0] arrives 1st: DE unpacked rx[1] arrives 2nd: AD unpacked rx[2] arrives 3rd: BE unpacked rx[3] arrives 4th: EF packed lanes[3] bits 31:24 packed lanes[2] bits 23:16 packed lanes[1] bits 15:8 packed lanes[0] bits 7:0
Read the diagram as text
  • rx[0]: arrives 1st: DE
  • rx[1]: arrives 2nd: AD
  • rx[2]: arrives 3rd: BE
  • rx[3]: arrives 4th: EF
  • lanes[3]: bits 31:24
  • lanes[2]: bits 23:16
  • lanes[1]: bits 15:8
  • lanes[0]: bits 7:0
  • rx[0] → lanes[3]
  • rx[1] → lanes[2]
  • rx[2] → lanes[1]
  • rx[3] → lanes[0]

The packed index decides significance; the unpacked index only decides order.

Packed [3:0][7:0] pUnpacked [7:0] u [4]
StorageOne 32-bit vectorFour 8-bit elements
Whole-value ops (+, ==, slicing)YesOnly element by element (whole-array == compares elements)
Element typesOnly bit-level typesAny type, including classes and strings
Typical useA bus, a register with fieldsA memory, a list of transactions

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Fresher)

A good fresher answer reads the range [3:0] to work out p[0]=dd. It explains that a packed array is one vector.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItCompareScale It

  1. Which Byte Is Index Zero?
  2. WhyWhy an Unpacked Array Is Not a VectorL1 Junior

    Why can't you just add or shift an unpacked array the way you can a packed one?

    Reveal the Model Answer

    The language guarantees no bit layout for unpacked elements: a simulator may store each element in its own word, with padding. Whole-value operators need one contiguous bit string, which only packed dimensions promise. Unpacked arrays support element-wise copy and equality instead.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Unpacked arrays cannot be compared with ==."

    You can assign and compare whole unpacked arrays of the same shape with == and !=, element by element. You cannot do arithmetic or bit slicing on them.

    Source IEEE 1800-2017 §7.6

  3. What IfBit-Stream Casts of Unpacked ArraysL1 JuniorL2 Mid-Level

    What if you cast an unpacked byte array to a packed word, and the sizes differ by one byte?

    Reveal the Model Answer

    A bit-stream cast needs both types to have exactly the same number of bits. With fixed-size types, a mismatch is a compile error. With a dynamic array or a queue, the cast fails at run time. So size the target from the source, and check the size before the cast.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "A cast trims or pads like an assignment does."

    That is true of a plain assignment between vectors. A bit-stream cast between aggregate types needs equal sizes and does not pad.

    Source IEEE 1800-2017 §6.24.3

  4. CompareStreaming Operators vs ConcatenationL1 JuniorL2 Mid-Level

    How do you turn the unpacked u[4] into a 32-bit word, and how do you then reverse its byte order? Predict the output of this code.

    systemverilog
    module tb;
      logic [7:0]  u [4];
      logic [31:0] v, w;
      initial begin
        u[0] = 8'hAA; u[1] = 8'hBB; u[2] = 8'hCC; u[3] = 8'hDD;
        v = {>>{u}};             // element 0 lands in the most significant byte
        w = {<<8{v}};            // reverse the byte order
        $display("v=%h w=%h", v, w);
      end
    endmodule
    
    Reveal the Model Answer

    It prints v=aabbccdd w=ddccbbaa. {>>{u}} streams the elements left to right, so element 0 lands in the most significant byte. {<<8{v}} reverses the order of 8-bit slices. A concatenation {u[0], u[1], u[2], u[3]} gives the same v but has to name every element, so it breaks when the size changes.

    Turning u[4] = {aa, bb, cc, dd} into a word
    ExpressionResultWhat it does
    {>>{u}}aabbccddStreams elements left to right; u[0] lands in the top byte
    {<<8{v}}ddccbbaaReverses the order of 8-bit slices
    {u[0], u[1], u[2], u[3]}aabbccddSame value, but every element is named by hand

    The first two results are the output of the run on this question.

    RUNVerilator · simulator service
    Edit the code, then run it
    Expected: v=aabbccdd w=ddccbbaa

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "{<<{v}} reverses the bytes."

    With no slice size the slice is one bit, so it reverses all 32 bits. Byte reversal needs {<<8{v}}.

    Source IEEE 1800-2017 §11.4.14

  5. Prove ItSolve 1.2.1: Byte-Lane ExtractionSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem 1.2.1

  6. Prove ItSolve 1.2.1: Byte-Lane ExtractionSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem 1.2.1

  7. Scale ItPacked Structs for a Register MapL2 Mid-LevelL3 Senior

    Your block has two hundred control registers with bit fields. How would you model them in the testbench so field mistakes are caught early?

    Reveal the Model Answer

    Describe each register as a packed struct with named fields. Then reg.mode replaces unnamed slices like r[6:4], and a width mismatch fails at compile time. Generate those types and the address map from the same specification the RTL uses, rather than writing them by hand. For a large map, the usual choice is a generated UVM register model. It adds access policies and a mirror of each register on top of the fields.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer generates the RTL view and the testbench view from one source of truth. It says what a hand-written map costs each time the spec changes.

    Wrong Altitude

    Proposes hand-coding the 200 structs from the PDF.

    The two copies drift the first time the spec changes. A senior answer removes the second copy instead of adding review effort to keep the copies equal.

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"p[0] is the first byte, the one written at the left of the literal."

Index order follows the declared range, not the order of writing. With [3:0] the left byte is index 3, as the twin shows.

Run It

A header byte taken as p[0] from a word written 32'hAABB_CCDD.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: header=dd FAIL: p[0] is the least significant byte (dd), not the first byte written
See the Fix
module tb;
  logic [3:0][7:0] p;
  logic [7:0] header;
  initial begin
    p = 32'hAABB_CCDD;        // AA is the byte written first, the most significant
    header = p[3];     // the fix: with [3:0], the top byte is index 3
    $display("header=%h", header);
    if (header !== 8'hAA) $display("FAIL: p[0] is the least significant byte (dd), not the first byte written");
    else $display("PASS: the header is the most significant byte");
  end
endmodule

Prints: header=aa PASS: the header is the most significant byte

Half-Truth

"Packed and unpacked are only a storage detail; the code is the same."

Only packed arrays act as one value. You cannot add two unpacked arrays or assign one from a vector without a cast or a stream.

Source IEEE 1800-2017 §7.4

Spec Misquote

"logic [7:0] u [4] indexes from 3 down to 0, like the packed range."

An unpacked size [4] means [0:3], the C style, so u[0] is the first element.

Source IEEE 1800-2017 §7.4.2

Learn It, Then Prove It