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
| Signal | Width | Role |
|---|---|---|
max_bytes | 32 | input of each check |
Full specification
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