Try   HackMD

Assignment3: SoftCPU

tags: Computer Architecture 2021

Assignment 1
Assignment 3 建置教學

Environment

  • srv32 : 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.

$ cd srv32/sim/ $ make

Unfortunately, some errors occured when I make in the sim folder.

/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

$ grep -r faligned-new
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.

#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.

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

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 that jserv comment on my Lab1, so I decide to write a new program which calculating 2 bits at a time. Thw following is my new program.

#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.

#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.