---------------------------------------------------------------------------
-- Copyright (c) 2018, TTTech Computertechnik AG
-- Project        : TTP Hub/Codec FPGA
---------------------------------------------------------------------------
-- File           : tb.vhd
-- Author(s)      : Nikola Avramovic
-- Created        : January 22nd, 2018
---------------------------------------------------------------------------
-- Description    :  Test Bench for Protocol Aware HW tester 
---------------------------------------------------------------------------

library ieee, sim, hw_tester;
   use ieee.std_logic_1164.ALL;
   use ieee.numeric_std.all;
   -- Avalon memory map packages
   use sim.p_avalon_mem_master_bfm.all;
   -- Hardwer tester
   use hw_tester.p_interfaces.all;
   use hw_tester.p_addresses.all;


entity tb is
end tb;

architecture behavioral of tb is
   
   -- Test Unit ------------------------------------------
   component test_ent is
   port (
      tb_stop            : out boolean;
      clk                : in std_logic;
      reset_n            : out std_logic;
      size               : out natural;
      dio_out_avst_ready : out std_logic
   );       
   end component; 
   -------------------------------------------------------------------------
   -- CONSTANTS
   -------------------------------------------------------------------------
   constant C_CLK_PERIOD      : time    := 20 ns;

   constant CONST_ADDR_WIDTH  : natural := 5;
   constant CONST_DATA_WIDTH  : natural := 8;
   constant C_BURSTCOUNT_WIDTH: natural := 5;

   -------------------------------------------------------------------------
   -- Auxiliary signals
   -------------------------------------------------------------------------
   -- Testbench control
   signal tb_stop             : boolean;
   signal rst                 : std_logic; 
   signal clk                 : std_logic;
   signal reset               : std_logic;
   signal reset_n             : std_logic;
   signal pckt_size           : natural := 8;
   signal dio_out_avst_ready  : std_logic;

   ------------------------------------------------------------
   -- DUT signals
   ------------------------------------------------------------
   -- to/from Avalon Memory Map BFM
   signal avalon_mm_to_hw_tester : TYPE_AVALON_MM_MASTER_TO_SLAVE_ARRAY(1 downto 0);
   signal hw_tester_to_avalon_mm : TYPE_AVALON_MM_SLAVE_TO_MASTER_ARRAY(1 downto 0);
   -- to/from generator(s)
   signal generator_to_avalon_st : TYPE_AVALON_ST_SOURCE_TO_SINK_ARRAY(0 downto 0); 
   signal avalon_st_to_generator : TYPE_AVALON_ST_SINK_TO_SOURCE_ARRAY(0 downto 0);
   -- to/from monitor(s)
   signal monitor_to_avalon_st   : TYPE_AVALON_ST_SINK_TO_SOURCE_ARRAY(0 downto 0);  
   signal avalon_st_to_monitor   : TYPE_AVALON_ST_SOURCE_TO_SINK_ARRAY(0 downto 0);

begin
 
   ---------------------------------------------------------------------------
   --  Test Controller
   ---------------------------------------------------------------------------
   test_ent_u : test_ent
   port map (
      tb_stop            => tb_stop, 
      clk                => clk,
      reset_n            => reset_n,
      size               => pckt_size,
      dio_out_avst_ready => dio_out_avst_ready
   );
     
  -----------------------------------------------------------------------------
  -- Clock process
  -----------------------------------------------------------------------------  
   p_clk: process
   begin
      if reset = '0' then
         clk <= '0', '1' after C_CLK_PERIOD / 2;
         wait for C_CLK_PERIOD;
      else
         clk <= '0';
         wait for C_CLK_PERIOD;
      end if;

      if tb_stop then
        wait;
      end if;
   end process;

   -----------------------------------------------------------------------------
   -- Reset process
   -----------------------------------------------------------------------------  
   -- Toggle the reset after 5 clock periods
   reset   <= '1', '0' after 5 *C_CLK_PERIOD;
   reset_n <= not reset;

   -------------------------------------------------------------------------
   -- DUT Protocol Aware  hardwer tester
   -------------------------------------------------------------------------
   pa_hw_dut_i: entity hw_tester.ea_top_pa_hw_tester
   port map( 
      clk                 => clk,
      reset               => reset,
      -- to/from NIOS II processor
      masteri             => avalon_mm_to_hw_tester,
      mastero             => hw_tester_to_avalon_mm,
      -- to/from generatior
      generatori          => avalon_st_to_generator,
      generatoro          => generator_to_avalon_st,
      -- to/from monitor
      monitori            => avalon_st_to_monitor,
      monitoro            => monitor_to_avalon_st
   );

   -- loopback is used for testing
   avalon_st_to_monitor   <= generator_to_avalon_st;
   avalon_st_to_generator <= monitor_to_avalon_st;

   --------------------------------------------------------------------
   -- Modules belowe will be used for testing of PA_ATE hardwer tester
   --------------------------------------------------------------------
   avalon_mm_master_gen_i: entity sim.avalon_mem_master_bfm
   generic map(
      G_INST_NAME         => "avalon_mm_master_gen_0",
      G_HANDLE_NO         => 0,
      G_ADDR_WIDTH        => CONST_ADDR_WIDTH,
      G_DATA_WIDTH        => CONST_DATA_WIDTH,
      G_BURSTCOUNT_WIDTH  => C_BURSTCOUNT_WIDTH
   ) port map(
      clk                 => clk,
      tb_stop             => tb_stop,
      -- Avalon MM master interface (connect to slave)
      -- address signal
      address             => avalon_mm_to_hw_tester(0).address,
      -- write master
      write               => avalon_mm_to_hw_tester(0).write,
      writedata           => avalon_mm_to_hw_tester(0).writedata,
      -- read master
      read                => avalon_mm_to_hw_tester(0).read,
      readdatavalid       => hw_tester_to_avalon_mm(0).readdatavalid,
      readdata            => hw_tester_to_avalon_mm(0).readdata,
      -- burst signals
      burstcount          => avalon_mm_to_hw_tester(0).burstcount,
      beginbursttransfer  => avalon_mm_to_hw_tester(0).beginbursttransfer,
      -- handshake signals
      byteenable          => avalon_mm_to_hw_tester(0).byteenable,
      waitrequest         => hw_tester_to_avalon_mm(0).waitrequest
   );

   --------------------------------------------------------------------
   -- Modules belowe will be used for testing of PA_ATE hardwer tester
   --------------------------------------------------------------------
   avalon_mm_master_mon_i: entity sim.avalon_mem_master_bfm
   generic map(
      G_INST_NAME         => "avalon_mm_master_mon_1",
      G_HANDLE_NO         => 1,
      G_ADDR_WIDTH        => CONST_ADDR_WIDTH,
      G_DATA_WIDTH        => CONST_DATA_WIDTH,
      G_BURSTCOUNT_WIDTH  => C_BURSTCOUNT_WIDTH
   ) port map(
      clk                 => clk,
      tb_stop             => tb_stop,
      -- Avalon MM master interface (connect to slave)
      -- address signal
      address             => avalon_mm_to_hw_tester(1).address,
      -- write master
      write               => avalon_mm_to_hw_tester(1).write,
      writedata           => avalon_mm_to_hw_tester(1).writedata,
      -- read master
      read                => avalon_mm_to_hw_tester(1).read,
      readdatavalid       => hw_tester_to_avalon_mm(1).readdatavalid,
      readdata            => hw_tester_to_avalon_mm(1).readdata,
      -- burst signals
      burstcount          => avalon_mm_to_hw_tester(1).burstcount,
      beginbursttransfer  => avalon_mm_to_hw_tester(1).beginbursttransfer,
      -- handshake signals
      byteenable          => avalon_mm_to_hw_tester(1).byteenable,
      waitrequest         => hw_tester_to_avalon_mm(1).waitrequest
   );


end behavioral;
