From 81aab2efc27dfe307234337c2879fbf21d1a6ded Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:41:34 +0200 Subject: [PATCH 1/7] :warning: [common] update linker script Rework section base & size configuration. --- sw/common/neorv32.ld | 75 +++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/sw/common/neorv32.ld b/sw/common/neorv32.ld index 4e4d01505..e906b129d 100644 --- a/sw/common/neorv32.ld +++ b/sw/common/neorv32.ld @@ -32,53 +32,58 @@ /* # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # */ /* ################################################################################################# */ -/* Default linker script, for normal executables */ -/* Copyright (C) 2014-2020 Free Software Foundation, Inc. - Copying and distribution of this script, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. */ - -/* modified for the NEORV32 processor by Stephan Nolting */ +/* Default linker script, for normal executables . + * Copyright (C) 2014-2020 Free Software Foundation, Inc. + * Copying and distribution of this script, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. + * Modified for the NEORV32 processor by Stephan Nolting. */ OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") OUTPUT_ARCH(riscv) ENTRY(_start) -SEARCH_DIR("/opt/riscv/riscv32-unknown-elf/lib"); SEARCH_DIR("=/opt/riscv/riscv64-unknown-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); - -/* ******************************************************************************************** - * NEORV32 memory section configuration. - * ******************************************************************************************** - * "ram" : data memory (int/ext DMEM) - make sure this is sync with the HW! - * "rom" : instruction memory (int/ext IMEM or bootloader ROM) - * "iodev" : peripheral/IO devices - * NOTE: All sections defined in this script start and end on a 32-bit (word) aligned boundary. - * ******************************************************************************************** */ -MEMORY -{ +SEARCH_DIR("/opt/riscv/riscv32-unknown-elf/lib") +SEARCH_DIR("=/opt/riscv/riscv64-unknown-linux-gnu/lib") +SEARCH_DIR("=/usr/local/lib") +SEARCH_DIR("=/lib") +SEARCH_DIR("=/usr/lib") - /* section base addresses and sizes have to be a multiple of 4 bytes - * ram section: first value of LENGTH => data memory used by bootloader (fixed!); second value of LENGTH => *physical* size of data memory - * adapt the right-most value to match the *total physical data memory size* of your setup */ - ram (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024 +/* ************************************************************************************************* */ +/* +++ NEORV32 memory configuration +++ */ +/* If the symbols are not explicitly defined the default configurations are used. If required, only */ +/* the edit the very last entry in each row. */ +/* NOTE: section sizes have to be a multiple of 4 bytes; base addresses have to be 32-bit-aligned. */ +/* ************************************************************************************************* */ - /* rom and iodev sections should NOT be modified by the user at all! - * rom section: first value of ORIGIN/LENGTH => bootloader ROM; second value of ORIGIN/LENGTH => maximum *logical* size of instruction memory */ +/* Default rom/ram (IMEM/DMEM) sizes */ +__neorv32_rom_size = DEFINED(__neorv32_rom_size) ? __neorv32_rom_size : 2048M; +__neorv32_ram_size = DEFINED(__neorv32_ram_size) ? __neorv32_ram_size : 8K; - rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 32K : 2048M - iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512 /* this is hardware-defined and must not be altered! */ +/* Default HEAP size (= 0; no heap at all) */ +__neorv32_heap_size = DEFINED(__neorv32_heap_size) ? __neorv32_heap_size : 0; -} -/* ************************************************************************* */ +/* Default section base addresses - do not change this unless the hardware-defined address space layout is changed! */ +__neorv32_rom_base = DEFINED(__neorv32_rom_base) ? __neorv32_rom_base : 0x00000000; /* = VHDL package's "ispace_base_c" */ +__neorv32_ram_base = DEFINED(__neorv32_ram_base) ? __neorv32_ram_base : 0x80000000; /* = VHDL package's "dspace_base_c" */ -SECTIONS + +/* ************************************************************************************************* */ +/* If compiling the bootloader, the rom section is automatically re-mapped to the processor-internal */ +/* bootloader ROM address space. */ +/* ************************************************************************************************* */ +MEMORY { + rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : __neorv32_rom_base, LENGTH = DEFINED(make_bootloader) ? 32K : __neorv32_rom_size + ram (rwx) : ORIGIN = __neorv32_ram_base, LENGTH = DEFINED(make_bootloader) ? 512 : __neorv32_ram_size + iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512 /* this is hardware-defined and should not be modified! */ +} - /* set heap size (for dynamic memory allocation) only if explicitly defined - * WARNING! the heap will collide with the stack if allocating too much memory! */ - __heap_size = DEFINED(__heap_size) ? __heap_size : 0; +/* ************************************************************************************************* */ +SECTIONS +{ /* First part of the actual executable file: actual instructions */ .text : ALIGN(4) @@ -211,7 +216,7 @@ SECTIONS .heap : ALIGN(4) { PROVIDE(__heap_start = .); - . = __heap_size; + . = __neorv32_heap_size; /* finish section on WORD boundary */ . = ALIGN(4); PROVIDE(__heap_end = .); @@ -292,7 +297,7 @@ SECTIONS /* Export symbols for neorv32 crt0 start-up code */ - PROVIDE(__crt0_max_heap = __heap_size); + PROVIDE(__crt0_max_heap = __neorv32_heap_size); PROVIDE(__crt0_imem_begin = ORIGIN(rom)); PROVIDE(__crt0_dmem_begin = ORIGIN(ram)); PROVIDE(__crt0_stack_begin = (ORIGIN(ram) + LENGTH(ram)) - 4); From 4a8755f7a2339639cc94dbe017f3878ec924160c Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:48:05 +0200 Subject: [PATCH 2/7] [docs] update section "Executable Image Format" --- docs/datasheet/software.adoc | 149 ++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/docs/datasheet/software.adoc b/docs/datasheet/software.adoc index ba5b89241..a203068ee 100644 --- a/docs/datasheet/software.adoc +++ b/docs/datasheet/software.adoc @@ -32,7 +32,7 @@ files and folders is shown below: .Software Documentation [TIP] -All core libraries and example programs are highly documented using **Doxygen**. +All core libraries and example programs are documented "in-code" using **Doxygen**. The documentation is automatically built and deployed to GitHub pages and is available online at https://stnolting.github.io/neorv32/sw/files.html. @@ -54,11 +54,9 @@ Make sure the toolchain / toolchain build is configured accordingly. * `MARCH=rv32i` * `MABI=ilp32` +* `RISCV_PREFIX=riscv32-unknown-elf-` -Alternatively, you can download my prebuilt `rv32i/e` toolchains for 64-bit x86 Linux from: https://github.com/stnolting/riscv-gcc-prebuilt - -The default toolchain prefix used by the project's makefiles is **`riscv32-unknown-elf`**, which can be changes -using makefile flags at any time. +These default configurations can be override at any times using <<_application_makefile>> variables. [TIP] More information regarding the toolchain (building from scratch or downloading the prebuilt ones) @@ -70,13 +68,13 @@ can be found in the user guides' section https://stnolting.github.io/neorv32/ug/ :sectnums: === Core Libraries -The NEORV32 project provides a set of C libraries that allows an easy usage of the processor/CPU features +The NEORV32 project provides a set of pre-defined C libraries that allow an easy integration of the processor/CPU features (also called "HAL" - hardware abstraction layer). All driver and runtime-related files are located in -`sw/lib`. These are automatically included and linked by adding the following _include statement_: +`sw/lib`. These are automatically included and linked by adding the following include statement: [source,c] ---- -#include // add NEORV32 HAL, core and runtime libraries +#include // NEORV32 HAL, core and runtime libraries ---- [cols="<3,<4,<8"] @@ -90,7 +88,7 @@ footnote:[This driver file only represents a stub, since the real CFS drivers ar | `neorv32_cpu_cfu.c` | `neorv32_cpu_cfu.h` | HW driver functions for the NEORV32 **CFU** (custom instructions) | `neorv32_gpio.c` | `neorv32_gpio.h` | HW driver functions for the **GPIO** | `neorv32_gptmr.c` | `neorv32_gptmr.h` | HW driver functions for the **GPTRM** -| - | `neorv32_intrinsics.h` | macros for custom intrinsics & instructions +| - | `neorv32_intrinsics.h` | macros for intrinsics & custom instructions | `neorv32_mtime.c` | `neorv32_mtime.h` | HW driver functions for the **MTIME** | `neorv32_neoled.c` | `neorv32_neoled.h` | HW driver functions for the **NEOLED** | `neorv32_pwm.c` | `neorv32_pwm.h` | HW driver functions for the **PWM** @@ -103,7 +101,7 @@ footnote:[This driver file only represents a stub, since the real CFS drivers ar | `neorv32_wdt.c` | `neorv32_wdt.h` | HW driver functions for the **WDT** | `neorv32_xip.c` | `neorv32_xip.h` | HW driver functions for the **XIP** | `neorv32_xirq.c` | `neorv32_xirq.h` | HW driver functions for the **XIRQ** -| `syscalls.c` | - | newlib system calls +| `syscalls.c` | - | newlib "system calls" |======================= .Core Library Documentation @@ -121,15 +119,17 @@ A CMSIS-SVD-compatible **System View Description (SVD)** file including all peri :sectnums: === Application Makefile -Application compilation is based on a single, centralized **GNU makefiles** `sw/common/common.mk`. Each project in the -`sw/example` folder features a makefile that just includes this central makefile. When creating a new project copy an -existing project folder or at least the makefile to the new project folder. It is suggested to create new projects also -in `sw/example` to keep the file dependencies. However, these dependencies can be manually configured via makefiles -variables when the new project is located somewhere else. +Application compilation is based on a single, centralized **GNU makefile** (`sw/common/common.mk`). Each project in the +`sw/example` folder provides a makefile that just includes this central makefile. + +[TIP] +When creating a new project, copy an existing project folder or at least the makefile to the new project folder. +It is recommended to create new projects also in `sw/example` to keep the file dependencies. However, these +dependencies can be manually configured via makefile variables if the new project is located somewhere else. [NOTE] -Before the makefile can be used to compile applications, the RISC-V GCC toolchain needs to be installed. Furthermore, -the `bin` folder of the compiler needs to be added to the system's `PATH` variable. More information can be found in +Before the makefile can be used to compile applications, the RISC-V GCC toolchain needs to be installed and +the compiler's `bin` folder has to be added to the system's `PATH` variable. More information can be found in https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[User Guide: Software Toolchain Setup]. The makefile is invoked by simply executing `make` in the console. For example: @@ -241,7 +241,7 @@ default `sw/example` folder ==== Default Compiler Flags The following default compiler flags are used for compiling an application. These flags are defined via the -`CC_OPTS` variable. Custom flags can be _appended_ to it using the `USER_FLAGS` variable. +`CC_OPTS` variable. [cols="<3,<9"] [grid="none"] @@ -260,76 +260,95 @@ The following default compiler flags are used for compiling an application. Thes | `-falign-jumps=4` |======================= +:sectnums: +==== Custom (Compiler) Flags + +Custom flags can be _appended_ to the `USER_FLAGS` variable. This allows to customize the entire software framework while +calling `make` without the need to change the makefile(s) or the linker script. + +The following example will add debug symbols to the executable (`-g`) and will also define the linker script's +`__neorv32_heap_size` setting the maximal heap size to 4096 bytes: + +.Example: using the `USER_FLAGS` variable for customization +[source,bash] +---- +$ make USER_FLAGS+="-g -Wl,--__neorv32_heap_size,__heap_size=4096" clean_all exe +---- + <<< // #################################################################################################################### :sectnums: === Executable Image Format -In order to generate a file, which can be executed by the processor, all source files have to be compiler, linked -and packed into a final _executable_. +In order to generate an executable for th processors all source files have to be compiled, linked +and packed into a _final executable_. :sectnums: ==== Linker Script -When all the application sources have been compiled, they need to be _linked_ in order to generate a unified -program file. For this purpose the makefile uses the NEORV32-specific linker script `sw/common/neorv32.ld` for -linking all object files that were generated during compilation. - -The linker script defines three memory _sections_: `rom`, `ram` and `iodev`. Each section provides specific -access _attributes_: read access (`r`), write access (`w`) and executable (`x`). +After all the application sources have been compiled, they need to be _linked_. +For this purpose the makefile uses the NEORV32-specific linker script `sw/common/neorv32.ld` for +linking all object files that were generated during compilation. In general, the linker script defines +three memory sections: `rom`, `ram` and `iodev`. -.Linker memory sections - general -[cols="<2,^1,<7"] +.Linker script - memory sections +[cols="<2,<8"] [options="header",grid="rows"] |======================= -| Memory section | Attributes | Description -| `ram` | `rwx` | Data memory address space (processor-internal/external DMEM) -| `rom` | `rx` | Instruction memory address space (processor-internal/external IMEM) _or_ internal bootloader ROM -| `iodev` | `rw` | Processor-internal memory-mapped IO/peripheral devices address space +| Memory section | Description +| `ram` | Data memory address space (processor-internal/external DMEM) +| `rom` | Instruction memory address space (processor-internal/external IMEM) _or_ internal bootloader ROM +| `iodev` | Processor-internal memory-mapped IO/peripheral devices address space |======================= -These sections are defined right at the beginning of the linker script: +[NOTE] +The `iodev` section is entirely defined by the processor hardware layout and should not be modified at all. -.Linker memory sections - cut-out from linker script `neorv32.ld` -[source,c] +[NOTE] +The `rom` section is automatically re-mapped to the processor-internal <<_bootloader_rom_bootrom>> when (re-)compiling the +bootloader + +Each section has two main attributes: `ORIGIN` and `LENGTH`. `ORIGIN` defines the base address of the according section +while `LENGTH` defines its size in bytes. The attributes are configured indirectly via variables that provide default values. + +.Linker script - section configuration +[source] ---- -MEMORY -{ - ram (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024 - rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 32K : 2048M - iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512 -} +/* Default rom/ram (IMEM/DMEM) sizes */ +__neorv32_rom_size = DEFINED(__neorv32_rom_size) ? __neorv32_rom_size : 2048M; +__neorv32_ram_size = DEFINED(__neorv32_ram_size) ? __neorv32_ram_size : 8K; + +/* Default section base addresses - do not change this unless the hardware-defined address space layout is changed! */ +__neorv32_rom_base = DEFINED(__neorv32_rom_base) ? __neorv32_rom_base : 0x00000000; /* = VHDL package's "ispace_base_c" */ +__neorv32_ram_base = DEFINED(__neorv32_ram_base) ? __neorv32_ram_base : 0x80000000; /* = VHDL package's "dspace_base_c" */ ---- -Each memory section provides a _base address_ `ORIGIN` and a _size_ `LENGTH`. The base address and size of the `iodev` section is -fixed and should not be altered. The base addresses and sizes of the `ram` and `rom` regions correspond to the total available instruction -and data memory address space (see section <<_address_space_layout>>) as defined in `rtl/core/neorv32_package.vhd`. +Only the region **sizes** should be modified by the user. The base addresses are defined by the processor's hardware (see section +<<_address_space>>) and should not be altered at all. The size (and base) configuration can be edited by the user - either by explicitly +changing the default values in the linker script or by overriding them when invoking `make`: + +.Overriding default rom size configuration (setting 4096 bytes) +[source, bash] +---- +$ make USER_FLAGS+="-Wl,--defsym,__neorv32_rom_size=4096" clean_all exe +---- [IMPORTANT] -`ORIGIN` of the `ram` section has to be always identical to the processor's `dspace_base_c` hardware configuration. + - + -`ORIGIN` of the `rom` section has to be always identical to the processor's `ispace_base_c` hardware configuration. +`neorv32_rom_base` (= `ORIGIN` of the `ram` section) has to be always identical to the processor's `dspace_base_c` hardware configuration. +Also, `neorv32_ram_base` (= `ORIGIN` of the `rom` section) has to be always identical to the processor's `ispace_base_c` hardware configuration. -The sizes of `rom` section is a little bit more complicated. The default linker script configuration assumes a _maximum_ of 2GB _logical_ -memory space, which is also the default configuration of the processor's hardware instruction memory address space. This size does not have +[NOTE] +The default configuration for the `rom` section assumes a maximum of 2GB _logical_ memory address space. This size does not have to reflect the _actual_ physical size of the instruction memory (internal IMEM and/or processor-external memory). It just provides a maximum -limit. When uploading new executable via the bootloader, the bootloader itself checks if sufficient _physical_ instruction memory is available. +limit. When uploading a new executable via the bootloader, the bootloader itself checks if sufficient _physical_ instruction memory is available. If a new executable is embedded right into the internal-IMEM the synthesis tool will check, if the configured instruction memory size is sufficient (e.g., via the <<_mem_int_imem_size>> generic). -[IMPORTANT] -The `rom` region uses a conditional assignment (via the `make_bootloader` symbol) for `ORIGIN` and `LENGTH` that is used to place -"normal executable" (i.e. for the IMEM) or "the bootloader image" to their according memories. + - + -The `ram` region also uses a conditional assignment (via the `make_bootloader` symbol) for `LENGTH`. When compiling the bootloader -(`make_bootloader` symbol is set) the generated bootloader will only use the _first_ 512 bytes of the data address space. This is -a fall-back to ensure the bootloader can operate independently of the actual _physical_ data memory size. - The linker maps all the regions from the compiled object files into five final sections: `.text`, `.rodata`, `.data`, `.bss` and `.heap`. These regions contain everything required for the application to run: -.Linker memory regions +.Linker script - memory regions [cols="<1,<9"] [options="header",grid="rows"] |======================= @@ -347,9 +366,9 @@ sections are extracted and concatenated into a single file `main.bin`. .Section Alignment [NOTE] -The default NEORV32 linker script aligns _all_ section so they start and end on a 32-bit (word) boundary. The default -NEORV32 start-up code (crt0) makes use of this alignment by using word-level memory instruction to initialize the `.data` -section and to clear the `.bss` section. +The default NEORV32 linker script aligns _all_ regions so they start and end on a 32-bit (word) boundary. The default +NEORV32 start-up code (crt0) makes use of this alignment by using word-level memory instructions to initialize the `.data` +section and to clear the `.bss` section (faster!). :sectnums: @@ -375,8 +394,10 @@ be used to configure a maximum size by adding a "protection area" between stack .Heap Size [IMPORTANT] -The maximum size of the heap is defined by the linker script's `__heap_size` symbol. This symbol has to be **explicitly defined** in order -to define a heap size (and to use dynamic memory allocation at all). By default, the heap size is set to zero. +The maximum size of the heap is defined by the linker script's `__neorv32_heap_size` variable. This variable has to be +**explicitly defined** in order to define a heap size (and to use dynamic memory allocation at all) other than zero. The user +can define the heap size while invoking the application makefile: `$ USER_FLAGS+="-Wl,--defsym,__neorv32_heap_size=4k" make clean_all exe` +(defines a heap size of 4*1024 bytes). .Heap-Stack Collisions [WARNING] From 3e436c5428310c8dbd3e8e066209e9247e1d7a23 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:48:28 +0200 Subject: [PATCH 3/7] [ug] update section "General Software Framework Setup" --- .../userguide/general_sw_framework_setup.adoc | 92 +++++++++++++++---- 1 file changed, 72 insertions(+), 20 deletions(-) diff --git a/docs/userguide/general_sw_framework_setup.adoc b/docs/userguide/general_sw_framework_setup.adoc index 1993ec10d..832a0fcdb 100644 --- a/docs/userguide/general_sw_framework_setup.adoc +++ b/docs/userguide/general_sw_framework_setup.adoc @@ -3,39 +3,91 @@ == General Software Framework Setup To allow executables to be _actually executed_ on the NEORV32 Processor the configuration of the software framework -has to be aware to the hardware configuration. This guide focuses on the memory configuration. To enabled +has to be aware to the hardware configuration. This guide focuses on the **memory configuration**. To enable certain CPU ISA features refer to the <<_enabling_risc_v_cpu_extensions>> section. +This guide shows how to configure the linker script for a given hardware memory configuration. More information regarding the +linker script itself can be found in the according section of the data sheet: https://stnolting.github.io/neorv32/#_linker_script + [TIP] If you have **not** changed the _default_ memory configuration in section <<_general_hardware_setup>> -you are already done and you can skip the rest of this guide. +you are already done and you can skip the rest of this section. + +[NOTE] +Always keep the processor's https://stnolting.github.io/neorv32/#_address_space[Address Space] layout in mind +when modifying the linker script + +There are two options to modify the default memory configuration of the linker script: + +[start=1] +. <<_modifying_the_linker_script>> +. <<_overriding_the_default_configuration>> (recommended!) + + +:sectnums: +=== Modifying the Linker Script + +This will modify the linker script _itself_. [start=1] . Open the NEORV32 linker script `sw/common/neorv32.ld` with a text editor. Right at the -beginning of this script you will find the `MEMORY` configuration listing the different memory section: +beginning of this script you will find the `+++ NEORV32 memory configuration +++` configuration section: -.Cut-out of the linker script `neorv32.ld`: `ram` memory section configuration -[source,c] +.Cut-out of the linker script `neorv32.ld` +[source] ---- -MEMORY -{ - ram (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024 <1> -... +/* Default rom/ram (IMEM/DMEM) sizes */ +__neorv32_rom_size = DEFINED(__neorv32_rom_size) ? __neorv32_rom_size : 2048M; <1> +__neorv32_ram_size = DEFINED(__neorv32_ram_size) ? __neorv32_ram_size : 8K; <2> + +/* Default HEAP size (= 0; no heap at all) */ +__neorv32_heap_size = DEFINED(__neorv32_heap_size) ? __neorv32_heap_size : 0; <3> + +/* Default section base addresses - do not change this unless the hardware-defined address space layout is changed! */ +__neorv32_rom_base = DEFINED(__neorv32_rom_base) ? __neorv32_rom_base : 0x00000000; /* = VHDL package's "ispace_base_c" */ <4> +__neorv32_ram_base = DEFINED(__neorv32_ram_base) ? __neorv32_ram_base : 0x80000000; /* = VHDL package's "dspace_base_c" */ <5> ---- -<1> Size of the data memory address space (right-most value) (internal/external DMEM); here 8kB +<1> Default (max) size of the instruction memory address space (right-most value) (internal/external IMEM): 2048MB +<2> Default size of the data memory address space (right-most value) (internal/external DMEM): 8kB +<3> Default size of the HEAP (right-most value): 0kB +<4> Default base address of the instruction memory address space (right-most value): `0x00000000` +<4> Default base address of the data memory address space (right-most value): `0x80000000` [start=2] -. We only need to change the `ram` section, which presents the available data address space. -If you have changed the DMEM (_MEM_INT_DMEM_SIZE_ generic) size adapt the `LENGTH` parameter of the `ram` -section (here: `8*1024`) so it is equal to your DMEM hardware configuration. - -[IMPORTANT] -Make sure you only modify the _right-most_ value (here: 8*1024)! + -The "`512`" are not relevant for the application. +. Only the the `neorv32_ram_size` variable needs to modified! If you have changed the default DMEM (_MEM_INT_DMEM_SIZE_ generic) +size then change the right-most parameter (here: `8kB`) so it is equal to your DMEM hardware configuration. The `neorv32_rom_size` +does not need to be modified even if you have changed the default IMEM size. +For more information see https://stnolting.github.io/neorv32/#_linker_script [start=3] . Done! Save your changes and close the linker script. -.Advanced: Section base address and size -[IMPORTANT] -More information can be found in the datasheet section https://stnolting.github.io/neorv32/#_address_space[Address Space]. + +:sectnums: +=== Overriding the Default Configuration + +This will not change the default linker script at all. Hence, this approach is recommended as it allows to make +per-project memory configuration without changing the code base. + +The RAM and ROM sizes from <<_modifying_the_linker_script>> (as well as the base addresses) can also be modified +by overriding the default values when invoking `make`. Therefore, the command needs to pass the according +values to the linker using the makefile's `USER_FLAGS` variable. + +[TIP] +See section "Application Makefile" of the data sheet for more information regarding the default makefile variables: +https://stnolting.github.io/neorv32/#_application_makefile + +.Example: override default RAM size while invoking make +[source, bash] +---- +$ make USER_FLAGS+="-Wl,--defsym,__neorv32_rom_size=16k" clean_all exe +---- + +The `-Wl` will pass the following commands/flags to the linker. `--defsym` will **define** a symbol for the linker. +`neorv32_rom_size` is the variable that will be defined and `16k` is the value assigned to it (= 16*1024kB). As a result, this +command will set the RAM region to a size of 16kB. + +[NOTE] +When using this approach the customized attributes have to be specified every time the makefile is invoked! +You can put the RAM/ROM override commands into the project's local makefile or define a simple shell script that defines +all the setup-related parameters (memory sizes, RISC-V ISA extensions, optimization goal, further tuning flags). From 5d9262802383a53c785bf08a8e57632e7f00101f Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:56:52 +0200 Subject: [PATCH 4/7] add v1.7.4.6 --- CHANGELOG.md | 1 + rtl/core/neorv32_package.vhd | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca9d0c5d9..aa0cf7668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12 | Date (*dd.mm.yyyy*) | Version | Comment | |:-------------------:|:-------:|:--------| +| 25.07.2022 | 1.7.4.6 | :warning: simplify memory configuration of **linker script**; :sparkles: add in-console configuration option; [#]375(https://github.com/stnolting/neorv32/pull/375) | | 22.07.2022 | 1.7.4.5 | add `CUSTOM_ID` generic; update bootloader; [#374](https://github.com/stnolting/neorv32/pull/374) | | 21.07.2022 | 1.7.4.4 | :lock: specify **physical memory attributes (PMA)** ;[#372](https://github.com/stnolting/neorv32/pull/372) | | 18.07.2022 | 1.7.4.3 | minor rtl edits and updates; [#369](https://github.com/stnolting/neorv32/pull/369) | diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 60cd97779..04e00173f 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -63,7 +63,7 @@ package neorv32_package is -- Architecture Constants (do not modify!) ------------------------------------------------ -- ------------------------------------------------------------------------------------------- constant data_width_c : natural := 32; -- native data path width - do not change! - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070405"; -- NEORV32 version - no touchy! + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070406"; -- NEORV32 version - no touchy! constant archid_c : natural := 19; -- official RISC-V architecture ID - hands off! -- Check if we're inside the Matrix ------------------------------------------------------- From 4eb170d59488c07b0879c46d46fd2a761f54aec1 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 25 Jul 2022 18:56:30 +0200 Subject: [PATCH 5/7] [ug] typo fix --- docs/userguide/general_sw_framework_setup.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/userguide/general_sw_framework_setup.adoc b/docs/userguide/general_sw_framework_setup.adoc index 832a0fcdb..f966f12b1 100644 --- a/docs/userguide/general_sw_framework_setup.adoc +++ b/docs/userguide/general_sw_framework_setup.adoc @@ -51,7 +51,7 @@ __neorv32_ram_base = DEFINED(__neorv32_ram_base) ? __neorv32_ram_base : 0x800000 <2> Default size of the data memory address space (right-most value) (internal/external DMEM): 8kB <3> Default size of the HEAP (right-most value): 0kB <4> Default base address of the instruction memory address space (right-most value): `0x00000000` -<4> Default base address of the data memory address space (right-most value): `0x80000000` +<5> Default base address of the data memory address space (right-most value): `0x80000000` [start=2] . Only the the `neorv32_ram_size` variable needs to modified! If you have changed the default DMEM (_MEM_INT_DMEM_SIZE_ generic) From 5dbb49d005d82532b4ea7c4d5081f14c2c838048 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 26 Jul 2022 13:10:58 +0200 Subject: [PATCH 6/7] [demo_newlib] minor updates define max heap size via makefile :warning: define USER_FLAGS in console _before_ invoking make --- sw/example/demo_newlib/main.c | 12 ++++++------ sw/example/demo_newlib/makefile | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sw/example/demo_newlib/main.c b/sw/example/demo_newlib/main.c index 04621d7ac..55566d968 100644 --- a/sw/example/demo_newlib/main.c +++ b/sw/example/demo_newlib/main.c @@ -53,7 +53,7 @@ /**********************************************************************//** - * @name Max heap size (from linker script) + * @name Max heap size (from linker script's "__neorv32_heap_size") **************************************************************************/ extern const unsigned __crt0_max_heap; @@ -90,7 +90,7 @@ int main() { neorv32_uart0_printf("MAX heap size: %u bytes\n", max_heap); } else { - neorv32_uart0_printf("ERROR! No heap size defined (linker script -> '__heap_size')!\n"); + neorv32_uart0_printf("ERROR! No heap size defined (linker script -> '__neorv32_heap_size')!\n"); return -1; } @@ -104,7 +104,7 @@ int main() { neorv32_uart0_printf(" test... "); srand(neorv32_cpu_csr_read(CSR_CYCLE)); // set random seed - neorv32_uart0_printf("%i, %i, %i, %i ", rand() % 100, rand() % 100, rand() % 100, rand() % 100); + neorv32_uart0_printf("%i, %i, %i, %i\n", rand() % 100, rand() % 100, rand() % 100, rand() % 100); char *char_buffer; // pointer for dynamic memory allocation @@ -134,9 +134,9 @@ int main() { free(char_buffer); - // NOTE: exit is highly oversized as it also includes clean-up functions (destructors), which - // is not required for bare-metal or RTOS applications... better use the simple 'return' or even better - // make sure main never returns. however, let's test that 'exit' works. + // NOTE: exit is highly over-sized as it also includes clean-up functions (destructors), which + // are not required for bare-metal or RTOS applications... better use the simple 'return' or even better + // make sure main never returns. Anyway, let's check if 'exit' works. neorv32_uart0_printf(" test..."); exit(0); diff --git a/sw/example/demo_newlib/makefile b/sw/example/demo_newlib/makefile index eb80b3074..f334a9c2c 100644 --- a/sw/example/demo_newlib/makefile +++ b/sw/example/demo_newlib/makefile @@ -34,6 +34,9 @@ # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # ################################################################################################# +# Configure max HEAP size +USER_FLAGS+="-Wl,--defsym,__neorv32_heap_size=1024" + # Modify this variable to fit your NEORV32 setup (neorv32 home folder) NEORV32_HOME ?= ../../.. From 269cfd69aea2902f3cebc6a75c0ee8ad222a4a93 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 26 Jul 2022 16:28:46 +0200 Subject: [PATCH 7/7] [ug] minor edits --- docs/userguide/general_sw_framework_setup.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/userguide/general_sw_framework_setup.adoc b/docs/userguide/general_sw_framework_setup.adoc index f966f12b1..9e11b72f7 100644 --- a/docs/userguide/general_sw_framework_setup.adoc +++ b/docs/userguide/general_sw_framework_setup.adoc @@ -66,7 +66,7 @@ For more information see https://stnolting.github.io/neorv32/#_linker_script :sectnums: === Overriding the Default Configuration -This will not change the default linker script at all. Hence, this approach is recommended as it allows to make +This will not change the default linker script at all. Hence, **this approach is recommended** as it allows to make per-project memory configuration without changing the code base. The RAM and ROM sizes from <<_modifying_the_linker_script>> (as well as the base addresses) can also be modified @@ -83,11 +83,11 @@ https://stnolting.github.io/neorv32/#_application_makefile $ make USER_FLAGS+="-Wl,--defsym,__neorv32_rom_size=16k" clean_all exe ---- -The `-Wl` will pass the following commands/flags to the linker. `--defsym` will **define** a symbol for the linker. -`neorv32_rom_size` is the variable that will be defined and `16k` is the value assigned to it (= 16*1024kB). As a result, this +The `-Wl` will pass the following commands/flags to the linker. `--defsym` will define a symbol for the linker. +`neorv32_rom_size` is the variable that will be defined and `16k` is the value assigned to it (= 16*1024 bytes). As a result, this command will set the RAM region to a size of 16kB. [NOTE] When using this approach the customized attributes have to be specified every time the makefile is invoked! You can put the RAM/ROM override commands into the project's local makefile or define a simple shell script that defines -all the setup-related parameters (memory sizes, RISC-V ISA extensions, optimization goal, further tuning flags). +all the setup-related parameters (memory sizes, RISC-V ISA extensions, optimization goal, further tuning flags, etc.).