ref: fa3c47fde6c5a46743f34bc972ece337a8974615 awk-riscv/README.md -rw-r--r-- 3.8 KiB
fa3c47fdCharles Daniels assemble lw and sw 1 year, 12 days ago


This program is a complete, self-contained simulator for most of the RV32I 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.


For usage, please see the comments in riscv.awk.


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

$ awk -f riscv.awk < fibo.txt

See fibo.txt, the input to the simulator, which was produced using fibo.asm. Converting an assembler file into something the simulator can run is done by hand for now, but with considerable help from RARS.

This program can also be used as a disassembler:

$ awk '($1 == "poke" && $2 != "0x10000") {print($3)}' < fibo.txt
$ awk '($1 == "poke" && $2 != "0x10000") {print($3)}' < fibo.txt  | awk -f riscv.awk -v mode=disasm
0x000102b7: LUI x5 0x10000
0x00028293: ADDI x5 x5 0
0x0002a503: LW x10 x5 0
0x00100593: ADDI x11 x0 1
0x00000613: ADDI x12 x0 0
0x00100693: ADDI x13 x0 1
0x00000713: ADDI x14 x0 0
0x00a6ce63: BLT x13 x10 0x1c
0xf0201073: CSRRW x0 x0 -254
0xf0301073: CSRRW x0 x0 -253
0x02c0006f: JAL x0 0x2c
0xf0269073: CSRRW x0 x13 -254
0xf0369073: CSRRW x0 x13 -253
0x0200006f: JAL x0 0x20
0x00d60733: ADD x14 x12 x13
0x00d00633: ADD x12 x0 x13
0x00e006b3: ADD x13 x0 x14
0x00158593: ADDI x11 x11 1
0xf0269073: CSRRW x0 x13 -254
0xf0359073: CSRRW x0 x11 -253
0xfea5c4e3: BLT x11 x10 0xffffffe8
0x00d2a223: SW x5 x13 4


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. This is not a particularly scientific assessment, but it is reasonable to assume that this simulator is not terribly fast. What did you expect?

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.

#Future Work

  • Better disassemble could be useful, especially with respect to load and store, and handling of non-canonical no-ops.

  • A mode could be added to allow streaming instructions directly into memory, rather than having to poke them in one at a time.

  • A simple assembler could be added, allowing riscv.awk to be used as a complete RISC-V toolchain.

  • A break directive could be added, which halts the simulation on some condition and implies a dump so it can later be resumed.


This started as a joke between myself and my friend Joshua Nelson. I decided to build it anyway, and here we are.

I have found AWK a surprisingly pleasant language in which to implement a CPU simulator. A lot of the challenge is getting data into and out of the simulator, and controlling it, which AWK makes very straightforward. The thinly provisioned memory is also handy.


If you have a question, comment, or patch, you should send it in via my public inbox.


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

#Unit tests

Unit tests organized as a directory of TSV files in the test/unit/ folder. The first column of each file is an input to riscv.awk, and the second column is the expected output. Each TSV file corresponds to one test case.

#Simulation tests

Files in test/simulation/ are each used as input to the program, and it's exit code is assumed to indicate a test failure in the event it is nonzero.