owned this note
owned this note
Published
Linked with GitHub
# Homework3 : SoftCPU
## 0, Prepare to setup the environment
### There are some essential commands.
1. [srv32](https://github.com/sysprog21/srv32)
```c=
$ sudo apt install autoconf automake autotools-dev curl gawk git \
build-essential bison flex texinfo gperf libtool patchutils bc git \
libmpc-dev libmpfr-dev libgmp-dev gawk zlib1g-dev libexpat1-dev
$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
$ mkdir -p build && cd build
../configure --prefix=/opt/riscv --enable-multilib
$ make -j$(nproc)
$ sudo apt install build-essential ccache
$ git clone https://github.com/sysprog21/srv32
```
Next
```c=
$ cd $HOME/srv32/tools/
$ make
$ cd $HOME/srv32/sim/
$ make
```
2. The xPack GNU RISC-V Embedded GCC.
```c=
$ cd /tmp
$ wget https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.2.0-1.2/xpack-riscv-none-embed-gcc-10.2.0-1.2-linux-x64.tar.gz
$ tar zxvf xpack-riscv-none-embed-gcc-10.2.0-1.2-linux-x64.tar.gz
$ cp -af xpack-riscv-none-embed-gcc-10.2.0-1.2 $HOME/riscv-none-embed-gcc
```
3. Install lcov
```c=
$ sudo apt-get install lcov
```
4. Install gtkwave
```c=
$ sudo apt install gtkwave
```
5. Configure PATH
```c=
$ cd $HOME/riscv-none-embed-gcc
$ echo "export PATH=`pwd`/bin:$PATH" > setenv
$ cd $HOME
$ source riscv-none-embed-gcc/setenv
$ riscv-none-embed-gcc -v
```
6. Enter "make all" under the folder "srv32"
:::spoiler **Result of command "make all" is shown below**

:::
## 1, Run simulation on srv32
1. I create the folder named "CA_hw3" in srv32/sw ,and then write the C code(CA_hw3.c) and Makefile in this folder.
**CA_hw3.c**
```c=
#include <stdio.h>
int AddDigits(int num){
int ans;
while (num >= 10) {
ans = 0;
while (num != 0) {
ans = ans + (num % 10);
num = num / 10;
}
num = ans;
}
return num;
}
int main(){
int a = 38;
int ans;
ans = AddDigits(a);
printf("%d\n",ans);
return 0;
}
```
2. Run the command "make CA_hw3" under srv32.
3. The result is following.
**Result**

## 2, Waveform
I take the instruction **"load word"** as the example.

**The screenshot is from GTKwave.**
```00000164 00052783 read 0x000213c0 => 0x00020558, x15 (a5) <= 0x00020558```
The above is from **srv32/sim/trace.log**.
00000164 → Instruction's address
00052783 → Instruction's mechine code.We even know this mechine code represents **"lw a15,0(a10)"**.
Then,We also can know funct3=010,opcode=0000011
* Let's trace the process of this instruction in this three stage pipeline processor.
* First of all, the instruction memory have got the address "00000164" in the prior clock,so in the next clock the processor got the instruction "0052783",which is stored in instruction memory's address "00000164".
* We can see the instruction's address go through from "if" stage to "wb" stage.
* Because we need the register(x10)'s value add immediate to calculate the address of data memory, we get the address(0x000213c0).
* In the next clock, processor will read the data(0x00020558) from address(0x000213c0) of the data memory.
* Then, After one clock, the value(0x00020558) will be stored in the register(x15).
## 3, Improve the code of HW1
:::spoiler **The improved C code**
```c=
#include <stdio.h>
int AddDigits(int num){
/*
int ans;
while (num >= 10) {
ans = 0;
while (num != 0) {
ans = ans + (num % 10);
num = num / 10;
}
num = ans;
}
return num;
*/
if (num == 0) return 0;
else if (num % 9 == 0) return 9;
else return num % 9;
}
int main(){
int a = 38;
int ans;
ans = AddDigits(a);
printf("%d\n",ans);
return 0;
}
```
:::
* Main Idea:
I change the solution of this question. In the new method, I found the number will cycle once every nine times. In other words,if the number is the multiple of nine, the answer will be 9.If the number is not the multiple of nine,we just need to take the remainder to the number '9'.
**Improved result**

* In conclusion, I observe the counts of the instruction are decreased from 1269 to 1245,and the counts of the cycle are decreased from 1629 to 1599.
## 4, How RISC-V Compliance Tests works
I see the documents of [RISC-V Compliance Tests](https://github.com/riscv-non-isa/riscv-arch-test/blob/master/doc/README.adoc).
From this documents, we can learn how RISC-V Compliance Tests works.
Then, I try to run two commands "make tests" and "make tests-sw".
The results are following seperately.
:::spoiler **Result of command "make tests"**

:::
:::spoiler **Result of command "make tests-sw"**

:::