-------------------------------------------------------------------------------
-- Title      : Sandbox register with wishbone interface
-- Project    : WhiteRabbit Switch
-------------------------------------------------------------------------------
-- File       : xwrsw_sandbox.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-08  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_sandbox is
  generic(
    g_interface_mode         : t_wishbone_interface_mode      := CLASSIC;
    g_address_granularity    : t_wishbone_address_granularity := WORD;
    g_address_storage_box    : boolean := false
    );
  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
  );
end xwrsw_sandbox;

architecture struct of xwrsw_sandbox is

  signal wb_in  : t_wishbone_slave_in;
  signal wb_out : t_wishbone_slave_out;
  
  signal sel_int : std_logic;
  signal wr_int  : std_logic;
  signal ack_int : std_logic;
  
  signal sandbox_reg : std_logic_vector(31 downto 0);

begin

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

  sel_int <= '1' when (unsigned(not wb_in.sel) = 0) else '0';

  p_gen_write_strobes : process(wb_in.we, wb_in.cyc, wb_in.stb, sel_int)
  begin
    if(wb_in.we = '1' and wb_in.cyc = '1' and wb_in.stb = '1' and sel_int = '1') then
      wr_int <= '1';
    else
      wr_int <= '0';
    end if;
  end process;

  p_wb_write: process (clk_sys_i)
  begin
    if rising_edge(clk_sys_i) then
      if rst_n_i = '0' then
        sandbox_reg <= (others => '0');
      else
        if(wr_int = '1') then
          if (g_address_storage_box) then
            sandbox_reg <= (others => '0');
            sandbox_reg(wb_in.adr'range) <= wb_in.adr;
          else
            sandbox_reg <= wb_in.dat;
          end if;
        end if;
      end if;
    end if;
  end process;
    
  p_wb_reads : process(clk_sys_i)
  begin
    if rising_edge(clk_sys_i) then
      if rst_n_i = '0' then
        wb_out.dat <= (others => '0');
      else
        wb_out.dat <= sandbox_reg;
      end if;
    end if;
  end process;

  p_gen_ack : process (clk_sys_i)
  begin
    if rising_edge(clk_sys_i) then
      if rst_n_i = '0' then
        ack_int <= '0';
      else
        if(ack_int = '1') then
          ack_int <= '0';
        elsif(wb_in.cyc = '1') and (wb_in.stb = '1') then
          ack_int <= '1';
        end if;
      end if;
    end if;
  end process;
      
  wb_out.ack <= ack_int;
  wb_out.stall <= '0';
  wb_out.err <= '0';
  wb_out.int <= '0';
  wb_out.rty <= '0';
  
end struct;

