RandomDriftOscillator

Package: inet.clock.oscillator

RandomDriftOscillator

simple module

C++ definition

Oscillator with time-varying drift driven by a bounded random walk.

Summary


The oscillator’s fractional frequency error (drift rate, in ppm) evolves over time. At the end of each changeInterval, an increment Δr (sampled from the volatile parameter driftRateChange) is added to the current drift rate, optionally clamped to [driftRateChangeLowerLimit, driftRateChangeUpperLimit]. This produces a bounded random walk starting from initialDriftRate.

Semantics


Let r_k be the drift rate (ppm) right after the k-th update (k ≥ 0), with r_0 = initialDriftRate. At each update time t_k: Δr_k := sample(driftRateChange) // volatile; re-evaluated each update r_k+1 := clamp(r_k + Δr_k, driftRateChangeLowerLimit, driftRateChangeUpperLimit) The effective tick-length factor is d ≈ 1 + r·1e−6, and the current tick length is L_current = L / d (L = nominal tick length). Phase/origin handling follows ~DriftingOscillatorBase: updates preserve tick phase (no double/missed ticks) by moving the computation origin to the change instant.

Timing of updates


  • Updates occur at the end of every changeInterval. Because it is declared volatile, changeInterval may be an expression/distribution; its value is (re)sampled whenever a new update is scheduled.
  • The drift-change event is scheduled with priority driftChangeEventSchedulingPriority.

Inheritance diagram

The following diagram shows inheritance relationships for this type. Unresolved types are missing from the diagram.

Extends

Name Type Description
DriftingOscillatorBase simple module

Base module for oscillators whose effective tick rate may drift relative to a nominal tick length. This module provides the mapping used by clocks without generating one event per tick.

Parameters

Name Type Default value Description
displayStringTextFormat string "%c (%n + %d)"

Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information

emitNumTicksSignal bool false

Enables emitting a signal at each oscillator tick, can be useful for validating the behavior of the more efficient implementation without events

oscillatorTickEventSchedulingPriority int 0

Specifies the scheduling priority of the tick event

nominalTickLength double

Specifies the elapsed time between oscillator ticks

tickOffset double 0s

Shifts ticks to the past, must be in the range of [0, current tick length)

initialDriftRate double 0ppm

Expressed as a ratio in parts per million

changeInterval double

Drift change happens at the end of every interval

driftRateChange double 0ppm

Integrated over time (random walk), no change by default

driftRateChangeLowerLimit double -inf ppm

Lower limit for random walk, no limit by default

driftRateChangeUpperLimit double inf ppm

Upper limit for random walk, no limit by default

driftChangeEventSchedulingPriority int 0

Specifies the scheduling priority of the drift change event

Properties

Name Value Description
class RandomDriftOscillator
display i=block/tunnel

Signals

Name Type Unit Description
postOscillatorStateChanged
preOscillatorStateChanged

Statistics

Name Title Source Record Unit Interpolation Mode Description
numTicksChanged number of ticks vector sample-hold
driftRateChanged Oscillator drift rate vector ppm sample-hold

Source code

//
// Oscillator with time-varying drift driven by a bounded random walk.
//
// Summary
// -------
// The oscillator’s fractional frequency error (drift rate, in ppm) evolves over
// time. At the end of each `changeInterval`, an increment Δr (sampled from the
// volatile parameter `driftRateChange`) is added to the current drift rate,
// optionally clamped to [driftRateChangeLowerLimit, driftRateChangeUpperLimit].
// This produces a bounded random walk starting from `initialDriftRate`.
//
// Semantics
// ---------
// Let r_k be the drift rate (ppm) right after the k-th update (k ≥ 0), with
// r_0 = initialDriftRate. At each update time t_k:
//   Δr_k  := sample(driftRateChange)          // volatile; re-evaluated each update
//   r_k+1 := clamp(r_k + Δr_k,
//                  driftRateChangeLowerLimit,
//                  driftRateChangeUpperLimit)
// The effective tick-length factor is d ≈ 1 + r·1e−6, and the current tick
// length is L_current = L / d (L = nominal tick length). Phase/origin handling
// follows ~DriftingOscillatorBase: updates preserve tick phase (no double/missed
// ticks) by moving the computation origin to the change instant.
//
// Timing of updates
// -----------------
// - Updates occur at the end of every `changeInterval`. Because it is declared
//   `volatile`, `changeInterval` may be an expression/distribution; its value is
//   (re)sampled whenever a new update is scheduled.
// - The drift-change event is scheduled with priority `driftChangeEventSchedulingPriority`.
//
simple RandomDriftOscillator extends DriftingOscillatorBase like IOscillator
{
    parameters:
        double initialDriftRate @unit(ppm) = default(0ppm); // Expressed as a ratio in parts per million
        volatile double changeInterval @unit(s); // Drift change happens at the end of every interval
        volatile double driftRateChange @unit(ppm) = default(0ppm); // Integrated over time (random walk), no change by default
        double driftRateChangeLowerLimit @unit(ppm) = default(-inf ppm); // Lower limit for random walk, no limit by default
        double driftRateChangeUpperLimit @unit(ppm) = default(inf ppm); // Upper limit for random walk, no limit by default
        int driftChangeEventSchedulingPriority = default(0); // Specifies the scheduling priority of the drift change event
        @class(RandomDriftOscillator);
}

File: src/inet/clock/oscillator/RandomDriftOscillator.ned