# Lab1:RV32I Simulator
contributed by <[`Evelyn`](https://github.com/tako861225/power-of-two)>
###### tags: `RISC-V`
## Power of Two
This problem is based on [LeetCode 231](https://leetcode.com/problems/power-of-two/). Given an integers, return `true` if the number is power of two that can represent to $2^{k}$ .Otherwise, return `false`
### C code
```clike=
#include<stdio.h>
bool isPowerOfTwo(int n){
while(n){
if (n==1) return true;
if(n%2)return false;
n/=2;
}
return false;
}
```
### Assembly code
```asm=
.data
argument: .word 2
str1: .string "ture"
str2: .string "false"
.text
main:
lw a0, argument # Load argument from static data
addi sp, sp, -4
sw a0 ,0(sp)
addi t2, t2, 1 # t2 = 1
jal ra, loop # Jump-and-link to the 'loop' label
lw a0,0(sp)
addi sp,sp, 4
jal ra, print
# Exit program
li a7, 10
ecall
loop:
beq a0, t2, true # if n==1 return true
andi t3, a0, 1 # t3 = n % 2
bne t3, zero, false # if t3!= 0 return false
srli a0, a0, 1 # shift right
bne a0, zero, loop # while(n)
beq a0, zero, false #if n = 0 return false
true:
addi a1, a1 , 1 # result
ret
false:
addi a1, a1 , 0
ret
print:
mv t0, a0 #t0 = n
mv a0,t0
li a7,1
ecall
mv t1, a1 #result
beq t1, zero, pf
la a0,str1
li a7,4
ecall
ret
pf:
la a0,str2
li a7,4
ecall
ret
```
### Pseudo instruction
```pse=
00000000 <main>:
0: 10000517 auipc x10 0x10000
4: 00052503 lw x10 0 x10
8: ffc10113 addi x2 x2 -4
c: 00a12023 sw x10 0 x2
10: 00138393 addi x7 x7 1
14: 018000ef jal x1 24 <loop>
18: 00012503 lw x10 0 x2
1c: 00410113 addi x2 x2 4
20: 034000ef jal x1 52 <print>
24: 00a00893 addi x17 x0 10
28: 00000073 ecall
0000002c <loop>:
2c: 00750c63 beq x10 x7 24 <true>
30: 00157e13 andi x28 x10 1
34: 000e1c63 bne x28 x0 24 <false>
38: 00155513 srli x10 x10 1
3c: fe0518e3 bne x10 x0 -16 <loop>
40: 00050663 beq x10 x0 12 <false>
00000044 <true>:
44: 00158593 addi x11 x11 1
48: 00008067 jalr x0 x1 0
0000004c <false>:
4c: 00058593 addi x11 x11 0
50: 00008067 jalr x0 x1 0
00000054 <print>:
54: 00050293 addi x5 x10 0
58: 00028513 addi x10 x5 0
5c: 00100893 addi x17 x0 1
60: 00000073 ecall
64: 00058313 addi x6 x11 0
68: 00030c63 beq x6 x0 24 <pf>
6c: 10000517 auipc x10 0x10000
70: f9850513 addi x10 x10 -104
74: 00400893 addi x17 x0 4
78: 00000073 ecall
7c: 00008067 jalr x0 x1 0
00000080 <pf>:
80: 10000517 auipc x10 0x10000
84: f8950513 addi x10 x10 -119
88: 00400893 addi x17 x0 4
8c: 00000073 ecall
90: 00008067 jalr x0 x1 0
```
### 5-stage pipelined processor

There are five stage in Ripe:

|abbreviation|work|
|:---:|:---:|
|IF|Instruction Fetch|
|ID|Instruction Decode & Register Read|
|EX|Execution or Address Calculation|
|MEM|Data Memory Access|
|WB|Write Back (to register)|
Take `auipc x10 0x10000` as an example.
## IF

In IF stage,Program Counter(PC) will load the first address 0x000000000 to Instr. memory,the instr. output will be 0x10000517.Simultaneously,PC will load the next address 0x000000000+4.
## ID

Next, decode the instruction `0x10000517` from IF which can be spilt into : opencode:auipc,wr idx: 0x0a ,imm. : 0x10000000.
## EX

ALU result will be register plus immediate value
0x10000000 = 0x00000000+0x10000000
## MEM

Load address from the result of ALU `0x10000000` ,then the value will be `0x00000010`
## WB

Write ALU result `0x10000000` to destination register `0x0a`