-------------------------------------------------------------------------------
-- Title      : Frequency measurement of clocks
-- Project    : WhiteRabbit Switch 
-------------------------------------------------------------------------------
-- File       : xwrsw_freq_measure.vhd
-- Company    : INCAA Computers
-- Created    : 2017-02-08
-- Platform   : FPGA-generics
-- Standard   : VHDL '93
-------------------------------------------------------------------------------
-- Description:
--
-- Sandbox with wishbone interface
-------------------------------------------------------------------------------
-- Copyright (c) 2017 Cern
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author          Description
-- 2017-02-15  1.0      INCAA Computers Created
-------------------------------------------------------------------------------

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

library work;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.freq_wbgen2_pkg.all;

entity xwrsw_freq_measure 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;
    
    clk_pck_i       : in std_logic; -- reference clock from AT91SAM, must be 10MHz to create a 1 second gate
    
    clk_dmtd_i      : in std_logic;
    clk_10mhz_ext_i : in std_logic;
    clk_25mhz_i     : in std_logic;
    clk_aux_i       : in std_logic;
    clk_serdes_i    : in std_logic;
    clk_ref_i       : in std_logic
  );
end xwrsw_freq_measure;

architecture struct of xwrsw_freq_measure is

  signal wb_in  : t_wishbone_slave_in;
  signal wb_out : t_wishbone_slave_out;
  
  component wb_freq_regs
    port (
      rst_n_i    : in     std_logic;
      clk_sys_i  : in     std_logic;
      wb_adr_i   : in     std_logic_vector(2 downto 0);
      wb_dat_i   : in     std_logic_vector(31 downto 0);
      wb_dat_o   : out    std_logic_vector(31 downto 0);
      wb_cyc_i   : in     std_logic;
      wb_sel_i   : in     std_logic_vector(3 downto 0);
      wb_stb_i   : in     std_logic;
      wb_we_i    : in     std_logic;
      wb_ack_o   : out    std_logic;
      wb_stall_o : out    std_logic;
      regs_i     : in     t_freq_in_registers;
      regs_o     : out    t_freq_out_registers
    );
  end component;
  
  signal freq_regs :  t_freq_in_registers;
  
  signal cntr_gate : unsigned(23 downto 0);
  signal gate_pulse : std_logic;

begin

  U_Adapter : wb_slave_adapter
    generic map (
      g_master_use_struct  => true,
      g_master_mode        => CLASSIC,
      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);

  U_Freq_Regs : wb_freq_regs
    port map (
      clk_sys_i  => clk_sys_i,
      rst_n_i    => rst_n_i,
      wb_adr_i   => wb_in.adr(2 downto 0),
      wb_dat_i   => wb_in.dat,
      wb_dat_o   => wb_out.dat,
      wb_cyc_i   => wb_in.cyc,
      wb_sel_i   => wb_in.sel,
      wb_stb_i   => wb_in.stb,
      wb_we_i    => wb_in.we,
      wb_ack_o   => wb_out.ack,
      wb_stall_o => wb_out.stall,
      regs_i     => freq_regs,
      regs_o     => open
    );
      
  wb_out.err <= '0';
  wb_out.int <= '0';
  wb_out.rty <= '0';
      
  p_gate_counter : process(clk_pck_i, rst_n_i)
    begin
      if rst_n_i = '0' then
        cntr_gate  <= (others => '0');
        gate_pulse <= '0';
      elsif rising_edge(clk_pck_i) then
        if(cntr_gate = to_unsigned(10000000-1, cntr_gate'length)) then
          cntr_gate  <= (others => '0');
          gate_pulse <= '1';
        else
          cntr_gate  <= cntr_gate + 1;
          gate_pulse <= '0';
        end if;
      end if;
    end process;
      
  U_Meas_DMTD_CLK_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_dmtd_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_dmtd_clk_freq_i,
      freq_valid_o => open);            

  U_Meas_CLK10MHZ_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_10mhz_ext_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_clk10mhz_ext_freq_i,
      freq_valid_o => open);            
  
  U_Meas_MAIN_CLK_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_25mhz_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_fpga_main_clk_freq_i,
      freq_valid_o => open);            
  
  U_Meas_AUX_CLK_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_aux_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_aux_clk_freq_i,
      freq_valid_o => open);            
      
  U_Meas_SERDES_CLK_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_serdes_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_serdes_clk_freq_i,
      freq_valid_o => open);            
      
  U_Meas_REF_CLK_Freq: gc_frequency_meter
    generic map (
      g_with_internal_timebase => false,
      g_clk_sys_freq           => 1,
      g_counter_bits           => 28)
    port map (
      clk_sys_i    => clk_pck_i,
      clk_in_i     => clk_ref_i,
      rst_n_i      => rst_n_i,
      pps_p1_i     => gate_pulse,
      freq_o       => freq_regs.f_ref_clk_freq_i,
      freq_valid_o => open);            
      
end struct;

