Q128FreeSystemVerilog
Build a first-fit range allocator
Interview prompt
Question
Maintain inclusive free address ranges. Allocate the first range large enough for a request, and return freed ranges while merging every overlap or adjacency.
Candidate starting point
Implementation scaffold
typedef struct {
int unsigned lo;
int unsigned hi;
} range_t;
class RangeAllocator;
range_t free_ranges[$];
int unsigned managed_base;
int unsigned managed_limit;
function new(int unsigned base, int unsigned size);
if (size == 0) $fatal(1, "allocator size must be positive");
if (base > 32'hffff_ffff - (size - 1))
$fatal(1, "managed range wraps the address space");
managed_base = base;
managed_limit = base + size - 1;
free_ranges.push_back('{lo: managed_base, hi: managed_limit});
endfunction
function bit alloc(int unsigned size, output int unsigned addr);
// Implement here: alloc.
endfunction
function void dealloc(int unsigned addr, int unsigned size);
// Implement here: dealloc.
endfunction
function void coalesce();
range_t merged[$];
range_t current;
// Implement here: coalesce.
endfunction
endclassReviewed example
Trace one case
Input
free=[[0x1000,0x10FF]]; alloc(0x20, addr); dealloc(addr=0x1000,size=0x20)Expected output
allocation base=0x1000; final free list=[[0x1000,0x10FF]]Allocation preserves suffix [0x1020,0x10FF], and the exact deallocation coalesces the returned prefix back into one maximal range.
What to cover
Requirements
- Reject zero-sized construction, allocation, and deallocation.
- Return the first sufficient range and its lowest address.
- Remove exact fits and preserve the remainder of partial fits.
- Keep the free list sorted, disjoint, and maximally coalesced after deallocation.
- The caller returns only valid, nonwrapping byte ranges within this allocator’s original pool and guarantees the returned bytes are no longer allocated to another owner. Ownership validation is outside this free-list core.
