---------------------------------------------------------------------------
-- File           : ea_avalon_mm_interface_mon.vhd
-- Author(s)      : Nikola Avramovic
-- Created        : March 11th, 2019
---------------------------------------------------------------------------
-- Description    : Input output control top moduel
---------------------------------------------------------------------------

---------------------------------------------------------------------------
library ieee, work;
   use ieee.std_logic_1164.all;
   use work.p_interfaces.all;
   use work.p_addresses.all;
   use work.p_monitor_interface.all;

entity ea_avalon_mm_interface_mon is
   generic(
      G_NO_OF_PATT_MON    : natural  := 2;
      G_PORT_MON_NO       : natural  := 1
      );
   port  (
      clk               : in  std_logic;
      reset             : in  std_logic;
      -- to/from NIOS II processor
      masteri           : in  TYPE_AVALON_MM_MASTER_TO_SLAVE;
      mastero           : out TYPE_AVALON_MM_SLAVE_TO_MASTER;
      -- to/from pattern monitor
      pattern_moni      : in  TYPE_PATTERN_MON_TO_CMD_DECODER_ARRAY(G_NO_OF_PATT_MON downto 1);
      pattern_mono      : out TYPE_CMD_DECODER_TO_PATTERN_MON_ARRAY(G_NO_OF_PATT_MON downto 1);
      -- to/from port monitor
      port_moni         : in  TYPE_PORT_MON_TO_CMD_DECODER;
      port_mono         : out TYPE_CMD_DECODER_TO_PORT_MON;
      -- to status object
      pattern_statusi   : in  TYPE_PATTERN_MON_TO_STATUS_ARRAY(G_NO_OF_PATT_MON downto 1);
      --pattern_statuso   : out TYPE_STATUS_TO_PATTERN_MON_ARRAY(G_NO_OF_PATT_MON downto 1);

      port_statusi      : in  TYPE_PORT_MON_TO_STATUS;
      port_statuso      : out TYPE_STATUS_TO_PORT_MON
   );
end entity ea_avalon_mm_interface_mon;

architecture rtl of ea_avalon_mm_interface_mon is

   -- wait request is signal from two modules 
   signal waitrequest                  : std_logic;

   -- avalon mm write
   signal master_to_fifo_cmd           : TYPE_MASTER_TO_FIFO_CMD;
   signal fifo_cmd_to_master           : TYPE_FIFO_CMD_TO_MASTER;
   -- in/out to command decoder
   signal cmd_decoder_to_fifo_cmd      : TYPE_CMD_DEC_TO_FIFO_CMD;
   signal fifo_cmd_to_cmd_decoder      : TYPE_FIFO_CMD_TO_CMD_DEC;

   -- status signals
   signal master_to_status             : TYPE_MASTER_TO_STATUS;
   signal status_to_master             : TYPE_STATUS_TO_MASTER;
   
begin

   fifo_cmd_i: entity work.ea_cmd_fifo_mon
   port map (
      clk               => clk,
      reset             => reset,
      -- to/from input monitor
      masteri           => master_to_fifo_cmd,
      mastero           => fifo_cmd_to_master,
      -- to/from command decoder
      cmd_decoderi      => cmd_decoder_to_fifo_cmd,
      cmd_decodero      => fifo_cmd_to_cmd_decoder
   );

   cmd_decoder_i: entity work.ea_cmd_mon_decoder
   port map (
      clk               => clk,
      reset             => reset,
      -- to/from FIFO command
      fifo_cmdi         => fifo_cmd_to_cmd_decoder,
      fifo_cmdo         => cmd_decoder_to_fifo_cmd,
      -- to/from pattern monitor
      pattern_moni      => pattern_moni,
      pattern_mono      => pattern_mono,
      -- to/from port monitor
      port_moni         => port_moni,
      port_mono         => port_mono
   );

   status_obj_i: entity work.ea_status_object_mon
   generic map (
      G_NO_OF_PATT_MON  => G_NO_OF_PATT_MON,
      G_PORT_MON_NO     => G_PORT_MON_NO
   )
   port map (
      clk               => clk,
      reset             => reset,
      -- to/from input
      masteri           => master_to_status,
      mastero           => status_to_master,
      -- to/from pattern monitor
      pattern_moni      => pattern_statusi,
      --pattern_mono      => pattern_statuso,
      -- to/from port monitor
      port_moni         => port_statusi,
      port_mono         => port_statuso
   );

   master_to_status   <= (address      => masteri.address,
                          read_req     => masteri.read,
                          read_count   => masteri.burstcount,  
                          start_reading=> masteri.beginbursttransfer);

   waitrequest        <= fifo_cmd_to_master.fifo_full when (masteri.write = '1') else status_to_master.wait_req;

   master_to_fifo_cmd <= (address       => masteri.address,
                          write_req     => masteri.write,
                          data_in       => masteri.writedata,
                          new_package   => masteri.beginbursttransfer,
                          write_count   => masteri.burstcount);

   mastero            <= (readdatavalid => status_to_master.data_valid,
                          readdata      => status_to_master.read_data,
                          waitrequest   => waitrequest);

end architecture rtl;