Package: inet.clock.oscillator
RandomDriftOscillator
simple moduleOscillator 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