Drill 1. rand bit [15:0] x: x is a power of two.
Drill 2. rand bit [7:0] m: exactly three bits of m are set.
Drill 3. rand bit [7:0] a, b: b differs from a in exactly one bit.
Write the three answers before opening the reveal. Copy the starter into the Code Lab, fill in each empty answer_c, and run it on Verilator. The grader solves each class hundreds of times and checks every result, then pins a few values that must be legal; it prints ok or the first rule your answer broke.
// Drill starter: write each answer_c, then run it.
// Drills: powers of two, set-bit counts and gray neighbours.
class drill1; // x is a power of two
rand bit [15:0] x;
constraint answer_c { /* your answer here */ }
endclass
class drill2; // exactly 3 of the 8 bits of m are set
rand bit [7:0] m;
constraint answer_c { /* your answer here */ }
endclass
class drill3; // b differs from a in exactly one bit
rand bit [7:0] a, b;
constraint answer_c { /* your answer here */ }
endclass
(x & (x - 1)) == 0 alone give a power of two?No. Zero satisfies it, and zero is not a power of two. Add x != 0, or use $countones(x) == 1.
One set of answers, run through the same grader:
// Drills: powers of two, set-bit counts and gray neighbours.
class drill1; // x is a power of two
rand bit [15:0] x;
constraint answer_c { x != 0; (x & (x - 1)) == 0; }
endclass
class drill2; // exactly 3 of the 8 bits of m are set
rand bit [7:0] m;
constraint answer_c { $countones(m) == 3; }
endclass
class drill3; // b differs from a in exactly one bit
rand bit [7:0] a, b;
constraint answer_c { $countones(a ^ b) == 1; }
endclass
drill 1, power of two: ok
drill 2, three bits set: ok
drill 3, gray neighbour: ok
PASS: all 3 drills rightFunction | True when | Whiteboard use |
|---|---|---|
| Exactly one bit is 1 | Powers of two, single grants |
| At most one bit is 1 | Grants where idle is legal |
| Always: returns the count | Bands, gray distance, fairness |
A power of two has exactly one bit set, so $countones(x) == 1 and the bit trick with x != 0 are the same set of 16 values. Exact counts and bands are one system function: $countones(m) == 3, or inside {[3:5]} for a band. Candidates who hand-roll a foreach sum over bits signal that they missed it.
XOR turns differing bits into ones, so a gray neighbour is a one-hot XOR: $countones(a ^ b) == 1. It composes two primitives, which interviewers reward.
A note on the grader: Verilator 5.048 spread drill 3 very unevenly. In 300 calls the flipped bit was bit 6 in 272 of them and bits 0, 2 and 4 never, though all eight are equally legal. The pinned values catch an answer that is too tight; only coverage would catch a solver that is.
Run with Verilator 5.048 (--binary --timing) on 2026-10-18; every bench printed the PASS line shown. Verilator prints a harmless WIDTHTRUNC warning for if (!obj.randomize()), because randomize() returns an int, and an UNSATCONSTR warning when a solve fails on purpose. Icarus 13 does not support constraints.
Each starter was run with its answers left empty, and its grader reported all three drills wrong; each revealed answer passed the same grader. The graders also caught an unwidened size * count and an over-tight even rule when tried.
Verilator flipped bit 6 in 272 of 300 gray-neighbour solves and bits 0, 2 and 4 never, though all are legal.