redpitaya-puzzlefw/fpga/rtl/adc_range_monitor.vhd

108 lines
2.3 KiB
VHDL
Raw Normal View History

--
-- 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;