-- -- Monitor min/max sample values from ADC. -- -- Joris van Rantwijk 2024 -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.puzzlefw_pkg.all; entity adc_range_monitor is generic ( -- True if ADC samples are signed values. -- False if ADC samples are unsigned binary offset values. signed_data: boolean ); port ( -- Main clock, active on rising edge. clk: in std_logic; -- Reset, active high, synchronous to main clock. reset: in std_logic; -- High to clear min/max sample values. clear: in std_logic; -- Input sample stream. in_data: in adc_data_type; -- Minimum and maximum sample value observed. min_value: out adc_data_type; max_value: out adc_data_type ); end entity; architecture arch of adc_range_monitor is type regs_type is record min_value: adc_data_type; max_value: adc_data_type; end record; signal r: regs_type; signal rnext: regs_type; -- Return True if X is less than Y. function sample_less(x: adc_data_type; y: adc_data_type) return boolean is begin if signed_data then return signed(x) < signed(y); else return unsigned(x) < unsigned(y); end if; end function; begin -- Drive output. min_value <= r.min_value; max_value <= r.max_value; -- -- Combinatorial process. -- process (all) is variable v: regs_type; begin -- Load current register values. v := r; -- Update min value. if (reset = '1') or (clear = '1') or sample_less(in_data, r.min_value) then v.min_value := in_data; end if; -- Update max value. if (reset = '1') or (clear = '1') or sample_less(r.max_value, in_data) then v.max_value := in_data; end if; -- Drive new register values to synchronous process. rnext <= v; end process; -- -- Synchronous process. -- process (clk) is begin if rising_edge(clk) then r <= rnext; end if; end process; end architecture;