OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [userguide/] [content.adoc] - Blame information for rev 63

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
Let's Get It Started!
2
 
3 63 zero_gravi
This user guide uses the NEORV32 project _as is_ from the official `neorv32` repository.
4
To make your first NEORV32 project run, follow the guides from the upcoming sections. It is recommended to
5
follow these guides step by step and eventually in the presented order.
6 60 zero_gravi
 
7 63 zero_gravi
[TIP]
8
This guide uses the minimalistic and platform/toolchain agnostic SoC test setups from
9
`rtl/test_setups` for illustration. You can use one of the provided test setups for
10
your first FPGA tests. Alternatively, have a look at the `setups` folder,
11
which provides more sophisticated example setups for various FPGAs/FPGA boards and toolchains.
12
 
13
 
14 60 zero_gravi
:sectnums:
15 61 zero_gravi
== Software Toolchain Setup
16 60 zero_gravi
 
17 61 zero_gravi
To compile (and debug) executables for the NEORV32 a RISC-V toolchain is required.
18
There are two possibilities to get this:
19 60 zero_gravi
 
20 63 zero_gravi
1. Download and _build_ the official RISC-V GNU toolchain yourself.
21 61 zero_gravi
2. Download and install a prebuilt version of the toolchain; this might also done via the package manager / app store of your OS
22 60 zero_gravi
 
23 63 zero_gravi
[NOTE]
24
The default toolchain prefix (`RISCV_PREFIX` variable) for this project is **`riscv32-unknown-elf-`**. Of course you can use any other RISC-V
25
toolchain (like `riscv64-unknown-elf-`) that is capable to emit code for a `rv32` architecture. Just change `RISCV_PREFIX`
26
according to your needs.
27 60 zero_gravi
 
28
 
29
:sectnums:
30
=== Building the Toolchain from Scratch
31
 
32 61 zero_gravi
To build the toolchain by yourself you can follow the guide from the official https://github.com/riscv/riscv-gnu-toolchain GitHub page.
33
You need to make sure the generated toolchain fits the architecture of the NEORV32 core. To get a toolchain that even supports minimal
34
ISA extension configurations, it is recommend to compile for `rv32i` only. Please note that this minimal ISA also provides further ISA
35
extensions like `m` or `c`. Of course you can use a `multilib` approach to generate
36
toolchains for several target ISAs.
37 60 zero_gravi
 
38 61 zero_gravi
.Configuring GCC build for `rv32i` (minimal ISA)
39 60 zero_gravi
[source,bash]
40
----
41
riscv-gnu-toolchain$ ./configure --prefix=/opt/riscv --with-arch=rv32i –-with-abi=ilp32
42
riscv-gnu-toolchain$ make
43
----
44
 
45 63 zero_gravi
[IMPORTANT]
46
Keep in mind that – for instance – a toolchain build with `--with-arch=rv32imc` only provides library code compiled with
47
compressed (`C`) and `mul`/`div` instructions (`M`)! Hence, this code cannot be executed (without
48
emulation) on an architecture without these extensions!
49 60 zero_gravi
 
50 63 zero_gravi
 
51 60 zero_gravi
:sectnums:
52
=== Downloading and Installing a Prebuilt Toolchain
53
 
54
Alternatively, you can download a prebuilt toolchain.
55
 
56 61 zero_gravi
:sectnums:
57
==== Use The Toolchain I have Build
58 60 zero_gravi
 
59 61 zero_gravi
I have compiled a GCC toolchain on a 64-bit x86 Ubuntu (Ubuntu on Windows, actually) and uploaded it to
60 60 zero_gravi
GitHub. You can directly download the according toolchain archive as single _zip-file_ within a packed
61 61 zero_gravi
release from https://github.com/stnolting/riscv-gcc-prebuilt.
62 60 zero_gravi
 
63
Unpack the downloaded toolchain archive and copy the content to a location in your file system (e.g.
64
`/opt/riscv`). More information about downloading and installing my prebuilt toolchains can be found in
65
the repository's README.
66
 
67
 
68 61 zero_gravi
:sectnums:
69
==== Use a Third Party Toolchain
70
 
71 60 zero_gravi
Of course you can also use any other prebuilt version of the toolchain. There are a lot  RISC-V GCC packages out there -
72 61 zero_gravi
even for Windows. On Linux system you might even be able to fetch a toolchain via your distribution's package manager.
73 60 zero_gravi
 
74
[IMPORTANT]
75
Make sure the toolchain can (also) emit code for a `rv32i` architecture, uses the `ilp32` or `ilp32e` ABI and **was not build** using
76
CPU extensions that are not supported by the NEORV32 (like `D`).
77
 
78
 
79
:sectnums:
80
=== Installation
81
 
82 61 zero_gravi
Now you have the toolchain binaries. The last step is to add them to your `PATH` environment variable (if you have not
83
already done so): make sure to add the _binaries_ folder (`bin`) of your toolchain.
84 60 zero_gravi
 
85
[source,bash]
86
----
87
$ export PATH:$PATH:/opt/riscv/bin
88
----
89
 
90
You should add this command to your `.bashrc` (if you are using bash) to automatically add the RISC-V
91
toolchain at every console start.
92
 
93
:sectnums:
94
=== Testing the Installation
95
 
96
To make sure everything works fine, navigate to an example project in the NEORV32 example folder and
97
execute the following command:
98
 
99
[source,bash]
100
----
101
neorv32/sw/example/blink_led$ make check
102
----
103
 
104 61 zero_gravi
This will test all the tools required for the generating NEORV32 executables.
105
Everything is working fine if `Toolchain check OK` appears at the end.
106 60 zero_gravi
 
107
 
108
 
109
<<<
110
// ####################################################################################################################
111
:sectnums:
112
== General Hardware Setup
113
 
114 63 zero_gravi
This guide shows the basics of setting up a NEORV32 project for FPGA implementation (or simulation only)
115
_from scratch_. It uses a _simplified_ test "SoC" setup of the processor to keeps things simple at the beginning.
116
This simple setup is intended for evaluation or as "hello world" project to check out the NEORV32
117
on _your_ FPGA board.
118 60 zero_gravi
 
119
[TIP]
120 63 zero_gravi
If you want to use a more sophisticated pre-defined setup to start with, check out the
121
`setups` folder, which provides example setups for various FPGA, boards and toolchains.
122 60 zero_gravi
 
123 63 zero_gravi
The NEORV32 project features two minimalistic pre-configured test setups in
124
https://github.com/stnolting/neorv32/blob/master/rtl/test_setups[`rtl/test_setups`].
125
Both test setups only implement very basic processor and CPU features.
126
The main difference between the two setups is the processor boot concept - so how to get a software executable
127
_into_ the processor:
128 60 zero_gravi
 
129 63 zero_gravi
* **`rtl/test_setups/neorv32_testsetup_approm.vhd`**: this setup does not require a connection via UART. The
130
software executable is "installed" into the bitstream to initialize a read-only memory. Use this setup
131
if your FPGA board does _not_ provide a UART interface.
132
* **`rtl/test_setups/neorv32_testsetup_bootloader.vhd`**: this setups uses the UART and the default NEORV32
133
bootloader to upload new software executables. Use this setup if your board _does_ provide a UART interface.
134
 
135
.NEORV32 "hello world" test setup (`rtl/test_setups/neorv32_testsetup_bootloader.vhd`)
136
image::neorv32_test_setup.png[align=center]
137
 
138
.External Clock Source
139
[NOTE]
140
These test setups are intended to be directly used as **design top entity**. Of course you can also instantiate them
141
into another design unit. If your FPGA board only provides _very fast_ external clock sources (like on the FOMU board)
142
you might need to add clock management components (PLLs, DCMs, MMCMs, ...) to the test setup or to the according top entity
143
if you instantiate one of the test setups.
144
 
145 61 zero_gravi
[start=1]
146 60 zero_gravi
. Create a new project with your FPGA EDA tool of choice.
147 63 zero_gravi
. Add all VHDL files from the project's `rtl/core` folder to your project.
148 61 zero_gravi
. Make sure to add all the rtl files to a new library called `neorv32`. If your FPGA tools does not
149
provide a field to enter the library name, check out the "properties" menu of the added rtl files.
150 63 zero_gravi
. The `rtl/core/neorv32_top.vhd` VHDL file is the top entity of the NEORV32 processor, which can be
151
instantiated into the "real" project. However, in this tutorial we will use one of the pre-defined
152
test setups from `rtl/test_setups` (see above).
153 61 zero_gravi
 
154
[IMPORTANT]
155
Make sure to include the `neorv32` package into your design when instantiating the processor: add
156
`library neorv32;` and `use neorv32.neorv32_package.all;` to your design unit.
157
 
158
[start=5]
159 63 zero_gravi
. Add the pre-defined test setup of choice to the project, too, and select it as _top entity_.
160
. The entity of both test setups
161
provide a minimal set of configuration generics, that might have to be adapted to match your FPGA and board:
162 60 zero_gravi
 
163 63 zero_gravi
.Test setup entity - configuration generics
164 60 zero_gravi
[source,vhdl]
165
----
166 63 zero_gravi
  generic (
167
    -- adapt these for your setup --
168
    CLOCK_FREQUENCY   : natural := 100000000; <1>
169
    MEM_INT_IMEM_SIZE : natural := 16*1024;   <2>
170
    MEM_INT_DMEM_SIZE : natural := 8*1024     <3>
171
  );
172 60 zero_gravi
----
173 61 zero_gravi
<1> Clock frequency of `clk_i` signal in Hertz
174
<2> Default size of internal instruction memory: 16kB
175
<3> Default size of internal data memory: 8kB
176 60 zero_gravi
 
177 63 zero_gravi
[start=7]
178
. If you feel like it – or if your FPGA does not provide sufficient resources – you can modify the
179
_memory sizes_ (`MEM_INT_IMEM_SIZE` and `MEM_INT_DMEM_SIZE` – marked with notes "2" and "3"). But as mentioned
180
above, let's keep things simple at first and use the standard configuration for now.
181
. There is one generic that _has to be set according to your FPGA board_ setup: the actual clock frequency
182
of the top's clock input signal (`clk_i`). Use the `CLOCK_FREQUENCY` generic to specify your clock source's
183
frequency in Hertz (Hz).
184 60 zero_gravi
 
185
[NOTE]
186 63 zero_gravi
If you have changed the default memory configuration (`MEM_INT_IMEM_SIZE` and `MEM_INT_DMEM_SIZE` generics)
187 61 zero_gravi
keep those new sizes in mind – these values are required for setting
188 60 zero_gravi
up the software framework in the next section <<_general_software_framework_setup>>.
189
 
190 63 zero_gravi
[start=9]
191 60 zero_gravi
. Depending on your FPGA tool of choice, it is time to assign the signals of the test setup top entity to
192 63 zero_gravi
the according pins of your FPGA board. All the signals can be found in the entity declaration of the
193
corresponding test setup:
194 60 zero_gravi
 
195 63 zero_gravi
.Entity signals of `neorv32_testsetup_approm.vhd`
196 60 zero_gravi
[source,vhdl]
197
----
198
  port (
199
    -- Global control --
200 63 zero_gravi
    clk_i       : in  std_ulogic; -- global clock, rising edge
201
    rstn_i      : in  std_ulogic; -- global reset, low-active, async
202 60 zero_gravi
    -- GPIO --
203 63 zero_gravi
    gpio_o      : out std_ulogic_vector(7 downto 0) -- parallel output
204
  );
205
----
206
 
207
.Entity signals of `neorv32_testsetup_bootloader.vhd`
208
[source,vhdl]
209
----
210
  port (
211
    -- Global control --
212
    clk_i       : in  std_ulogic; -- global clock, rising edge
213
    rstn_i      : in  std_ulogic; -- global reset, low-active, async
214
    -- GPIO --
215 60 zero_gravi
    gpio_o      : out std_ulogic_vector(7 downto 0); -- parallel output
216
    -- UART0 --
217
    uart0_txd_o : out std_ulogic; -- UART0 send data
218 63 zero_gravi
    uart0_rxd_i : in  std_ulogic  -- UART0 receive data
219
  );
220 60 zero_gravi
----
221
 
222 63 zero_gravi
.Signal Polarity
223
[NOTE]
224
If your FPGA board has inverse polarity for certain input/output you can add `not` gates. Example: The reset signal
225
`rstn_i` is low-active by default; the LEDs connected to `gpio_o` high-active by default.
226
You can do this in your board top if you instantiate the test setup,
227
or _inside_ the test setup if this is your top entity (low-active LEDs example: `gpio_o <= NOT con_gpio_o(7 downto 0);`).
228
 
229
[start=10]
230 60 zero_gravi
. Attach the clock input `clk_i` to your clock source and connect the reset line `rstn_i` to a button of
231
your FPGA board. Check whether it is low-active or high-active – the reset signal of the processor is
232
**low-active**, so maybe you need to invert the input signal.
233 63 zero_gravi
. If possible, connected _at least_ bit `0` of the GPIO output port `gpio_o` to a LED (see "Signal Polarity" note above).
234
. Finally, if your are using the UART-based test setup (`neorv32_testsetup_bootloader.vhd`)
235
connect the UART communication signals `uart0_txd_o` and `uart0_rxd_i` to the host interface (e.g. USB-UART converter).
236 60 zero_gravi
. Perform the project HDL compilation (synthesis, mapping, bitstream generation).
237 61 zero_gravi
. Program the generated bitstream into your FPGA and press the button connected to the reset signal.
238 63 zero_gravi
. Done! The LED at `gpio_o(0)` should be flashing now.
239 60 zero_gravi
 
240 63 zero_gravi
[TIP]
241
After the GCC toolchain for compiling RISC-V source code is ready (chapter <<_general_software_framework_setup>>),
242
you can advance to one of these chapters to learn how to get a software executable into your processor setup:
243
* If you are using the `neorv32_testsetup_approm.vhd` setup: See section <<_installing_an_executable_directly_into_memory>>.
244
* If you are using the `neorv32_testsetup_bootloader.vhd` setup: See section <<_uploading_and_starting_of_a_binary_executable_image_via_uart>>.
245 60 zero_gravi
 
246
 
247 63 zero_gravi
 
248 60 zero_gravi
<<<
249
// ####################################################################################################################
250
:sectnums:
251
== General Software Framework Setup
252
 
253 61 zero_gravi
To allow executables to be _actually executed_ on the NEORV32 Processor the configuration of the software framework
254
has to be aware to the hardware configuration. This guide focuses on the memory configuration. To enabled
255
certain CPU ISA festures refer to the <<_enabling_risc_v_cpu_extensions>> section.
256 60 zero_gravi
 
257 61 zero_gravi
[TIP]
258
If you have **not** changed the _default_ memory configuration in section <<_general_hardware_setup>>
259
you are already done and you can skip the rest of this guide.
260
 
261 60 zero_gravi
[start=1]
262
. Open the NEORV32 linker script `sw/common/neorv32.ld` with a text editor. Right at the
263 61 zero_gravi
beginning of this script you will find the `MEMORY` configuration listing the different memory section:
264 60 zero_gravi
 
265 61 zero_gravi
.Cut-out of the linker script `neorv32.ld`: `ram` memory section configuration
266 60 zero_gravi
[source,c]
267
----
268
MEMORY
269
{
270 61 zero_gravi
  ram  (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024 # <1>
271
...
272 60 zero_gravi
----
273 61 zero_gravi
<1> Size of the data memory address space (right-most value) (internal/external DMEM); here 8kB
274 60 zero_gravi
 
275 61 zero_gravi
[start=2]
276
. We only need to change the `ram` section, which presents the available data address space.
277
If you have changed the DMEM (_MEM_INT_DMEM_SIZE_ generic) size adapt the `LENGTH` parameter of the `ram`
278
section (here: `8*1024`) so it is equal to your DMEM hardware configuration.
279 60 zero_gravi
 
280 61 zero_gravi
[IMPORTANT]
281
Make sure you only modify the _right-most_ value (here: 8*1024)! +
282
The "`512`" are not relevant for the application.
283
 
284 60 zero_gravi
[start=3]
285 61 zero_gravi
. Done! Save your changes and close the linker script.
286 60 zero_gravi
 
287 61 zero_gravi
.Advanced: Section base address and size
288 60 zero_gravi
[IMPORTANT]
289 61 zero_gravi
More information can be found in the datasheet section https://stnolting.github.io/neorv32/#_address_space[Address Space].
290 60 zero_gravi
 
291
 
292
 
293
<<<
294
// ####################################################################################################################
295
:sectnums:
296
== Application Program Compilation
297
 
298 62 zero_gravi
This guide shows how to compile an example C-code application into a NEORV32 executable that
299 61 zero_gravi
can be uploaded via the bootloader or the on-chip debugger.
300
 
301
[IMPORTANT]
302
If your FPGA board does not provide such an interface - don't worry!
303
Section <<_installing_an_executable_directly_into_memory>> shows how to
304
run custom programs on your FPGA setup without having a UART.
305
 
306 60 zero_gravi
[start=1]
307 61 zero_gravi
. Open a terminal console and navigate to one of the project's example programs. For instance, navigate to the
308
simple `sw/example_blink_led` example program. This program uses the NEORV32 GPIO module to display
309 60 zero_gravi
an 8-bit counter on the lowest eight bit of the `gpio_o` output port.
310
. To compile the project and generate an executable simply execute:
311
 
312
[source,bash]
313
----
314 61 zero_gravi
neorv32/sw/example/blink_led$ make clean_all exe
315 60 zero_gravi
----
316
 
317
[start=3]
318 61 zero_gravi
. We are using the `clean_all` taret to make sure everything is re-build.
319 60 zero_gravi
. This will compile and link the application sources together with all the included libraries. At the end,
320 61 zero_gravi
your application is transformed into an ELF file (`main.elf`). The _NEORV32 image generator_ (in `sw/image_gen`)
321
takes this file and creates a final executable. The makefile will show the resulting memory utilization and
322
the executable size:
323 60 zero_gravi
 
324
[source,bash]
325
----
326 61 zero_gravi
neorv32/sw/example/blink_led$ make clean_all exe
327 60 zero_gravi
Memory utilization:
328 61 zero_gravi
   text    data     bss     dec     hex filename
329
   3176       0     120    3296     ce0 main.elf
330
Compiling ../../../sw/image_gen/image_gen
331 60 zero_gravi
Executable (neorv32_exe.bin) size in bytes:
332 62 zero_gravi
3188
333 60 zero_gravi
----
334
 
335 61 zero_gravi
[start=5]
336
. That's it. The `exe` target has created the actual executable `neorv32_exe.bin` in the current folder
337
that is ready to be uploaded to the processor.
338 60 zero_gravi
 
339
[TIP]
340 61 zero_gravi
The compilation process will also create a `main.asm` assembly listing file in the current folder, which
341
shows the actual assembly code of the application.
342 60 zero_gravi
 
343
 
344
 
345
<<<
346
// ####################################################################################################################
347
:sectnums:
348
== Uploading and Starting of a Binary Executable Image via UART
349
 
350 61 zero_gravi
Follow this guide to use the bootloader to upload an executable via UART.
351 60 zero_gravi
 
352 61 zero_gravi
[NOTE]
353
This concept uses the default "Indirect Boot" scenario that uses the bootloader to upload new executables.
354
See datasheet section https://stnolting.github.io/neorv32/#_indirect_boot[Indirect Boot] for more information.
355 60 zero_gravi
 
356 61 zero_gravi
[IMPORTANT]
357
If your FPGA board does not provide such an interface - don't worry!
358
Section <<_installing_an_executable_directly_into_memory>> shows how to
359
run custom programs on your FPGA setup without having a UART.
360 60 zero_gravi
 
361
[start=1]
362 61 zero_gravi
. Connect the primary UART (UART0) interface of your FPGA board to a serial port of your host computer.
363
. Start a terminal program. In this tutorial, I am using TeraTerm for Windows. You can download it fore free
364
from https://ttssh2.osdn.jp/index.html.en
365 60 zero_gravi
 
366 61 zero_gravi
[NOTE]
367
_Any_ terminal program that can connect to a serial port should work. However, make sure the program
368
can transfer data in _raw_ byte mode without any protocol overhead around it.
369 60 zero_gravi
 
370
[start=3]
371 61 zero_gravi
. Open a connection to the the serial port your UART is connected to. Configure the terminal setting according to the
372 60 zero_gravi
following parameters:
373
 
374
* 19200 Baud
375
* 8 data bits
376
* 1 stop bit
377
* no parity bits
378 61 zero_gravi
* _no_ transmission/flow control protocol
379
* receiver (host computer) newline on `\r\n` (carriage return & newline)
380 60 zero_gravi
 
381
[start=4]
382 61 zero_gravi
. Also make sure that single chars are send from your computer _without_ any consecutive "new line" or "carriage
383 60 zero_gravi
return" commands (this is highly dependent on your terminal application of choice, TeraTerm only
384
sends the raw chars by default).
385
. Press the NEORV32 reset button to restart the bootloader. The status LED starts blinking and the
386
bootloader intro screen appears in your console. Hurry up and press any key (hit space!) to abort the
387
automatic boot sequence and to start the actual bootloader user interface console.
388
 
389
.Bootloader console; aborted auto-boot sequence
390
[source,bash]
391
----
392
<< NEORV32 Bootloader >>
393
 
394
BLDV: Mar 23 2021
395
HWV:  0x01050208
396
CLK:  0x05F5E100
397
MISA: 0x40901105
398
ZEXT: 0x00000023
399
PROC: 0x0EFF0037
400
IMEM: 0x00004000 bytes @ 0x00000000
401
DMEM: 0x00002000 bytes @ 0x80000000
402
 
403
Autoboot in 8s. Press key to abort.
404
Aborted.
405
 
406
Available commands:
407
h: Help
408
r: Restart
409
u: Upload
410
s: Store to flash
411
l: Load from flash
412
e: Execute
413
CMD:>
414
----
415
 
416
[start=6]
417 61 zero_gravi
. Execute the "Upload" command by typing `u`. Now the bootloader is waiting for a binary executable to be send.
418 60 zero_gravi
 
419
[source,bash]
420
----
421
CMD:> u
422
Awaiting neorv32_exe.bin...
423
----
424
 
425
[start=7]
426 61 zero_gravi
. Use the "send file" option of your terminal program to send a NEORV32 executable (`neorv32_exe.bin`).
427
. Again, make sure to transmit the executable in raw binary mode (no transfer protocol).
428
When using TeraTerm, select the "binary" option in the send file dialog.
429 60 zero_gravi
. If everything went fine, OK will appear in your terminal:
430
 
431
[source,bash]
432
----
433
CMD:> u
434
Awaiting neorv32_exe.bin... OK
435
----
436
 
437
[start=10]
438 61 zero_gravi
. The executable is now in the instruction memory of the processor. To execute the program right
439 60 zero_gravi
now run the "Execute" command by typing `e`:
440
 
441
[source,bash]
442
----
443
CMD:> u
444
Awaiting neorv32_exe.bin... OK
445
CMD:> e
446
Booting...
447
Blinking LED demo program
448
----
449
 
450
[start=11]
451 61 zero_gravi
. If everything went fine, you should see the LEDs blinking.
452 60 zero_gravi
 
453 61 zero_gravi
[NOTE]
454
The bootloader will print error codes if something went wrong.
455
See section https://stnolting.github.io/neorv32/#_bootloader[Bootloader] of the NEORV32 datasheet for more information.
456 60 zero_gravi
 
457 61 zero_gravi
[TIP]
458
See section <<_programming_an_external_spi_flash_via_the_bootloader>> to learn how to use an external SPI
459
flash for nonvolatile program storage.
460 60 zero_gravi
 
461 61 zero_gravi
[TIP]
462
Executables can also be uploaded via the **on-chip debugger**.
463
See section <<_debugging_with_gdb>> for more information.
464
 
465
 
466
 
467 60 zero_gravi
<<<
468
// ####################################################################################################################
469
:sectnums:
470 61 zero_gravi
== Installing an Executable Directly Into Memory
471 60 zero_gravi
 
472 61 zero_gravi
If you do not want to use the bootloader (or the on-chip debugger) for executable upload or if your setup does not provide
473
a serial interface for that, you can also directly install an application into embedded memory.
474 60 zero_gravi
 
475 61 zero_gravi
This concept uses the "Direct Boot" scenario that implements the processor-internal IMEM as ROM, which is
476
pre-initialized with the application's executable during synthesis. Hence, it provides _non-volatile_ storage of the
477
executable inside the processor. This storage cannot be altered during runtime and any source code modification of
478
the application requires to re-program the FPGA via the bitstream.
479
 
480
[TIP]
481
See datasheet section https://stnolting.github.io/neorv32/#_direct_boot[Direct Boot] for more information.
482
 
483
 
484
 
485
Using the IMEM as ROM:
486
 
487
* for this boot concept the bootloader is no longer required
488
* this concept only works for the internal IMEM (but can be extended to work with external memories coupled via the processor's bus interface)
489 62 zero_gravi
* make sure that the memory components (like block RAM) the IMEM is mapped to support an initialization via the bitstream
490 61 zero_gravi
 
491 60 zero_gravi
[start=1]
492 61 zero_gravi
. At first, make sure your processor setup actually implements the internal IMEM: the `MEM_INT_IMEM_EN` generics has to be set to `true`:
493
 
494
.Processor top entity configuration - enable internal IMEM
495
[source,vhdl]
496
----
497
  -- Internal Instruction memory --
498
  MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
499
----
500
 
501
[start=2]
502
. For this setup we do not want the bootloader to be implemented at all. Disable implementation of the bootloader by setting the
503 62 zero_gravi
`INT_BOOTLOADER_EN` generic to `false`. This will also modify the processor-internal IMEM so it is initialized with the executable during synthesis.
504 61 zero_gravi
 
505
.Processor top entity configuration - disable internal bootloader
506
[source,vhdl]
507
----
508
  -- General --
509
  INT_BOOTLOADER_EN => false, -- boot configuration: false = boot from int/ext (I)MEM
510
----
511
 
512
[start=3]
513
. To generate an "initialization image" for the IMEM that contains the actual application, run the `install` target when compiling your application:
514
 
515
[source,bash]
516
----
517
neorv32/sw/example/blink_led$ make clean_all install
518
Memory utilization:
519
   text    data     bss     dec     hex filename
520
   3176       0     120    3296     ce0 main.elf
521
Compiling ../../../sw/image_gen/image_gen
522
Installing application image to ../../../rtl/core/neorv32_application_image.vhd
523
----
524
 
525
[start=4]
526
. The `install` target has compiled all the application sources but instead of creating an executable (`neorv32_exe.bit`) that can be uploaded via the
527
bootloader, it has created a VHDL memory initialization image `core/neorv32_application_image.vhd`.
528
. This VHDL file is automatically copied to the core's rtl folder (`rtl/core`) so it will be included for the next synthesis.
529
. Perform a new synthesis. The IMEM will be build as pre-initialized ROM (inferring embedded memories if possible).
530
. Upload your bitstream. Your application code now resides unchangeable in the processor's IMEM and is directly executed after reset.
531
 
532
 
533
The synthesis tool / simulator will print asserts to inform about the (IMEM) memory / boot configuration:
534
 
535
[source]
536
----
537
NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM).
538
NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (3176 bytes), pre-initialized with application.
539
----
540
 
541
 
542
 
543
<<<
544
// ####################################################################################################################
545
:sectnums:
546
== Setup of a New Application Program Project
547
 
548
[start=1]
549
. The easiest way of creating a _new_ software application project is to copy an _existing_ one. This will keep all
550
file dependencies. For example you can copy `sw/example/blink_led` to `sw/example/flux_capacitor`.
551
. If you want to place you application somewhere outside `sw/example` you need to adapt the application's makefile.
552
In the makefile you will find a variable that keeps the relative or absolute path to the NEORV32 repo home
553 60 zero_gravi
folder. Just modify this variable according to your new project's home location:
554
 
555
[source,makefile]
556
----
557
# Relative or absolute path to the NEORV32 home folder (use default if not set by user)
558
NEORV32_HOME ?= ../../..
559
----
560
 
561
[start=3]
562 61 zero_gravi
. If your project contains additional source files outside of the project folder, you can add them to
563
the `APP_SRC` variable:
564 60 zero_gravi
 
565
[source,makefile]
566
----
567
# User's application sources (add additional files here)
568
APP_SRC = $(wildcard *.c) ../somewhere/some_file.c
569
----
570
 
571
[start=4]
572 61 zero_gravi
. You also can add a folder containing your application's include files to the
573
`APP_INC` variable (do not forget the `-I` prefix):
574 60 zero_gravi
 
575
[source,makefile]
576
----
577
# User's application include folders (don't forget the '-I' before each entry)
578
APP_INC = -I . -I ../somewhere/include_stuff_folder
579
----
580
 
581
 
582
 
583
<<<
584
// ####################################################################################################################
585
:sectnums:
586
== Enabling RISC-V CPU Extensions
587
 
588 61 zero_gravi
Whenever you enable/disable a RISC-V CPU extensions via the according `CPU_EXTENSION_RISCV_x` generic, you need to
589 60 zero_gravi
adapt the toolchain configuration so the compiler can actually generate according code for it.
590
 
591
To do so, open the makefile of your project (for example `sw/example/blink_led/makefile`) and scroll to the
592 61 zero_gravi
"USER CONFIGURATION" section right at the beginning of the file. You need to modify the `MARCH` variable and eventually
593
the `MABI` variable according to your CPU hardware configuration.
594 60 zero_gravi
 
595
[source,makefile]
596
----
597
# CPU architecture and ABI
598
MARCH = -march=rv32i # <1>
599
MABI = -mabi=ilp32 # <2>
600
----
601
<1> MARCH = Machine architecture ("ISA string")
602
<2> MABI = Machine binary interface
603
 
604 61 zero_gravi
For example, if you enable the RISC-V `C` extension (16-bit compressed instructions) via the `CPU_EXTENSION_RISCV_C`
605 62 zero_gravi
generic (set `true`) you need to add the `c` extension also to the `MARCH` ISA string in order to make the compiler
606 61 zero_gravi
emit compressed instructions.
607 60 zero_gravi
 
608 62 zero_gravi
.Privileged Architecture Extensions
609
[IMPORTANT]
610
Privileged architecture extensions like `Zicsr` or `Zifencei` are "used" _implicitly_ by the compiler. Hence, according
611
instruction will only be generated when "encoded" via inline assembly or when linking according libraries. In this case,
612
these instruction will _always_ be emitted (even if the according extension is not specified in `MARCH`). +
613
**I recommend to _not_ specify any privileged architecture extensions in `MARCH`.**
614
 
615 61 zero_gravi
[WARNING]
616
ISA extension enabled in hardware can be a superset of the extensions enabled in software, but not the other way
617
around. For example generating compressed instructions for a CPU configuration that has the `c` extension disabled
618
will cause _illegal instruction exceptions_ at runtime.
619 60 zero_gravi
 
620 61 zero_gravi
You can also override the default `MARCH` and `MABI` configurations from the makefile when invoking the makefile:
621
 
622 60 zero_gravi
[source,bash]
623
----
624
$ make MARCH=-march=rv32ic clean_all all
625
----
626
 
627
[NOTE]
628 62 zero_gravi
The RISC-V ISA string for `MARCH` follows a certain _canonical_ structure:
629
`rev32[i/e][m][a][f][d][g][q][c][b][v][n]...` For example `rv32imac` is valid while `rv32icma` is not.
630 60 zero_gravi
 
631
 
632
 
633
<<<
634
// ####################################################################################################################
635
:sectnums:
636 63 zero_gravi
== Application-Specific Processor Configuration
637
 
638
Due to the processor's configuration options, which are mainly defined via the top entity VHDL generics, the SoC
639
can be tailored to the application-specific requirements. Note that this chapter does not focus on optional
640
_SoC features_ like IO/peripheral modules. It rather gives ideas on how to optimize for _overall goals_
641
like performance and area.
642
 
643
[NOTE]
644
Please keep in mind that optimizing the design in one direction (like performance) will also effect other potential
645
optimization goals (like area and energy).
646
 
647
=== Optimize for Performance
648
 
649
The following points show some concepts to optimize the processor for performance regardless of the costs
650
(i.e. increasing area and energy requirements):
651
 
652
* Enable all performance-related RISC-V CPU extensions that implement dedicated hardware accelerators instead
653
of emulating operations entirely in software:  `M`, `C`, `Zfinx`
654
* Enable mapping of compleX CPU operations to dedicated hardware: `FAST_MUL_EN => true` to use DSP slices for
655
multiplications, `FAST_SHIFT_EN => true` use a fast barrel shifter for shift operations.
656
* Implement the instruction cache: `ICACHE_EN => true`
657
* Use as many _internal_ memory as possible to reduce memory access latency: `MEM_INT_IMEM_EN => true` and
658
`MEM_INT_DMEM_EN => true`, maximize `MEM_INT_IMEM_SIZE` and `MEM_INT_DMEM_SIZE`
659
* Increase the CPU's instruction prefetch buffer size: `CPU_IPB_ENTRIES`
660
* _To be continued..._
661
 
662
 
663
=== Optimize for Size
664
 
665
The NEORV32 is a size-optimized processor system that is intended to fit into tiny niches within large SoC
666
designs or to be used a customized microcontroller in really tiny / low-power FPGAs (like Lattice iCE40).
667
Here are some ideas how to make the processor even smaller while maintaining it's _general purpose system_
668
concept and maximum RISC-V compatibility.
669
 
670
**SoC**
671
 
672
* This is obvious, but exclude all unused optional IO/peripheral modules from synthesis via the processor
673
configuration generics.
674
* If an IO module provides an option to configure the number of "channels", constrain this number to the
675
actually required value (e.g. the PWM module `IO_PWM_NUM_CH` or the external interrupt controller `XIRQ_NUM_CH`).
676
* Reduce the FIFO sizes of implemented modules (e.g. `SLINK_TX_FIFO`).
677
* Disable the instruction cache (`ICACHE_EN => false`) if the design only uses processor-internal IMEM
678
and DMEM memories.
679
* _To be continued..._
680
 
681
**CPU**
682
 
683
* Use the _embedded_ RISC-V CPU architecture extension (`CPU_EXTENSION_RISCV_E`) to reduce block RAM utilization.
684
* The compressed instructions extension (`CPU_EXTENSION_RISCV_C`) requires additional logic for the decoder but
685
also reduces program code size by approximately 30%.
686
* If not explicitly used/required, constrain the CPU's counter sizes: `CPU_CNT_WIDTH` for `[m]instret[h]`
687
(number of instruction) and `[m]cycle[h]` (number of cycles) counters. You can even remove these counters
688
by setting `CPU_CNT_WIDTH => 0` if they are not used at all (note, this is not RISC-V compliant).
689
* Reduce the CPU's prefetch buffer size (`CPU_IPB_ENTRIES`).
690
* Map CPU shift operations to a small and iterative shifter unit (`FAST_SHIFT_EN => false`).
691
* If you have unused DSP block available, you can map multiplication operations to those slices instead of
692
using LUTs to implement the multiplier (`FAST_MUL_EN => true`).
693
* If there is no need to execute division in hardware, use the `Zmmul` extension instead of the full-scale
694
`M` extension.
695
* Disable CPU extension that are not explicitly used (`A`, `U`, `Zfinx`).
696
* _To be continued..._
697
 
698
=== Optimize for Clock Speed
699
 
700
The NEORV32 Processor and CPU are designed to provide minimal logic between register stages to keep the
701
critical path as short as possible. When enabling additional extension or modules the impact on the existing
702
logic is also kept at a minimum to prevent timing degrading. If there is a major impact on existing
703
logic (example: many physical memory protection address configuration registers) the VHDL code automatically
704
adds additional register stages to maintain critical path length. Obviously, this increases operation latency.
705
 
706
In order to optimize for a minimal critical path (= maximum clock speed) the following points should be considered:
707
 
708
* Complex CPU extensions (in terms of hardware requirements) should be avoided (examples: floating-point unit, physical memory protection).
709
* Large carry chains (>32-bit) should be avoided (constrain CPU counter sizes: e.g. `CPU_CNT_WIDTH => 32` and `HPM_NUM_CNTS => 32`).
710
* If the target FPGA provides sufficient DSP resources, CPU multiplication operations can be mapped to DSP slices (`FAST_MUL_EN => true`)
711
reducing LUT usage and critical path impact while also increasing overall performance.
712
* Use the synchronous (registered) RX path configuration of the external memory interface (`MEM_EXT_ASYNC_RX => false`).
713
* _To be continued..._
714
 
715
[NOTE]
716
The short and fixed-length critical path allows to integrate the core into existing clock domains.
717
So no clock domain-crossing and no sub-clock generation is required. However, for very high clock
718
frequencies (this is technology / platform dependent) clock domain crossing becomes crucial for chip-internal
719
connections.
720
 
721
 
722
=== Optimize for Energy
723
 
724
There are no _dedicated_ configuration options to optimize the processor for energy (minimal consumption;
725
energy/instruction ratio) yet. However, a reduced processor area (<<_optimize_for_size>>) will also reduce
726
static energy consumption.
727
 
728
To optimize your setup for low-power applications, you can make use of the CPU sleep mode (`wfi` instruction).
729
Put the CPU to sleep mode whenever possible. Disable all processor modules that are not actually used (exclude them
730
from synthesis if the will be _never_ used; disable the module via it's control register if the module is not
731
_currently_ used). When is sleep mode, you can keep a timer module running (MTIME or the watch dog) to wake up
732
the CPU again. Since the wake up is triggered by _any_ interrupt, the external interrupt controller can also
733
be used to wake up the CPU again. By this, all timers (and all other modules) can be deactivated as well.
734
 
735
.Processor-internal clock generator shutdown
736
[TIP]
737
If _no_ IO/peripheral module is currently enabled, the processor's internal clock generator circuit will be
738
shut down reducing switching activity and thus, dynamic energy consumption.
739
 
740
 
741
 
742
<<<
743
// ####################################################################################################################
744
:sectnums:
745 61 zero_gravi
== Customizing the Internal Bootloader
746 60 zero_gravi
 
747 61 zero_gravi
The NEORV32 bootloader provides several options to configure and customize it for a certain application setup.
748
This configuration is done by passing _defines_ when compiling the bootloader. Of course you can also
749
modify to bootloader source code to provide a setup that perfectly fits your needs.
750 60 zero_gravi
 
751 61 zero_gravi
[IMPORTANT]
752
Each time the bootloader sources are modified, the bootloader has to be re-compiled (and re-installed to the
753
bootloader ROM) and the processor has to be re-synthesized.
754 60 zero_gravi
 
755 61 zero_gravi
[NOTE]
756
Keep in mind that the maximum size for the bootloader is limited to 32kB and should be compiled using the
757
base ISA `rv32i` only to ensure it can work independently of the actual CPU configuration.
758 60 zero_gravi
 
759 61 zero_gravi
.Bootloader configuration parameters
760
[cols="<2,^1,^2,<6"]
761
[options="header", grid="rows"]
762
|=======================
763
| Parameter | Default | Legal values | Description
764
4+^| Serial console interface
765
| `UART_EN`   | `1` | `0`, `1` | Set to `0` to disable UART0 (no serial console at all)
766
| `UART_BAUD` | `19200` | _any_ | Baud rate of UART0
767
4+^| Status LED
768
| `STATUS_LED_EN`  | `1` | `0`, `1` | Enable bootloader status led ("heart beat") at `GPIO` output port pin #`STATUS_LED_PIN` when `1`
769
| `STATUS_LED_PIN` | `0` | `0` ... `31` | `GPIO` output pin used for the high-active status LED
770
4+^| Boot configuration
771
| `AUTO_BOOT_SPI_EN`  | `0` | `0`, `1` | Set `1` to enable immediate boot from external SPI flash
772
| `AUTO_BOOT_OCD_EN`  | `0` | `0`, `1` | Set `1` to enable boot via on-chip debugger (OCD)
773
| `AUTO_BOOT_TIMEOUT` | `8` | _any_ | Time in seconds after the auto-boot sequence starts (if there is no UART input by user); set to 0 to disabled auto-boot sequence
774
4+^| SPI configuration
775 63 zero_gravi
| `SPI_EN`                | `1` | `0`, `1` | Set `1` to enable the usage of the SPI module (including load/store executables from/to SPI flash options)
776 61 zero_gravi
| `SPI_FLASH_CS`          | `0` | `0` ... `7` | SPI chip select output (`spi_csn_o`) for selecting flash
777
| `SPI_FLASH_SECTOR_SIZE` | `65536` | _any_ | SPI flash sector size in bytes
778
| `SPI_FLASH_CLK_PRSC`    | `CLK_PRSC_8`  | `CLK_PRSC_2` `CLK_PRSC_4` `CLK_PRSC_8` `CLK_PRSC_64` `CLK_PRSC_128` `CLK_PRSC_1024` `CLK_PRSC_2024` `CLK_PRSC_4096` | SPI clock pre-scaler (dividing main processor clock)
779
| `SPI_BOOT_BASE_ADDR`    | `0x08000000` | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
780
|=======================
781 60 zero_gravi
 
782 61 zero_gravi
Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
783
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
784
(using `+=`) to the makefile's `USER_FLAGS` variable. Make sure to use the `-D` prefix here.
785 60 zero_gravi
 
786 61 zero_gravi
For example, to configure a UART Baud rate of 57600 and redirecting the status LED to output pin 20
787
use the following command (_in_ the bootloader's source folder `sw/bootloader`):
788 60 zero_gravi
 
789 61 zero_gravi
.Example: customizing, re-compiling and re-installing the bootloader
790
[source,console]
791 60 zero_gravi
----
792 61 zero_gravi
$ make USER_FLAGS+=-DUART_BAUD=57600 USER_FLAGS+=-DSTATUS_LED_PIN=20 clean_all bootloader
793 60 zero_gravi
----
794
 
795 61 zero_gravi
[NOTE]
796
The `clean_all` target ensure that all libraries are re-compiled. The `bootloader` target will automatically
797
compile and install the bootloader to the HDL boot ROM (updating `rtl/core/neorv32_bootloader_image.vhd`).
798 60 zero_gravi
 
799 61 zero_gravi
:sectnums:
800
=== Bootloader Boot Configuration
801 60 zero_gravi
 
802 61 zero_gravi
The bootloader provides several _boot configurations_ that define where the actual application's executable
803
shall be fetched from. Note that the non-default boot configurations provide a smaller memory footprint
804
reducing boot ROM implementation costs.
805 60 zero_gravi
 
806 61 zero_gravi
:sectnums!:
807
==== Default Boot Configuration
808 60 zero_gravi
 
809 61 zero_gravi
The _default_ bootloader configuration provides a UART-based user interface that allows to upload new executables
810
at any time. Optionally, the executable can also be programmed to an external SPI flash by the bootloader (see
811
section <<_programming_an_external_spi_flash_via_the_bootloader>>).
812 60 zero_gravi
 
813 61 zero_gravi
This configuration also provides an _automatic boot sequence_ (auto-boot) which will start fetching an executable
814
from external SPI flash using the default SPI configuration. By this, the default bootloader configuration
815
provides a "non volatile program storage" mechanism that automatically boot from external SPI flash
816
(after `AUTO_BOOT_TIMEOUT`) while still providing the option to re-program SPI flash at any time
817
via the UART interface.
818 60 zero_gravi
 
819 61 zero_gravi
:sectnums!:
820
==== `AUTO_BOOT_SPI_EN`
821 60 zero_gravi
 
822 61 zero_gravi
The automatic boot from SPI flash (enabled when `AUTO_BOOT_SPI_EN` is `1`) will fetch an executable from an external
823
SPI flash (using the according _SPI configuration_) right after reset. The bootloader will start fetching
824
the image at SPI flash base address `SPI_BOOT_BASE_ADDR`.
825 60 zero_gravi
 
826 61 zero_gravi
Note that there is _no_ UART console to interact with the bootloader. However, this boot configuration will
827
output minimal status messages via UART (if `UART_EN` is `1`).
828 60 zero_gravi
 
829 61 zero_gravi
:sectnums!:
830
==== `AUTO_BOOT_OCD_EN`
831 60 zero_gravi
 
832 61 zero_gravi
If `AUTO_BOOT_OCD_EN` is `1` the bootloader is implemented as minimal "halt loop" to be used with the on-chip debugger.
833
After initializing the hardware, the CPU waits in this endless loop until the on-chip debugger takes control over
834
the core (to upload and run the actual executable). See section <<_debugging_using_the_on_chip_debugger>>
835
for more information on how to use the on-chip debugger to upload and run executables.
836 60 zero_gravi
 
837 61 zero_gravi
[NOTE]
838
All bootloader boot configuration support uploading new executables via the on-chip debugger.
839 60 zero_gravi
 
840 61 zero_gravi
[WARNING]
841
Note that this boot configuration does not load any executable at all! Hence,
842 62 zero_gravi
this boot configuration is intended to be used with the on-chip debugger only.
843 60 zero_gravi
 
844
 
845
 
846 61 zero_gravi
<<<
847
// ####################################################################################################################
848
:sectnums:
849
== Programming an External SPI Flash via the Bootloader
850 60 zero_gravi
 
851 61 zero_gravi
The default processor-internal NEORV32 bootloader supports automatic booting from an external SPI flash.
852
This guide shows how to write an executable to the SPI flash via the bootloader so it can be automatically
853
fetched and executed after processor reset. For example, you can use a section of the FPGA bitstream configuration
854
memory to store an application executable.
855 60 zero_gravi
 
856 61 zero_gravi
[NOTE]
857
This section assumes the _default_ configuration of the NEORV32 bootloader.
858
See section <<_customizing_the_internal_bootloader>> on how to customize the bootloader and its setting
859
(for example the SPI chip-select port, the SPI clock speed or the flash base address for storing the executable).
860 60 zero_gravi
 
861
 
862 61 zero_gravi
:sectnums:
863
=== SPI Flash
864 60 zero_gravi
 
865 61 zero_gravi
The bootloader can access an SPI compatible flash via the processor top entity's SPI port. By default, the flash
866
chip-select line is to `spi_csn_o(0)` and uses 1/8 of the processor's main clock as clock frequency.
867
The SPI flash has to support single-byte read and write, 24-bit addresses and at least the following standard commands:
868 60 zero_gravi
 
869 61 zero_gravi
* READ `0x03`
870
* READ STATUS `0x05`
871
* WRITE ENABLE `0x06`
872
* PAGE PROGRAM `0x02`
873
* SECTOR ERASE `0xD8`
874
* READ ID `0x9E`
875 60 zero_gravi
 
876 61 zero_gravi
Compatible (FGPA configuration) SPI flash memories are for example the "Winbond W25Q64FV2 or the "Micron N25Q032A".
877 60 zero_gravi
 
878
 
879
:sectnums:
880 61 zero_gravi
=== Programming an Executable
881 60 zero_gravi
 
882
[start=1]
883
. At first, reset the NEORV32 processor and wait until the bootloader start screen appears in your terminal program.
884
. Abort the auto boot sequence and start the user console by pressing any key.
885 61 zero_gravi
. Press u to upload the executable that you want to store to the external flash:
886 60 zero_gravi
 
887
[source]
888
----
889
CMD:> u
890
Awaiting neorv32_exe.bin...
891
----
892
 
893
[start=4]
894 61 zero_gravi
. Send the binary in raw binary via your terminal program. When the upload is completed and "OK"
895 60 zero_gravi
appears, press `p` to trigger the programming of the flash (do not execute the image via the `e`
896
command as this might corrupt the image):
897
 
898
[source]
899
----
900
CMD:> u
901
Awaiting neorv32_exe.bin... OK
902
CMD:> p
903
Write 0x000013FC bytes to SPI flash @ 0x00800000? (y/n)
904
----
905
 
906
[start=5]
907
. The bootloader shows the size of the executable and the base address inside the SPI flash where the
908
executable is going to be stored. A prompt appears: Type `y` to start the programming or type `n` to
909 61 zero_gravi
abort.
910 60 zero_gravi
 
911 61 zero_gravi
[TIP]
912
Section <<_customizing_the_internal_bootloader>> show the according C-language `define` that can be modified
913
to specify the base address of the executable inside the SPI flash.
914
 
915 60 zero_gravi
[source]
916
----
917
CMD:> u
918
Awaiting neorv32_exe.bin... OK
919
CMD:> p
920 61 zero_gravi
Write 0x000013FC bytes to SPI flash @ 0x08000000? (y/n) y
921 60 zero_gravi
Flashing... OK
922
CMD:>
923
----
924
 
925
[start=6]
926
. If "OK" appears in the terminal line, the programming process was successful. Now you can use the
927
auto boot sequence to automatically boot your application from the flash at system start-up without
928
any user interaction.
929
 
930
 
931
 
932
<<<
933
// ####################################################################################################################
934
:sectnums:
935 61 zero_gravi
== Packaging the Processor as IP block for Xilinx Vivado Block Designer
936
 
937 62 zero_gravi
[start=1]
938
. Import all the core files from `rtl/core` and assign them to a _new_ design library `neorv32`.
939
. Instantiate the `rtl/wrappers/neorv32_top_axi4lite.vhd` module.
940
. Then either directly use that module in a new block-design ("Create Block Design", right-click -> "Add Module",
941
thats easier for a first try) or package it ("Tools", "Create and Package new IP") for the use in other projects.
942
. Connect your AXI-peripheral directly to the core's AXI4-Interface if you only have one, or to an AXI-Interconnect
943
(from the IP-catalog) if you have multiple peripherals.
944
. Connect ALL the `ACLK` and `ARESETN` pins of all peripherals and interconnects to the processor's clock and reset
945
signals to have a _unified_ clock and reset domain (easier for a first setup).
946
. Open the "Address Editor" tab and let Vivado assign the base-addresses for the AXI-peripherals (you can modify them
947
according to your needs).
948
. For all FPGA-external signals (like UART signals) make all the connections you need "external"
949
(right-click on the signal/pin -> "Make External").
950
. Save everything, let VIVADO create a HDL-Wrapper for the block-design and choose this as your _Top Level Design_.
951
. Define your constraints and generate your bitstream.
952 61 zero_gravi
 
953 62 zero_gravi
[NOTE]
954
Guide provided by GitHub user https://github.com/AWenzel83[`AWenzel83`] from
955
https://github.com/stnolting/neorv32/discussions/52#discussioncomment-819013
956 61 zero_gravi
 
957
 
958 62 zero_gravi
 
959 61 zero_gravi
<<<
960
// ####################################################################################################################
961
:sectnums:
962 60 zero_gravi
== Simulating the Processor
963
 
964 61 zero_gravi
:sectnums:
965
=== Testbench
966
 
967 63 zero_gravi
The NEORV32 project features a simple, plain-VHDL (no third-party libraries) default testbench (`sim/neorv32_tb.simple.vhd`)
968
that can be used to simulate and test the processor setup. This testbench features a 100MHz clock and enables all optional
969
peripheral and CPU extensions except for the `E` extension and the TRNG IO module (that CANNOT be simulated due to its
970
combinatorial (looped) architecture).
971 60 zero_gravi
 
972
The simulation setup is configured via the "User Configuration" section located right at the beginning of
973
the testbench's architecture. Each configuration constant provides comments to explain the functionality.
974
 
975
Besides the actual NEORV32 Processor, the testbench also simulates "external" components that are connected
976
to the processor's external bus/memory interface. These components are:
977
 
978
* an external instruction memory (that also allows booting from it)
979
* an external data memory
980
* an external memory to simulate "external IO devices"
981
* a memory-mapped registers to trigger the processor's interrupt signals
982
 
983
The following table shows the base addresses of these four components and their default configuration and
984
properties (attributes: `r` = read, `w` = write, `e` = execute, `a` = atomic accesses possible, `8` = byte-accessible, `16` =
985
half-word-accessible, `32` = word-accessible).
986
 
987
.Testbench: processor-external memories
988
[cols="^4,>3,^5,<11"]
989
[options="header",grid="rows"]
990
|=======================
991
| Base address | Size          | Attributes           | Description
992
| `0x00000000` | `imem_size_c` | `r/w/e,  a, 8/16/32` | external IMEM (initialized with application image)
993
| `0x80000000` | `dmem_size_c` | `r/w/e,  a, 8/16/32` | external DMEM
994
| `0xf0000000` |      64 bytes | `r/w/e, !a, 8/16/32` | external "IO" memory, atomic accesses will fail
995
| `0xff000000` |       4 bytes | `-/w/-,  a,  -/-/32` | memory-mapped register to trigger "machine external", "machine software" and "SoC Fast Interrupt" interrupts
996
|=======================
997
 
998 63 zero_gravi
[NOTE]
999
The simulated NEORV32 does not use the bootloader and _directly boots_ the current application image (from
1000
the `rtl/core/neorv32_application_image.vhd` image file).
1001 60 zero_gravi
 
1002 63 zero_gravi
.UART output during simulation
1003 60 zero_gravi
[NOTE]
1004
Data written to the NEORV32 UART0 / UART1 transmitter is send to a virtual UART receiver implemented
1005
as part of the testbench. Received chars are send to the simulator console and are also stored to a log file
1006 63 zero_gravi
(`neorv32.testbench_uart0.out` for UART0, `neorv32.testbench_uart1.out` for UART1) inside the simulation's home folder.
1007
**Please note that printing via the native UART receiver takes a lot of time.** For faster simulation console output
1008
see section <<_faster_simulation_console_output>>.
1009 60 zero_gravi
 
1010
 
1011 61 zero_gravi
:sectnums:
1012
=== Faster Simulation Console Output
1013
 
1014 60 zero_gravi
When printing data via the UART the communication speed will always be based on the configured BAUD
1015
rate. For a simulation this might take some time. To have faster output you can enable the **simulation mode**
1016
or UART0/UART1 (see section https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0[Documentation: Primary Universal Asynchronous Receiver and Transmitter (UART0)]).
1017
 
1018
ASCII data send to UART0 will be immediately printed to the simulator console. Additionally, the
1019
ASCII data is logged in a file (`neorv32.uart0.sim_mode.text.out`) in the simulator home folder. All
1020
written 32-bit data is also dumped as 8-char hexadecimal value into a file
1021
(`neorv32.uart0.sim_mode.data.out`) also in the simulator home folder.
1022
 
1023
ASCII data send to UART1 will be immediately printed to the simulator console. Additionally, the
1024
ASCII data is logged in a file (`neorv32.uart1.sim_mode.text.out`) in the simulator home folder. All
1025
written 32-bit data is also dumped as 8-char hexadecimal value into a file
1026
(`neorv32.uart1.sim_mode.data.out`) also in the simulator home folder.
1027
 
1028
You can "automatically" enable the simulation mode of UART0/UART1 when compiling an application. In this case the
1029
"real" UART0/UART1 transmitter unit is permanently disabled. To enable the simulation mode just compile
1030
and install your application and add _UART0_SIM_MODE_ for UART0 and/or _UART1_SIM_MODE_ for UART1 to
1031
the compiler's _USER_FLAGS_ variable (do not forget the `-D` suffix flag):
1032
 
1033
[source, bash]
1034
----
1035
sw/example/blink_led$ make USER_FLAGS+=-DUART0_SIM_MODE clean_all all
1036
----
1037
 
1038 63 zero_gravi
The provided define will change the default UART0/UART1 setup function in order to set the simulation
1039
mode flag in the according UART's control register.
1040 60 zero_gravi
 
1041
[NOTE]
1042
The UART simulation output (to file and to screen) outputs "complete lines" at once. A line is
1043
completed with a line feed (newline, ASCII `\n` = 10).
1044
 
1045
 
1046 61 zero_gravi
:sectnums:
1047
=== Simulation using GHDL
1048 60 zero_gravi
 
1049 61 zero_gravi
To simulate the processor using _GHDL_ navigate to the `sim` folder and run the provided shell script.
1050
Any arguments that are provided while executing this script are passed to GHDL.
1051
For example the simulation time can be set to 20ms using `--stop-time=20ms` as argument.
1052 60 zero_gravi
 
1053
[source, bash]
1054
----
1055 61 zero_gravi
neorv32/sim$ sh ghdl_sim.sh --stop-time=20ms
1056 60 zero_gravi
----
1057
 
1058
 
1059 63 zero_gravi
:sectnums:
1060
=== In-Console Application Simulation
1061 60 zero_gravi
 
1062 63 zero_gravi
To directly compile and run a program in the console (using the default testbench and GHDL
1063
as simulator) you can use the `sim` makefile target. Make sure to use the UART simulation mode
1064
(`USER_FLAGS+=-DUART0_SIM_MODE` and/or `USER_FLAGS+=-DUART1_SIM_MODE`) to get
1065
faster / direct-to-console UART output.
1066
 
1067
[source, bash]
1068
----
1069
sw/example/blink_led$ make USER_FLAGS+=-DUART0_SIM_MODE clean_all sim
1070
[...]
1071
Blinking LED demo program
1072
----
1073
 
1074
 
1075
:sectnums:
1076
=== Hello World!
1077
 
1078
To do a quick test of the NEORV32 make sure to have [GHDL](https://github.com/ghdl/ghdl) and a
1079
[RISC-V gcc toolchain](https://github.com/stnolting/riscv-gcc-prebuilt) installed, navigate to the project's
1080
`sw/example/hello_world` folder and run `make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim`:
1081
 
1082
[TIP]
1083
The simulator will output some _sanity check_ notes (and warnings or even errors if something is ill-configured)
1084
right at the beginning of the simulation to give a brief overview of the actual NEORV32 SoC and CPU configurations.
1085
 
1086
[source, bash]
1087
----
1088
stnolting@Einstein:/mnt/n/Projects/neorv32/sw/example/hello_world$ make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim
1089
../../../sw/lib/source/neorv32_uart.c: In function 'neorv32_uart0_setup':
1090
../../../sw/lib/source/neorv32_uart.c:301:4: warning: #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! [-Wcpp]
1091
  301 |   #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only!
1092
      |    ^~~~~~~
1093
Memory utilization:
1094
   text    data     bss     dec     hex filename
1095
   4612       0     120    4732    127c main.elf
1096
Compiling ../../../sw/image_gen/image_gen
1097
Installing application image to ../../../rtl/core/neorv32_application_image.vhd
1098
Simulating neorv32_application_image.vhd...
1099
Tip: Compile application with USER_FLAGS+=-DUART[0/1]_SIM_MODE to auto-enable UART[0/1]'s simulation mode (redirect UART output to simulator console).
1100
Using simulation runtime args: --stop-time=10ms
1101
../rtl/core/neorv32_top.vhd:347:3:@0ms:(assertion note): NEORV32 PROCESSOR IO Configuration: GPIO MTIME UART0 UART1 SPI TWI PWM WDT CFS SLINK NEOLED XIRQ
1102
../rtl/core/neorv32_top.vhd:370:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM).
1103
../rtl/core/neorv32_top.vhd:394:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD).
1104
../rtl/core/neorv32_cpu.vhd:169:3:@0ms:(assertion note): NEORV32 CPU ISA Configuration (MARCH): RV32IMACU_Zbb_Zicsr_Zifencei_Zfinx_Debug
1105
../rtl/core/neorv32_cpu.vhd:189:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant  = TRUE to configure a DEFINED reset value for all CPU registers.
1106
../rtl/core/neorv32_imem.vhd:107:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (16384 bytes), pre-initialized with application (4612 bytes).
1107
../rtl/core/neorv32_dmem.vhd:89:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal DMEM (RAM, 8192 bytes).
1108
../rtl/core/neorv32_wishbone.vhd:136:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol.
1109
../rtl/core/neorv32_wishbone.vhd:140:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing auto-timeout (255 cycles).
1110
../rtl/core/neorv32_wishbone.vhd:144:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order.
1111
../rtl/core/neorv32_wishbone.vhd:148:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing registered RX path.
1112
../rtl/core/neorv32_slink.vhd:161:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing 8 RX and 8 TX stream links.
1113
 
1114
                                                                                       ##
1115
                                                                                       ##         ##   ##   ##
1116
 ##     ##   #########   ########    ########   ##      ##   ########    ########      ##       ################
1117
####    ##  ##          ##      ##  ##      ##  ##      ##  ##      ##  ##      ##     ##     ####            ####
1118
## ##   ##  ##          ##      ##  ##      ##  ##      ##          ##         ##      ##       ##   ######   ##
1119
##  ##  ##  #########   ##      ##  #########   ##      ##      #####        ##        ##     ####   ######   ####
1120
##   ## ##  ##          ##      ##  ##    ##     ##    ##           ##     ##          ##       ##   ######   ##
1121
##    ####  ##          ##      ##  ##     ##     ##  ##    ##      ##   ##            ##     ####            ####
1122
##     ##    #########   ########   ##      ##      ##       ########   ##########     ##       ################
1123
                                                                                       ##         ##   ##   ##
1124
                                                                                       ##
1125
Hello world! :)
1126
----
1127
 
1128
 
1129
:sectnums:
1130
=== Advanced Simulation using VUNIT
1131
 
1132
.WORK IN PROGRESS
1133
[WARNING]
1134
This Section Is Under Construction! +
1135
 +
1136
FIXME!
1137
 
1138
The NEORV32 provides a more sophisticated simulation setup using https://vunit.github.io/[VUNIT].
1139
The according VUNIT-based testbench is `sim/neorv32_tb.vhd`.
1140
 
1141
**WORK-IN-PROGRESS**
1142
 
1143
 
1144
 
1145 60 zero_gravi
<<<
1146
// ####################################################################################################################
1147
:sectnums:
1148
== Building the Documentation
1149
 
1150 61 zero_gravi
The documentation (datasheet + user guide) is written using `asciidoc`. The according source files
1151
can be found in `docs/...`. The documentation of the software framework is written _in-code_ using `doxygen`.
1152 60 zero_gravi
 
1153 62 zero_gravi
A makefiles in the project's `docs` directory is provided to build all of the documentation as HTML pages
1154 60 zero_gravi
or as PDF documents.
1155
 
1156
[TIP]
1157 61 zero_gravi
Pre-rendered PDFs are available online as _nightly pre-releases_: https://github.com/stnolting/neorv32/releases.
1158 60 zero_gravi
The HTML-based documentation is also available online at the project's https://stnolting.github.io/neorv32/[GitHub Pages].
1159
 
1160
The makefile provides a help target to show all available build options and their according outputs.
1161
 
1162
[source,bash]
1163
----
1164 62 zero_gravi
neorv32/docs$ make help
1165 60 zero_gravi
----
1166
 
1167
.Example: Generate HTML documentation (data sheet) using `asciidoctor`
1168
[source,bash]
1169
----
1170 62 zero_gravi
neorv32/docs$ make html
1171 60 zero_gravi
----
1172
 
1173
[TIP]
1174
If you don't have `asciidoctor` / `asciidoctor-pdf` installed, you can still generate all the documentation using
1175
a _docker container_ via `make container`.
1176
 
1177
 
1178
 
1179
<<<
1180
// ####################################################################################################################
1181
:sectnums:
1182
== FreeRTOS Support
1183
 
1184
A NEORV32-specific port and a simple demo for FreeRTOS (https://github.com/FreeRTOS/FreeRTOS) are
1185 61 zero_gravi
available in the `sw/example/demo_freeRTOS` folder. See the according documentation (`sw/example/demo_freeRTOS/README.md`)
1186
for more information.
1187 60 zero_gravi
 
1188
 
1189
 
1190
// ####################################################################################################################
1191
:sectnums:
1192
== RISC-V Architecture Test Framework
1193
 
1194
The NEORV32 Processor passes the according tests provided by the official RISC-V Architecture Test Suite
1195
(V2.0+), which is available online at GitHub: https://github.com/riscv/riscv-arch-test
1196
 
1197
All files required for executing the test framework on a simulated instance of the processor (including port
1198 62 zero_gravi
files) are located in the `sw/isa-test` folder of the NEORV32 repository. The test framework is executed via the
1199
`sim/run_riscv_arch_test.sh` script. Take a look at the provided `sim/README.md`
1200
(https://github.com/stnolting/neorv32/tree/master/sim[online at GitHub])
1201 60 zero_gravi
file for more information on how to run the tests and how testing is conducted in detail.
1202
 
1203
 
1204
 
1205
<<<
1206
// ####################################################################################################################
1207
:sectnums:
1208
== Debugging using the On-Chip Debugger
1209
 
1210 61 zero_gravi
The NEORV32 on-chip debugger allows _online_ in-system debugging via an external JTAG access port from a
1211 60 zero_gravi
host machine. The general flow is independent of the host machine's operating system. However, this tutorial uses
1212
Windows and Linux (Ubuntu on Windows) in parallel.
1213
 
1214 61 zero_gravi
[TIP]
1215
See datasheet section https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd[On Chip Debugger (OCD)]
1216
for more information.
1217
 
1218 60 zero_gravi
[NOTE]
1219
This tutorial uses `gdb` to **directly upload an executable** to the processor. If you are using the default
1220
processor setup _with_ internal instruction memory (IMEM) make sure it is implemented as RAM
1221 61 zero_gravi
(_INT_BOOTLOADER_EN_ generic = true).
1222 60 zero_gravi
 
1223
 
1224
:sectnums:
1225
=== Hardware Requirements
1226
 
1227
Make sure the on-chip debugger of your NEORV32 setups is implemented (_ON_CHIP_DEBUGGER_EN_ generic = true).
1228
Connect a JTAG adapter to the NEORV32 `jtag_*` interface signals. If you do not have a full-scale JTAG adapter, you can
1229
also use a FTDI-based adapter like the "FT2232H-56Q Mini Module", which is a simple and inexpensive FTDI breakout board.
1230
 
1231
.JTAG pin mapping
1232
[cols="^3,^2,^2"]
1233
[options="header",grid="rows"]
1234
|=======================
1235
| NEORV32 top signal | JTAG signal | FTDI port
1236
| `jtag_tck_i`       | TCK         | D0
1237
| `jtag_tdi_i`       | TDI         | D1
1238
| `jtag_tdo_o`       | TDO         | D2
1239
| `jtag_tms_i`       | TMS         | D3
1240
| `jtag_trst_i`      | TRST        | D4
1241
|=======================
1242
 
1243
[TIP]
1244
The low-active JTAG _test reset_ (TRST) signals is _optional_ as a reset can also be triggered via the TAP controller.
1245
If TRST is not used make sure to pull the signal _high_.
1246
 
1247
 
1248
:sectnums:
1249
=== OpenOCD
1250
 
1251
The NEORV32 on-chip debugger can be accessed using the https://github.com/riscv/riscv-openocd[RISC-V port of OpenOCD].
1252
Prebuilt binaries can be obtained - for example - from https://www.sifive.com/software[SiFive]. A pre-configured
1253
OpenOCD configuration file (`sw/openocd/openocd_neorv32.cfg`) is available that allows easy access to the NEORV32 CPU.
1254
 
1255
[NOTE]
1256
You might need to adapt `ftdi_vid_pid`, `ftdi_channel` and `ftdi_layout_init` in `sw/openocd/openocd_neorv32.cfg`
1257
according to your interface chip and your operating system.
1258
 
1259
[TIP]
1260
If you want to modify the JTAG clock speed (via `adapter speed` in `sw/openocd/openocd_neorv32.cfg`) make sure to meet
1261
the clock requirements noted in https://stnolting.github.io/neorv32/#_debug_module_dm[Documentation: Debug Transport Module (DTM)].
1262
 
1263
To access the processor using OpenOCD, open a terminal and start OpenOCD with the pre-configured configuration file.
1264
 
1265
.Connecting via OpenOCD (on Windows)
1266
[source, bash]
1267
--------------------------
1268
N:\Projects\neorv32\sw\openocd>openocd -f openocd_neorv32.cfg
1269
Open On-Chip Debugger 0.11.0-rc1+dev (SiFive OpenOCD 0.10.0-2020.12.1)
1270
Licensed under GNU GPL v2
1271
For bug reports:
1272
        https://github.com/sifive/freedom-tools/issues
1273
1
1274
Info : Listening on port 6666 for tcl connections
1275
Info : Listening on port 4444 for telnet connections
1276
Info : clock speed 1000 kHz
1277
Info : JTAG tap: neorv32.cpu tap/device found: 0x0cafe001 (mfg: 0x000 (), part: 0xcafe, ver: 0x0)
1278
Info : datacount=1 progbufsize=2
1279
Info : Disabling abstract command reads from CSRs.
1280
Info : Examined RISC-V core; found 1 harts
1281
Info :  hart 0: XLEN=32, misa=0x40801105
1282
Info : starting gdb server for neorv32.cpu.0 on 3333
1283
Info : Listening on port 3333 for gdb connections
1284
--------------------------
1285
 
1286
OpenOCD has successfully connected to the NEORV32 on-chip debugger and has examined the CPU (showing the content of
1287
the `misa` CSRs). Now you can use `gdb` to connect via port 3333.
1288
 
1289
 
1290
:sectnums:
1291
=== Debugging with GDB
1292
 
1293
This guide uses the simple "blink example" from `sw/example/blink_led` as simplified test application to
1294
show the basics of in-system debugging.
1295
 
1296
At first, the application needs to be compiled. We will use the minimal machine architecture configuration
1297
(`rv32i`) here to be independent of the actual processor/CPU configuration.
1298
Navigate to `sw/example/blink_led` and compile the application:
1299
 
1300
.Compile the test application
1301
[source, bash]
1302
--------------------------
1303
.../neorv32/sw/example/blink_led$ make MARCH=-march=rv32i clean_all all
1304
--------------------------
1305
 
1306
This will generate an ELF file `main.elf` that contains all the symbols required for debugging.
1307
Furthermore, an assembly listing file `main.asm` is generated that we will use to define breakpoints.
1308
 
1309
Open another terminal in `sw/example/blink_led` and start `gdb`.
1310 61 zero_gravi
The GNU debugger is part of the toolchain (see <<_software_toolchain_setup>>).
1311 60 zero_gravi
 
1312
.Starting GDB (on Linux (Ubuntu on Windows))
1313
[source, bash]
1314
--------------------------
1315
.../neorv32/sw/example/blink_led$ riscv32-unknown-elf-gdb
1316
GNU gdb (GDB) 10.1
1317
Copyright (C) 2020 Free Software Foundation, Inc.
1318
License GPLv3+: GNU GPL version 3 or later 
1319
This is free software: you are free to change and redistribute it.
1320
There is NO WARRANTY, to the extent permitted by law.
1321
Type "show copying" and "show warranty" for details.
1322
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv32-unknown-elf".
1323
Type "show configuration" for configuration details.
1324
For bug reporting instructions, please see:
1325
.
1326
Find the GDB manual and other documentation resources online at:
1327
    .
1328
 
1329
For help, type "help".
1330
Type "apropos word" to search for commands related to "word".
1331
(gdb)
1332
--------------------------
1333
 
1334
Now connect to OpenOCD using the default port 3333 on your local machine.
1335
Set the ELF file we want to debug to the recently generated `main.elf` from the `blink_led` example.
1336
Finally, upload the program to the processor.
1337
 
1338
[NOTE]
1339
The executable that is uploaded to the processor is **not** the default NEORV32 executable (`neorv32_exe.bin`) that
1340
is used for uploading via the bootloader. Instead, all the required sections (like `.text`) are extracted from `mail.elf`
1341
by GDB and uploaded via the debugger's indirect memory access.
1342
 
1343
.Running GDB
1344
[source, bash]
1345
--------------------------
1346
(gdb) target remote localhost:3333 <1>
1347
Remote debugging using localhost:3333
1348
warning: No executable has been specified and target does not support
1349
determining executable automatically.  Try using the "file" command.
1350
0xffff0c94 in ?? () <2>
1351
(gdb) file main.elf <3>
1352
A program is being debugged already.
1353
Are you sure you want to change the file? (y or n) y
1354
Reading symbols from main.elf...
1355
(gdb) load <4>
1356
Loading section .text, size 0xd0c lma 0x0
1357
Loading section .rodata, size 0x39c lma 0xd0c
1358
Start address 0x00000000, load size 4264
1359
Transfer rate: 43 KB/sec, 2132 bytes/write.
1360
(gdb)
1361
--------------------------
1362
<1> Connect to OpenOCD
1363
<2> The CPU was still executing code from the bootloader ROM - but that does not matter here
1364
<3> Select `mail.elf` from the `blink_led` example
1365
<4> Upload the executable
1366
 
1367
After the upload, GDB will make the processor jump to the beginning of the uploaded executable
1368
(by default, this is the beginning of the instruction memory at `0x00000000`) skipping the bootloader
1369
and halting the CPU right before executing the `blink_led` application.
1370
 
1371
 
1372
:sectnums:
1373
==== Breakpoint Example
1374
 
1375
The following steps are just a small showcase that illustrate a simple debugging scheme.
1376
 
1377
While compiling `blink_led`, an assembly listing file `main.asm` was generated.
1378
Open this file with a text editor to check out what the CPU is going to do when resumed.
1379
 
1380
The `blink_led` example implements a simple counter on the 8 lowest GPIO output ports. The program uses
1381
"busy wait" to have a visible delay between increments. This waiting is done by calling the `neorv32_cpu_delay_ms`
1382
function. We will add a _breakpoint_ right at the end of this wait function so we can step through the iterations
1383
of the counter.
1384
 
1385
.Cut-out from `main.asm` generated from the `blink_led` example
1386
[source, assembly]
1387
--------------------------
1388
00000688 <__neorv32_cpu_delay_ms_end>:
1389
 688:   01c12083                lw      ra,28(sp)
1390
 68c:   02010113                addi    sp,sp,32
1391
 690:   00008067                ret
1392
--------------------------
1393
 
1394
The very last instruction of the `neorv32_cpu_delay_ms` function is `ret` (= return)
1395
at hexadecimal `690` in this example. Add this address as _breakpoint_ to GDB.
1396
 
1397
[NOTE]
1398
The address might be different if you use a different version of the software framework or
1399
if different ISA options are configured.
1400
 
1401
.Adding a GDB breakpoint
1402
[source, bash]
1403
--------------------------
1404
(gdb) b * 0x690
1405
Breakpoint 1 at 0x690
1406
--------------------------
1407
 
1408
Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
1409
By this we can "step" from increment to increment.
1410
 
1411
.Iterating from breakpoint to breakpoint
1412
[source, bash]
1413
--------------------------
1414
Breakpoint 1 at 0x690
1415
(gdb) c
1416
Continuing.
1417
 
1418
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
1419
(gdb) c
1420
Continuing.
1421
 
1422
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
1423
(gdb) c
1424
Continuing.
1425
--------------------------
1426
 
1427
include::../legal.adoc[]

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.