# Assignment3: SoftCPU
###### tags: `Computer Architecture (Fall 2021)`
## Set Environment
1. Download [**xPack RISC-V Embedded GCC package**](https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/)
```shell=
$ cd ~
$ tar xvf ~/Downloads/xpack-riscv-none-embed-gcc-8.2.1-3.1-linux-x64.tgz
$ 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
$ mv xpack-riscv-none-embed-gcc-10.2.0-1.2 riscv-none-embed-gcc
```
2. Load config and check
```shell=
$ source ~/riscv-none-embed-gcc/setenv
$ riscv-none-embed-gcc -v
```
3.clone the [srv32](https://github.com/sysprog21/srv32) and compile
```shell=
$ git clone git@github.com:sysprog21/srv32.git
$ cd srv32/
$ cd srv32/tools
$ make
$ cd ../sim
$ make
```
## srv32 Simulation
Make the folder `hw3` in `srv32/sw`
And write the C code `hw3.c`
```shell=
$ cd ~/srv32/sw
$ mkdir hw3
$ nano hw3.c
```
```c=
#include <stdio.h>
#define max(a, b) ((a > b) ? a : b)
int main()
{
int gain[] = {-5,1,5,0,-7, -5, 10, 9, -4, 8, -4, 2, -4, 4, 3, -2}, len = 16;
int altitude = 0, highest = 0;
for(int i = 0; i < len; i++) {
altitude += gain[i];
highest = max(highest, altitude);
}
printf("highest altitude : %d\n", highest);
return 0;
}
```
Refer to Makefile in `hello` folder to create Makefile.
```
include ../common/Makefile.common
EXE = .elf
SRC = hw3.c
CFLAGS += -L../common
LDFLAGS += -T ../common/default.ld
TARGET = hw3
OUTPUT = $(TARGET)$(EXE)
.PHONY: all clean
all: $(TARGET)
$(TARGET): $(SRC)
$(CC) $(CFLAGS) -o $(OUTPUT) $(SRC) $(LDFLAGS)
$(OBJCOPY) -j .text -O binary $(OUTPUT) imem.bin
$(OBJCOPY) -j .data -O binary $(OUTPUT) dmem.bin
$(OBJCOPY) -O binary $(OUTPUT) memory.bin
$(OBJDUMP) -d $(OUTPUT) > $(TARGET).dis
$(READELF) -a $(OUTPUT) > $(TARGET).symbol
clean:
$(RM) *.o $(OUTPUT) $(TARGET).dis $(TARGET).symbol [id]mem.bin memory.bin
```
Compile and run.
```shell=
$ make
$ cd ~/srv32/tools
$ ./rvsim --memsize 128 -l trace.log ../sw/hw3/hw3.elf
highest altitude : 13
Excuting 2202 instructions, 2796 cycles, 1.270 CPI
Program terminate
Simulation statistics
=====================
Simulation time : 0.002 s
Simulation cycles: 2796
Simulation speed : 1.470 MHz
```
## GTKWave
Install the GTKWave.
```shell=
$ sudo apt install gtkwave
```
```shell=
$ make hw3
$ gtkwave sim/wave.fst
```

Srv32 is 3 stage pipeline processors.
Fetch and decode (F/D), execution (E) and write back (WB).

### Data hazard
Srv32 supports full forwarding so when there is data hazard such as WAW, WAR or RAW , there will not be still.
### Control hazard

There is a `banch` at `7C`, but there jump to `54` brfore 2 instrution.
Becuse the branch is taken at the execute stage, it needs to flush the instructions that have been fetched into the pipeline.

## Software Optimization
Modify define `max` function use the `if`
```c=
#include <stdio.h>
int main()
{
int gain[] = {-5,1,5,0,-7, -5, 10, 9, -4, 8, -4, 2, -4, 4, 3, -2}, len = 16;
int altitude = 0, highest = 0;
for(int i = 0; i < len; i++) {
altitude += gain[i];
if(highest < altitude)
highest = altitude;
}
printf("highest altitude : %d\n", highest);
return 0;
}
```
Let cycles reduce from 2796 to 2790.
```
highest altitude : 13
Excuting 2178 instructions, 2790 cycles, 1.281 CPI
Program terminate
Simulation statistics
=====================
Simulation time : 0.002 s
Simulation cycles: 2790
Simulation speed : 1.452 MHz
```