CS/COE 447: Spring 2010 Lab 9 YOUR NAME: YOUR PARTNER'S NAME: Each of you should hand in a hardcopy of your own solution. This lab will give you practice with the hardware algorithms for multiplication and division that we covered in class. We will use a datapath of only 4 bits (while MIPS is 32 bits), to make tracing through the examples more feasible. "n" below is the size of the datapath (whatever it may be). =====PART 1: MULTIPLICATION [50 points] This part begins with notes from lecture. The question is below. Here is a long-hand (human) multiplication of 15 * 15 (binary): 1111 1111 ---- 00000000 00001111 -------- 00001111 + 00011110 -------- 00101101 + 00111100 -------- 01101001 + 01111000 -------- 11100001 Here is the algorithm for the third implementation of multiplication that we covered in class: Initialize: product = {n{0},n-bit multiplier} multiplicand = multiplicand (n bits) Repeat n times: Step 1: Test product[0] Step 2: if 1, add multiplicand to left half of product and place the result in the left half of the product register Step 3: shift product register right 1 bit Here is a trace of the above example: Initilize: product = 00001111 multiplicand = 1111 ***The starred digits are the bits of the multiplier that are left Iter1: product = 00001111 +1111 ----- product = 11111111 **** product = 01111111 *** Iter2: product = 01111111 + 1111 ------ product = 101101111 *** product = 10110111 ** ** if there is a carry, it needs to be shifted in, rather than a 0 Iter3: product = 10110111 + 1111 ------ product = 110100111 ** product = 11010011 * Iter4: product = 11010011 + 1111 ------ product = 111000011 * multiplier = 0000 product = 11100001 ==================================== ****Question:***** Now, you do the same as the above for 1100 * 1101, including writing down the long-hand human multiplication (but no need to rewrite the algorithm). Check your answers, to be sure you are correct! =====PART 2: INTEGER DIVISION OF UNSIGNED NUMBERS [50 points] This part also begins with notes from lecture. The question is below. quotient ------------ divisor | dividend -------- remainder Example for reference: 11 ---------- 0010 | 00000111 0010 ----- 00011 0010 ----- 1 7 / 2 is 3 with a remainder of 1 Algorithm: Size of dividend is 2 * size of divisor Size of quotient == size of divisor Initialization: quotient register = 0 remainder register = dividend divisor register = divisor in left half Repeat for 33 iterations (size divisor + 1): step 1: remainderReg = remainderReg - divisorReg step 2: If Remainder >= 0: shift quotientReg left 1 bit, placing 1 in bit 0 Else: remainderReg = remainderReg + divisorReg shift quotientReg left 1 bit, placing 0 in bit 0 step 3: shift divisorReg right 1 bit Our example: Although the hardware needs to, I won't bother subtracting and then adding. I'll just indicate "no change". Initilize: remainderReg = 0000 0111 divisorReg = 0010 0000 quotientReg = 0000 n + 1 iterations. We are using a 4-bit datapath in these examples, so there are 5 iterations. Iter 1: 0000 0111 - 0010 0000 < 0: remainderReg = 0000 0111 no change divisorReg = 0001 0000 quotientReg = 0000 Iter 2: 0000 0111 - 0001 0000 < 0: remainderReg = 0000 0111 no change divisorReg = 0000 1000 quotientReg = 0000 Iter 3: 0000 0111 - 0000 1000 < 0: remainderReg = 0000 0111 no change divisorReg = 0000 0100 quotientReg = 0000 Iter 4: 0000 0111 - 0000 0100 >= 0: remainderReg = 0000 0111 - 0000 0100 0000 0011 divisorReg = 0000 0010 quotientReg = 0001 Iter 5: 0000 0011 - 0000 0010 >= 0: remainderReg = 0000 0011 - 0000 0010 0000 0001 divisorReg = 0000 0001 quotientReg = 0011 So the quotient is 1100 and the remainder is 0001 (or 3 remainder 1 decimal) just like we got with the longhand. ****Question:***** Now, you do the same as the above for 11 / 3, including writing down the long-hand human division (but no need to rewrite the algorithm). Check your answers, to be sure you are correct! ===== Try these code segments: li $t0,-1 li $t1,32 mult $t0,$t1 mflo $t3 mfhi $t4 This places 0xffffffe0 --> $t3 and 0xffffffff --> $t4 Why? 0xffffffe0 = -32 decimal (check this, by taking the 2s complement of 32). "mult" treats its operands as signed. Since it creates a 2-word result, $t4 contains all 1s, due to sign extension. The same values, but using multu (treating the operands as unsigned): li $t0,-1 li $t1,32 multu $t0,$t1 mflo $t3 mfhi $t4 0xffffffe0 --> $t3 0x0000001f --> $t4 Why? -1 = 0xffffffff = 2^32 - 1 decimal To multiply this by 32, shift the number 5 bits to the left. You will need 2 words to represent the result: 0x00000000ffffffff = following in binary 0000000000000000000000000000000011111111111111111111111111111111 shift that 5 left (to multiply by 32): 0000000000000000000000000001111111111111111111111111111111100000 translate to hex: 0x0000001fffffffff which explains what we saw above. If you don't understand, please talk about it together and/or ask a TA. There is nothing to hand in for this section.