~charles/awk-riscv

c845fe8b0755808255f001d01a0b23e6549eef03 — Charles Daniels 10 months ago 0d5fb33
update README, add demo
4 files changed, 109 insertions(+), 22 deletions(-)

M README.md
A fibo.asm
D fibo.hex
A fibo.txt
M README.md => README.md +37 -1
@@ 1,6 1,42 @@
# riscv.awk

This program is a complete, self-contained simulator for most of the
[RV32I](https://riscv.org//wp-content/uploads/2017/05/riscv-spec-v2.2.pdf)
instruction set. It is implemented entirely in AWK. I have tested it only under
GNU AWK 5.0.1, it may or may not work under other AWKs.

# Usage

For usage, please see the comments in [riscv.awk](./riscv.awk).

# Demo

Here is the simulator running a RISC-V assembler program which computes the
20th Fibonacci number (6765, 0x1a6d).

```
$ awk -f riscv.awk < fibo.txt
0x00001a6d
```

See [`fibo.txt`](./fibo.txt), the input to the simulator, which was produced
using [`fibo.asm`](./fibo.asm). Converting an assembler file into something the
simulator can run is done by hand for now, but with considerable help from
[RARS](https://github.com/TheThirdOne/rars).

# Performance

According to `time` on an i5-4670K, this script takes 2.186 seconds to run,
simulating 10000 CPU cycles in that time, for an effective clock rate of
~4.5kHZ.

Memory is allocated on-the-fly, since AWK "arrays" are actually hash tables,
and uninitialized locations are 0 by default. Thus this simulator should be
fairly memory efficient.

# Tests

Tests can be run using the `.run_tests.sh` script.
Tests can be run using the `./scripts/run_tests.sh` script.

## Unit tests


A fibo.asm => fibo.asm +39 -0
@@ 0,0 1,39 @@
# This program computes the value of the nth number in the fibonacci sequence,
# where n is read from memory address 0x10000. The result is written to memory
# address 0x10004.

li x5 0x10000
lw x10 0(x5)  # n <- mem[0x10000]
li x11 1      # i <- 1
li x12 0      # F[0] <- 0
li x13 1      # F[1] <- 1
li x14 0      # next <- 0

# x12 and x13 will be used to track the previous two elements of the fibonacci
# sequence as we advance through the loop

bgt x10 x13 input_is_other      # if n > 1

input_is_zero:
csrw x0 io2
csrw x0 io3
j end

input_is_one:
csrw x13 io2
csrw x13 io3
j end

input_is_other:

fibo:
add x14 x12 x13         # next <- F[i] + F[i-1]
mv x12 x13              # F[i-1] <- F[i]
mv x13 x14              # F[i] <- next
addi x11 x11 1          # i++
csrw x13 io2            # HEX <- F[i]
csrw x11 io3            # LEDs <- i
blt x11 x10 fibo        # while(i < n)

end:
sw x13 4(x5)   # mem[0x10004] <- F[n]

D fibo.hex => fibo.hex +0 -21
@@ 1,21 0,0 @@
0xf0002573
0x00100593
0x00000613
0x00100693
0x00000713
0x00a6ce63
0xf0201073
0xf0301073
0x02c0006f
0xf0269073
0xf0369073
0x0200006f
0x00d60733
0x00d00633
0x00e006b3
0x00158593
0xf0269073
0xf0359073
0xfea5c4e3
0x00000013
0xffdff06f

A fibo.txt => fibo.txt +33 -0
@@ 0,0 1,33 @@
# set n
poke 0x10000 20

# poke in the program, execution starts at 0, this code was assembled using
# RARS
poke 0x00000000  0x000102b7  # lui x5,0x00000010
poke 0x00000004  0x00028293  # addi x5,x5,0x00000000
poke 0x00000008  0x0002a503  # lw x10,0x00000000(x5)
poke 0x0000000c  0x00100593  # addi x11,x0,0x000000017
poke 0x00000010  0x00000613  # addi x12,x0,0x000000008
poke 0x00000014  0x00100693  # addi x13,x0,0x000000019
poke 0x00000018  0x00000713  # addi x14,x0,0x0000000010
poke 0x0000001c  0x00a6ce63  # blt x13,x10,0x0000000e15
poke 0x00000020  0xf0201073  # csrrw x0,0x00000f02,x018
poke 0x00000024  0xf0301073  # csrrw x0,0x00000f03,x019
poke 0x00000028  0x02c0006f  # jal x0,0x00000016
poke 0x0000002c  0xf0269073  # csrrw x0,0x00000f02,x123
poke 0x00000030  0xf0369073  # csrrw x0,0x00000f03,x124
poke 0x00000034  0x0200006f  # jal x0,0x00000010
poke 0x00000038  0x00d60733  # add x14,x12,x13
poke 0x0000003c  0x00d00633  # add x12,x0,x13
poke 0x00000040  0x00e006b3  # add x13,x0,x14
poke 0x00000044  0x00158593  # addi x11,x11,0x000000033
poke 0x00000048  0xf0269073  # csrrw x0,0x00000f02,x134
poke 0x0000004c  0xf0359073  # csrrw x0,0x00000f03,x135
poke 0x00000050  0xfea5c4e3  # blt x11,x10,0xfffffff436
poke 0x00000054  0x00d2a223  # sw x13,0x00000004(x5)

# advance simulation by 10000 CPU cycles
step 10000

# read the result, note that the 20th fibonacci number is 6765, which is 0x1a6d
peek 0x10004