-- ================================================================================ --
-- NEORV32 SoC - Processor-Internal Bootloader ROM (BOOTROM)                        --
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32              --
-- Copyright (c) NEORV32 contributors.                                              --
-- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved.                  --
-- Licensed under the BSD-3-Clause license, see LICENSE for details.                --
-- SPDX-License-Identifier: BSD-3-Clause                                            --
-- ================================================================================ --

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

library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_bootloader_image.all; -- (re-)generated by the image generator

entity neorv32_boot_rom is
  port (
    clk_i     : in  std_ulogic; -- global clock line
    rstn_i    : in  std_ulogic; -- async reset, low-active
    bus_req_i : in  bus_req_t;  -- bus request
    bus_rsp_o : out bus_rsp_t   -- bus response
  );
end neorv32_boot_rom;

architecture neorv32_boot_rom_rtl of neorv32_boot_rom is

  -- auto-configuration --
  constant awidth_c : natural := index_size_f(bootloader_image_size_c/4); -- word address width

  -- local signals --
  signal rden  : std_ulogic;
  signal rdata : std_ulogic_vector(31 downto 0);

begin

  -- ROM Access -----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  rom_access: process(clk_i)
  begin
    if rising_edge(clk_i) then
      if (bus_req_i.stb = '1') then
        rdata <= bootloader_image_data_c(to_integer(unsigned(bus_req_i.addr(awidth_c+1 downto 2))));
      end if;
    end if;
  end process rom_access;

  -- size notifier --
  assert false report
    "[NEORV32] Implementing boot ROM (" & natural'image(4*(2**awidth_c)) & " bytes)." severity note;

  -- size check --
  assert (bootloader_image_size_c <= iodev_size_c) report
    "[NEORV32] Bootloader image (" & natural'image(bootloader_image_size_c) & " bytes) " &
    "overflows processor-internal BOOTROM (" & natural'image(iodev_size_c) & " bytes)!" severity error;


  -- Bus Handshake --------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  bus_handshake: process(rstn_i, clk_i)
  begin
    if (rstn_i = '0') then
      rden <= '0';
    elsif rising_edge(clk_i) then
      rden <= bus_req_i.stb and (not bus_req_i.rw); -- read-only
    end if;
  end process bus_handshake;

  -- output gate --
  bus_rsp_o.data <= rdata when (rden = '1') else (others => '0');
  bus_rsp_o.ack  <= rden;
  bus_rsp_o.err  <= '0';

end neorv32_boot_rom_rtl;
