Frequency meter
PulsePins includes a multi-channel frequency meter for reporting the observed frequencies of important on-board clocks.
The hardware implementation is in ip/freq_meter/freq_meter.sv, and the C++ interface is in c++/freq_meter.hh.
For a maintainer-oriented RTL map, see ip/freq_meter/README.md.
For maintainers, the most important split is:
ip/freq_meter/freq_meter.svowns the CDC-heavy hardware measurement pipelinec++/freq_meter.hhowns gate configuration, Hz conversion, and PulsePins-specific channel naming
Hardware model
The current block is an Avalon-MM controlled frequency meter with:
N_CH = 4channels by default- a programmable gate length in reference-clock cycles
- per-channel sampled results exposed through a small register file
The design counts transitions in each input clock domain and transfers results back into the Avalon clock domain using Gray-coded counters and synchronization stages.
The measurement path is intentionally CDC-heavy because each observed signal is itself a running clock. Rather than sampling those clocks directly in the Avalon domain, the hardware increments a per-channel counter in the input-clock domain, converts it to Gray code, synchronizes that Gray value into the gate/reference clock domain, and computes a delta at the end of each gate interval.
One important consequence is that the reported values are per-gate edge counts, not continuously updated instantaneous frequencies. The host-side wrapper is responsible for turning those per-gate counts into Hz.
Register model
The key register groups are:
- control register - enable and clear
- gate length register - measurement window in reference-clock cycles
- number-of-channels register
- one result register per channel
More concretely, the current word offsets are:
0x00- control (enable,clear)0x04- gate length0x08- number of channels0x10and up - per-channel results
The clear control behaves like a pulse request, while enable keeps periodic measurements running.
The C++ wrapper treats the gate length as the main measurement configuration knob.
C++ interface
The freq_meter class provides:
set_gate_len()- configure the measurement window in cyclesset_gate_time()- configure the same window in secondsread()- read the raw result counterread_freq()- convert the raw count to Hzread_freq_str()- return a formatted frequency stringwait_one_gate_time()- wait for one fresh measurement interval
The class also keeps track of:
- the nominal counter clock frequency used for conversion to Hz
- an optional correction factor for calibration
- the gate length currently programmed into the hardware
The higher-level pp_freq_meter wrapper additionally:
- applies an optional correction factor
- reads all four standard channels
- stores the measured streamer clock in the
FPGAobject
That last step is important because other software layers may rely on the measured streamer clock when converting counts to time-based values.
The shared executable bootstrap in c++/host_runtime.hh constructs this wrapper during startup and reports the initial frequencies before command execution begins.
The user-facing command implementation lives in c++/pptool_measurement.cc.
Standard channels
The current C++ layer names the four channels as:
- external clock
- internal clock
- streamer clock
- core clock
The wrapper currently expects all four channels to be present.
The standard channel IDs in c++/freq_meter.hh are:
0- external clock1- internal clock2- streamer clock3- core clock
Tool integration
ppfreq is the user-facing command-line interface to this subsystem.
It can be configured either by:
- gate time in seconds, or
- gate length in clock cycles
If both are available conceptually, gate time is the more user-friendly view and gate length is the lower-level hardware-facing view.
Longer gate intervals improve frequency resolution but reduce update rate. Shorter gate intervals provide faster feedback but coarser measurements.
Typical use cases
Use the frequency meter for:
- verifying external clock presence
- checking PLL and streamer clock configuration
- measuring startup or runtime clock conditions before streaming
- calibrating clock scaling using the optional correction factor
The correction factor is especially useful when the nominal reference clock is known to differ slightly from its ideal value.
Related pages
ppfreq.mdcpp.mdbuild.md