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);
38// ================================================================================================
39// Inline Load/Store
40// ================================================================================================
41
42
43/**********************************************************************/
51inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata) {
52
53 uint32_t reg_addr = addr;
54 uint32_t reg_data = wdata;
55 asm volatile ("sw %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
56}
57
58
59/**********************************************************************/
67inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
68
69 uint32_t reg_addr = addr;
70 uint32_t reg_data = (uint32_t)wdata;
71 asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
72}
73
74
75/**********************************************************************/
81inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
82
83 uint32_t reg_addr = addr;
84 uint32_t reg_data = (uint32_t)wdata;
85 asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
86}
87
88
89/**********************************************************************/
97inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
98
99 uint32_t reg_addr = addr;
100 uint32_t reg_data;
101 asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
102 return reg_data;
103}
104
105
106/**********************************************************************/
114inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
115
116 uint32_t reg_addr = addr;
117 uint16_t reg_data;
118 asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
119 return reg_data;
120}
121
122
123/**********************************************************************/
131inline int16_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_half(uint32_t addr) {
132
133 uint32_t reg_addr = addr;
134 int16_t reg_data;
135 asm volatile ("lh %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
136 return reg_data;
137}
138
139
140/**********************************************************************/
146inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
147
148 uint32_t reg_addr = addr;
149 uint8_t reg_data;
150 asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
151 return reg_data;
152}
153
154
155/**********************************************************************/
161inline int8_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_byte(uint32_t addr) {
162
163 uint32_t reg_addr = addr;
164 int8_t reg_data;
165 asm volatile ("lb %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
166 return reg_data;
167}
168
169
170// ================================================================================================
171// Inline CSR Access
172// ================================================================================================
173
174
175/**********************************************************************/
181inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_read(const int csr_id) {
182
183 uint32_t csr_data;
184 asm volatile ("csrr %[dst], %[id]" : [dst] "=r" (csr_data) : [id] "i" (csr_id));
185 return csr_data;
186}
187
188
189/**********************************************************************/
195inline void __attribute__ ((always_inline)) neorv32_cpu_csr_write(const int csr_id, uint32_t data) {
196
197 uint32_t csr_data = data;
198 asm volatile ("csrw %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
199}
200
201
202/**********************************************************************/
208inline void __attribute__ ((always_inline)) neorv32_cpu_csr_set(const int csr_id, uint32_t mask) {
209
210 uint32_t csr_data = mask;
211 asm volatile ("csrs %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
212}
213
214
215/**********************************************************************/
221inline void __attribute__ ((always_inline)) neorv32_cpu_csr_clr(const int csr_id, uint32_t mask) {
222
223 uint32_t csr_data = mask;
224 asm volatile ("csrc %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
225}
226
227
228// ================================================================================================
229// Inline Atomic Memory Access
230// ================================================================================================
231
232
233/**********************************************************************/
240inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata) {
241
242 uint32_t tmp;
243 asm volatile ("csrrw %[dst], %[id], %[src]" : [dst] "=r" (tmp) : [id] "i" (csr_id), [src] "r" (wdata));
244 return tmp;
245}
246
247
248/**********************************************************************/
257inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amolr(uint32_t addr) {
258
259#if defined(__riscv_a) || defined(__riscv_zalrsc)
260 uint32_t amo_addr = addr;
261 uint32_t amo_rdata;
262
263 asm volatile ("lr.w %[dst], 0(%[addr])" : [dst] "=r" (amo_rdata) : [addr] "r" (amo_addr));
264
265 return amo_rdata;
266#else
267 (void)addr;
268
269 return 0;
270#endif
271}
272
273
274/**********************************************************************/
284inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amosc(uint32_t addr, uint32_t wdata) {
285
286#if defined(__riscv_a) || defined(__riscv_zalrsc)
287 uint32_t amo_addr = addr;
288 uint32_t amo_wdata = wdata;
289 uint32_t amo_status;
290
291 asm volatile ("sc.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_status) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
292
293 return amo_status;
294#else
295 (void)addr;
296 (void)wdata;
297
298 return 1; // always fail
299#endif
300}
301
302
303/**********************************************************************/
313inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata) {
314
315#if defined(__riscv_a) || defined(__riscv_zaamo)
316 uint32_t amo_addr = addr;
317 uint32_t amo_wdata = wdata;
318 uint32_t amo_rdata;
319
320 asm volatile ("amoswap.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
321
322 return amo_rdata;
323#else
324 (void)addr;
325 (void)wdata;
326
327 return 0;
328#endif
329}
330
331
332/**********************************************************************/
342inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata) {
343
344#if defined(__riscv_a) || defined(__riscv_zaamo)
345 uint32_t amo_addr = addr;
346 uint32_t amo_wdata = wdata;
347 uint32_t amo_rdata;
348
349 asm volatile ("amoadd.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
350
351 return amo_rdata;
352#else
353 (void)addr;
354 (void)wdata;
355
356 return 0;
357#endif
358}
359
360
361/**********************************************************************/
371inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata) {
372
373#if defined(__riscv_a) || defined(__riscv_zaamo)
374 uint32_t amo_addr = addr;
375 uint32_t amo_wdata = wdata;
376 uint32_t amo_rdata;
377
378 asm volatile ("amoxor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
379
380 return amo_rdata;
381#else
382 (void)addr;
383 (void)wdata;
384
385 return 0;
386#endif
387}
388
389
390/**********************************************************************/
400inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoand(uint32_t addr, uint32_t wdata) {
401
402#if defined(__riscv_a) || defined(__riscv_zaamo)
403 uint32_t amo_addr = addr;
404 uint32_t amo_wdata = wdata;
405 uint32_t amo_rdata;
406
407 asm volatile ("amoand.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
408
409 return amo_rdata;
410#else
411 (void)addr;
412 (void)wdata;
413
414 return 0;
415#endif
416}
417
418
419/**********************************************************************/
429inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoor(uint32_t addr, uint32_t wdata) {
430
431#if defined(__riscv_a) || defined(__riscv_zaamo)
432 uint32_t amo_addr = addr;
433 uint32_t amo_wdata = wdata;
434 uint32_t amo_rdata;
435
436 asm volatile ("amoor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
437
438 return amo_rdata;
439#else
440 (void)addr;
441 (void)wdata;
442
443 return 0;
444#endif
445}
446
447
448/**********************************************************************/
458inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomin(uint32_t addr, uint32_t wdata) {
459
460#if defined(__riscv_a) || defined(__riscv_zaamo)
461 uint32_t amo_addr = addr;
462 uint32_t amo_wdata = wdata;
463 uint32_t amo_rdata;
464
465 asm volatile ("amomin.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
466
467 return amo_rdata;
468#else
469 (void)addr;
470 (void)wdata;
471
472 return 0;
473#endif
474}
475
476
477/**********************************************************************/
487inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomax(uint32_t addr, uint32_t wdata) {
488
489#if defined(__riscv_a) || defined(__riscv_zaamo)
490 uint32_t amo_addr = addr;
491 uint32_t amo_wdata = wdata;
492 uint32_t amo_rdata;
493
494 asm volatile ("amomax.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
495
496 return amo_rdata;
497#else
498 (void)addr;
499 (void)wdata;
500
501 return 0;
502#endif
503}
504
505
506/**********************************************************************/
516inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amominu(uint32_t addr, uint32_t wdata) {
517
518#if defined(__riscv_a) || defined(__riscv_zaamo)
519 uint32_t amo_addr = addr;
520 uint32_t amo_wdata = wdata;
521 uint32_t amo_rdata;
522
523 asm volatile ("amominu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
524
525 return amo_rdata;
526#else
527 (void)addr;
528 (void)wdata;
529
530 return 0;
531#endif
532}
533
534
535/**********************************************************************/
545inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata) {
546
547#if defined(__riscv_a) || defined(__riscv_zaamo)
548 uint32_t amo_addr = addr;
549 uint32_t amo_wdata = wdata;
550 uint32_t amo_rdata;
551
552 asm volatile ("amomaxu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
553
554 return amo_rdata;
555#else
556 (void)addr;
557 (void)wdata;
558
559 return 0;
560#endif
561}
562
563
564// ================================================================================================
565// Inline Misc
566// ================================================================================================
567
568
569/**********************************************************************/
575inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
576
577 asm volatile ("wfi");
578}
579
580
581#endif // NEORV32_CPU_H
Main NEORV32 core library / driver / HAL include file.
void neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:51
uint32_t neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:371
void neorv32_cpu_set_mcycle(uint64_t value)
Definition neorv32_cpu.c:47
void neorv32_cpu_csr_set(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:208
uint32_t neorv32_cpu_pmp_get_num_regions(void)
Definition neorv32_cpu.c:133
void neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata)
Definition neorv32_cpu.h:67
int8_t neorv32_cpu_load_signed_byte(uint32_t addr)
Definition neorv32_cpu.h:161
uint16_t neorv32_cpu_load_unsigned_half(uint32_t addr)
Definition neorv32_cpu.h:114
uint64_t neorv32_cpu_get_instret(void)
Definition neorv32_cpu.c:89
uint32_t neorv32_cpu_load_unsigned_word(uint32_t addr)
Definition neorv32_cpu.h:97
uint32_t neorv32_cpu_amoand(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:400
void neorv32_cpu_set_minstret(uint64_t value)
Definition neorv32_cpu.c:114
uint32_t neorv32_cpu_amosc(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:284
uint32_t neorv32_cpu_amominu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:516
uint32_t neorv32_cpu_hpm_get_num_counters(void)
Definition neorv32_cpu.c:281
void neorv32_cpu_sleep(void)
Definition neorv32_cpu.h:575
uint32_t neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:342
uint32_t neorv32_cpu_amoor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:429
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
uint32_t neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:313
uint32_t neorv32_cpu_csr_read(const int csr_id)
Definition neorv32_cpu.h:181
uint32_t neorv32_cpu_amomax(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:487
uint32_t neorv32_cpu_amomin(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:458
void neorv32_cpu_csr_clr(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:221
uint64_t neorv32_cpu_get_cycle(void)
Definition neorv32_cpu.c:22
uint8_t neorv32_cpu_load_unsigned_byte(uint32_t addr)
Definition neorv32_cpu.h:146
uint32_t neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata)
Definition neorv32_cpu.h:240
uint64_t neorv32_cpu_get_time(void)
Definition neorv32_cpu.c:64
uint32_t neorv32_cpu_amolr(uint32_t addr)
Definition neorv32_cpu.h:257
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
uint32_t neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:545
int16_t neorv32_cpu_load_signed_half(uint32_t addr)
Definition neorv32_cpu.h:131
void neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata)
Definition neorv32_cpu.h:81
void neorv32_cpu_csr_write(const int csr_id, uint32_t data)
Definition neorv32_cpu.h:195