diff --git a/week1/PES2UG22EC115_Week1_Lab.md b/week1/PES2UG22EC115_Week1_Lab.md new file mode 100644 index 00000000..e3ec33d3 --- /dev/null +++ b/week1/PES2UG22EC115_Week1_Lab.md @@ -0,0 +1,89 @@ +# Program 1: +### Statement: Convert a 32-bit value from Little Endian to Big Endian format using RISC-V assembly + +### Name of file: +PES2UG22EC115_Week1_Lab.s + +### Observation - Single Cycle +- First we load the word data into register x11 using load word (lw). We define an iterating variable in x3 to know when to stop the loop. Using andi instruction to mask the MSB we obtain the least significant byte into register x12. +- We shift the extracted value to the left by required amount to get it towards MSB position and shift the original nummber to the right by 8 bits to remove the already extracted byte. +- Using branch if not equal to zero we can stop the loop when iterating variable hits 0. Finally we do the final masking and addition to complete the reversal of bytes. We write back this value into another location in data memory to be able to compare little endian with big endian order of storing data. + +### Observation - Single Cycle +- **Cycles:** 25 +- **Frequency:** 10.53 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 33 +- **Frequency:** 6.49 Hz +- **CPI:** 1.32 +- **IPC:** 0.758 + +### Register Mapping +- **x11:** 0x00000012   Final value (Right Shifted in every iteration of loop) +- **x12:** 0x00000034 +- **x14:** 0x78563400 +- **x15:** 0x78563412 + +### Data Mapping +- **0x10000000:** 0x12345678   Little Endian +- **0x10000004:** 0x78563412   Big Endian + +### Snapshot +![little2big](https://github.com/user-attachments/assets/76b08735-2096-4a9e-85e5-028c8bc85401) + + +... + + + +# Program 2: +### Statement: Write an Assembly Program for addition of 2 64-bit numbers on RV32I + +### Name of file: +PES2UG22EC115_Week1_Lab.s + +### Observation - Single Cycle +- Store the 64-bit (double word) numbers into 4 32-bit registers in the order of MSB1, LSB1, MSB2, LSB2. +- Load the LSB values of both numbers into 2 registers and add them. Check for carry using sltu instruction and store in another register. (sets value 1 if result value is greater than either of the operands). +- Perform the same steps for MSB of both numbers. FInally add the carry to the sum of MSB values. Check for carry in MSB addition using sltu to check for overflow in addition. +- Result (MSB,LSB final value) is stored back into memory. + +### Observation - Single Cycle +- **Cycles:** 13 +- **Frequency:** 6.21 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 19 +- **Frequency:** 5.85 Hz +- **CPI:** 1.46 +- **IPC:** 0.684 + +### Register Mapping +- **x2:** 0x10000000 +- **x18:** 0x90000123 +- **x19:** 0xffffffff +- **x20:** 0x90000122 +- **x21:** 0x00000001 +- **x22:** 0x80001234 +- **x23:** 0x90001234 +- **x24:** 0x10002468 +- **x25:** 0x00000001 +- **x26:** 0x10002469 + +### Data Mapping +- **0x10000000:** 0x80001234 +- **0x10000004:** 0x90000123 +- **0x10000008:** 0x90001234 +- **0x1000000c:** 0xffffffff +- **0x10000014:** 0x90000122 +- **0x10000018:** 0x10002469 + +### Snapshot +![adding64bit](https://github.com/user-attachments/assets/9de90ea5-8e58-4133-acb2-2c5d3b8ceecd) + +... diff --git a/week1/PES2UG22EC115_Week1_Lab.s b/week1/PES2UG22EC115_Week1_Lab.s new file mode 100644 index 00000000..9512279a --- /dev/null +++ b/week1/PES2UG22EC115_Week1_Lab.s @@ -0,0 +1,39 @@ +# PROGRAM 1 +# PROGRAM 1 +.data +a: .word 0x12345678 + +.text +la x10,a +lw x11,0(x10) +addi x3,x0,3 # Iterating variable assigned to 3 because we are using word data +back: + andi x12,x11,0xFF # Masking the MSB to get the 2 least significant bytes + add x14,x14,x12 # Adding the two numbers to join the bytes into 1 number + slli x14,x14,8 # Shifting left to move the above bytes to MSB position + srli x11,x11,8 # Shifting right to remove the LSB that has already been extracted + addi x3,x3,-1 # Modify iterating variable +bnez x3,back +andi x15,x11,0xFF # Final byte +add x15,x14,x15 +sw x15,4(x10) # Writeback to data memory + + + +# PROGRAM 2 +.data +a: .word 0x80001234 , 0x90000123 , 0x90001234 , 0xFFFFFFFF + +.text +la x2, a +lw x18,4(x2) +lw x19,12(x2) +add x20,x18,x19 # Adding LSB of both numbers +sltu x21,x20,x18 +lw x22,0(x2) +lw x23,8(x2) +add x24,x22,x23 # Adding LSB of both numbers +sltu x25,x24,x22 # Checks for overflow +add x26,x24,x21 # Adds carry of LSB to MSB result +sw x26,24(x2) # MSB of result +sw x20,20(x2) # LSB of result diff --git a/week10/alu_control.png b/week10/alu_control.png new file mode 100644 index 00000000..f1d0a7af Binary files /dev/null and b/week10/alu_control.png differ diff --git a/week10/alu_control.sv b/week10/alu_control.sv new file mode 100644 index 00000000..f93c2dbd --- /dev/null +++ b/week10/alu_control.sv @@ -0,0 +1,26 @@ +module alu_control( + input logic [2:0]funct3, + input logic [6:0]funct7, + input logic [1:0]alu_op, + output logic [3:0]alu_control + ); + always_comb + case(alu_op) + 2'b10: begin + if(funct3[2:0]==0) + begin + if(funct7[5]) + alu_control=0110; //sub + else + alu_control=0010; //add + end + else if(funct3[2:0]==3'b111) + alu_control=0000; //AND + else + alu_control=0001; //OR + end + 2'b00 : alu_control=0010; + 2'b01 : alu_control=0110; + default : alu_control=0000; + endcase +endmodule \ No newline at end of file diff --git a/week10/control_unit.png b/week10/control_unit.png new file mode 100644 index 00000000..8a286e2a Binary files /dev/null and b/week10/control_unit.png differ diff --git a/week10/control_unit.sv b/week10/control_unit.sv new file mode 100644 index 00000000..9d086a84 --- /dev/null +++ b/week10/control_unit.sv @@ -0,0 +1,49 @@ +module control_unit( + input logic [6:0] opcode, + input logic [2:0] funct3, + output logic [2:0] mem_control, + output logic [1:0] alu_op, + output logic reg_write,mem_read,mem_write, + output logic alu_src, + output logic mem_to_reg + ); + + always_comb + begin + alu_op = 2'b0; + alu_src = 1'b0; + mem_to_reg = 1'b0; + reg_write = 1'b0; + mem_read = 1'b0; + mem_write = 1'b0; + case(opcode) + 7'b0110011 : begin // R Type + reg_write = 1'b1; + alu_op = 2'b10; + end + 7'b0000011 : begin // Load + alu_src = 1'b1; + mem_read = 1'b1; + mem_to_reg = 1'b1; + reg_write = 1'b1; + alu_op = 2'b00; + case(funct3) + 3'b000: mem_control = 3'b000; // LB + 3'b001: mem_control = 3'b001; // LH + 3'b010: mem_control = 3'b010; // LW + 3'b100: mem_control = 3'b011; // LBU + 3'b101: mem_control = 3'b100; // LHU + default: mem_control = 3'bX; // Malformed instruction + endcase + end + 7'b0100011 : begin // Store + alu_src = 1'b1; + alu_op = 2'b00; + mem_write = 1'b1; + end + 7'b1100011 : begin // Branch + mem_to_reg = 1'bx; + end + endcase + end +endmodule \ No newline at end of file diff --git a/week2/PES2UG22EC115_Week2_Lab.md b/week2/PES2UG22EC115_Week2_Lab.md new file mode 100644 index 00000000..a4e15646 --- /dev/null +++ b/week2/PES2UG22EC115_Week2_Lab.md @@ -0,0 +1,144 @@ +# Program 1a: +### Statement: Write an Assembly Program for addition of 2 words + +### Name of file: +PES2UG22EC115_Week2_Lab.s + +### Observation - Explanation +- Two word-sized values are defined and stored in memory. We access data memory locations using physical address (Base Address + Immediate Offset) +- Values are loaded into saved registers using load word (lw), added together, and the result is stored back in destination register. +- Result stored in destination register is stored into data memory using store word (sw) instruction. + +### Observation - Single Cycle +- **Cycles:** 6 +- **Frequency:** 6.45 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 11 +- **Frequency:** 6.67 Hz +- **CPI:** 1.83 +- **IPC:** 0.545 + +### Register Mapping +- **x18:** 0x80001234 +- **x19:** 0x90000123 +- **x20:** 0x10001357 + +### Data Mapping +- **0x10000008:** 0x10001357 +- **0x10000004:** 0x90000123 +- **0x10000000:** 0x80001234 + +### Snapshot +![word_addi](https://github.com/user-attachments/assets/757aab2f-d554-4949-9b1a-d517bc421745) + +# Program 1b: +### Statement: Write an Assembly Program for addition of 2 half words + +### Name of file: +PES2UG22EC115_Week2_Lab.s + +### Observation - Explanation +- Two 16-bit values are defined and stored in memory. We access data memory locations using physical address (Base Address + Immediate Offset) +- Values are loaded into saved registers using load halfword (lh), added together, and the result is stored back in destination register. +- Result stored in destination register is stored into data memory using store half-word (sh) instruction. + +### Observation - Single Cycle +- **Cycles:** 6 +- **Frequency:** 6.33 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 11 +- **Frequency:** 6.49 Hz +- **CPI:** 1.83 +- **IPC:** 0.545 + +### Register Mapping +- **x18:** 0x000061a8 +- **x19:** 0x00000350 +- **x20:** 0x000064f8 + +### Data Mapping +- **0x10000004:** 0x000064f8 +- **0x10000000:** 0x035061a8 + +### Snapshot +![half_addi](https://github.com/user-attachments/assets/74abd484-3d3b-4eb3-a821-642cca698b6c) + + +# Program 1c: +### Statement: Write an Assembly Program for addition of 2 bytes + +### Name of file: +PES2UG22EC115_Week2_Lab.s + +### Observation - Explanation +- Two byte (8-bit) values are defined and stored in memory. We access data memory locations using physical address (Base Address + Immediate Offset) +- Values are loaded into saved registers using load halfword (lb), added together, and the result is stored back in destination register. +- Result stored in destination register is stored into data memory using store half-word (sb) instruction. + +### Observation - Single Cycle +- **Cycles:** 6 +- **Frequency:** 6.02 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 11 +- **Frequency:** 6.58 Hz +- **CPI:** 1.83 +- **IPC:** 0.545 + +### Register Mapping +- **x18:** 0x00000006 +- **x19:** 0x00000002 +- **x20:** 0x00000008 + +### Data Mapping +- **0x10000000:** 0x00080206 + +### Snapshot +![byte_addi](https://github.com/user-attachments/assets/acb0c159-0a62-4e66-a67a-55e2ded76fc9) + +# Program 2: +### Statement: Write an Assembly program for calculating x = (y + m) - (L - D) + (Z + C) - D, where x, y, m, L, D, Z, C are elements of 32-bits wide + +### Name of file: +PES2UG22EC115_Week2_Lab.s + +### Observation - Explanation +- + +### Observation - Single Cycle +- **Cycles:** 12 +- **Frequency:** 6.06 Hz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 16 +- **Frequency:** 5.56 Hz +- **CPI:** 1.33 +- **IPC:** 0.75 + +### Register Mapping +- **x6:** `0x0000000a` +- **x7:** `0x00000005` +- **x8:** `0x00000014` +- **x9:** `0x00000003` +- **x10:** `0x0000000f` +- **x11:** `0x00000008` +- **x12:** `0x0000000f` +- **x13:** `0x00000011` +- **x14:** `0xfffffffe` +- **x15:** `0x00000017` +- **x16:** `0x00000015` +- **x17:** `0x00000012` + + +### Snapshot +![eqnprob](https://github.com/user-attachments/assets/ac9e0fea-574d-444a-b8ad-29e72a1de6a4) diff --git a/week2/PES2UG22EC115_Week2_Lab.s b/week2/PES2UG22EC115_Week2_Lab.s new file mode 100644 index 00000000..5a537bf9 --- /dev/null +++ b/week2/PES2UG22EC115_Week2_Lab.s @@ -0,0 +1,50 @@ +# PROGRAM 1a +.data +a: .word 0x80001234 , 0x90000123 + +.text +la x2, a +lw x18, 0(x2) +lw x19, 4(x2) +add x20,x18,x19 +sw x20,8(x2) + +# PROGRAM 1b +.data +a: .half 0x61A8 , 0x350 + +.text +la x2, a +lh x18, 0(x2) +lh x19, 2(x2) +add x20,x18,x19 +sh x20,6(x2) + +# PROGRAM 1c +.data +a: .byte 0x06 , 0x02 + +.text +la x2, a +lb x18, 0(x2) +lb x19, 1(x2) +add x20,x18,x19 +sb x20,2(x2) + + + +# PROGRAM 2 +.text +addi x6, x0, 10 +addi x7, x0, 5 +addi x8, x0, 20 +addi x9, x0, 3 +addi x10, x0, 15 +addi x11, x0, 8 +add x12, x6, x7 +sub x13, x8, x9 +sub x14, x12, x13 +add x15, x10, x11 +add x16, x14, x15 +sub x17, x16, x9 + diff --git a/week3/PES2UG22EC115_Week3_Lab.s b/week3/PES2UG22EC115_Week3_Lab.s new file mode 100644 index 00000000..1a56c6b6 --- /dev/null +++ b/week3/PES2UG22EC115_Week3_Lab.s @@ -0,0 +1,58 @@ +# Program 1 +.data +a: .byte 0x5,0x2 +.text +la x10,a +lb x11,0(x10) +lb x4,1(x10) +srli x12,x11,5 +addi x13,x0,0 #x13 is count +addi x2,x0,1 #x2 is to and it with x11 +bne x12,x0,exit +loop1:and x14,x11,x2 + bne x14,x0,next + addi x2,x2,1 + beq x0,x0,loop1 +next:addi x13,x13,1 + beq x13,x4,exit + addi x2,x2,1 + beq x0,x0,loop1 +exit:addi x15 x0,0x03 + + +# Program 2 +.data +code1: .byte 0x01,0x00,0x01,0x01 # P1= 1 P2 = 0 P3 = 0 output 1010101 +code2: .byte 0x01,0x01,0x00,0x00 # P1= 1 P2 = 0 P3 = 0 output 1100001 +.text +la x1,code2 + +Hamming: + lb x3,0x03(x1) #d0 + lb x4,0x02(x1) #d1 + lb x5,0x01(x1) #d2 + lb x6,0x00(x1) #d3 + + xor x11,x3,x4 # P1 = x11 + xor x11,x11,x6 + + xor x12,x3,x5 # P2 = x12 + xor x12,x12,x6 + + xor x13,x4,x5 # P3 = x13 + xor x13,x13,x6 + + slli x12,x12,0x01 + slli x13,x13,0x03 + add x15,x12,x13 + add x15,x15,x11 + + slli x3,x3,0x02 + slli x4,x4,0x04 + slli x5,x5,0x05 + slli x6,x6,0x06 + add x15,x15,x3 + add x15,x15,x4 + add x15,x15,x5 + add x15,x15,x6 + sb x15,0x04(x1) \ No newline at end of file diff --git a/week3/prog1_5-stage.png b/week3/prog1_5-stage.png new file mode 100644 index 00000000..60ba354f Binary files /dev/null and b/week3/prog1_5-stage.png differ diff --git a/week3/prog1_singlestage.png b/week3/prog1_singlestage.png new file mode 100644 index 00000000..f39b0521 Binary files /dev/null and b/week3/prog1_singlestage.png differ diff --git a/week3/prog2_5-stage.png b/week3/prog2_5-stage.png new file mode 100644 index 00000000..b6138525 Binary files /dev/null and b/week3/prog2_5-stage.png differ diff --git a/week3/prog2_singlestage.png b/week3/prog2_singlestage.png new file mode 100644 index 00000000..80512cb3 Binary files /dev/null and b/week3/prog2_singlestage.png differ diff --git a/week4/PES2UG22EC115_Week4_Lab.s b/week4/PES2UG22EC115_Week4_Lab.s new file mode 100644 index 00000000..d10e1da7 --- /dev/null +++ b/week4/PES2UG22EC115_Week4_Lab.s @@ -0,0 +1,51 @@ +# Program : Write an assembly program to find whether a given string is a palindrome or not, using stack operations +.data +a: .byte 0x11, 0x22, 0x33, 0x33, 0x22, 0x11 +.text +palindrome: + la x10, a + la x15, a + addi x15, x15, 5 + addi x11, x0, 1 +loop1: + lb x20, 0(x10) + lb x21, 0(x15) + bne x20, x21, nopl + addi x10, x10, 1 + addi x15, x15, -1 + blt x10, x15, loop1 + j exit +nopl: + addi x11, x0, 0 +exit: + addi x0, x0, 0 + + + +# Program : Write an assembly program to search a given number in an array +.data +array: .word 5, 12, 7, 20, 14, 7, 18 + +.text +main: + la x10, array + addi x11, x0, 7 + addi x12, x0, 7 + addi x13, x0, 0 + addi x14, x0, -1 + addi x15, x0, 0 +search_loop: + beq x15, x11, not_found + lw x16, 0(x10) + beq x16, x12, found + addi x10, x10, 4 + addi x15, x15, 1 + jal x0, search_loop +found: + add x14, x15, x0 + jal x0, exit +not_found: + addi x14, x0, -1 +exit: + add x0, x0, x0 + diff --git a/week4/prog1_5-stage.png b/week4/prog1_5-stage.png new file mode 100644 index 00000000..fcda3e06 Binary files /dev/null and b/week4/prog1_5-stage.png differ diff --git a/week4/prog1_singlestage.png b/week4/prog1_singlestage.png new file mode 100644 index 00000000..b11a4f76 Binary files /dev/null and b/week4/prog1_singlestage.png differ diff --git a/week4/prog2_5-stage.png b/week4/prog2_5-stage.png new file mode 100644 index 00000000..91f893df Binary files /dev/null and b/week4/prog2_5-stage.png differ diff --git a/week4/prog2_singlestage.png b/week4/prog2_singlestage.png new file mode 100644 index 00000000..9fc8f509 Binary files /dev/null and b/week4/prog2_singlestage.png differ diff --git a/week5/PES2UG22EC115_Week5_Lab.md b/week5/PES2UG22EC115_Week5_Lab.md new file mode 100644 index 00000000..9a98bd76 --- /dev/null +++ b/week5/PES2UG22EC115_Week5_Lab.md @@ -0,0 +1,120 @@ +# Program 1: +### Statement: Write an assembly program to check whether a given number in an array of elements is divisible by 9 + +### Name of file: +PES2UG22EC115_Week5_Lab.s + +### Observation - Explanation +- We define an array of numbers (18, 27, 20, 45, 81) and store its size (5).We load the base address of the input array and the results array and initialize a loop counter variable i to 0. +- The code performs a modulus calculation for each array element: + It loads the current array element into a register. + It performs a modulus operation to check if the element is divisible by 9. + It stores the result (1 if divisible, 0 if not) in the corresponding results array element. +- The code increments the loop counter and jumps back to the beginning of the loop until all array elements have been processed. +- Finally, the code enters an infinite loop to halt the program execution. +### Observation - Single Cycle +- **Cycles:** 143 +- **Frequency:** 207.30 mHz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 217 +- **Frequency:** 209.60 mHz +- **CPI:** 1.53 +- **IPC:** 0.654 + +### Memory Mapping +- **0x10000000:** `0x00000012` +- **0x10000004:** `0x0000001b` +- **0x10000008:** `0x00000014` +- **0x1000000c:** `0x0000002d` +- **0x10000010:** `0x00000051` +- **0x10000014:** `0x00000005` +- **0x10000018:** `0x00000001` +- **0x1000001c:** `0x00000001` +- **0x10000020:** `0x00000000` +- **0x10000024:** `0x00000001` +- **0x10000028:** `0x00000001` + +### Register Mapping +- **x5:** `0x00000005` +- **x6:** `0x00000010` +- **x7:** `0x10000010` +- **x10:** `0x10000000` +- **x11:** `0x00000005` +- **x12:** `0x10000018` +- **x28:** `0x00000051` +- **x29:** `0x00000009` +- **x30:** `0x10000028` +- **x31:** `0x00000001` + + +### Snapshot +![divby9](https://github.com/user-attachments/assets/bf273489-2eb4-449f-98e7-411597435621) + + +# Program 2: +### Write an Assembly Program for the following C code: +``` +main() { + unsigned short int a[11] = {0x1234, 0x5678, ...}; + unsigned short int b[11] = {0x1234, 0x5678, ...}; + unsigned short int c[11] = {0x1234, 0x5678, ...}; + for(i = 0; i < 10; i++) + { + c[i] = a[i] * b[i] + c[i-1]; + } +``` +### Name of file: +PES2UG22EC115_Week5_Lab.s + +### Observation - Explanation +- Array Initialization and Setup: The program loads the base addresses of the arrays a, b, and c into registers s0, s1, and s2, respectively. It initializes the loop counter i (in t0) to 0 to start iterating over the arrays. + +- Loop Control: The loop runs as long as i is less than 10 (bge t0, t1, loop_end), where t1 is set to 10 as the loop's upper bound. If i reaches 10, the program jumps to loop_end to terminate. + +- Element Access and Computation: The program calculates the addresses for a[i] and b[i], loads their values into t3 and t4, and computes a[i] * b[i] into t5. If i > 0, it adds c[i-1] to t5 to compute the result c[i] = a[i] * b[i] + c[i-1]. + +- Storing and Loop Continuation: The result in t5 is stored into c[i] using the address calculated with t2. The loop counter i (t0) is incremented, and the program jumps back to loop_start to continue the process until i reaches 10. The program then enters an infinite loop at loop_end. + +### Observation - Single Cycle +- **Cycles:** 143 +- **Frequency:** 207.30 mHz +- **CPI:** 1 +- **IPC:** 1 + +### Observation - 5 Stage +- **Cycles:** 217 +- **Frequency:** 209.60 mHz +- **CPI:** 1.53 +- **IPC:** 0.654 + +### Memory Mapping +- **0x10000000:** `0x00000012` +- **0x10000004:** `0x0000001b` +- **0x10000008:** `0x00000014` +- **0x1000000c:** `0x0000002d` +- **0x10000010:** `0x00000051` +- **0x10000014:** `0x00000005` +- **0x10000018:** `0x00000001` +- **0x1000001c:** `0x00000001` +- **0x10000020:** `0x00000000` +- **0x10000024:** `0x00000001` +- **0x10000028:** `0x00000001` + +### Register Mapping +- **x5:** `0x00000005` +- **x6:** `0x00000010` +- **x7:** `0x10000010` +- **x10:** `0x10000000` +- **x11:** `0x00000005` +- **x12:** `0x10000018` +- **x28:** `0x00000051` +- **x29:** `0x00000009` +- **x30:** `0x10000028` +- **x31:** `0x00000001` + + +### Snapshot +![cprogtoasm](https://github.com/user-attachments/assets/b90f13d2-a24b-4cff-aef0-d698ccbac689) diff --git a/week5/PES2UG22EC115_Week5_Lab.s b/week5/PES2UG22EC115_Week5_Lab.s new file mode 100644 index 00000000..2b59e5f5 --- /dev/null +++ b/week5/PES2UG22EC115_Week5_Lab.s @@ -0,0 +1,75 @@ +# Program 1 + +.data +array: .word 18, 27, 20, 45, 81 +size: .word 5 +results: .word 0, 0, 0, 0, 0 + +.text +start: + la a0, size + lw a1, 0(a0) + la a0, array + la a2, results + addi t0, x0, 0 +loop: + bge t0, a1, end_loop + slli t1, t0, 2 + add t2, a0, t1 + lw t3, 0(t2) + addi t4, x0, 9 + add t5, t3, x0 + addi t6, x0, 0 +modulus_loop: + blt t5, t4, check_remainder + sub t5, t5, t4 + beq x0, x0, modulus_loop +check_remainder: + beq t5, x0, divisible + addi t6, x0, 0 + beq x0, x0, store_result +divisible: + addi t6, x0, 1 +store_result: + add t5, a2, t1 + sw t6, 0(t5) + addi t0, t0, 1 + beq x0, x0, loop +end_loop: + beq x0, x0, end_loop + + + +# Program 2 + +.data +a: .half 0x1234, 0x5678, 0xABCD, 0xEF01 +b: .half 0x1234, 0x5678, 0xABCD, 0xEF01 +c: .half 0x1234, 0x5678, 0xABCD, 0xEF01 +.text +main: + la s0, a + la s1, b + la s2, c + addi t0, x0, 0 +loop_start: + addi t1, x0, 10 + bge t0, t1, loop_end + slli t2, t0, 1 + add t2, s0, t2 + lh t3, 0(t2) + add t2, s1, t2 + lh t4, 0(t2) + mul t5, t3, t4 + beqz t0, skip_prev_c + addi t2, t2, -2 + add t2, s2, t2 + lh t4, 0(t2) + add t5, t5, t4 +skip_prev_c: + add t2, s2, t2 + sh t5, 0(t2) + addi t0, t0, 1 + j loop_start +loop_end: + j loop_end diff --git a/week6/PES2UG22EC115_Week6_Lab.s b/week6/PES2UG22EC115_Week6_Lab.s new file mode 100644 index 00000000..34319afa --- /dev/null +++ b/week6/PES2UG22EC115_Week6_Lab.s @@ -0,0 +1,43 @@ +# Program 1 +.data # bubble sort +a: .byte 0x0e, 0x0d, 0x10, 0x02, 0x07, 0x04 + +.text +addi x21, x0, 5 # final index or number of element +la x10, a # Initial address +add x20, x10, x21 # final address +loop1: # outer loop + loop2: # inner loop + lbu x11, 0(x10) # Get element + lbu x12, 1(x10) # Get next element + bgt x11, x12, swap + addi x10, x10 ,1 # Goto next element + bne x10, x20, loop2 # Loop until it reaches final address + addi x20, x20, -1 # reduce cycle count by not check the last elements + la x10, a # Reset address or go back to beginning of array + addi x1, x1, 1 # Outer counter + bne x1, x21, loop1 # Loop until all indexes covered + j exit +swap: + sb x11, 1(x10) + sb x12, 0(x10) + j loop2 +exit: + addi a0, x0, 0 # exit code + addi a7, x0, 93 + + +# Program 2 +.data +fact: .byte 0x05 +.text +la x10,fact +lw x11,0(x10) +addi x12,x0,1 +loop: + blez x11,out + mul x12,x12,x11 + addi x11,x11,-1 + j loop +out: + add x15,x0,x12 \ No newline at end of file diff --git a/week6/adder.png b/week6/adder.png new file mode 100644 index 00000000..e8a08348 Binary files /dev/null and b/week6/adder.png differ diff --git a/week6/adder.sv b/week6/adder.sv new file mode 100644 index 00000000..ca9d1771 --- /dev/null +++ b/week6/adder.sv @@ -0,0 +1,6 @@ +module adder( + input logic [31:0] a,b, + output logic [31:0] sum + ); + assign sum = a + b; +endmodule \ No newline at end of file diff --git a/week6/async_reset_ff.png b/week6/async_reset_ff.png new file mode 100644 index 00000000..fa0f9fd1 Binary files /dev/null and b/week6/async_reset_ff.png differ diff --git a/week6/async_reset_ff.sv b/week6/async_reset_ff.sv new file mode 100644 index 00000000..a8eed913 --- /dev/null +++ b/week6/async_reset_ff.sv @@ -0,0 +1,16 @@ +module async_reset_dff ( + input logic clk, + input logic reset_n, + input logic d, + output logic q +); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + q <= 1'b0; + end else begin + q <= d; + end + end + +endmodule diff --git a/week6/instr_fetch.png b/week6/instr_fetch.png new file mode 100644 index 00000000..240755fd Binary files /dev/null and b/week6/instr_fetch.png differ diff --git a/week6/instr_fetch.sv b/week6/instr_fetch.sv new file mode 100644 index 00000000..7f0bde61 --- /dev/null +++ b/week6/instr_fetch.sv @@ -0,0 +1,14 @@ +module instr_fetch( + input bit clk,reset, + input logic branch_sel, + input logic [31:0] branch_ip, + output logic [31:0] instr,pc_present,pc_next + ); + + logic [31:0] pc_i; + + instr_mem mem1(.pc_i(pc_present), .data_o(instr)); + adder add1(.a(4), .b(pc_present), .sum(pc_next)); + mux21 mux1(.in1(pc_next), .in2(branch_ip), .select(branch_sel), .y(pc_i)); + pc_reg pc1(.clk(clk), .reset(reset), .pc_i(pc_i), .pc_out(pc_present)); +endmodule \ No newline at end of file diff --git a/week6/instr_mem.png b/week6/instr_mem.png new file mode 100644 index 00000000..5b2b79a0 Binary files /dev/null and b/week6/instr_mem.png differ diff --git a/week6/instr_mem.sv b/week6/instr_mem.sv new file mode 100644 index 00000000..86e249c4 --- /dev/null +++ b/week6/instr_mem.sv @@ -0,0 +1,19 @@ +module instr_mem( + input logic [31:0] pc_i, + output logic [31:0] data_o + ); + + logic [4:0] addr; + logic [7:0] mem [31:0] = '{8'bX, 8'bX, 8'bX, 8'bX, + 8'bX, 8'bX, 8'bX, 8'bX, + 8'bX, 8'bX, 8'bX, 8'bX, + 8'hX, 8'hX, 8'hX, 8'hX, + 8'b00, 8'b00, 8'b00, 8'b00, + 8'h00, 8'h84, 8'h89, 8'h33, + 8'h10, 8'h10, 8'h04, 8'h93, + 8'h01, 8'h00, 8'h04, 8'h13}; + + assign addr = pc_i[4:0]; + + assign data_o = {mem [addr+3], mem [addr+2], mem [addr+1], mem [addr]}; +endmodule \ No newline at end of file diff --git a/week6/mux21.png b/week6/mux21.png new file mode 100644 index 00000000..ef69fd82 Binary files /dev/null and b/week6/mux21.png differ diff --git a/week6/mux21.sv b/week6/mux21.sv new file mode 100644 index 00000000..455b4ad8 --- /dev/null +++ b/week6/mux21.sv @@ -0,0 +1,7 @@ +module mux21( + input logic [31:0] in1,in2, + input logic select, + output logic [31:0] y + ); + assign y = select ? in1 : in2; +endmodule \ No newline at end of file diff --git a/week6/mux31.png b/week6/mux31.png new file mode 100644 index 00000000..71daaa3e Binary files /dev/null and b/week6/mux31.png differ diff --git a/week6/mux31.sv b/week6/mux31.sv new file mode 100644 index 00000000..999951ad --- /dev/null +++ b/week6/mux31.sv @@ -0,0 +1,9 @@ +module mux31( + input logic [31:0] a,b,c, + input logic [1:0] select, + output logic [31:0] y + ); + + assign y = select[1] ? c : (select[0] ? b : a); + +endmodule \ No newline at end of file diff --git a/week6/prog1_5-stage.png b/week6/prog1_5-stage.png new file mode 100644 index 00000000..9664b4e8 Binary files /dev/null and b/week6/prog1_5-stage.png differ diff --git a/week6/prog1_singlestage.png b/week6/prog1_singlestage.png new file mode 100644 index 00000000..bed996ec Binary files /dev/null and b/week6/prog1_singlestage.png differ diff --git a/week6/prog2_5-stage.png b/week6/prog2_5-stage.png new file mode 100644 index 00000000..042b462e Binary files /dev/null and b/week6/prog2_5-stage.png differ diff --git a/week6/prog2_singlestage.png b/week6/prog2_singlestage.png new file mode 100644 index 00000000..de483510 Binary files /dev/null and b/week6/prog2_singlestage.png differ diff --git a/week6/sync_reset_ff.png b/week6/sync_reset_ff.png new file mode 100644 index 00000000..f1100340 Binary files /dev/null and b/week6/sync_reset_ff.png differ diff --git a/week6/sync_reset_ff.sv b/week6/sync_reset_ff.sv new file mode 100644 index 00000000..4ccc2082 --- /dev/null +++ b/week6/sync_reset_ff.sv @@ -0,0 +1,16 @@ +module sync_reset_dff ( + input logic clk, + input logic reset_n, + input logic d, + output logic q +); + + always_ff @(posedge clk) begin + if (!reset_n) begin + q <= 1'b0; + end else begin + q <= d; + end + end + +endmodule diff --git a/week7/instr_decode.png b/week7/instr_decode.png new file mode 100644 index 00000000..c2261ed9 Binary files /dev/null and b/week7/instr_decode.png differ diff --git a/week7/instr_decode.sv b/week7/instr_decode.sv new file mode 100644 index 00000000..b5793205 --- /dev/null +++ b/week7/instr_decode.sv @@ -0,0 +1,66 @@ +module instr_decode( + input bit clk,reset,wr_en, + input logic [31:0] instr_i,data, + output logic [4:0] rs1,rs2,rd, + output logic [6:0] opcode,funct7, + output logic [2:0] funct3, + output logic [31:0] reg1,reg2, + output logic r_type, + output logic i_type, + output logic s_type, + output logic b_type, + output logic u_type, + output logic j_type, + output logic [31:0] imm_o + ); + logic[31:0] instr_imm; + logic[31:0] i_type_imm; + logic[31:0] s_type_imm; + logic[31:0] b_type_imm; + logic[31:0] u_type_imm; + logic[31:0] j_type_imm; + + assign rd = instr_i[11:7]; + assign rs1 = instr_i[19:15]; + assign rs2 = instr_i[24:20]; + assign opcode = instr_i[6:0]; + assign funct3 = instr_i[14:12]; + assign funct7 = instr_i[31:25]; + + assign i_type_imm = {{20{instr_i[31]}},instr_i[31:20]}; + assign s_type_imm = {{20{instr_i[31]}},instr_i[31:25],instr_i[11:7]}; + assign b_type_imm = {{20{instr_i[31]}},instr_i[7],instr_i[30:25],instr_i[11:8],1'b0}; + assign u_type_imm = {instr_i[31:12],12'b0}; + assign j_type_imm = {{12{instr_i[31]}},instr_i[19:12],instr_i[20],instr_i[30:21],1'b0}; + + assign imm_o = r_type ? 32'h0 : + i_type ? i_type_imm : + s_type ? s_type_imm : + b_type ? b_type_imm : + u_type ? u_type_imm : + j_type_imm ; + + always_comb + begin + r_type = 1'b0; + j_type = 1'b0; + i_type = 1'b0; + s_type = 1'b0; + b_type = 1'b0; + u_type = 1'b0; + case(opcode) + 7'b0110011 : r_type = 1'b1; + 7'b0010011, + 7'b0000011, + 7'b1100111 : i_type = 1'b1; + 7'b0110111, + 7'b0010111 : u_type = 1'b1; + 7'b1101111 : j_type = 1'b1; + 7'b0100011 : s_type = 1'b1; + 7'b1100011 : b_type = 1'b1; + default; + endcase + end + + reg_file regfile(.data_i(data), .rd(rd), .rs1(rs1), .rs2(rs2), .wr_en(wr_en), .reg1(reg1), .reg2(reg2), .clk(clk)); +endmodule diff --git a/week7/reg_file.png b/week7/reg_file.png new file mode 100644 index 00000000..758b1c7f Binary files /dev/null and b/week7/reg_file.png differ diff --git a/week7/reg_file.sv b/week7/reg_file.sv new file mode 100644 index 00000000..c7c3b926 --- /dev/null +++ b/week7/reg_file.sv @@ -0,0 +1,23 @@ +module reg_file( + input bit clk,wr_en, + input logic [4:0] rs1,rs2,rd, + input logic [31:0] data_i, + output logic [31:0] reg1,reg2 + ); + + logic [31:0] reg_data [0:31]; + + always_comb + begin + for(int i = 0; i<32; i++) + reg_data[i] <= 32'b0; + end + + always @(posedge wr_en) + reg_data[rd] <= data_i; + + always_comb begin + reg1 = reg_data[rs1]; + reg2 = reg_data[rs2]; + end +endmodule diff --git a/week8/ALU.png b/week8/ALU.png new file mode 100644 index 00000000..220b1a4b Binary files /dev/null and b/week8/ALU.png differ diff --git a/week8/ALU.sv b/week8/ALU.sv new file mode 100644 index 00000000..c2c03989 --- /dev/null +++ b/week8/ALU.sv @@ -0,0 +1,18 @@ +module ALU( + input logic [31:0] opr1,opr2, + input logic [3:0] alu_control, + output logic [31:0] result + ); + + logic [31:0] sd1,sd2; + + always_comb + case(alu_control) + 4'b0000 : result = opr1 & opr2; //and + 4'b0001 : result = opr1 | opr2; //or + 4'b0010 : result = opr1 + opr2; //add + 4'b0110 : result = opr1 - opr2; //sub + 4'b1100 : result = !(opr1 + opr2); //nor + default : result = 0; + endcase +endmodule \ No newline at end of file diff --git a/week8/instr_execute.png b/week8/instr_execute.png new file mode 100644 index 00000000..f6f19307 Binary files /dev/null and b/week8/instr_execute.png differ diff --git a/week8/instr_execute.sv b/week8/instr_execute.sv new file mode 100644 index 00000000..0fb734c8 --- /dev/null +++ b/week8/instr_execute.sv @@ -0,0 +1,18 @@ +module instr_execute( + input logic [31:0] reg1,reg2, + input logic [31:0] pc_present, + input logic [31:0] imm_o, + input logic [3:0] alu_op, + input logic [2:0] branch_control, + input logic alu_src_1, alu_src_2, + output logic [31:0] result, + output logic branch_sel + ); + + logic [31:0] opr1,opr2; + + mux21 mux2(.in1(pc_present), .in2(reg1), .select(alu_src_1), .y(opr1)); + mux21 mux3(.in1(imm_o), .in2(reg2), .select(alu_src_2), .y(opr2)); + ALU alu1(.opr1(opr1), .opr2(opr2), .result(result), .alu_control(alu_op)); + branch_control brcon1(.branch_control(branch_control), .rs1(reg1), .rs2(reg2), .branch_sel(branch_sel)); +endmodule \ No newline at end of file diff --git a/week9/data_mem.png b/week9/data_mem.png new file mode 100644 index 00000000..3db0c29e Binary files /dev/null and b/week9/data_mem.png differ diff --git a/week9/data_mem.sv b/week9/data_mem.sv new file mode 100644 index 00000000..2b23e743 --- /dev/null +++ b/week9/data_mem.sv @@ -0,0 +1,41 @@ +module data_mem( + input bit clk, + input bit mem_read,mem_write, + input logic [31:0] data_in, + input logic [11:0] addr, + output logic [31:0] data_out + ); + logic [7:0] data [0:4095]; + + always @(mem_read) begin + if(mem_read == 1) begin + data_out[7:0] <= data[addr]; + data_out[15:8] <= data[addr+1]; + data_out[23:16] <= data[addr+2]; + data_out[31:24] <= data[addr+3]; + end + else + data_out <= 32'bX; + end + + always @(posedge clk) begin + if(mem_write == 1) begin + if(data_in[31:24] != 8'bX) + data[addr+3] <= data_in[31:24]; + else + data[addr+3] <= 8'b0; + if(data_in[23:16] != 8'bX) + data[addr+2] <= data_in[23:16]; + else + data[addr+3] <= 8'b0; + if (data_in[15:8] != 8'bX) + data[addr+1] <= data_in[15:8]; + else + data[addr+3] <= 8'b0; + if (data_in[7:0] != 8'bX) + data[addr] <= data_in[7:0]; + else + data[addr] <= 8'b0; + end + end +endmodule \ No newline at end of file diff --git a/week9/mem_access.png b/week9/mem_access.png new file mode 100644 index 00000000..31688a3f Binary files /dev/null and b/week9/mem_access.png differ diff --git a/week9/mem_access.sv b/week9/mem_access.sv new file mode 100644 index 00000000..9b3c9a8d --- /dev/null +++ b/week9/mem_access.sv @@ -0,0 +1,50 @@ +module mem_access( + input bit clk, + input bit mem_write, mem_read, + input logic [31:0] addr, data_in, + input logic [2:0] mem_control, + output logic [31:0] data_out + ); + + logic [11:0] addr_i; + logic [31:0] data_w_i, data_r_i; + + data_mem memory(.clk(clk), .addr(addr_i), .data_in(data_w_i), .data_out(data_r_i), .mem_read(mem_read), .mem_write(mem_write)); + + always_comb begin + case(mem_control) + 3'b000: begin //LB + if (data_r_i[7] == 1'b1) + data_out = {24'b1, data_r_i[7:0]}; + else + if (data_r_i[7] == 1'b0) + data_out = {24'b0, data_r_i[7:0]}; + end + 3'b001: begin //LH + if (data_r_i[15] == 1'b1) + data_out = {16'b1, data_r_i[15:0]}; + else + if (data_r_i[7] == 1'b0) + data_out = {16'b0, data_in[15:0]}; + end + 3'b010: begin //LW + data_out = data_r_i; + end + 3'b011: begin //LBU + data_out = {24'b0, data_r_i[7:0]}; + end + 3'b100: begin //LHU + data_out = {16'b0, data_r_i[15:0]}; + end + 3'b101: begin // SB + data_w_i = {24'b0, data_r_i[7:0]}; + end + 3'b110: begin // SH + data_w_i = {16'b0, data_in[15:0]}; + end + 3'b111: begin // SW + data_w_i = data_in; + end + endcase + end +endmodule \ No newline at end of file