Joseph Gilbert, Kat Canavan, and Arturo Joya
This repository contains the files used to create a command-line based simulation of a RISC-V CPU using Python. Both a debugging and educational tool, this program takes assembly as input and returns the register files after each instruction. Note that store/load half and byte instructions are not supported.
For the conversion from assembly to binary we've slightly modified some course material, assembler.py
from Avinash Nonholonomy's Olin Computer Architecture course material ([GitHub](GitHub - avinash-nonholonomy/olin-cafe-f22: Repository for Olin's ENGR3410 - Fall 2022)). Thanks Avinash!
This simulation was run and tested using Python 3.10. Prior versions of Python are not compatible.
Only one library that needs to be installed is bitstring which can either be installed with pip install bitstring
or
pip install -r requirements.txt
This program requires the user to be at least somewhat familiar with command line interfaces. Create a clone of this repository to your local machine and navigate to that directory in a command-line terminal.
There are two methods of inputting RISC-V assembly code:
-
Enter instructions line-by-line, live, through the terminal and immediately see the result of each given command. Since this is live, only I Type, R Type, and store word instructions are supported.
-
Process an entire assembly (.s) file. All instructions are processed and when the program is complete the relevant registers are displayed per step. This mode supports all RISC-V 32I instructions except those involving halfs and bytes.
Each of these methods are described in more detail below.
To test assembly code live, a line at a time, simply run python3 main.py
. You will be prompted to type in assembly code (e.g addi t0, zero, 42
to store the immediate 42
to register t0).
Enter instruction: addi x2 x0 42
addi x2 x0 42
0x00000000
Fetch
0x00000004
Decode
0x00000004
Execute I
0x00000004
alu writeback
Intruction : 02a00113
PC : 00000004
+----Register File----+
|x00 | zero | 00000000|
|x02 | sp | 0000002a|
+---------------------+
As you can see, the output only displays the registers that have been changed so far. Assuming that addi t0, zero, 42
was already run, typing in addi t1, t0, 63
would result in the following output. We implemented the output this way as we figured it would be way easier to debug a program without having to scroll through lots of meaningless register outputs (meaningless in the context of the user's specific program, that is).
Enter instruction: addi sp sp 2
addi sp sp 2
0x00000004
Fetch
0x00000008
Decode
0x00000008
Execute I
0x00000008
alu writeback
Instruction : 00210113
PC : 00000008
+----Register File----+
|x00 | zero | 00000000|
|x02 | sp | 0000002c|
+---------------------+
To test assembly code through a file, run python3 main.py FILENAME.s
(where FILENAME.s
is the filepath). This will run the simulation automatically and output the register file after executing each instruction. The following is an example output from a file containing the assembly code from the Line by Line example in non-verbose display.
Enter instruction: addi x2 x0 42
addi x2 x0 42
0x00000000
Fetch
0x00000004
Decode
0x00000004
Execute I
0x00000004
alu writeback
Intruction : 02a00113
PC : 00000004
+----Register File----+
|x00 | zero | 00000000|
|x02 | sp | 0000002a|
+---------------------+
Enter instruction: addi sp sp 2
addi sp sp 2
0x00000004
Fetch
0x00000008
Decode
0x00000008
Execute I
0x00000008
alu writeback
Instruction : 00210113
PC : 00000008
+----Register File----+
|x00 | zero | 00000000|
|x02 | sp | 0000002c|
+---------------------+
We decided to implement this simulation using object oriented design. We followed the model-view-controller architecture to divide the program's functionality. The following is a quick breakdown of our program
You can read through the comments on our code and function docstrings for more information on precisely how the it works.
Test cases with randomly generated instruction were used to test the system. The code behind these tests can be found in test_single_line.py
, although it should be noted that the tests will be different each time.