Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
lab8
- Loading branch information
Jerry Shi
committed
Mar 22, 2024
1 parent
aee68b7
commit bc199a5
Showing
4 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# A RISC-V Simulator | ||
|
||
**This lab is worth 200 points**. 150 points from the code graded by the auto | ||
grader and 50 points from Lab8-test in HuskyCT. | ||
|
||
**The coding component is mandatory.** | ||
|
||
**Firm-deadline, for Lab8-test**: Monday, 4/8/2024. The questions do not depend | ||
on your code. Please take it early. | ||
|
||
**Deadline, for code:** Monday, 4/8/2024 | ||
|
||
**Late Deadline, for code:** Friday, 4/26/2024. | ||
|
||
*If you work on a lab computer, save your files to cloud storage like OneDrive. | ||
Otherwise, you may lose your files.* | ||
|
||
## Learning Objectives | ||
|
||
* Implement a single-cycle RISC-V processor in MyHDL | ||
|
||
* Build a processor from existing modules | ||
|
||
## Description | ||
|
||
In this lab, we complete the design of a single-cycle RISC-V processor, | ||
following the diagram we have constructed. The diagram is Figure 4.21 in | ||
textbook. A copy has been posted in HuskyCT. | ||
|
||
### Instructions supported by the processor | ||
|
||
The processor supports the subset of instructions we have studied. | ||
|
||
``` | ||
ADD, SUB, AND, OR, LW, SW, BEQ | ||
``` | ||
|
||
In addition, the ALU supports shift operations, although the shift operations | ||
are done in a separator module in real processors. ImmGen, ALU control, and the | ||
main control have been improved to support ALU operations with an immediate. | ||
Therefore, the following instructions are also supported, without changing the | ||
diagram. | ||
|
||
``` | ||
ADDI, ANDI, ORI | ||
SLLI, SRLI, SRAI | ||
SLL, SRL, SRA | ||
``` | ||
|
||
### Code | ||
|
||
Implementing a processor requires a lot of work. However, we have done the | ||
heavy lifting. The remaining work is limited to one file, or a few files if you | ||
would like to improve the processor. | ||
|
||
The files provided to you are in a single ZIP file. Descriptions of the files | ||
in the package are in `README.md`. Read it carefully. | ||
|
||
Note that the software is copyrighted to limit its distribution. A lot of | ||
efforts have been put in the design of the assignment so students can learn | ||
from the code provided and also have opportunities to explore themselves. | ||
Please limit the use of the code in this course. See `LICENSE.txt` in the | ||
downloaded files for detail. | ||
|
||
### Tasks | ||
|
||
The main task is to complete the design of a single-cycle RISC-V core. Since | ||
all supporting modules are already provided, the main task is to follow Figure | ||
4.21 in the textbook and put everything together. | ||
|
||
We will mainly work on `sc_core.py`. Read the code provided in `sc_core.py` | ||
carefully. Many packages are imported at the beginning of the file. From the | ||
import statements, we can find out where to find the file for a particular | ||
module. | ||
|
||
Study the signals in `sc_signals.py` and locate them in the diagram. | ||
|
||
Starting from PC (already in the file), create the modules in the diagram one | ||
by one. | ||
|
||
* Find a module that are connected to the modules that are already created. For | ||
example, PC is already created, the next one would be the instruction memory. | ||
|
||
* Find the interface of the module by reading the documentations and studying its | ||
source code. | ||
|
||
* Instantiate the module with proper signals connected to it. This is the step | ||
where students make many mistakes. | ||
|
||
After the diagram is implemented in Python code, test the simulator. See | ||
`README.md` for more instructions. Although some expected outputs are provided, | ||
some programs generate different output when argument registers like `a0` and | ||
`a1` are changed. Run those programs with different initial values in | ||
registers and explain the results from the simulator. | ||
|
||
### Debugging | ||
|
||
Start from small programs, for example, programs having only R-type | ||
instructions. After the R-type instructions are working, move on to check other | ||
types of instructions: shift instructions, I-type instructions, load, store, and | ||
so on. | ||
|
||
Here are some steps we can follow for testing the simulator. | ||
|
||
1. Save the output of the simulator in a file. | ||
|
||
2. Compare it with expected output. | ||
|
||
3. Identify mismatched signals and check related modules. For example, if | ||
PC is correct but instruction is not correct, check instruction memory. | ||
|
||
## Deliverables | ||
|
||
Submit `sc_core.py` and take Lab8-test in HuskyCT by the deadline. | ||
|
||
## Mistakes | ||
|
||
Here are some mistakes students made in previous semesters. | ||
|
||
* Did not check the simulator locally. Sometimes the submitted code does not | ||
terminate, or it does not print anything. It is easier to identify problems | ||
when running the simulator locally and comparing its output with the | ||
expected. | ||
|
||
* Missed some modules. Double check that the simulator has all the | ||
components. Probably print a hard copy of the diagram and mark a module | ||
when it is placed in the simulator. | ||
|
||
* Did not connect correct signals to a module. Double check every signal connected | ||
to a module. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
# RISC-V Simulator | ||
|
||
## Files | ||
|
||
The files under the root directory of the projects are the following. | ||
|
||
``` | ||
rvsim.py The main file. We start the simulator with this file. | ||
utilities.py Help functions. | ||
sc_signals.py A class that has all signals in the single-cycle processor. | ||
sc_core.py The processor core. To be completed. | ||
maincontro.py The main control. | ||
immgen.py The ImmGen module. | ||
alucontrol.py The ALU Control module. | ||
README.md This file. | ||
LICENSE.txt License information. | ||
``` | ||
|
||
The files in `hardware` directory are hardware modules, including basic | ||
gates, MUX, adder, ALU, register, register file, and memory. | ||
|
||
We can use pydoc module to read the docstrings in Python files. For example, | ||
|
||
``` | ||
py -m pydoc hardware/gates.py | ||
py -m pydoc hardware/alu.py | ||
py -m pydoc sc_signals.py | ||
``` | ||
|
||
If pydoc does not work for some files, read the comments in the code with a | ||
text editor. | ||
|
||
## Running the simulator | ||
|
||
The simulator starts with `rvsim.py`. It accepts a few arguments from the | ||
command line. | ||
|
||
* `-h`: display the help message. | ||
|
||
* `<program>`: specify the program to run on the simulator. For example, | ||
|
||
``` | ||
py rvsim.py input\fib.txt | ||
or | ||
python rvsim.py input/fib.txt | ||
``` | ||
|
||
* `-a <num>`: set the argument registers before the simulation starts. For | ||
example, `-a 100` sets register `a0` to 10. `-a 100 200` sets `a0` to 100 | ||
and `a1` to 200. | ||
|
||
* `-n <num>`: specify the number of cycles to simulate. Without the option, | ||
the simulator runs until PC is larger than the largest address in the | ||
instruction memory. | ||
|
||
* `-s <start>` and `-e <end>`. These two options specify in which cycle the | ||
simulator starts to print signal values and in which cycle printing stops. | ||
By default, printing starts in cycle 0. | ||
|
||
These two options help us focus on signal values in particular cycles. We can | ||
also suppress printing to make the simulator run faster on large programs. For | ||
example, with `-e 0`, the simulator does not print signal values because | ||
printing stops at cycle 0. | ||
|
||
* `--display`. Treat the memory region starting from the address in register | ||
`tp` as the display buffer. | ||
|
||
## Test programs | ||
|
||
A few test programs are in input directory. The expected output are in output directory. | ||
The description of test programs are in [testprog.md](testprog.md). | ||
|
||
### Initial values in registers | ||
|
||
Registers x2 (sp), x3 (gp), and x4 (tp) are intialized with memory addresses | ||
for stack, global data, and thread local storage, respectively. x2 (sp) is the | ||
address of the word at the top of the stack. x3 (gp) is the starting address of | ||
global data section. | ||
|
||
All other registers are initialized to their register number. For example, 1 in | ||
x1, 5 in x5, and so on. | ||
|
||
Argument registers, a0, a1, and so on, can be set from the command line | ||
arguments using the `-a` option. | ||
|
||
### Creating your own test program | ||
|
||
The simulator accepts dump files from RARS. For example, the following command | ||
assembles the source code `prog.s` and saves the machine code and matching | ||
lines in the source code to `prog.txt`. The simulator can extract the machine | ||
code from `prog.txt`. Note that not all the instructions are supported by the | ||
simulator. | ||
|
||
``` | ||
java -jar rars.jar a dump .text SegmentWindow prog.txt prog.s | ||
``` | ||
|
||
Note that RARS may have a different filename on your computer. Also replace | ||
`prog.s` with the actual RISC-V souce code filename. | ||
|
||
## Features and limitations | ||
|
||
ImmGen supports I, S, and SB types. It can be (easily) extended to support U | ||
and UJ types. | ||
|
||
I-type instructions that have opcode 0b0010011(0x13) are similar to many R-type | ||
instructions. ALUOp for these instructions is to 0b11. | ||
|
||
ALU Control can generate proper ALU operation for most of R-type, ALU I-type, | ||
load, store, and branch instructions. | ||
|
||
ALU, in hardware folder, supports shift operations required for SLL, SRL, and | ||
SRA although the shift operations are performed in a separate functional unit | ||
in real processors. | ||
|
||
When the simulator can execute ADD, SUB, AND, OR, and LW instructions, it | ||
should be able to execute SLL, SRL, and SRA instructions, and the coresponding | ||
I-type instructions like ADDI and SLLI. | ||
|
||
The line endings in the files are `\r\n`, the one on Windows systems. | ||
|
||
## Why copyright notice? | ||
|
||
We have spent a lot of time to prepare the lab and plan to use it in many | ||
semesters to come. We restrict the dissemination of the code so that students | ||
who take the course in the future have the opportunities to solve the problems | ||
themselves. | ||
|
||
It happened in the past that some assignments and solutions were posted in | ||
public servers, by mistake or on purpose. It was hard to get them removed. | ||
A copyright infringement notice may make it easier. |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Test programs | ||
|
||
The test programs are in the `input` directory. The expected outputs are in | ||
`expected` directory. The output of the programs depends on the values in | ||
argument registers. The expected output files were generated using the default | ||
values in argument registers, for example, `a0` = 10, `a1` = 11, and so on. | ||
Test the processor and programs with more values. The autograder may test the | ||
submitted code with different values set in argument registers. | ||
|
||
We can save the output of the simulator in a file, and then compare it with the | ||
expected output with software tools. However, please examine the output | ||
manually, too. Tools are just helping. | ||
|
||
The command syntax for saving program output in a file depends on the OS and | ||
the shell. Here are some examples. The provided output files were generated by | ||
`run-tests.ps1` in Powershell Core 7.2, in a virtual environment. | ||
|
||
``` | ||
# cmd and Powershell Core on Windows | ||
python rvsim.py input\t-add.txt > t-add-out.txt | ||
# Windows Powershell 5.x | ||
python rvsim.py input\t-add.txt | out-file -encoding ascii t-add-out.txt | ||
# Linux (Ubuntu). bash | ||
python3 rvsim.py input/t-add.txt > t-add-out.txt | ||
``` | ||
|
||
Then we may use a file comparison tool to compare the output of your simulator | ||
with the expected output files. We may need to deal with different line | ||
endings. The provided files have Windows line endings. On Linux, we can use | ||
`dos2unix` program to convert Windows line endings to unix line endings, or ask | ||
the software tool to ignore ending spaces if it is supported. | ||
|
||
``` | ||
# Linux | ||
# add -Z option if two files have different line ending characters | ||
diff file1 file2 | ||
# Windows, if fc.exe is available | ||
fc.exe file1 file2 | ||
# Powershell | ||
diff (cat file1) (cat file2) | ||
Compare-Object (Get-Content file1) (Get-Content file2) | ||
# Python with difflib installed | ||
diff.py file1 file2 | ||
# if the path is not set, we can specify the full path of diff.py | ||
py C:\Python310\Tools\script\diff.py file1 file2 | ||
#vim | ||
vim -d file1 file2 | ||
vimdiff file1 file2 | ||
``` | ||
|
||
## List of RIS-V test code | ||
|
||
Here are brief descriptons of the test programs in input directory. We can see | ||
the instructions in the provided files under the input directory. | ||
|
||
* t-add tests ADD and SUB. | ||
|
||
* t-and tests AND and OR. | ||
|
||
* t-sll tests SLL, SRL, and SRA. | ||
|
||
* t-i tests instructions with immediate. | ||
|
||
* t-sw tests SW and LW. | ||
|
||
* t-beq tests BEQ. | ||
|
||
* t-hello prints "Hello" and the character in register a0. | ||
|
||
* reversebytes reverses the order of bytes in a register. | ||
|
||
* fib. Compute Fibonacci sequence until F(n) and save the numbers in memory. | ||
n is in a0. | ||
|
||
* fact. Compute n! and save the numbers in memory. n is in a0. |