1.3.1 Header field decoder

EasyImplementIcarus Verilog · browserReview the topic

Declare a packet header as a packed struct whose field order matches the wire, and decode a raw word with it.

Hardware context: Packet-header formatter and command decoder at a hardware endpoint. Decode the packed fields received from a header bus into named monitor fields.

A testbench sends a WRITE and the DUT performs a READ to a different address. The header struct in the testbench listed the fields in a different order from the specification. In a packed struct the first field is the most significant, so two fields traded places on the wire and nothing warned anyone.

This header is 16 bits: a 2-bit version on top, then a 2-bit kind, a 4-bit tag and an 8-bit length at the bottom. Declare header_t as a packed struct with exactly that layout, and write decode_header(word), which returns the header held in a raw 16-bit word.

For word = 16'h6512 the fields are version 1, kind 2, tag 5 and length 0x12.

The starter names the four fields for you. Give each one its width and put them in wire order.

Signals in the timeline

SignalWidthRole
word16input of each check
Full specification
FieldBits of the word
version15:14
kind13:12
tag11:8
length7:0
Names to keep
typedef struct packed { ... } header_t;
function automatic header_t decode_header(input logic [15:0] word);

header_t must be exactly 16 bits wide, with no padding. Every encoding is accepted; this decoder does not check whether a kind is legal.

Each case also reports $bits(header_t), so a struct of the wrong width shows up directly.

Examples

Example 1

Every field different
Input
word = 16'h6512
Output
struct_width = 16, version = 1, kind = 2, tag = 5, length = 0x12

0x6512 is 01 10 0101 00010010 in binary: version 1, kind 2, tag 5, length 0x12.

Example 2

Zero is still a header
Input
word = 16'h0000
Output
struct_width = 16, version = 0, kind = 0, tag = 0, length = 0x0

Every field is 0, and the struct is still 16 bits wide.

Example 3

Every field at its maximum
Input
word = 16'hFFFF
Output
struct_width = 16, version = 3, kind = 3, tag = 15, length = 0xff

version 3, kind 3, tag 15 and length 0xFF: each field is as wide as the table says.

Constraints and contract

  • word is a known 16-bit value.
  • Keep the field names version, kind, tag and length, and the names header_t and decode_header.
  • All fields are unsigned.

Hints

Hint 1

Which field must come first in the declaration: the one at the top of the word or the one at the bottom?

Hint 2

Add up the widths from the table. The struct must come to exactly 16 bits.

Hint 3

Once the struct matches the wire, a raw 16-bit word and a header_t hold the same bits, so the decoder needs no shifting or masking.

What this judge verifies: Your struct and decoder are run on single-bit words for every bit position, on asymmetric field values and on seeded words; each case also reports the struct width. Passing shows the layout matches the table.

275 checks on Icarus Verilog · browser. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.

See all 5 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

Every field different

Input
word = 16'h6512
Expected output
struct_width = 16, version = 1, kind = 2, tag = 5, length = 0x12

0x6512 is 01 10 0101 00010010 in binary: version 1, kind 2, tag 5, length 0x12.

Run samples executes all 3 example checks. Check all tests runs 275 checks.

Icarus Verilog · browser