Timegate (timegate)
Timed transmit of data using the timed sample protocol.
Design
If the bypass property is set to True, sample messages are transferred from the input to the output port. Alternatively, when set to False the transfer of sample messages is determined based on the time.
Until a Time message is received, the component remains in its default state where timed samples on the input are transferred to the output port without delay. Once a Time message is received on the input port, the Time will be stored. If the gate_all_opcodes property is set to True the next received Sample, Sample Interval, Flush or Metadata message will cause the gate to close, otherwise when set to False only a sample message will cause the gate to close. Once closed no further input messages will be consumed on the input port, until the current time matches or exceeds the stored (gated) time minus the time_correction property. This will then result in the timed samples being transferred to the output port.
The \(\text{time}_\text{current} - (\text{time}_\text{stored} - \texttt{time_correction})\) will be captured when the gate is opened and provided as the actual_time_to_requested_time_delta (Q32.32) property. If the current time already exceeds the stored (gated) time minus the time_correction property when the subsequent message is received, the late_time_sticky property will be set True and the actual_time_to_requested_time_delta will be non-zero. The late_time_sticky will remain True until the application writes a True to clear it.
A Discontinuity message will return the Timegate to its default state where timed samples on the input are transferred to the output port without delay. If this message is queued behind a Sample message then it would not be actioned until the time is reached and the preceding samples are transferred through the Timegate.
To determine the time to open the gate, the time_correction (Q0.32) is deducted from the timestamp (Q32.64) and, with the lower 32 bits ignored, compared against the current time (Q32.32). Note, the ARM Q notation has been used, where the sign bit is included in the stated integer bits.
Interface
<?xml version="1.0"?>
<componentspec>
<property name="bypass" type="bool" writable="true" default="false"
description="Ignores timestamps, disabling the time-gating functionality."/>
<property name="gate_all_opcodes" type="bool" initial="true" writable="false" default="false"
description="Gating applies to all but time and discontinuity opcodes when true, otherwise only applies to sample opcodes."/>
<property name="leap_seconds" type="uchar" writable="true" default="0"
description="Current number of leap seconds between UTC and GPS time."/>
<property name="time_correction" type="ulong" writable="true" default="0"
description="Unsigned fixed point fraction of second which is subtracted from the applied time to open the gate early so that
the actual RF transmission happens at the right time"/>
<property name="late_time_sticky" type="bool" writable="true" volatile="true"
description="Reports timestamp (corrected) arrived too late - after the indicated time on read, flag cleared on write of true"/>
<property name="actual_time_to_requested_time_delta" type="ulonglong" writable="false" volatile="true"
description="Delta between the actual time transmitted (when the gate opens to allow samples through) to the requested
timestamp (corrected)."/>
<property name="port_width" type="uchar" initial="true" writable="false" default="16"
description="Defines the input data width in bits."/>
<port name="input" producer="false" numberofopcodes="6" defaultbuffersize="16384"/>
<port name="output" producer="true" numberofopcodes="6" defaultbuffersize="16384"/>
</componentspec>
Opcode Handling
Refer to the design section for detailed behaviour on opcode handling.
Properties
bypass: Ignores timestamps, disabling the time-gating functionality.Type:
boolAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
false
gate_all_opcodes: Gating applies to all but time and discontinuity opcodes when true, otherwise only applies to sample opcodes.Type:
boolAccess:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
False
Default value:
false
leap_seconds: Current number of leap seconds between UTC and GPS time. The default value has been set to0to enforce the setting to the latest published leap second value. At the end of 2016, the number of leap seconds was incremented to18. This value is only required for the RCC worker since the time service will provide GPS time for the HDL worker.Type:
ucharAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
0
time_correction: Unsigned fixed point fraction of second which is subtracted from the applied time to open the gate early so that the actual RF transmission happens at the right time.Type:
ulongAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
0
late_time_sticky: Reports timestamp (corrected) arrived too late - after the indicated time on read, flag cleared on write of true.Type:
boolAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
True
Default value:
None
actual_time_to_requested_time_delta: Delta between the actual time transmitted (when the gate opens to allow samples through) to the requested timestamp (corrected).Type:
ulonglongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
True
Default value:
None
port_width: Defines the input data width in bits.Type:
ucharAccess:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
False
Default value:
16
Ports
Inputs:
input: Primary input samples port.Protocol:
NoneOptional:
False
Outputs:
output: Primary output samples port.Protocol:
NoneOptional:
False
Implementations
Example Application
<?xml version="1.0"?>
<application done="file_write">
<instance component="ocpi.core.file_read" connect="timegate">
<property name="filename" value="input.bin"/>
</instance>
<instance component="ocpi.comp.sdr.util.timegate" connect="file_write">
<property name="bypass" value="false"/>
<property name="gate_all_opcodes" value="false"/>
<property name="leap_seconds" value="0"/>
<property name="time_correction" value="0"/>
<property name="late_time_sticky" value="false"/>
<property name="port_width" value="16"/>
</instance>
<instance component="ocpi.core.file_write">
<property name="filename" value="output.bin"/>
</instance>
</application>
Dependencies
The dependencies to other elements in OpenCPI are:
HDL OpenCPI dependencies:
ocpi.wci.control_op_t
ocpi.util.max
sdr_util.sdr_util.slv_to_opcode
sdr_util.sdr_util.opcode_tClock Domain Crossing - Fast pulse to slow sticky primitive.
Clock Domain Crossing - First In First Out memory primitive.
RCC OpenCPI dependencies:
components/math/common/time_utils.hh
components/util/common/opcodes.hh
There is also a dependency on:
HDL specific dependencies:
ieee.std_logic_1164
ieee.numeric_std
ieee.math_realRCC specific dependencies:
<cmath>
<cstdint>
<chrono>
Limitations
Limitations of timegate are:
The time client only provides 32-bits for the fractional part whereas the timed sample protocol supports 64-bits.
Due to the way the RCC generates the GPS time from UTC time, there is a
leap_secondsproperty for users to manually set this offset value.All unit test cases are implemented to validate the timegate component, however whilst running virtually and with the limitations of the framework the
bypassproperty is set toTruerendering the component to be non-gated, allowing all data and opcodes to pass from input to output.Tested on a PlutoSDR, data was gated as expected and the properties
actual_time_to_requested_time_deltaandlate_time_stickyreturned sensible results.
Testing
Tested platforms: None
Component testing not completed.