5.1.1 Legal packet length

EasyImplementVerilator · local serverReview the topic

Write the constraint that keeps a packet length legal, and a send function that reports when randomize() fails.

Hardware context: Constrained stimulus for a packet-processing or memory engine. Generate a legal packet length before handing the object to the driver.

A packet generator sizes each packet to fit the receive buffer. The test sets max_bytes, the room left in the buffer, before each call. When the buffer is full, no length is legal, randomize() returns 0, and the object keeps its old length. A generator that ignores the 0 sends the old length anyway, and overruns the buffer.

Write the constraint block legal_length: a length is 1 to 12 bytes and never more than max_bytes. Then write send_packet(p, wanted). With wanted below 0 it randomizes freely; otherwise it asks for exactly that length. It returns the new length, or -1 when the call fails.

With max_bytes = 5, lengths 1 to 5 are reachable and 6 is refused. With max_bytes = 0, every call returns -1.

Signals in the timeline

SignalWidthRole
max_bytes32input of each check
Full specification
What you write (keep the names)
class sized_packet;
  rand bit [3:0] length;
  int max_bytes;
  constraint legal_length { ... }
endclass
function automatic int send_packet(sized_packet p, int wanted);

Each case sets max_bytes and a seed, asks send_packet for every length from 0 to 15, then makes 8 free calls. It reports the set of lengths that came back, how many calls returned a length other than the one asked for, and how the free calls ended: a legal length, an illegal one, or -1.

max_bytes is a signed int and may be negative.

Examples

Example 1

A small buffer
Input
max_bytes = 5
Output
reachable_lengths = {1, 2, 3, 4, 5}, wrong_length_returned = 0, free_calls_legal = 8, free_calls_illegal = 0, free_calls_failed = 0

Lengths 1 to 5 come back; asking for 0 or 6 to 15 returns -1. All 8 free calls give a legal length.

Example 2

A full buffer
Input
max_bytes = 0
Output
reachable_lengths = {}, wrong_length_returned = 0, free_calls_legal = 0, free_calls_illegal = 0, free_calls_failed = 8

No length is legal, so every call fails and returns -1, including the 8 free calls.

Example 3

Plenty of room
Input
max_bytes = 20
Output
reachable_lengths = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, wrong_length_returned = 0, free_calls_legal = 8, free_calls_illegal = 0, free_calls_failed = 0

The protocol limit of 12 bytes decides now: 1 to 12 are reachable.

Constraints and contract

  • Legal lengths are 1 to 12 and at most max_bytes.
  • Return -1 whenever randomize() returns 0.
  • Keep the class, field, constraint and function names.

Hints

Hint 1

A constraint block is a list of conditions that must all hold. Which two conditions describe a legal length?

Hint 2

length is 4 bits and max_bytes is a signed int. Compare them as ints so a negative max_bytes still works.

Hint 3

randomize() returns 1 or 0. Keep the result in a variable, and return -1 before you read length when it is 0.

What this judge verifies: Every length from 0 to 15 is requested at eight buffer sizes, and free calls are checked against the rules. Passing shows your constraint allows exactly the legal lengths and that failures are reported.

8 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 6 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

A small buffer

Input
max_bytes = 5
Expected output
reachable_lengths = {1, 2, 3, 4, 5}, wrong_length_returned = 0, free_calls_legal = 8, free_calls_illegal = 0, free_calls_failed = 0

Lengths 1 to 5 come back; asking for 0 or 6 to 15 returns -1. All 8 free calls give a legal length.

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

Verilator · local server