<<<
:sectnums:
==== Instruction Memory (IMEM)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_imem.entity.vhd      | entity-only definition
|                          | mem/neorv32_imem.default.vhd | default _platform-agnostic_ memory architecture
|                          | mem/neorv32_imem.legacy.vhd  | alternative legacy-style memory architecture
| Software driver file(s): | none                         | _implicitly used_
| Top entity port:         | none                         | 
| Configuration generics:  | `MEM_INT_IMEM_EN`            | implement processor-internal IMEM when `true`
|                          | `MEM_INT_IMEM_SIZE`          | IMEM size in bytes (use a power of 2)
|                          | `INT_BOOTLOADER_EN`          | use internal bootloader when `true` (implements IMEM as _uninitialized_ RAM, otherwise the IMEM is implemented an _pre-intialized_ ROM)
| CPU interrupts:          | none                         | 
|=======================

Implementation of the processor-internal instruction memory is enabled by the processor's
`MEM_INT_IMEM_EN` generic. The total memory size in bytes is defined via the `MEM_INT_IMEM_SIZE` generic.
Note that this size should be a power of two to optimize physical implementation. If the IMEM is implemented,
it is mapped to base address `0x00000000` by default (see section <<_address_space>>).

By default the IMEM is implemented as true RAM so the content can be modified during run time. This is
required when using the bootloader (or the on-chip debugger) so it can update the content of the IMEM at
any time. If this feature is not required the IMEM can be implemented as _pre-intialized_ ROM so that the
application code permanently resides in memory. This is automatically implemented when the
processor-internal bootloader is disabled (`INT_BOOTLOADER_EN` = `false`).

When the IMEM is implemented as ROM, it will be initialized during synthesis with the actual application program
image. The compiler toolchain provides an option to generate and override the default VHDL initialization file
`rtl/core/neorv32_application_image.vhd`, which is automatically inserted into the IMEM. If the IMEM is implemented
as RAM (default), the memory block will **not be initialized at all**.

.Memory Size
[IMPORTANT]
If the configured memory size (via the `MEM_INT_IMEM_SIZE` generic) is **not** a power of two the actual memory
size will be auto-adjusted to the next power of two (e.g. configuring a memory size of 60kB will result in a
physical memory size of 64kB).

.VHDL Source File
[NOTE]
The actual IMEM is split into two design files: a plain entity definition (`neorv32_imem.entity.vhd`) and the actual
architecture definition `mem/neorv32_imem.default.vhd`. This **default architecture** provides a _generic_ and
_platform independent_ memory design that infers embedded memory blocks (blockRAM). The default architecture can
be replaced by platform-specific modules in order to use platform-specific features or to improve technology mapping
and/or timing. A "legacy-style" memory architecture is provided in `rtl/mem` that can be used if the synthesis does
not correctly infer blockRAMs.

.Read-Only Access
[NOTE]
If the IMEM is implemented as true ROM any write attempt to it will raise a _store access fault_ exception.
