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 - 2026 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 <neorv32.h>
18#include <stdint.h>
19
20/**********************************************************************/
24uint64_t neorv32_cpu_get_cycle(void);
25void neorv32_cpu_set_mcycle(uint64_t value);
26uint64_t neorv32_cpu_get_time(void);
27uint64_t neorv32_cpu_get_instret(void);
28void neorv32_cpu_set_minstret(uint64_t value);
31int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config);
33uint32_t neorv32_cpu_hpm_get_size(void);
37// ================================================================================================
38// Inline Load/Store
39// ================================================================================================
40
41/**********************************************************************/
49static inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata) {
50
51 uint32_t reg_addr = addr;
52 uint32_t reg_data = wdata;
53 asm volatile ("sw %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr) : "memory");
54}
55
56/**********************************************************************/
64static inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
65
66 uint32_t reg_addr = addr;
67 uint32_t reg_data = (uint32_t)wdata;
68 asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr) : "memory");
69}
70
71/**********************************************************************/
77static inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
78
79 uint32_t reg_addr = addr;
80 uint32_t reg_data = (uint32_t)wdata;
81 asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr) : "memory");
82}
83
84/**********************************************************************/
92static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
93
94 uint32_t reg_addr = addr;
95 uint32_t reg_data;
96 asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr) : "memory");
97 return reg_data;
98}
99
100/**********************************************************************/
108static inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
109
110 uint32_t reg_addr = addr;
111 uint16_t reg_data;
112 asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr) : "memory");
113 return reg_data;
114}
115
116/**********************************************************************/
124static inline int16_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_half(uint32_t addr) {
125
126 uint32_t reg_addr = addr;
127 int16_t reg_data;
128 asm volatile ("lh %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr) : "memory");
129 return reg_data;
130}
131
132/**********************************************************************/
138static inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
139
140 uint32_t reg_addr = addr;
141 uint8_t reg_data;
142 asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr) : "memory");
143 return reg_data;
144}
145
146/**********************************************************************/
152static inline int8_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_byte(uint32_t addr) {
153
154 uint32_t reg_addr = addr;
155 int8_t reg_data;
156 asm volatile ("lb %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr) : "memory");
157 return reg_data;
158}
159
160// ================================================================================================
161// Inline CSR Access
162// ================================================================================================
163
164/**********************************************************************/
170static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_read(const int csr_id) {
171
172 uint32_t csr_data;
173 asm volatile ("csrr %[dst], %[id]" : [dst] "=r" (csr_data) : [id] "i" (csr_id));
174 return csr_data;
175}
176
177/**********************************************************************/
183static inline void __attribute__ ((always_inline)) neorv32_cpu_csr_write(const int csr_id, uint32_t data) {
184
185 uint32_t csr_data = data;
186 asm volatile ("csrw %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
187}
188
189/**********************************************************************/
195static inline void __attribute__ ((always_inline)) neorv32_cpu_csr_set(const int csr_id, uint32_t mask) {
196
197 uint32_t csr_data = mask;
198 asm volatile ("csrs %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
199}
200
201/**********************************************************************/
207static inline void __attribute__ ((always_inline)) neorv32_cpu_csr_clr(const int csr_id, uint32_t mask) {
208
209 uint32_t csr_data = mask;
210 asm volatile ("csrc %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
211}
212
213// ================================================================================================
214// Inline Atomic Memory Access
215// ================================================================================================
216
217/**********************************************************************/
224static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata) {
225
226 uint32_t tmp;
227 asm volatile ("csrrw %[dst], %[id], %[src]" : [dst] "=r" (tmp) : [id] "i" (csr_id), [src] "r" (wdata) : "memory");
228 return tmp;
229}
230
231/**********************************************************************/
240static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amolr(uint32_t addr) {
241
242#if defined(__riscv_a) || defined(__riscv_zalrsc)
243 uint32_t amo_addr = addr;
244 uint32_t amo_rdata;
245
246 asm volatile ("lr.w %[dst], 0(%[addr])" : [dst] "=r" (amo_rdata) : [addr] "r" (amo_addr) : "memory");
247
248 return amo_rdata;
249#else
250 (void)addr;
251
252 return 0;
253#endif
254}
255
256/**********************************************************************/
266static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amosc(uint32_t addr, uint32_t wdata) {
267
268#if defined(__riscv_a) || defined(__riscv_zalrsc)
269 uint32_t amo_addr = addr;
270 uint32_t amo_wdata = wdata;
271 uint32_t amo_status;
272
273 asm volatile ("sc.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_status) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
274
275 return amo_status;
276#else
277 (void)addr;
278 (void)wdata;
279
280 return 1; // always fail
281#endif
282}
283
284/**********************************************************************/
294static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata) {
295
296#if defined(__riscv_a) || defined(__riscv_zaamo)
297 uint32_t amo_addr = addr;
298 uint32_t amo_wdata = wdata;
299 uint32_t amo_rdata;
300
301 asm volatile ("amoswap.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
302
303 return amo_rdata;
304#else
305 (void)addr;
306 (void)wdata;
307
308 return 0;
309#endif
310}
311
312/**********************************************************************/
322static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata) {
323
324#if defined(__riscv_a) || defined(__riscv_zaamo)
325 uint32_t amo_addr = addr;
326 uint32_t amo_wdata = wdata;
327 uint32_t amo_rdata;
328
329 asm volatile ("amoadd.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
330
331 return amo_rdata;
332#else
333 (void)addr;
334 (void)wdata;
335
336 return 0;
337#endif
338}
339
340/**********************************************************************/
350static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata) {
351
352#if defined(__riscv_a) || defined(__riscv_zaamo)
353 uint32_t amo_addr = addr;
354 uint32_t amo_wdata = wdata;
355 uint32_t amo_rdata;
356
357 asm volatile ("amoxor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
358
359 return amo_rdata;
360#else
361 (void)addr;
362 (void)wdata;
363
364 return 0;
365#endif
366}
367
368/**********************************************************************/
378static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoand(uint32_t addr, uint32_t wdata) {
379
380#if defined(__riscv_a) || defined(__riscv_zaamo)
381 uint32_t amo_addr = addr;
382 uint32_t amo_wdata = wdata;
383 uint32_t amo_rdata;
384
385 asm volatile ("amoand.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
386
387 return amo_rdata;
388#else
389 (void)addr;
390 (void)wdata;
391
392 return 0;
393#endif
394}
395
396/**********************************************************************/
406static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoor(uint32_t addr, uint32_t wdata) {
407
408#if defined(__riscv_a) || defined(__riscv_zaamo)
409 uint32_t amo_addr = addr;
410 uint32_t amo_wdata = wdata;
411 uint32_t amo_rdata;
412
413 asm volatile ("amoor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
414
415 return amo_rdata;
416#else
417 (void)addr;
418 (void)wdata;
419
420 return 0;
421#endif
422}
423
424/**********************************************************************/
434static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomin(uint32_t addr, uint32_t wdata) {
435
436#if defined(__riscv_a) || defined(__riscv_zaamo)
437 uint32_t amo_addr = addr;
438 uint32_t amo_wdata = wdata;
439 uint32_t amo_rdata;
440
441 asm volatile ("amomin.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
442
443 return amo_rdata;
444#else
445 (void)addr;
446 (void)wdata;
447
448 return 0;
449#endif
450}
451
452/**********************************************************************/
462static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomax(uint32_t addr, uint32_t wdata) {
463
464#if defined(__riscv_a) || defined(__riscv_zaamo)
465 uint32_t amo_addr = addr;
466 uint32_t amo_wdata = wdata;
467 uint32_t amo_rdata;
468
469 asm volatile ("amomax.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
470
471 return amo_rdata;
472#else
473 (void)addr;
474 (void)wdata;
475
476 return 0;
477#endif
478}
479
480/**********************************************************************/
490static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amominu(uint32_t addr, uint32_t wdata) {
491
492#if defined(__riscv_a) || defined(__riscv_zaamo)
493 uint32_t amo_addr = addr;
494 uint32_t amo_wdata = wdata;
495 uint32_t amo_rdata;
496
497 asm volatile ("amominu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
498
499 return amo_rdata;
500#else
501 (void)addr;
502 (void)wdata;
503
504 return 0;
505#endif
506}
507
508/**********************************************************************/
518static inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata) {
519
520#if defined(__riscv_a) || defined(__riscv_zaamo)
521 uint32_t amo_addr = addr;
522 uint32_t amo_wdata = wdata;
523 uint32_t amo_rdata;
524
525 asm volatile ("amomaxu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr) : "memory");
526
527 return amo_rdata;
528#else
529 (void)addr;
530 (void)wdata;
531
532 return 0;
533#endif
534}
535
536// ================================================================================================
537// Inline Misc
538// ================================================================================================
539
540/**********************************************************************/
546static inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
547
548 asm volatile ("wfi");
549}
550
551#endif // NEORV32_CPU_H
Main NEORV32 core library / driver / HAL include file.
static uint32_t neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:518
static uint32_t neorv32_cpu_csr_read(const int csr_id)
Definition neorv32_cpu.h:170
static uint32_t neorv32_cpu_amomin(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:434
void neorv32_cpu_set_mcycle(uint64_t value)
Definition neorv32_cpu.c:47
uint32_t neorv32_cpu_pmp_get_num_regions(void)
Definition neorv32_cpu.c:133
static void neorv32_cpu_csr_clr(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:207
static void neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata)
Definition neorv32_cpu.h:64
static uint32_t neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:322
uint64_t neorv32_cpu_get_instret(void)
Definition neorv32_cpu.c:89
static uint32_t neorv32_cpu_amominu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:490
static uint32_t neorv32_cpu_load_unsigned_word(uint32_t addr)
Definition neorv32_cpu.h:92
static uint32_t neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:350
static uint32_t neorv32_cpu_amolr(uint32_t addr)
Definition neorv32_cpu.h:240
void neorv32_cpu_set_minstret(uint64_t value)
Definition neorv32_cpu.c:114
static void neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata)
Definition neorv32_cpu.h:77
uint32_t neorv32_cpu_hpm_get_num_counters(void)
Definition neorv32_cpu.c:281
static uint32_t neorv32_cpu_amoand(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:378
static uint16_t neorv32_cpu_load_unsigned_half(uint32_t addr)
Definition neorv32_cpu.h:108
static uint8_t neorv32_cpu_load_unsigned_byte(uint32_t addr)
Definition neorv32_cpu.h:138
static void neorv32_cpu_csr_write(const int csr_id, uint32_t data)
Definition neorv32_cpu.h:183
static uint32_t neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:294
static void neorv32_cpu_sleep(void)
Definition neorv32_cpu.h:546
static uint32_t neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata)
Definition neorv32_cpu.h:224
static uint32_t neorv32_cpu_amosc(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:266
static uint32_t neorv32_cpu_amomax(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:462
int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config)
Definition neorv32_cpu.c:213
int neorv32_cpu_hwtrig_get_number(void)
Definition neorv32_cpu.c:405
static void neorv32_cpu_csr_set(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:195
static int8_t neorv32_cpu_load_signed_byte(uint32_t addr)
Definition neorv32_cpu.h:152
uint64_t neorv32_cpu_get_cycle(void)
Definition neorv32_cpu.c:22
uint64_t neorv32_cpu_get_time(void)
Definition neorv32_cpu.c:64
static uint32_t neorv32_cpu_amoor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:406
uint32_t neorv32_cpu_pmp_get_granularity(void)
Definition neorv32_cpu.c:173
uint32_t neorv32_cpu_hpm_get_size(void)
Definition neorv32_cpu.c:365
static int16_t neorv32_cpu_load_signed_half(uint32_t addr)
Definition neorv32_cpu.h:124
static void neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:49