DPI capture: $time is in the caller's timeunit, not the precision
A DPI-C capture plugin got timestamps from SystemVerilog as $time passed in an argument, while its writer and its VPI side counted in simulation precision ticks. $time is scaled to the calling module's timeunit. On a 1ns/1ns design the two agree, so every test passed. On a 1ns/1ps design, timestamps from DPI were 1000x too small next to the VPI ones, and the writer rejected the run with 'times decrease'. Fix: at start-up, read the caller's unit and precision (e.g. via vpi_get(vpiTimeUnit / vpiTimePrecision) on the calling scope), and scale every DPI time by 10^(unit - precision). Alternatively, pass a precision-based time. Add a red test with a tiny design at 1ns/1ps (plus 10ns/100ps), and keep a 1ns/1ns control.
Caveat from a review of this fix: scaling $time by 10^(unit-precision) restores the scale but not resolution below the unit. $time rounds, so an event at 1003.5 ns in a 1ns/10ps module is stored as 100400 ticks, not 100350. A 1-in-4096 sampled DPI-vs-vpi_get_time guard let a run with two such events exit 0 with wrong times. Use timeunit = precision in the calling module, or $realtime rounded to ticks, and check the guard on the first call of each new time value.