--
-- VHDL Architecture FACT_FAD_lib.spi_distributor.beha
--
-- Created:
--          by - Benjamin Krumm.UNKNOWN (EEPC8)
--          at - 09:24:21 23.04.2010
--
-- using Mentor Graphics HDL Designer(TM) 2009.1 (Build 12)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
LIBRARY FACT_FAD_lib;
USE FACT_FAD_lib.fad_definitions.all;

ENTITY spi_distributor IS

-- TEMP_MEASUREMENT_BEAT * clk ist the measurement period of the 
-- Temperature measurement
-- e.g. 5*10**6 means every second

  GENERIC(
    TEMP_MEASUREMENT_BEAT : integer := 5*10**6
    );

  PORT(
    clk               : IN 			std_logic; -- 50MHz
    config_start      : IN 			std_logic;
    config_ready, config_started      : OUT   std_logic := '0'; 
    sensor_valid      : OUT 		std_logic := '0';
    dac_array         : IN 			dac_array_type;
    sensor_array      : OUT 		sensor_array_type; 
    dac_config_start  : OUT   std_logic := '0';
    dac_config_ready  : IN    std_logic;
    sensor_read_start : OUT   std_logic := '0';
    sensor_read_valid : IN    std_logic;
    dac_id            : OUT   std_logic_vector(2 downto 0) := (others => '0');
    sensor_id         : OUT   std_logic_vector(1 downto 0) := (others => '0');
    data              : INOUT std_logic_vector(15 downto 0) := (others => 'Z')
  );
END ENTITY spi_distributor;

ARCHITECTURE beha OF spi_distributor IS

  type TYPE_SPI_DISTRIBUTION_STATE is (INIT, IDLE, READ_SENSOR, CONFIG_DAC);
    
  signal spi_distr_state       : TYPE_SPI_DISTRIBUTION_STATE := INIT;
  signal int_sensor_read_start : std_logic := '0';
  signal int_sensor_valid      : std_logic := '0';
  signal int_sensor_array      : sensor_array_type;
  signal sensor_id_cnt         : integer range 0 to 4 := 0;
  signal dac_id_cnt            : integer range 0 to 7 := 0;
  
  
BEGIN
  
  spi_distribute_proc: process (clk)
  begin
    
    if rising_edge(clk) then
      data <= (others => 'Z');
      case spi_distr_state is
        when INIT =>
          data <= (others => 'Z');
          int_sensor_valid <= '0';
          spi_distr_state <= READ_SENSOR;
        when IDLE =>
          if (int_sensor_valid = '1') then
            sensor_array <= int_sensor_array;
            sensor_valid <= '1';
          end if;
          data <= (others => 'Z');
         -- start DAC configuration
          if (config_start = '1' AND int_sensor_valid = '1') then
            config_started <= '1';
            config_ready <= '0';
            dac_config_start <= '1';
            dac_id <= conv_std_logic_vector(dac_id_cnt, dac_id'length);
            data <= conv_std_logic_vector(dac_array(dac_id_cnt),data'length);
            spi_distr_state <= CONFIG_DAC;
          -- start temperature sensor reading
          elsif (dac_config_ready <= '1' AND int_sensor_read_start = '1') then
            int_sensor_valid <= '0';
            sensor_read_start <= '1';
            sensor_id <= conv_std_logic_vector(sensor_id_cnt, sensor_id'length);
            spi_distr_state <= READ_SENSOR;
          end if;
       
        -- sensor reading   
        when READ_SENSOR =>
          sensor_read_start <= '1';
          sensor_id <= conv_std_logic_vector(sensor_id_cnt, sensor_id'length);
          if (sensor_read_valid = '1') then
            int_sensor_array(sensor_id_cnt) <= conv_integer(data);
            sensor_read_start <= '0';
            if (sensor_id_cnt < 3) then
              sensor_id_cnt <= sensor_id_cnt + 1;
              sensor_read_start <= '1';
              spi_distr_state <= READ_SENSOR;
            else
              sensor_id_cnt <= 0;
              sensor_valid <= '0';
              int_sensor_valid <= '1';
              spi_distr_state <= IDLE;
            end if;
          end if;
          
        -- DAC configuration
        when CONFIG_DAC =>
          dac_config_start <= '1';
          dac_id <= conv_std_logic_vector(dac_id_cnt, dac_id'length);
          data <= conv_std_logic_vector(dac_array(dac_id_cnt),data'length);
          if (dac_config_ready = '1') then
            dac_config_start <= '0';
            if (dac_id_cnt < 7) then 
              dac_id_cnt <= dac_id_cnt + 1;
              dac_config_start <= '1';
              spi_distr_state <= CONFIG_DAC;
            else
              dac_id_cnt <= 0;
              config_started <= '0';
              config_ready <= '1';
              spi_distr_state <= IDLE;
            end if;
          end if; 
      end case;  
    end if;
    
  end process spi_distribute_proc;

  sensor_tmr_proc: process (clk)
    variable Z: integer range 0 to (TEMP_MEASUREMENT_BEAT - 1);
  begin
    if rising_edge(clk) then
      int_sensor_read_start <= '0';
      if (Z < TEMP_MEASUREMENT_BEAT - 1) then 
        Z := Z + 1;
      else 
        Z := 0;
      end if;
      if (Z = 0) then 
        int_sensor_read_start <= '1';
      end if;
    end if;
  end process sensor_tmr_proc;
  
  
END ARCHITECTURE beha;

