CDL Modules
|
Files | |
file | hysteresis_switch.cdl |
A hystersis detector using counter pairs. | |
module hysteresis_switch::hysteresis_switch | ( | clock | clk, |
input bit | reset_n, | ||
input bit | clk_enable, | ||
input bit | input_value, | ||
output bit | output_value, | ||
input bit | filter_period[16], | ||
input bit | filter_level[16] | ||
) |
CDL implementation of a module that takes an input signal and notionally keeps a count of cycles that the input is low, and cycles that the input is high; using these counters it makes a decision on the real value of the output, using hysteresis.
Since infinite history is not sensible and the counters cannot run indefinitely without overflow anyway, the counters divide by 2 on a configurable divider (effectively filtering the input stream).
The two notional counters are cycles_low and cycles_high.
To switch to a 'high' output from a current 'low' output requires the cycles_high - cycles_low to be greater than half of the filter period.
To switch to a 'low' output from a current 'high' output requires the cycles_high - cycles_low to be less than minus half of the filter period.
Hence a n+1 bit difference would need to be maintained for cycles_high and cycles_low. This difference would increase by 1 if the input is high, and decrease by 1 if the input is low.
Hence an actual implementation can maintain an up/down counter cycles_diff, which is divided by 2 every filter period, and which is incremented on input of 1, and decremented on input of 0.
When the output is low and the cycles_diff is > half the filter period the output shifts to high.
When the output is high and the cycles_diff is < -half the filter period the output shifts to low.
Clock for all the logic, based on an enable in
[in] | clk | Clock for the module |
[in] | reset_n | Active low reset |
[in] | clk_enable | Assert to enable the internal clock; this permits I/O switches to easily use a slower clock |
[in] | input_value | Input pin level, to apply hysteresis to |
[out] | output_value | Output level, after hysteresis |
[in] | filter_period | Period over which to filter the input - the larger the value, the longer it takes to switch, but the more glitches are removed |
[in] | filter_level | Value to exceed to switch output levels - the larger the value, the larger the hysteresis; must be less than 2*filter_period |