mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-23 21:57:33 -04:00
updated documentation
This commit is contained in:
parent
583bbf59da
commit
31826d3cfa
4 changed files with 29 additions and 23 deletions
18
README.md
18
README.md
|
@ -99,16 +99,18 @@ The processor passes the official `rv32i`, `rv32im`, `rv32imc`, `rv32Zicsr` and
|
|||
The custom extensions are always enabled and are indicated via the `X` bit in the `misa` CSR.
|
||||
|
||||
* Four *fast interrupt* request channels with according control/status bits in `mie` and `mip` and custom exception codes in `mcause`
|
||||
* `mzext` CSR to check for implemented Z* CPU extensions
|
||||
|
||||
|
||||
### To-Do / Wish List
|
||||
|
||||
- Add AXI(-Lite) bridges
|
||||
- Synthesis results for more platforms
|
||||
- Port Dhrystone benchmark
|
||||
- Implement atomic operations (`A` extension) and floating-point operations (`F` extension)
|
||||
- Maybe port an RTOS (like [Zephyr](https://github.com/zephyrproject-rtos/zephyr), [freeRTOS](https://www.freertos.org) or [RIOT](https://www.riot-os.org))
|
||||
|
||||
- Implement further CPU extensions:
|
||||
- Atomic operations (`A`)
|
||||
- Floating-point instructions (`F`)
|
||||
- ...
|
||||
|
||||
|
||||
## Features
|
||||
|
@ -177,7 +179,7 @@ the [ `mie` `mtvec` `mscratch` `mepc` `mcause`(read-only!) `mtval` `mip` `mvendorid` `marchid` `mimpid` `mhartid`
|
||||
* Machine CSRs: `mstatus` `misa`(read-only!) `mie` `mtvec` `mscratch` `mepc` `mcause`(read-only!) `mtval` `mip` `mvendorid` `marchid` `mimpid` `mhartid` `mzext`(custom)
|
||||
* Supported exceptions and interrupts:
|
||||
* Misaligned instruction address
|
||||
* Instruction access fault
|
||||
|
@ -274,7 +276,7 @@ The [CoreMark CPU benchmark](https://www.eembc.org/coremark) was executed on the
|
|||
[sw/example/coremark](https://github.com/stnolting/neorv32/blob/master/sw/example/coremark) project folder. This benchmark
|
||||
tests the capabilities of a CPU itself rather than the functions provided by the whole system / SoC.
|
||||
|
||||
Results generated for hardware version: `1.3.7.0`
|
||||
Results generated for hardware version: `1.3.7.3`
|
||||
|
||||
~~~
|
||||
**Configuration**
|
||||
|
@ -289,7 +291,7 @@ Peripherals: UART for printing the results
|
|||
| `rv32i` | 26 748 bytes | `-O3` | 28.98 | 0.2898 |
|
||||
| `rv32im` | 25 580 bytes | `-O3` | 60.60 | 0.6060 |
|
||||
| `rv32imc` | 19 636 bytes | `-O3` | 62.50 | 0.6250 |
|
||||
| `rv32imc` + FAST_MUL | 19 636 bytes | `-O3` | 74.07 | 0.7407 |
|
||||
| `rv32imc` + FAST_MUL | 19 636 bytes | `-O3` | 76.92 | 0.7692 |
|
||||
|
||||
The _FAST_MUL_ configuration uses DSPs for the multiplier of the `M` extension (enabled via the `FAST_MUL_EN` generic).
|
||||
|
||||
|
@ -308,14 +310,14 @@ iterations, which reflects a pretty good "real-life" work load. The average CPI
|
|||
dividing the total number of required clock cycles (only the timed core to avoid distortion due to IO wait cycles; sampled via the `cycle[h]` CSRs)
|
||||
by the number of executed instructions (`instret[h]` CSRs). The executables were generated using optimization `-O3`.
|
||||
|
||||
Results generated for hardware version: `1.3.7.0`
|
||||
Results generated for hardware version: `1.3.7.3`
|
||||
|
||||
| CPU | Required Clock Cycles | Executed Instructions | Average CPI |
|
||||
|:---------------------|----------------------:|----------------------:|:-----------:|
|
||||
| `rv32i` | 6 955 817 507 | 1 468 927 290 | 4.73 |
|
||||
| `rv32im` | 3 376 961 507 | 601 565 750 | 5.61 |
|
||||
| `rv32imc` | 3 274 832 513 | 601 565 964 | 5.44 |
|
||||
| `rv32imc` + FAST_MUL | 2 711 072 513 | 601 566 024 | 4.51 |
|
||||
| `rv32imc` + FAST_MUL | 2 689 845 200 | 601 565 890 | 4.47 |
|
||||
|
||||
The _FAST_MUL_ configuration uses DSPs for the multiplier of the `M` extension (enabled via the `FAST_MUL_EN` generic).
|
||||
|
||||
|
|
BIN
docs/NEORV32.pdf
BIN
docs/NEORV32.pdf
Binary file not shown.
|
@ -52,40 +52,37 @@
|
|||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Main function, shows an incrementing 8-bit timer on GPIO.output(7:0).
|
||||
* Main function; shows an incrementing 8-bit counter on GPIO.output(7:0).
|
||||
*
|
||||
* @note This program requires the GPIO to be synthesized (the UART is optional).
|
||||
* @note This program requires the GPIO controller to be synthesized (the UART is optional).
|
||||
*
|
||||
* @return Irrelevant.
|
||||
**************************************************************************/
|
||||
int main() {
|
||||
|
||||
// init UART at default baud rate, no rx interrupt, no tx interrupt
|
||||
neorv32_uart_setup(BAUD_RATE, 0, 0);
|
||||
|
||||
// check if GPIO unit is implemented at all
|
||||
if (neorv32_gpio_available() == 0) {
|
||||
return 0; // nope, no GPIO unit synthesized :(
|
||||
neorv32_uart_print("Error! No GPIO unit synthesized!\n");
|
||||
return 0; // nope, no GPIO unit synthesized
|
||||
}
|
||||
|
||||
|
||||
// capture all exceptions and give debug info via UART
|
||||
// this is not required, but keeps us safe
|
||||
neorv32_rte_setup();
|
||||
|
||||
|
||||
// init UART at default baud rate, no rx interrupt, no tx interrupt
|
||||
neorv32_uart_setup(BAUD_RATE, 0, 0);
|
||||
|
||||
// say hello
|
||||
neorv32_uart_print("Blinking LED demo program\n");
|
||||
|
||||
|
||||
neorv32_gpio_port_set(0); // clear gpio output put
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
while (1) {
|
||||
neorv32_gpio_port_set(cnt & 0xFF); // mask for lowest 8 bit
|
||||
neorv32_cpu_delay_ms(200); // wait 0.2s using busy wait
|
||||
cnt++; // increment counter
|
||||
neorv32_gpio_port_set(cnt++ & 0xFF); // increment counter and mask for lowest 8 bit
|
||||
neorv32_cpu_delay_ms(200); // wait 200ms using busy wait
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
#define NUM_CELLS_Y 40
|
||||
/** Delay between generations in ms */
|
||||
#define GEN_DELAY 500
|
||||
/** Symbol for dead cell */
|
||||
#define CELL_DEAD (' ')
|
||||
/** Symbol for alive cell */
|
||||
#define CELL_ALIVE ('#')
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
@ -172,7 +176,10 @@ int main(void) {
|
|||
cell = get_cell(u, x, y); // state of current cell
|
||||
n = get_neighborhood(u, x, y); // number of living neighbor cells
|
||||
|
||||
// classic rule set
|
||||
// -- classic rule set --
|
||||
// if center cell is dead -> cell comes to life when there are exactly 3 living cells around
|
||||
// if center cell is alive -> stay alive if there are 2 or three living cells around
|
||||
// else -> cell is/becomes dead
|
||||
if (((cell == 0) && (n == 3)) || ((cell != 0) && ((n == 2) || (n == 3)))) {
|
||||
set_cell((u + 1) & 1, x, y);
|
||||
}
|
||||
|
@ -214,9 +221,9 @@ void print_universe(int u){
|
|||
|
||||
for (x=0; x<NUM_CELLS_X; x++) {
|
||||
if (get_cell(u, x, y))
|
||||
neorv32_uart_putc('#');
|
||||
neorv32_uart_putc((char)CELL_ALIVE);
|
||||
else
|
||||
neorv32_uart_putc(' ');
|
||||
neorv32_uart_putc((char)CELL_DEAD);
|
||||
}
|
||||
|
||||
// end of line
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue