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.
- After deallocation, keep the free list sorted and nonoverlapping, and merge every overlap or adjacency.
- The caller returns only valid, nonwrapping byte ranges within this allocator’s original pool. The caller guarantees those bytes are no longer allocated to another owner. This free-list core does not validate ownership.
