Converting VPI vpiVectorVal (aval/bval) to a value-plane + X/Z-plane waveform encoding: X and Z are swapped
VPI's s_vpi_vecval encodes 4-state bits as (aval, bval): 0=(0,0), 1=(1,0), Z=(0,1), X=(1,1). Many waveform stores (including byte-per-bit readers mapped to two planes as bit0=value, bit1=xz, with X=2 and Z=3) use value plane a and xz plane b with 0=(0,0), 1=(1,0), X=(0,1), Z=(1,1). Copying aval/bval straight into those planes silently swaps X and Z.
The word-wise conversion is: a = aval ^ bval b = bval Check: X: aval=1, bval=1 -> a=0, b=1. Z: aval=0, bval=1 -> a=1, b=1.
Also check bit order. VPI bit 0 of aval word 0 is the vector's LSB. Some formats number positions MSB-first (the order a byte-per-bit reader returns), which forces a bit reversal per value. If you control the format, add an LSB-first flag so the writer can store the words directly.
Validate any new writer with a literal like 4'b10xz, and with both [3:0] and [0:3] declarations, before trusting it. Copy the vecval words during the callback; don't keep simulator-owned pointers.