Fix a helper that freezes the address for one call, so it always hands the object back with its modes restored.
Hardware context: Targeted random stimulus with temporarily frozen fields or disabled preferences. Freeze an initialized transaction field while varying other legal fields.
This is a Fix problem: the code in the editor has one realistic defect. Find it and fix it.
A directed test calls randomize_at(r, addr) to send one request to a chosen address: it freezes addr with rand_mode(0), randomizes the other fields, and restores the address’s mode. Tests share the request object, and the next test randomizes it freely.
Most runs pass. But after a test that asked for a misaligned address, every later request in the run goes to that same address, and the address coverage collapses to one value.
Make randomize_at hand the object back with addr’s rand_mode exactly as it was before the call, whatever the outcome of randomize().
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
fixed_addr | 8 | input of each check |
prior_mode | 1 | input of each check |
Full specification
class bus_req;
rand bit [7:0] addr;
rand bit [3:0] len;
constraint aligned { addr[1:0] == 0; }
constraint sized { len inside {[1:8]}; }
endclass
function automatic bit randomize_at(bus_req r, input bit [7:0] fixed_addr);
Each case sets addr’s rand_mode (usually 1; sometimes the caller has already frozen it), calls randomize_at once, then makes 8 ordinary randomize() calls. It reports whether randomize_at succeeded, whether addr held the fixed value, addr’s rand_mode afterwards, and whether the address moved during the later calls.
A misaligned fixed address breaks the aligned constraint, so randomize() returns 0: constraints still apply to a frozen field.
Examples
Example 1
Hold an aligned address- Input
fixed_addr = 8'h40
- Output
randomize_ok = yes, addr_held = yes, addr_rand_mode_after = 1, addr_moves_later = yes
randomize() succeeds with addr kept at 40. The mode goes back to 1, so later calls move the address again.
Example 2
A misaligned address- Input
fixed_addr = 8'h41
- Output
randomize_ok = no, addr_held = yes, addr_rand_mode_after = 1, addr_moves_later = yes
The aligned constraint cannot hold, so the call fails. The mode must still go back to 1.
Example 3
Already frozen by the caller- Input
fixed_addr = 8'h80, rand_mode was 0
- Output
randomize_ok = yes, addr_held = yes, addr_rand_mode_after = 0, addr_moves_later = no
The caller froze addr on purpose. It must still be frozen afterwards, so the address stays at 80.
Constraints and contract
- randomize_at returns randomize()’s status.
- Afterwards addr’s rand_mode equals its value before the call.
- Keep the class and function names.
Hints
Hint 1
Run the second example. What is addr’s rand_mode after the call, and what does that do to the next test’s randomize()?
Hint 2
Follow every path out of the function. Does each one undo the change it made to the object?
Hint 3
Restore the saved mode on the way out, and only then return the status.
What this judge verifies: The helper is called with aligned and misaligned addresses, with the address frozen or not beforehand, and the object is checked during the next 8 calls. Passing shows the helper always leaves the modes as it found them.
12 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