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