<<< :sectnums: == Installing an Executable Directly Into Memory If you do not want to use the bootloader (or the on-chip debugger) for executable upload or if your setup does not provide a serial interface for that, you can also directly install an application into embedded memory. This concept uses the "Direct Boot" scenario that implements the processor-internal IMEM as ROM, which is pre-initialized with the application's executable during synthesis. Hence, it provides _non-volatile_ storage of the executable inside the processor. This storage cannot be altered during runtime and any source code modification of the application requires to re-program the FPGA via the bitstream. [TIP] See datasheet section https://stnolting.github.io/neorv32/#_direct_boot[Direct Boot] for more information. Using the IMEM as ROM: * for this boot concept the bootloader is no longer required * this concept only works for the internal IMEM (but can be extended to work with external memories coupled via the processor's bus interface) * make sure that the memory components (like block RAM) the IMEM is mapped to support an initialization via the bitstream [start=1] . At first, make sure your processor setup actually implements the internal IMEM: the `MEM_INT_IMEM_EN` generics has to be set to `true`: .Processor top entity configuration - enable internal IMEM [source,vhdl] ---- -- Internal Instruction memory -- MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory ---- [start=2] . For this setup we do not want the bootloader to be implemented at all. Disable implementation of the bootloader by setting the `INT_BOOTLOADER_EN` generic to `false`. This will also modify the processor-internal IMEM so it is initialized with the executable during synthesis. .Processor top entity configuration - disable internal bootloader [source,vhdl] ---- -- General -- INT_BOOTLOADER_EN => false, -- boot configuration: false = boot from int/ext (I)MEM ---- [start=3] . To generate an "initialization image" for the IMEM that contains the actual application, run the `install` target when compiling your application: [source,bash] ---- neorv32/sw/example/demo_blink_led$ make clean_all install Memory utilization: text data bss dec hex filename 1004 0 0 1004 3ec main.elf Compiling ../../../sw/image_gen/image_gen Executable (neorv32_exe.bin) size in bytes: 1016 Installing application image to ../../../rtl/core/neorv32_application_image.vhd ---- [start=4] . The `install` target has compiled all the application sources but instead of creating an executable (`neorv32_exe.bit`) that can be uploaded via the bootloader, it has created a VHDL memory initialization image `core/neorv32_application_image.vhd`. . This VHDL file is automatically copied to the core's rtl folder (`rtl/core`) so it will be included for the next synthesis. . Perform a new synthesis. The IMEM will be build as pre-initialized ROM (inferring embedded memories if possible). . Upload your bitstream. Your application code now resides unchangeable in the processor's IMEM and is directly executed after reset. The synthesis tool / simulator will print asserts to inform about the (IMEM) memory / boot configuration: [source] ---- NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM). NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (1016 bytes), pre-initialized with application. ----