owned this note
owned this note
Published
Linked with GitHub
# Assignment3: SoftCPU
###### tags: `Computer Architecture 2021`
## Link
[Assignment 1](https://hackmd.io/jj61kCP_R-etsz4c7KTOSw)
[Assignment 3 建置教學](https://hackmd.io/@eecheng/B1fEgnQwF)
## Environment
* [srv32](https://hackmd.io/@sysprog/S1Udn1Xtt) : A simple RISC-V 3-stage pipeline processor
## Setting up the Environment
After finishing setting up the Environment,I try to make in the tools folder and sim folder.
```bash=
$ cd srv32/sim/
$ make
```
Unfortunately, some errors occured when I make in the sim folder.
```bash=
/home/xueyang/srv32/sim/../verilator/bin/verilator -O3 -cc -Wall -Wno-STMTDLY -Wno-UNUSED +define+MEMSIZE=128 --trace-fst --Mdir sim_cc --build --exe sim_main.cpp getch.cpp -o sim -f filelist.txt ../rtl/top.v
make[1]: Entering directory '/home/xueyang/srv32/sim/sim_cc'
ccache g++ -I. -MMD -I/home/xueyang/srv32/sim/../verilator/include -I/home/xueyang/srv32/sim/../verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -DVM_TRACE_FST=1 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -std=gnu++14 -Os -c -o getch.o ../getch.cpp
g++: error: unrecognized command line option ‘-faligned-new’; did you mean ‘-falign-jumps’?
g++: error: unrecognized command line option ‘-fcf-protection=none’; did you mean ‘-flto-partition=none’?
make[1]: *** [Vriscv.mk:63: getch.o] Error 1
make[1]: Leaving directory '/home/xueyang/srv32/sim/sim_cc'
%Error: make -C sim_cc -f Vriscv.mk exited with 2
%Error: Command Failed /home/xueyang/srv32/sim/../verilator/bin/verilator_bin -O3 -cc -Wall -Wno-STMTDLY -Wno-UNUSED +define+MEMSIZE=128 --trace-fst --Mdir sim_cc --build --exe sim_main.cpp getch.cpp -o sim -f filelist.txt ../rtl/top.v
make: *** [Makefile:61: sim] Error 2
```
So, I find the `-faligned-new` and `-fcf-protection=none` in the /srv32/verilator/include/verilated.mk
```bash=
$ grep -r faligned-new
```
```bash=
verilator/include/verilated.mk:CFG_CXXFLAGS_NO_UNUSED = -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow
```
Now, it can work smoothly.
## Requirements 1
The hw.c is below.
```c=
#include<stdio.h>
#include<stdint.h>
int number_of_1bits(uint32_t n){
int count = 0;
while (n != 0){
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
uint32_t input = 24;
int ans = number_of_1bits(input);
printf("%d\n",ans);
return 0;
}
```
The Makefile is below.
```c=
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
```
I found that `printf` must contain `\n` in the end, otherwise it can't work fine. Also, we should make at the root directory.

I found that dhrystone and cormark is in the `sw` folder, so I create a foler to store hw.c and Makefile. At the root directory, I can use `make hw3` and the result is following.

## Requirements 2
```c=
0000003c <number_of_1bits>:
3c: 00050793 mv a5,a0
40: 00000513 li a0,0
44: 00078c63 beqz a5,5c <number_of_1bits+0x20>
48: fff78713 addi a4,a5,-1
4c: 00e7f7b3 and a5,a5,a4
50: 00150513 addi a0,a0,1
54: fe079ae3 bnez a5,48 <number_of_1bits+0xc>
58: 00008067 ret
5c: 00008067 ret
```
There are RAW data hazard as below.But I found that number_of_1bits function is not executed in the trace.log.
| IF/ID | EX | WB |
| -------- | -------- | -------- |
| beqz a5,address | addi a4,a5,-1 | and a5,a5,a4 |
we can found that branch penalty is 2 cycle.

## Requirements 3
I have to check this [note](https://hackmd.io/@WeiCheng14159/BkiRTKdUP) that jserv comment on my [Lab1](https://hackmd.io/jj61kCP_R-etsz4c7KTOSw), so I decide to write a new program which calculating 2 bits at a time. Thw following is my new program.
```c=
#include<stdio.h>
#include<stdint.h>
int number_of_1bits(uint32_t n){
uint32_t mask[] = {0x55555555,0x33333333,0x0F0F0F0F,0x00FF00FF,0x0000FFFF};
for(int i = 0,j = 1;i < 5; i++,j <<= 1){
n = (n & mask[i]) + ((n >> j) & mask[i]);
}
return n;
}
int main()
{
uint32_t input = 0xFFFFFFFF;
int ans = number_of_1bits(input);
printf("%d\n",ans);
return 0;
}
```
Before I make, I expect that the cycles count of the new program will be much less than that of the version 1 program.The following is new program information.

The following is first written.

Based on the same input value(0xFFFFFFFF),the result is not as I expected.
I modify the code of version 2. The following is a code of modified version 2.
```c=
#include<stdio.h>
#include<stdint.h>
int number_of_1bits(uint32_t n){
uint32_t mask[] = {0x55555555,0x33333333,0x0F0F0F0F,0x00FF00FF,0x0000FFFF};
n = (n & mask[0]) + ((n >> 1) & mask[0]);
n = (n & mask[1]) + ((n >> 2) & mask[1]);
n = (n & mask[2]) + ((n >> 4) & mask[2]);
n = (n & mask[3]) + ((n >> 8) & mask[3]);
n = (n & mask[4]) + ((n >> 16) & mask[4]);
return n;
}
int main()
{
uint32_t input = 0xFFFFFFFF;
int ans = number_of_1bits(input);
printf("%d\n",ans);
return 0;
}
```
I do the loop unrolling for number_of_1bits function

Now,it look the same as version 1.Also,I found that the number of instruction of version 2 that it does not do the loop unrolling is 1541.After doing the loop unrolling, the number of instruction is 1510. It reduces to 31 intructions and 35 cycles.
## Requirement 4
This assignment gave me a better understanding of hardware operation. Using the GTKWave sofrware,I can choose signal wire that I want to observe.From this assignment 3,I learned srv32 how to work on 3 pipelines and how to handle data harzard.