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

use work.mem_utils.all;

entity diot_hydra2_periph is
  port(
    -- Inputs
    clk_i                               : in  std_logic;
    DEVRST_N                            : in  std_logic;
    POWER_ON_RESET_N                    : out std_logic;

    HPMS_FIC_0_USER_MASTER_HADDR_M0 : in  std_logic_vector(31 downto 0);
    HPMS_FIC_0_USER_MASTER_HBURST_M0 : in  std_logic_vector(2 downto 0);
    HPMS_FIC_0_USER_MASTER_HMASTLOCK_M0 : in  std_logic;
--    HPMS_FIC_0_USER_MASTER_HSEL_M0      : in  std_logic;
    HPMS_FIC_0_USER_MASTER_HSIZE_M0     : in  std_logic_vector(2 downto 0);
    HPMS_FIC_0_USER_MASTER_HTRANS_M0   : in  std_logic_vector(1 downto 0);
    HPMS_FIC_0_USER_MASTER_HPROT_M0 : in  std_logic_vector(3 downto 0);
    HPMS_FIC_0_USER_MASTER_HWDATA_M0    : in  std_logic_vector(31 downto 0);
    HPMS_FIC_0_USER_MASTER_HWRITE_M0    : in  std_logic;

    HPMS_FIC_0_USER_MASTER_HRDATA_M0    : out std_logic_vector(31 downto 0);
    HPMS_FIC_0_USER_MASTER_HREADY_M0    : out  std_logic;
--  HPMS_FIC_0_USER_MASTER_HREADYOUT_M0 : out std_logic;
    HPMS_FIC_0_USER_MASTER_HRESP_M0     : out std_logic_vector(1 downto 0);

    clk_sys_o : out std_logic;
    clk_cpu1_o : out std_logic;
    clk_cpu2_o : out std_logic;
    clk_cpu3_o : out std_logic
    );
end diot_hydra2_periph;

architecture arch of diot_hydra2_periph is
begin
  process
    variable mem: mem_t (4095 downto 0) := (others => (others => '0'));
  begin
    read_mem (mem, "fip_urv.mem");
    loop
      wait until rising_edge(clk_i);
      if HPMS_FIC_0_USER_MASTER_HTRANS_M0 = "10" then
        assert HPMS_FIC_0_USER_MASTER_HSIZE_M0 = "010";
        if HPMS_FIC_0_USER_MASTER_HADDR_M0(31 downto 16) = x"6000" then
          -- eNVM
          assert HPMS_FIC_0_USER_MASTER_HWRITE_M0 = '0';
          HPMS_FIC_0_USER_MASTER_HREADY_M0 <= '1';
          HPMS_FIC_0_USER_MASTER_HRDATA_M0 <= mem (to_integer (unsigned (HPMS_FIC_0_USER_MASTER_HADDR_M0(13 downto 2))));
        elsif HPMS_FIC_0_USER_MASTER_HADDR_M0 = x"6008_0120" then
          -- Ready
          assert HPMS_FIC_0_USER_MASTER_HWRITE_M0 = '0';
          HPMS_FIC_0_USER_MASTER_HREADY_M0 <= '1';
          HPMS_FIC_0_USER_MASTER_HRDATA_M0 <= x"0000_0001";
        elsif HPMS_FIC_0_USER_MASTER_HADDR_M0(31 downto 16) = x"4000" then
          --  UART
          if HPMS_FIC_0_USER_MASTER_HADDR_M0(15 downto 0) = x"0014" then
            --  LSR: tx is always empty, no rx
            HPMS_FIC_0_USER_MASTER_HRDATA_M0 <= x"000000" & b"0110_0000";
          elsif HPMS_FIC_0_USER_MASTER_HADDR_M0(15 downto 0) = x"0000" then
            --  THR.
            --  FIXME: keep LCR bit to unalias with DLR
            if HPMS_FIC_0_USER_MASTER_HWRITE_M0 = '1' then
              report "uart tx: " & character'val(to_integer(unsigned (HPMS_FIC_0_USER_MASTER_HWDATA_M0(7 downto 0))));
            end if;
          end if;
        end if;
      end if;
    end loop;
  end process;

  clk_sys_o <= clk_i;
  clk_cpu1_o <= clk_i;
  clk_cpu2_o <= clk_i;
  clk_cpu3_o <= clk_i;

  POWER_ON_RESET_N <= DEVRST_N;
end arch;
