4.1.1 Construct a valid packet

EasyImplementVerilator · local serverReview the topic

Write a constructor that leaves every packet object in a valid state, or clearly marked invalid.

Hardware context: Transaction objects passed from a bus monitor to multiple checking consumers. Construct a valid captured packet with explicit identity and payload-length invariants.

A monitor builds one captured_packet object for each packet it sees. A constructor cannot return an error, so the object itself must say whether it is valid, and every field must already hold its final value when new returns.

Write the constructor new(observed_id, declared_length, raw_bytes). raw_bytes holds up to four bytes, byte 0 in bits 7:0. For a length from 0 to 4, the packet is valid: keep the ID, make payload exactly that many bytes long and copy those low bytes in order. Bytes beyond the length are ignored.

For id 7, length 3 and raw_bytes 32'hFF030201, the payload is [01, 02, 03]: the FF is outside the packet. A length of 0 is a valid empty packet. Any other length gives an invalid packet that keeps its ID, with length 0 and an empty payload.

Signals in the timeline

SignalWidthRole
packet_id8input of each check
declared_length32input of each check
raw_bytes32input of each check
Full specification
The class (keep its names)
class captured_packet;
  bit valid;
  bit [7:0] id;
  int length;
  byte unsigned payload[];
  function new(input bit [7:0] observed_id, input int declared_length, input bit [31:0] raw_bytes);
endclass

Check the length before you allocate or read any byte. Each case builds a real object and reports valid, id, length, the payload size, the payload packed back into a word (byte 0 lowest) and the sum of its bytes.

Examples

Example 1

Ignore the byte outside the packet
Input
id = 7, length = 3, raw_bytes = 32'hFF030201
Output
valid = yes, id = 7, length = 3, payload_size = 3, payload_bytes = 0x30201, byte_sum = 6

The payload is [01, 02, 03], packed back as 0x030201, with sum 6.

Example 2

Empty is valid
Input
id = 255, length = 0, raw_bytes = 32'hFFFFFFFF
Output
valid = yes, id = 255, length = 0, payload_size = 0, payload_bytes = 0x0, byte_sum = 0

A valid packet with no payload: every payload field is 0.

Example 3

A length that does not fit
Input
id = 9, length = 5, raw_bytes = 32'h11223344
Output
valid = no, id = 9, length = 0, payload_size = 0, payload_bytes = 0x0, byte_sum = 0

Only four bytes exist, so the packet is invalid. It keeps ID 9; everything else is 0.

Constraints and contract

  • declared_length is a signed int; only 0 to 4 are valid.
  • An invalid packet keeps its ID and has an empty payload.
  • Keep the class, field and constructor names.

Hints

Hint 1

A constructor runs once per object and cannot return a status. Which field carries the answer to "is this packet any good"?

Hint 2

Decide validity first, then size the payload, then copy into it.

Hint 3

Start from the invalid state (valid 0, length 0, empty payload, ID kept) and change it only when the length is in range.

What this judge verifies: Your constructor is called for every length from -2 to 6 with seeded IDs and byte patterns, and each case inspects the real object. Passing shows every field is set correctly.

147 checks on Verilator · local server. 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

Ignore the byte outside the packet

Input
id = 7, length = 3, raw_bytes = 32'hFF030201
Expected output
valid = yes, id = 7, length = 3, payload_size = 3, payload_bytes = 0x30201, byte_sum = 6

The payload is [01, 02, 03], packed back as 0x030201, with sum 6.

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

Verilator · local server