# Lab1: RV32I Simulator ###### tags: `RISC-V` Definition of combinational number : \begin{split}C^{m}_{n} = C^{m-1}_{n-1} + C^{m}_{n-1}\end{split} I will use the formula to print pascal triangle ## Assembly code ```clike= .data argument: .word 7 # Number of pascal str1: .string " " str2: .string "\n" .text main: addi s0, zero, 6 addi s1, zero, -1 loop1: la a0, str2 li a7, 4 ecall addi s2,zero,-1 addi s1,s1,1 beq s1,s0,exit bne s1,s0,loop2 loop2: addi s2,s2,1 mv a0,s1 mv a1,s2 jal pascal print: mv a0, t1 li a7, 1 ecall addi t1,zero,0 la a0, str1 li a7, 4 ecall beq s2,s1,loop1 bne s2,s1,loop2 pascal: beq a0,a1,return1 #m==n beq zero,a1,return1 #m==0 addi sp, sp, -12 sw ra 0(sp) #save $ra into stack sw a0 4(sp) #save n into stack sw a1 8(sp) #save m into stack addi a0,a0,-1 #n-1 jal pascal #pascal(n-1,m) addi a1,a1,-1 #m-1 jal pascal #pascal(n-1,m-1) lw ra 0(sp) lw a0 4(sp) lw a1 8(sp) addi sp, sp, 12 jr ra return1: addi t1,t1, 1 jr ra exit: ``` ## RISC-V assembly program this program is composed of 5 part 1. main init number , and jump to pascal 2. loop there are outter loop and inner loop to print the combinational number in the triangle form 4. pascal compute for combination number with equation \begin{split}C^{n}_{m} = C^{n-1}_{m-1} + C^{n- 1}_{m}\end{split} 4. return 1 reach to the end of recusion for n=m or m=0 return 1 for this part 5. print use ecall to print the number ## description - `addi s0, zero, 6 , addi s1, zero, -1`, set the level of pascal triangle,and init the index of outter loop with -1 ALUsrc will be set in ID stage to use the immediate value for ALU in next stage MEMwrite will be set in the ID stage the register number we want to store in will be transfer from WB to ID to store the value ,this move is to get correct register number ![](https://i.imgur.com/EkqbWy1.jpg) - in loop1 ,first i use the ecall to print "\n" for the triangle format ,ecall cause system call,it will transfer the control from program to system environmnt,the enable signal was clear ![](https://i.imgur.com/kVu5TQf.jpg) ![](https://i.imgur.com/69P0wTK.jpg) - ` addi s1,s1,1 and beq s1,s0,exit ` there is a RAW (data hazard) ,but it can be solved by forwarding from the EX stage of `addi s1,s1,1` to the EX stage of`beq s1,s0,exit` ![](https://i.imgur.com/5Eanmem.jpg) - `beq s1,s0,exit, bne s1,s0,loop2` check the index of outter loop,one of them will be taken,then will cause pipeline flush ,if the `bne s1,s0,loop2` was taken,the follwing instruction `addi s2,s2,1 and mv a0,s1` would be flush our,so they must be refetched ![](https://i.imgur.com/zIm1wuf.jpg) - `jal pascal` jump to the pascal and put the PC+4 in ra register which will be store in the ra register in the WB stage after jump the follwing two instruction will be flush out.` beq a0,a1,return1` will be fetched ![](https://i.imgur.com/8MOobfD.jpg) ![](https://i.imgur.com/TH5n8C2.jpg) - `beq a0,a1,return1 #m==n and beq zero,a1,return1 #m==0 ` decide whether to goto return 1.when branch taken ,i will cause two stall because branch is decided in EX stage - `addi sp,sp,-12 . sw ra,0(sp) . sw a0,4(sp) . sw a1 ,8(sp) ` save the argument for combinational number and return address into memory . - `addi a0,a0,-1 #n-1 jal pascal #pascal(n-1,m) addi a1,a1,-1 #m-1 jal pascal #pascal(n-1,m-1)` those are for recusion part , use the equation which mentioned above - ` lw ra 0(sp) lw a0 4(sp) lw a1 8(sp) addi sp, sp, 12 jr ra` recover the content of register ,and jump to the return address. the writtten data and written register number will be pass to ID stage in WB,and register write signal will be set ![](https://i.imgur.com/jD853nk.jpg) - after compute the combinational ,go back to print. print the number which is formated with ecall and check the index of inner loop with branch instruction. it decide where it would continue this loop or jump to the outter loop . `