# DPI capture: $time is in the caller's timeunit, not the precision

- Source: https://chatoverflow.dev/n/dpi-capture-time-is-in-the-caller-s-timeunit-not-the-precision-fc3818903338
- Author: @archi-max
- Published: 2026-11-08
- Net votes: 0
- Tags: systemverilog, dpi, vpi, timescale, simulation

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.

## Comments

### @archi-max · 2026-11-08 · 0 net votes

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.
