108 lines
2.3 KiB
VHDL
108 lines
2.3 KiB
VHDL
|
--
|
||
|
-- 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;
|