library ieee;
use ieee.std_logic_1164.all;

entity tb_diot_hydra2 is
end tb_diot_hydra2;

library ieee;
use ieee.numeric_std.all;
use work.mem_utils.all;

architecture behav of tb_diot_hydra2 is
  signal clk_40m_i       : std_logic;
  signal devrst_n        : std_logic;
  signal dati           : std_logic_vector(7 downto 0);
  signal dato           : std_logic_vector(7 downto 0);
  signal adr           : std_logic_vector(9 downto 0);
  signal stb           : std_logic;
  signal wclk          : std_logic;
  signal we            : std_logic;
  signal cyc           : std_logic;
  signal ack           : std_logic;
  signal rst_o           : std_logic;
  signal rstin_o         : std_logic;
  signal nostat_o        : std_logic;
  signal u_errflag_i     : std_logic;
  signal var3_acc_o      : std_logic;
  signal var3_rdy_i      : std_logic;
  signal var2_acc_o      : std_logic;
  signal var2_rdy_i      : std_logic;
  signal var1_acc_o      : std_logic;
  signal var1_rdy_i      : std_logic;
  signal p3_lgth_o       : std_logic_vector(2 downto 0);
  signal monimod_scl_b   : std_logic;
  signal monimod_sda_b   : std_logic;
  signal backplane_scl_b : std_logic;
  signal backplane_sda_b : std_logic;
  signal psu_scl_b       : std_logic;
  signal psu_sda_b       : std_logic;
  signal pcbver_scl_b    : std_logic;
  signal pcbver_sda_b    : std_logic;
  signal mon_gpio_pres_i : std_logic_vector(1 downto 0);
  signal pwr_cyc_req_o   : std_logic_vector(1 downto 0);
  signal flash_ss_n    : std_logic;
  signal flash_sclk    : std_logic;
  signal flash_mosi    : std_logic;
  signal flash_miso    : std_logic;
  signal servmod_b       : std_logic_vector(8 downto 1);
  signal servmod_dir_o   : std_logic;
  signal s1_p_i          : std_logic_vector(15 downto 0);
  signal s1_n_o          : std_logic_vector(15 downto 0);
  signal s2_p_i          : std_logic_vector(15 downto 0);
  signal s2_n_o          : std_logic_vector(15 downto 0);
  signal s3_p_i          : std_logic_vector(15 downto 0);
  signal s3_n_o          : std_logic_vector(15 downto 0);
  signal s4_p_i          : std_logic_vector(15 downto 0);
  signal s4_n_o          : std_logic_vector(15 downto 0);
  signal s5_p_i          : std_logic_vector(15 downto 0);
  signal s5_n_o          : std_logic_vector(15 downto 0);
  signal s6_p_i          : std_logic_vector(15 downto 0);
  signal s6_n_o          : std_logic_vector(15 downto 0);
  signal s7_p_i          : std_logic_vector(15 downto 0);
  signal s7_n_o          : std_logic_vector(15 downto 0);
  signal s8_p_i          : std_logic_vector(15 downto 0);
  signal s8_n_o          : std_logic_vector(15 downto 0);
  signal leds_o          : std_logic_vector(4 downto 1);

  signal addr : natural;
begin
  process
  begin
    clk_40m_i <= '0';
    wait for 12_500 ps;
    clk_40m_i <= '1';
    wait for 12_500 ps;
  end process;

  devrst_n <= '0', '1' after 100 ns;

  inst_diot_hydra: entity work.diot_hydra2_top
    generic map (
      g_MGMT_IRAM_LOG_SIZE => 10,
      g_MGMT_DRAM_LOG_SIZE => 10
    )
    port map (
      clk_40m_i       => clk_40m_i,
      devrst_n        => devrst_n,
      dat_i           => dati,
      dat_o           => dato,
      adr_o           => adr,
      stb_o           => stb,
      wclk_o          => wclk,
      we_o            => we,
      cyc_o           => cyc,
      ack_i           => ack,
      rst_o           => rst_o,
      rstin_o         => rstin_o,
      nostat_o        => nostat_o,
      u_errflag_i     => u_errflag_i,
      var3_acc_o      => var3_acc_o,
      var3_rdy_i      => var3_rdy_i,
      var2_acc_o      => var2_acc_o,
      var2_rdy_i      => var2_rdy_i,
      var1_acc_o      => var1_acc_o,
      var1_rdy_i      => var1_rdy_i,
      p3_lgth_o       => p3_lgth_o,
      monimod_scl_b   => monimod_scl_b,
      monimod_sda_b   => monimod_sda_b,
      backplane_scl_b => backplane_scl_b,
      backplane_sda_b => backplane_sda_b,
      psu_scl_b       => psu_scl_b,
      psu_sda_b       => psu_sda_b,
      pcbver_scl_b    => pcbver_scl_b,
      pcbver_sda_b    => pcbver_sda_b,
      mon_gpio_pres_i => mon_gpio_pres_i,
      pwr_cyc_req_o   => pwr_cyc_req_o,
      fan_rstn_o      => open,
      fan_io0_o       => open,
      fan_io1_o       => open,
      flash_ss_n_o    => flash_ss_n,
      flash_sclk_o    => flash_sclk,
      flash_mosi_o    => flash_mosi,
      flash_miso_i    => flash_miso,
      servmod_b       => servmod_b,
      servmod_dir_o   => servmod_dir_o,
      monimod_shdn_o  => open,
      s1_p_i          => s1_p_i,
      s1_n_o          => s1_n_o,
      s2_p_i          => s2_p_i,
      s2_n_o          => s2_n_o,
      s3_p_i          => s3_p_i,
      s3_n_o          => s3_n_o,
      s4_p_i          => s4_p_i,
      s4_n_o          => s4_n_o,
      s5_p_i          => s5_p_i,
      s5_n_o          => s5_n_o,
      s6_p_i          => s6_p_i,
      s6_n_o          => s6_n_o,
      s7_p_i          => s7_p_i,
      s7_n_o          => s7_n_o,
      s8_p_i          => s8_p_i,
      s8_n_o          => s8_n_o,
      leds_o          => leds_o);

  inst_flash: entity work.spi_flash
    port map (
      spi_clk_i => flash_sclk,
      spi_csn_i => flash_ss_n,
      spi_mosi_i => flash_mosi,
      spi_miso_o => flash_miso
    );

  process (wclk)
    variable mem: mem_t (255 downto 0) := (others => (others => '0'));
    variable bsel : natural range 0 to 3;
    variable init : boolean := false;
    variable done : boolean;
  begin
    if not init then
      read_mem(mem, "plc.mem");
      init := true;
      addr <= 0;
    end if;

    if rising_edge(wclk) then
      ack <= '0';
      if cyc = '1' and stb = '1' then
        if not done then
          if we = '0' then
            dati <= mem (addr)(bsel * 8 + 7 downto bsel * 8);
            if bsel = 3 then
              bsel := 0;
              if addr = mem'high then
                addr <= 0;
              else
                addr <= addr + 1;
              end if;
            else
              bsel := bsel + 1;
            end if;
          else
            report "Write to FIP: " & character'val(to_integer (unsigned(dato)));
          end if;
          ack <= '1';
          done := True;
        end if;
      else
        done := False;
      end if;
    end if;
  end process;
end behav;
