library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;

entity variable_monitor is
generic (
  LEN : positive := 11 );
port (
  clk         : in std_logic;
  we          : in std_logic;
  address_bus : in std_logic_vector(11 downto 0);
  data_bus    : in std_logic_vector(15 downto 0) );
  
  attribute black_box : string;
  attribute black_box of variable_monitor : entity is "true";  
  
end variable_monitor;

architecture variable_monitor_arch of variable_monitor is

  type name_value_pair_t is record
    name  : string(1 to LEN);
    value : integer;
  end record;

  type monitor_list_t is array (natural range <>) of name_value_pair_t;
 
  -- UPDATE THESE VARIABLE NAMES AND ADDRESSES TO MATCH CODE
  -- NAME LENGTH MUST MATCH THE GENERIC PARAMETER "LEN", IF NEEDED PAD WITH SPACES
  -- LEN CAN BE REDUCED TO SUIT REQUIREMENTS
 
  constant MONITOR_LIST : monitor_list_t := (
    (name => "TMP        ", value => 71),
    (name => "X          ", value => 73),   
    (name => "W          ", value => 72), 
    (name => "Z          ", value => 76)	 
 );

begin

  monitor_bus : process(clk)
    variable current_address : integer;
    variable current_data    : integer;
    variable l               : line;
  begin
    if clk='0' and clk'event
    then
      if we = '1'
      then
        if not is_X( address_bus ) 
        then
          current_address := to_integer(unsigned(address_bus));
			 
          if not is_X( data_bus ) 
          then
            current_data := to_integer(unsigned(data_bus));

            for i in MONITOR_LIST'range 
            loop
              if current_address = MONITOR_LIST(i).value 
              then
                write(l, string'(" (At: "));
                write(l, now);
                write(l, string'(" ")); 
                write(l, MONITOR_LIST(i).name);
                write(l, string'(" (ADDR: "));
                write(l, current_address);
                write(l, string'(" (DATA: "));
                write(l, current_data);
                write(l, string'(")"));
                writeline(output, l);            
                exit;
              end if;
            end loop; 
			 end if;
        end if;
      end if;
    end if;
  end process;

end variable_monitor_arch;
