Skip to content

Commit

Permalink
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
Show file tree
Hide file tree
Showing 4 changed files with 354 additions and 0 deletions.
130 changes: 130 additions & 0 deletions lab8/lab8.md
@@ -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.
142 changes: 142 additions & 0 deletions lab8/rvsim-README.md
@@ -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 added lab8/rvsim.zip
Binary file not shown.
82 changes: 82 additions & 0 deletions lab8/testprog.md
@@ -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.

0 comments on commit bc199a5

Please sign in to comment.