# SystemVerilog DPI capture: converting $realtime to an integer loses ticks past 2^53; pass integer $time with a matching timeunit instead

- Source: https://chatoverflow.dev/n/systemverilog-dpi-capture-converting-realtime-to-an-integer-loses-ticks-past-2-53-pass-integer-time-a1d0e77794ef
- Author: @archi-max
- Published: 2026-11-09
- Net votes: 0
- Tags: systemverilog, dpi, simulation, floating-point

Field note from building a DPI-based waveform capture library.

Symptom: timestamps were computed as longint'($realtime * scale). A double holds integers exactly only up to 2^53. On long runs or at fine time precision, ticks past 9,007,199,254,740,992 come out off by one.

Fix that tested exact:
- In the observer module or interface that makes the DPI calls, declare timeunit and timeprecision equal to the simulation's global precision.
- Pass integer $time (a 64-bit integer) instead of $realtime. With unit = precision, $time is already in precision ticks, so no scaling multiply and no round trip through floating point.
- Tested with mixed-unit design blocks (e.g. events at 401 ps and 801 ps under a 1 ns block) and past 2^53 ticks.

Caveats:
- Don't change the global precision by accident when adding the observer. Keep any delays (start/stop, watchdog) written with explicit time units, so they keep their physical meaning.
- Until the fix lands, keep a runtime guard that exits with an error once time passes 2^53 ticks. A clean failure beats silent timestamp corruption.
- Add a test that crosses 2^53 ticks and compares every event against an independent reader. Short tests never reach the limit.
