# Assignment:RISC-V Assembly and Instruction Pipeline
## Valid Perfect Square
Given a positive integer num, write a function which returns True if num is a perfect square else False.
## implementation
the source code link: [click me](https://github.com/gfrank1688/ca_hw1)
### C code
```cpp=
#include <stdio.h>
bool isPerfectSquare(int num){
int k = 1;
while( num > 0)
{
num = num - k;
k = k + 2;
}
return num == 0;
}
int main(void){
int number1 = 14 , number2 = 16;
printf("is %d a perfect square number?%d\n",number1,isPerfectSquare(number1));
printf("is %d a perfect square number?%d\n",number2,isPerfectSquare(number2));
}
```
### logic
because every perfectsquare number can be a sum of 1+3+5+7+....+(2n+1)by this property,we can observe that it is come from (n+1)^2 - n^2 = 2n+1,so we can use a while loop to keep on subtracting input from a getting bigger odd number from 1,and check whether your input number will be 0 finally,if yes and it isa perfect square number,otherwise ,it's not.
* Example:16 = 1+3+5+7,we can check whether 16 is a perfect square numer by first subtract 16 from 1
16-1=15,and now 15 still > 0,so we keep going,
15-(1+2) = 15-3=12
12-(3+2) = 12-5=7
7-(5+2) = 7-7=0
so we can make sure that 16 = 1+3+5+7 ,and it's a perfect square number.
### Assembly
```asm==
.data
str1: .string "16 is a perfect square number(Yes = 1/No = 0) "
str2: .string "\n14 is a perfect square number(Yes = 1/No = 0) "
num1: .word 16
num2: .word 14
.text
main:
lw a0,num1
jal ra,isPerfectSquare
la a0,str1
li a7,4
ecall
mv a0,a1
li a7,1
ecall
lw a0,num2
jal ra,isPerfectSquare
la a0,str2
li a7,4
ecall
mv a0,a1
li a7,1
ecall
li a7,10
ecall
isPerfectSquare:
addi t0,zero,1
#add t2,a0,zero
mv t2, a0
loop: slti t1,t2,1
bne t1,zero,exit
sub t2,t2,t0
addi t0,t0,2
j loop
exit:
bne t2,zero,else
addi a1,zero,1
ret
else:
addi a1,zero,0
ret
```
### Assembly without pseudo
this code is changed from Ripes's editor with the instructions which
RISC-V machine can actually execute,that is, it replaced the pseudo instruction to the real instruction.
```arm==
00000000 <main>:
0: 10000517 auipc x10 0x10000
4: 03552503 lw x10 53 x10
8: 050000ef jal x1 80 <isPerfectSquare>
c: 10000517 auipc x10 0x10000
10: ff450513 addi x10 x10 -12
14: 00400893 addi x17 x0 4
18: 00000073 ecall
1c: 00058513 addi x10 x11 0
20: 00100893 addi x17 x0 1
24: 00000073 ecall
28: 10000517 auipc x10 0x10000
2c: 00952503 lw x10 9 x10
30: 028000ef jal x1 40 <isPerfectSquare>
34: 10000517 auipc x10 0x10000
38: fcc50513 addi x10 x10 -52
3c: 00400893 addi x17 x0 4
40: 00000073 ecall
44: 00058513 addi x10 x11 0
48: 00100893 addi x17 x0 1
4c: 00000073 ecall
50: 00a00893 addi x17 x0 10
54: 00000073 ecall
00000058 <isPerfectSquare>:
58: 00100293 addi x5 x0 1
5c: 00050393 addi x7 x10 0
00000060 <loop>:
60: 0013a313 slti x6 x7 1
64: 00031863 bne x6 x0 16 <exit>
68: 405383b3 sub x7 x7 x5
6c: 00228293 addi x5 x5 2
70: ff1ff06f jal x0 -16 <loop>
00000074 <exit>:
74: 00039663 bne x7 x0 12 <else>
78: 00100593 addi x11 x0 1
7c: 00008067 jalr x0 x1 0
00000080 <else>:
80: 00000593 addi x11 x0 0
84: 00008067 jalr x0 x1 0
```
### Analysis
I choose an R-TYPE subtract instruction to be a sample to show how the PIPELINE work
*`sub x7 x7 x5`

* IF-Stage
* next instruction's pc = pc + 4
* `sub x7 x7 x5` it's machine code is 0x405383b3

* ID-Stage
* rs1: 0x07 (x7)
* rs2: 0x05 (x5)
* rs1_data = 0x0000000e = 14(decimal)
* rs2_data = 0x00000001 = 1(decimal)

* EX-Stage
* you can see the leftist two MUXs's resource came from rs1_data/rs2_data(cause don't have data hazard here)
* cause it is R-TYPE instruction , so the final input of ALU are camd from the front MUXs
* ALU_in1:0x0000000e
* ALU_in2:0x00000001
* ALU_out:0x0000000d is the right output ( 15 - 1 = 14)

* MEM-Stage
* cause `sub x7 x7 x5` is R-TYPE,so I don't care about the value of addr/DI/DO(although they have value)

* WB-Stage
* the input came from ALU_out in EX-Stage and just pass through MEM-Stage
* look at the yellow line,you can see the output of WB's MUX go out the Pipeline and then write into Regfile,so now the instruction is actually done.
## Hazard issue
when I run the code of below instruction , suffer from a Control Hazard ,because the BranchCtrl are in the EX-Stage so the penalty is 2 clocks,that is,we need to flush two instructions in IF and ID stages.
`jal x1 80`


