NEORV32 Software Framework Documentation
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);
36// ================================================================================================
37// Inline Load/Store
38// ================================================================================================
39
40
41/**********************************************************************/
49inline 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));
54}
55
56
57/**********************************************************************/
65inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
66
67 uint32_t reg_addr = addr;
68 uint32_t reg_data = (uint32_t)wdata;
69 asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
70}
71
72
73/**********************************************************************/
79inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
80
81 uint32_t reg_addr = addr;
82 uint32_t reg_data = (uint32_t)wdata;
83 asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
84}
85
86
87/**********************************************************************/
95inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
96
97 uint32_t reg_addr = addr;
98 uint32_t reg_data;
99 asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
100 return reg_data;
101}
102
103
104/**********************************************************************/
112inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
113
114 uint32_t reg_addr = addr;
115 uint16_t reg_data;
116 asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
117 return reg_data;
118}
119
120
121/**********************************************************************/
129inline int16_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_half(uint32_t addr) {
130
131 uint32_t reg_addr = addr;
132 int16_t reg_data;
133 asm volatile ("lh %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
134 return reg_data;
135}
136
137
138/**********************************************************************/
144inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
145
146 uint32_t reg_addr = addr;
147 uint8_t reg_data;
148 asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
149 return reg_data;
150}
151
152
153/**********************************************************************/
159inline int8_t __attribute__ ((always_inline)) neorv32_cpu_load_signed_byte(uint32_t addr) {
160
161 uint32_t reg_addr = addr;
162 int8_t reg_data;
163 asm volatile ("lb %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
164 return reg_data;
165}
166
167
168// ================================================================================================
169// Inline CSR Access
170// ================================================================================================
171
172
173/**********************************************************************/
179inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_read(const int csr_id) {
180
181 uint32_t csr_data;
182 asm volatile ("csrr %[dst], %[id]" : [dst] "=r" (csr_data) : [id] "i" (csr_id));
183 return csr_data;
184}
185
186
187/**********************************************************************/
193inline void __attribute__ ((always_inline)) neorv32_cpu_csr_write(const int csr_id, uint32_t data) {
194
195 uint32_t csr_data = data;
196 asm volatile ("csrw %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
197}
198
199
200/**********************************************************************/
206inline void __attribute__ ((always_inline)) neorv32_cpu_csr_set(const int csr_id, uint32_t mask) {
207
208 uint32_t csr_data = mask;
209 asm volatile ("csrs %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
210}
211
212
213/**********************************************************************/
219inline void __attribute__ ((always_inline)) neorv32_cpu_csr_clr(const int csr_id, uint32_t mask) {
220
221 uint32_t csr_data = mask;
222 asm volatile ("csrc %[id], %[src]" : : [id] "i" (csr_id), [src] "r" (csr_data));
223}
224
225
226// ================================================================================================
227// Inline Atomic Memory Access
228// ================================================================================================
229
230
231/**********************************************************************/
238inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata) {
239
240 uint32_t tmp;
241 asm volatile ("csrrw %[dst], %[id], %[src]" : [dst] "=r" (tmp) : [id] "i" (csr_id), [src] "r" (wdata));
242 return tmp;
243}
244
245
246/**********************************************************************/
255inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amolr(uint32_t addr) {
256
257#if defined __riscv_atomic
258 uint32_t amo_addr = addr;
259 uint32_t amo_rdata;
260
261 asm volatile ("lr.w %[dst], 0(%[addr])" : [dst] "=r" (amo_rdata) : [addr] "r" (amo_addr));
262
263 return amo_rdata;
264#else
265 (void)addr;
266
267 return 0;
268#endif
269}
270
271
272/**********************************************************************/
282inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amosc(uint32_t addr, uint32_t wdata) {
283
284#if defined __riscv_atomic
285 uint32_t amo_addr = addr;
286 uint32_t amo_wdata = wdata;
287 uint32_t amo_status;
288
289 asm volatile ("sc.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_status) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
290
291 return amo_status;
292#else
293 (void)addr;
294 (void)wdata;
295
296 return 1; // always fail
297#endif
298}
299
300
301/**********************************************************************/
311inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata) {
312
313#if defined __riscv_atomic
314 uint32_t amo_addr = addr;
315 uint32_t amo_wdata = wdata;
316 uint32_t amo_rdata;
317
318 asm volatile ("amoswap.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
319
320 return amo_rdata;
321#else
322 (void)addr;
323 (void)wdata;
324
325 return 0;
326#endif
327}
328
329
330/**********************************************************************/
340inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata) {
341
342#if defined __riscv_atomic
343 uint32_t amo_addr = addr;
344 uint32_t amo_wdata = wdata;
345 uint32_t amo_rdata;
346
347 asm volatile ("amoadd.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
348
349 return amo_rdata;
350#else
351 (void)addr;
352 (void)wdata;
353
354 return 0;
355#endif
356}
357
358
359/**********************************************************************/
369inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata) {
370
371#if defined __riscv_atomic
372 uint32_t amo_addr = addr;
373 uint32_t amo_wdata = wdata;
374 uint32_t amo_rdata;
375
376 asm volatile ("amoxor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
377
378 return amo_rdata;
379#else
380 (void)addr;
381 (void)wdata;
382
383 return 0;
384#endif
385}
386
387
388/**********************************************************************/
398inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoand(uint32_t addr, uint32_t wdata) {
399
400#if defined __riscv_atomic
401 uint32_t amo_addr = addr;
402 uint32_t amo_wdata = wdata;
403 uint32_t amo_rdata;
404
405 asm volatile ("amoand.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
406
407 return amo_rdata;
408#else
409 (void)addr;
410 (void)wdata;
411
412 return 0;
413#endif
414}
415
416
417/**********************************************************************/
427inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amoor(uint32_t addr, uint32_t wdata) {
428
429#if defined __riscv_atomic
430 uint32_t amo_addr = addr;
431 uint32_t amo_wdata = wdata;
432 uint32_t amo_rdata;
433
434 asm volatile ("amoor.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
435
436 return amo_rdata;
437#else
438 (void)addr;
439 (void)wdata;
440
441 return 0;
442#endif
443}
444
445
446/**********************************************************************/
456inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomin(uint32_t addr, uint32_t wdata) {
457
458#if defined __riscv_atomic
459 uint32_t amo_addr = addr;
460 uint32_t amo_wdata = wdata;
461 uint32_t amo_rdata;
462
463 asm volatile ("amomin.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
464
465 return amo_rdata;
466#else
467 (void)addr;
468 (void)wdata;
469
470 return 0;
471#endif
472}
473
474
475/**********************************************************************/
485inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomax(uint32_t addr, uint32_t wdata) {
486
487#if defined __riscv_atomic
488 uint32_t amo_addr = addr;
489 uint32_t amo_wdata = wdata;
490 uint32_t amo_rdata;
491
492 asm volatile ("amomax.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
493
494 return amo_rdata;
495#else
496 (void)addr;
497 (void)wdata;
498
499 return 0;
500#endif
501}
502
503
504/**********************************************************************/
514inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amominu(uint32_t addr, uint32_t wdata) {
515
516#if defined __riscv_atomic
517 uint32_t amo_addr = addr;
518 uint32_t amo_wdata = wdata;
519 uint32_t amo_rdata;
520
521 asm volatile ("amominu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
522
523 return amo_rdata;
524#else
525 (void)addr;
526 (void)wdata;
527
528 return 0;
529#endif
530}
531
532
533/**********************************************************************/
543inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_amomaxu(uint32_t addr, uint32_t wdata) {
544
545#if defined __riscv_atomic
546 uint32_t amo_addr = addr;
547 uint32_t amo_wdata = wdata;
548 uint32_t amo_rdata;
549
550 asm volatile ("amomaxu.w %[dst], %[src], (%[addr])" : [dst] "=r" (amo_rdata) : [src] "r" (amo_wdata), [addr] "r" (amo_addr));
551
552 return amo_rdata;
553#else
554 (void)addr;
555 (void)wdata;
556
557 return 0;
558#endif
559}
560
561
562// ================================================================================================
563// Inline Misc
564// ================================================================================================
565
566
567/**********************************************************************/
573inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
574
575 asm volatile ("wfi");
576}
577
578
579#endif // NEORV32_CPU_H
void neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:49
uint32_t neorv32_cpu_amoxor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:369
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:206
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:65
int8_t neorv32_cpu_load_signed_byte(uint32_t addr)
Definition neorv32_cpu.h:159
uint16_t neorv32_cpu_load_unsigned_half(uint32_t addr)
Definition neorv32_cpu.h:112
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:95
uint32_t neorv32_cpu_amoand(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:398
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:282
uint32_t neorv32_cpu_amominu(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:514
uint32_t neorv32_cpu_hpm_get_num_counters(void)
Definition neorv32_cpu.c:282
void neorv32_cpu_sleep(void)
Definition neorv32_cpu.h:573
uint32_t neorv32_cpu_amoadd(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:340
uint32_t neorv32_cpu_amoor(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:427
int neorv32_cpu_pmp_configure_region(int index, uint32_t addr, uint8_t config)
Definition neorv32_cpu.c:214
uint32_t neorv32_cpu_amoswap(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:311
uint32_t neorv32_cpu_csr_read(const int csr_id)
Definition neorv32_cpu.h:179
uint32_t neorv32_cpu_amomax(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:485
uint32_t neorv32_cpu_amomin(uint32_t addr, uint32_t wdata)
Definition neorv32_cpu.h:456
void neorv32_cpu_csr_clr(const int csr_id, uint32_t mask)
Definition neorv32_cpu.h:219
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:144
uint32_t neorv32_cpu_csr_swap(const int csr_id, uint32_t wdata)
Definition neorv32_cpu.h:238
uint32_t neorv32_cpu_amolr(uint32_t addr)
Definition neorv32_cpu.h:255
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:543
int16_t neorv32_cpu_load_signed_half(uint32_t addr)
Definition neorv32_cpu.h:129
void neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata)
Definition neorv32_cpu.h:79
void neorv32_cpu_csr_write(const int csr_id, uint32_t data)
Definition neorv32_cpu.h:193