-------------------------------------------------------------------------------
-- Title      : Virtex 6 System Monitor with wishbone interface
-- Project    : WhiteRabbit Switch
-------------------------------------------------------------------------------
-- File       : xwrsw_syst_mon.vhd
-- Company    : INCAA Computers
-- Created    : 2017-01-31
-- Platform   : FPGA-generics
-- Standard   : VHDL '93
-------------------------------------------------------------------------------
-- Description:
--
-- Virtex 6 System Monitor with wishbone interface
-------------------------------------------------------------------------------
-- Copyright (c) 2017 Cern
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author          Description
-- 2017-01-31  1.0      INCAA Computers Created
-------------------------------------------------------------------------------

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

library work;
use work.wishbone_pkg.all;

entity xwrsw_syst_mon is
  generic(
    g_interface_mode         : t_wishbone_interface_mode      := CLASSIC;
    g_address_granularity    : t_wishbone_address_granularity := WORD
    );
  port(
    clk_sys_i : in std_logic;
    rst_n_i   : in std_logic;

    slave_i : in  t_wishbone_slave_in;
    slave_o : out t_wishbone_slave_out;
    
    vaux_p_i : in std_logic_vector(7 downto 0);   -- Auxiliary Channels
    vaux_n_i : in std_logic_vector(7 downto 0);
    v_p_i : in std_logic;                         -- Dedicated Analog Input Pair
    v_n_i : in std_logic
  );
end xwrsw_syst_mon;

architecture struct of xwrsw_syst_mon is

  function f_zeros(size : integer)
    return std_logic_vector is
  begin
    return std_logic_vector(to_unsigned(0, size));
  end f_zeros;

  signal s_den  : std_logic;
  signal s_dwe  : std_logic;
  signal s_drdy : std_logic;
  signal s_rst  : std_logic;

  signal wb_in  : t_wishbone_slave_in;
  signal wb_out : t_wishbone_slave_out;

  component syst_mon
    port (
      DADDR_IN            : in  STD_LOGIC_VECTOR (6 downto 0);     -- Address bus for the dynamic reconfiguration port
      DCLK_IN             : in  STD_LOGIC;                         -- Clock input for the dynamic reconfiguration port
      DEN_IN              : in  STD_LOGIC;                         -- Enable Signal for the dynamic reconfiguration port
      DI_IN               : in  STD_LOGIC_VECTOR (15 downto 0);    -- Input data bus for the dynamic reconfiguration port
      DWE_IN              : in  STD_LOGIC;                         -- Write Enable for the dynamic reconfiguration port
      RESET_IN            : in  STD_LOGIC;                         -- Reset signal for the System Monitor control logic
      VAUXP0              : in  STD_LOGIC;                         -- Auxiliary Channel 0
      VAUXN0              : in  STD_LOGIC;
      VAUXP1              : in  STD_LOGIC;                         -- Auxiliary Channel 1
      VAUXN1              : in  STD_LOGIC;
      VAUXP2              : in  STD_LOGIC;                         -- Auxiliary Channel 2
      VAUXN2              : in  STD_LOGIC;
      VAUXP3              : in  STD_LOGIC;                         -- Auxiliary Channel 3
      VAUXN3              : in  STD_LOGIC;
      VAUXP4              : in  STD_LOGIC;                         -- Auxiliary Channel 4
      VAUXN4              : in  STD_LOGIC;
      VAUXP5              : in  STD_LOGIC;                         -- Auxiliary Channel 5
      VAUXN5              : in  STD_LOGIC;
      VAUXP6              : in  STD_LOGIC;                         -- Auxiliary Channel 6
      VAUXN6              : in  STD_LOGIC;
      VAUXP7              : in  STD_LOGIC;                         -- Auxiliary Channel 7
      VAUXN7              : in  STD_LOGIC;
      BUSY_OUT            : out  STD_LOGIC;                        -- ADC Busy signal
      CHANNEL_OUT         : out  STD_LOGIC_VECTOR (4 downto 0);    -- Channel Selection Outputs
      DO_OUT              : out  STD_LOGIC_VECTOR (15 downto 0);   -- Output data bus for dynamic reconfiguration port
      DRDY_OUT            : out  STD_LOGIC;                        -- Data ready signal for the dynamic reconfiguration port
      EOC_OUT             : out  STD_LOGIC;                        -- End of Conversion Signal
      EOS_OUT             : out  STD_LOGIC;                        -- End of Sequence Signal
      VP_IN               : in  STD_LOGIC;                         -- Dedicated Analog Input Pair
      VN_IN               : in  STD_LOGIC
    );
  end component;
  
begin

  U_Adapter : wb_slave_adapter
    generic map (
      g_master_use_struct  => true,
      g_master_mode        => g_interface_mode,
      g_master_granularity => WORD,
      g_slave_use_struct   => true,
      g_slave_mode         => g_interface_mode,
      g_slave_granularity  => g_address_granularity)
    port map (
      clk_sys_i => clk_sys_i,
      rst_n_i   => rst_n_i,
      slave_i   => slave_i,
      slave_o   => slave_o,
      master_i  => wb_out,
      master_o  => wb_in);

  s_rst <= not rst_n_i;
      
  U_SystemMonitor : syst_mon
    port map (
      DADDR_IN    => wb_in.adr(6 downto 0),
      DCLK_IN     => clk_sys_i,
      DEN_IN      => s_den,
      DI_IN       => wb_in.dat(15 downto 0),
      DWE_IN      => s_dwe,
      RESET_IN    => s_rst,
      VAUXP0      => vaux_p_i(0),
      VAUXN0      => vaux_n_i(0),
      VAUXP1      => vaux_p_i(1),
      VAUXN1      => vaux_n_i(1),
      VAUXP2      => vaux_p_i(2),
      VAUXN2      => vaux_n_i(2),
      VAUXP3      => vaux_p_i(3),
      VAUXN3      => vaux_n_i(3),
      VAUXP4      => vaux_p_i(4),
      VAUXN4      => vaux_n_i(4),
      VAUXP5      => vaux_p_i(5),
      VAUXN5      => vaux_n_i(5),
      VAUXP6      => vaux_p_i(6),
      VAUXN6      => vaux_n_i(6),
      VAUXP7      => vaux_p_i(7),
      VAUXN7      => vaux_n_i(7),
      BUSY_OUT    => open,
      CHANNEL_OUT => open,
      DO_OUT      => wb_out.dat(15 downto 0),
      DRDY_OUT    => s_drdy,
      EOC_OUT     => open,
      EOS_OUT     => open,
      VP_IN       => v_p_i,
      VN_IN       => v_n_i
    );
      
  wb_out.dat(c_wishbone_data_width-1 downto 16) <= (others => '0');
      
  s_den <= wb_in.stb and wb_in.cyc;
  s_dwe <= wb_in.we and wb_in.stb and wb_in.cyc;

  process(clk_sys_i)
  begin
    if(rising_edge(clk_sys_i)) then
      if(rst_n_i = '0') then
        wb_out.ack <= '0';
      else
        if(wb_out.ack = '1' and g_interface_mode = CLASSIC) then
          wb_out.ack <= '0';
        else
          if (wb_in.we = '1') then
            wb_out.ack <= wb_in.cyc and wb_in.stb;
          else
            wb_out.ack <= wb_in.cyc and s_drdy;
          end if;
        end if;
      end if;
    end if;
  end process;

  wb_out.stall <= '0';
  wb_out.err <= '0';
  wb_out.rty <= '0';
  
end struct;

