NEORV32 API Reference
The NEORV32 RISC-V Processor
Loading...
Searching...
No Matches
neorv32_cpu.h
Go to the documentation of this file.
1// ================================================================================ //
2// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
3// Copyright (c) NEORV32 contributors. //
4// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
5// Licensed under the BSD-3-Clause license, see LICENSE for details. //
6// SPDX-License-Identifier: BSD-3-Clause //
7// ================================================================================ //
8
14#ifndef NEORV32_CPU_H
15#define NEORV32_CPU_H
16
17#include <stdint.h>
18
19
20/**********************************************************************/
24uint64_t neorv32_cpu_get_cycle(void);
25void neorv32_cpu_set_mcycle(uint64_t value);
26uint64_t neorv32_cpu_get_instret(void);
27void neorv32_cpu_set_minstret(uint64_t value);
30int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config);
32uint32_t neorv32_cpu_hpm_get_size(void);
37// ================================================================================================
38// Inline Load/Store
39// ================================================================================================
40
41
42/**********************************************************************/
50inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata) {
51
52 uint32_t reg_addr = addr;
53 uint32_t reg_data = wdata;
54 asm volatile ("sw %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
55}
56
57
58/**********************************************************************/
66inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
67
68 uint32_t reg_addr = addr;
69 uint32_t reg_data = (uint32_t)wdata;
70 asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
71}
72
73
74/**********************************************************************/
80inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
81
82 uint32_t reg_addr = addr;
83 uint32_t reg_data = (uint32_t)wdata;
84 asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
85}
86
87
88/**********************************************************************/
96inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
97
98 uint32_t reg_addr = addr;
99 uint32_t reg_data;
100 asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
101 return reg_data;
102}
103
104
105/**********************************************************************/
113inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
114
115 uint32_t reg_addr = addr;
116 uint16_t reg_data;
117 asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
118 return reg_data;
119}
120
121
122/**********************************************************************/
130inline int16_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_half(uint32_t addr) {
131
132 uint32_t reg_addr = addr;
133 int16_t reg_data;
134 asm volatile ("lh %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
135 return reg_data;
136}
137
138
139/**********************************************************************/
145inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
146
147 uint32_t reg_addr = addr;
148 uint8_t reg_data;
149 asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
150 return reg_data;
151}
152
153
154/**********************************************************************/
160inline int8_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_byte(uint32_t addr) {
161
162 uint32_t reg_addr = addr;
163 int8_t reg_data;
164 asm volatile ("lb %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
165 return reg_data;
166}
167
168
169// ================================================================================================
170// Inline CSR Access
171// ================================================================================================
172
173
174/**********************************************************************/
180inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_read(const int csr_id) {
181
182 uint32_t csr_data;
183 asm volatile ("csrr %[dst], %[id]" : [dst] "=r" (csr_data) : [id] "i" (csr_id));
184 return csr_data;
185}
186
187
188/**********************************************************************/
194inline void __attribute__ ((always_inline)) neorv32_cpu_csr_write(const int csr_id, uint32_t data) {
195
196 uint32_t csr_data = data;
197 asm volatile ("csrw %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
198}
199
200
201/**********************************************************************/
207inline void __attribute__ ((always_inline)) neorv32_cpu_csr_set(const int csr_id, uint32_t mask) {
208
209 uint32_t csr_data = mask;
210 asm volatile ("csrs %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
211}
212
213
214/**********************************************************************/
220inline void __attribute__ ((always_inline)) neorv32_cpu_csr_clr(const int csr_id, uint32_t mask) {
221
222 uint32_t csr_data = mask;
223 asm volatile ("csrc %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
224}
225
226
227// ================================================================================================
228// Inline Atomic Memory Access
229// ================================================================================================
230
231
232/**********************************************************************/
239inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata) {
240
241 uint32_t tmp;
242 asm volatile ("csrrw %[dst], %[id], %[src]" : [dst] "=r" (tmp) : [id] "i" (csr_id), [src] "r" (wdata));
243 return tmp;
244}
245
246
247/**********************************************************************/
256inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amolr(uint32_t addr) {
257
258#if defined __riscv_atomic
259 uint32_t amo_addr = addr;
260 uint32_t amo_rdata;
261
262 asm volatile ("lr.w %[dst], 0(%[addr])" : [dst] "=r" (amo_rdata) : [addr] "r" (amo_addr));
263
264 return amo_rdata;
265#else
266 (void)addr;
267
268 return 0;
269#endif
270}
271
272
273/**********************************************************************/
283inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amosc(uint32_t addr, uint32_t wdata) {
284
285#if defined __riscv_atomic
286 uint32_t amo_addr = addr;
287 uint32_t amo_wdata = wdata;
288 uint32_t amo_status;
289
290 asm volatile ("sc.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_status) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
291
292 return amo_status;
293#else
294 (void)addr;
295 (void)wdata;
296
297 return 1; // always fail
298#endif
299}
300
301
302/**********************************************************************/
312inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata) {
313
314#if defined __riscv_atomic
315 uint32_t amo_addr = addr;
316 uint32_t amo_wdata = wdata;
317 uint32_t amo_rdata;
318
319 asm volatile ("amoswap.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
320
321 return amo_rdata;
322#else
323 (void)addr;
324 (void)wdata;
325
326 return 0;
327#endif
328}
329
330
331/**********************************************************************/
341inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata) {
342
343#if defined __riscv_atomic
344 uint32_t amo_addr = addr;
345 uint32_t amo_wdata = wdata;
346 uint32_t amo_rdata;
347
348 asm volatile ("amoadd.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
349
350 return amo_rdata;
351#else
352 (void)addr;
353 (void)wdata;
354
355 return 0;
356#endif
357}
358
359
360/**********************************************************************/
370inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata) {
371
372#if defined __riscv_atomic
373 uint32_t amo_addr = addr;
374 uint32_t amo_wdata = wdata;
375 uint32_t amo_rdata;
376
377 asm volatile ("amoxor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
378
379 return amo_rdata;
380#else
381 (void)addr;
382 (void)wdata;
383
384 return 0;
385#endif
386}
387
388
389/**********************************************************************/
399inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoand(uint32_t addr, uint32_t wdata) {
400
401#if defined __riscv_atomic
402 uint32_t amo_addr = addr;
403 uint32_t amo_wdata = wdata;
404 uint32_t amo_rdata;
405
406 asm volatile ("amoand.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
407
408 return amo_rdata;
409#else
410 (void)addr;
411 (void)wdata;
412
413 return 0;
414#endif
415}
416
417
418/**********************************************************************/
428inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoor(uint32_t addr, uint32_t wdata) {
429
430#if defined __riscv_atomic
431 uint32_t amo_addr = addr;
432 uint32_t amo_wdata = wdata;
433 uint32_t amo_rdata;
434
435 asm volatile ("amoor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
436
437 return amo_rdata;
438#else
439 (void)addr;
440 (void)wdata;
441
442 return 0;
443#endif
444}
445
446
447/**********************************************************************/
457inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomin(uint32_t addr, uint32_t wdata) {
458
459#if defined __riscv_atomic
460 uint32_t amo_addr = addr;
461 uint32_t amo_wdata = wdata;
462 uint32_t amo_rdata;
463
464 asm volatile ("amomin.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
465
466 return amo_rdata;
467#else
468 (void)addr;
469 (void)wdata;
470
471 return 0;
472#endif
473}
474
475
476/**********************************************************************/
486inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomax(uint32_t addr, uint32_t wdata) {
487
488#if defined __riscv_atomic
489 uint32_t amo_addr = addr;
490 uint32_t amo_wdata = wdata;
491 uint32_t amo_rdata;
492
493 asm volatile ("amomax.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
494
495 return amo_rdata;
496#else
497 (void)addr;
498 (void)wdata;
499
500 return 0;
501#endif
502}
503
504
505/**********************************************************************/
515inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amominu(uint32_t addr, uint32_t wdata) {
516
517#if defined __riscv_atomic
518 uint32_t amo_addr = addr;
519 uint32_t amo_wdata = wdata;
520 uint32_t amo_rdata;
521
522 asm volatile ("amominu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
523
524 return amo_rdata;
525#else
526 (void)addr;
527 (void)wdata;
528
529 return 0;
530#endif
531}
532
533
534/**********************************************************************/
544inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata) {
545
546#if defined __riscv_atomic
547 uint32_t amo_addr = addr;
548 uint32_t amo_wdata = wdata;
549 uint32_t amo_rdata;
550
551 asm volatile ("amomaxu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
552
553 return amo_rdata;
554#else
555 (void)addr;
556 (void)wdata;
557
558 return 0;
559#endif
560}
561
562
563// ================================================================================================
564// Inline Misc
565// ================================================================================================
566
567
568/**********************************************************************/
574inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
575
576 asm volatile ("wfi");
577}
578
579
580#endif // NEORV32_CPU_H
void neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:50
uint32_t neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:370
void neorv32_cpu_set_mcycle(uint64_t value)
Definition neorv32_cpu.c:69
void neorv32_cpu_csr_set(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:207
uint32_t neorv32_cpu_pmp_get_num_regions(void)
Definition neorv32_cpu.c:130
void neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata)
Definition neorv32_cpu.h:66
int8_t neorv32_cpu_load_signed_byte(uint32_t addr)
Definition neorv32_cpu.h:160
uint16_t neorv32_cpu_load_unsigned_half(uint32_t addr)
Definition neorv32_cpu.h:113
uint64_t neorv32_cpu_get_instret(void)
Definition neorv32_cpu.c:86
uint32_t neorv32_cpu_load_unsigned_word(uint32_t addr)
Definition neorv32_cpu.h:96
uint32_t neorv32_cpu_amoand(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:399
void neorv32_cpu_set_minstret(uint64_t value)
Definition neorv32_cpu.c:111
uint32_t neorv32_cpu_amosc(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:283
uint32_t neorv32_cpu_amominu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:515
uint32_t neorv32_cpu_hpm_get_num_counters(void)
Definition neorv32_cpu.c:282
void neorv32_cpu_sleep(void)
Definition neorv32_cpu.h:574
uint32_t neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:341
uint32_t neorv32_cpu_amoor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:428
int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config)
Definition neorv32_cpu.c:214
int neorv32_cpu_hwtrig_get_number(void)
Definition neorv32_cpu.c:374
uint32_t neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:312
uint32_t neorv32_cpu_csr_read(const int csr_id)
Definition neorv32_cpu.h:180
uint32_t neorv32_cpu_amomax(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:486
uint32_t neorv32_cpu_amomin(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:457
void neorv32_cpu_csr_clr(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:220
uint64_t neorv32_cpu_get_cycle(void)
Definition neorv32_cpu.c:44
uint8_t neorv32_cpu_load_unsigned_byte(uint32_t addr)
Definition neorv32_cpu.h:145
uint32_t neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata)
Definition neorv32_cpu.h:239
uint32_t neorv32_cpu_amolr(uint32_t addr)
Definition neorv32_cpu.h:256
uint32_t neorv32_cpu_pmp_get_granularity(void)
Definition neorv32_cpu.c:174
uint32_t neorv32_cpu_hpm_get_size(void)
Definition neorv32_cpu.c:334
uint32_t neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:544
int16_t neorv32_cpu_load_signed_half(uint32_t addr)
Definition neorv32_cpu.h:130
void neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata)
Definition neorv32_cpu.h:80
void neorv32_cpu_csr_write(const int csr_id, uint32_t data)
Definition neorv32_cpu.h:194