Homework Assignment 12 Advanced Computer Architecture CS 350c Unique Number: 51160 Spring, 2016 Given: April 19, 2016 Due: April 28, 2016 Below is the programmer's view of our SM definition. To implement the SM ISA with a five-stage (fetch, decode, execute, memory, and write-back) pipeline, we need to identify for each instruction (type) what operations need to be accomplished. This identification will then allow us to break up the work of implementing each instruction into the five stages our SM implementation will include. For each instruction type (listed on the right-most column below), identify what each pipeline stage should do for each instruction. For example: Group 0 NOP fetch Fetch instruction, Increment PC decode Separate instruction into fn, rnum{a,b,c}, data Read regfile contents at rnum{a,b,c} into regc{a,b,c} execute Do nothing memory Do nothing write-back Do nothing Group 1 NOT, NEG, CNOT, POPCNT, BITREV fetch Fetch instruction, Increment PC decode Separate instruction into fn, rnum{a,b,c}, data Read Regfile contents at rnum{a,b,c} into regc{a,b,c} execute perform NOT, NEG, CNOT, POPCNT, or BITREV, ALU operation memory Do nothing writeback Store ALU result in Regfile Complete this table for instruction groups 2 through 10. Are 10 different groups actually necessary? If not, please suggest what groups can/should be combined. i16 mem[ MEMSIZE ]; i16 reg[ REGS ]; u16 pc; void micro_step( ) { u16 instruction = (u16) mem[ pc ]; pc = (u16) pc + 1; // Increment program counter u16 fn = (u16) ((instruction >> 12) & BITS_4); u16 rnumc = (u16) ((instruction >> 8) & BITS_4); u16 rnumb = (u16) ((instruction >> 4) & BITS_4); u16 rnuma = (u16) ((instruction ) & BITS_4); u16 data = (u16) ((instruction ) & BITS_8); u16 addr; i16 regc = reg[ rnumc ]; i16 regb = reg[ rnumb ]; i16 rega = reg[ rnuma ]; switch ( fn ) { case 0: switch ( rnumb ) { case 0: break; // noop00 0 case 1: reg[ rnumc ] = mem[ (u16) rega ]; break; // ldmem 5 case 2: mem[ (u16) regc ] = rega; break; // stmem 6 case 3: rega = rega - 1; // 7 reg[ rnuma ] = rega; mem[ (u16) rega ] = pc; pc = (u16) regc; break; // call case 4: pc = (u16) mem[ (u16) rega ]; // 8 reg[ rnuma ] = rega + 1; break; // return case 5: pc = (regc) ? ((u16) rega) : pc; break; // jump 4 case 6: pc = (regc) ? ((u16) rega) + pc : pc; break; // bra, branch 4 case 7: break; // unassigned 0 case 8: break; // unassigned 0 case 9: reg[ rnumc ] = ~ rega; break; // not 1 case 10: reg[ rnumc ] = - rega; break; // neg, negate 1 case 11: reg[ rnumc ] = ! rega; break; // cnot 1 case 12: reg[ rnumc ] = pop_count( rega ); break; // popcnt 1 case 13: reg[ rnumc ] = bit_reverse( rega ); break; // bitrev 1 case 14: reg[ rnumc ] = mem[ (u16) rega ]; // 9 reg[ rnuma ] = rega + 1; break; // pop case 15: addr = (u16) rega - 1; // 10 mem[ addr ] = regc; reg[ rnuma ] = addr; break; // push default: break; } break; // End of case 0 case 1: reg[ rnumc ] = regb + rega; break; // add 2 case 2: reg[ rnumc ] = regb - rega; break; // sub 2 case 3: reg[ rnumc ] = regb * rega; break; // mul 2 case 4: reg[ rnumc ] = regb / rega; break; // div 2 case 5: reg[ rnumc ] = regb ^ rega; break; // xor 2 case 6: reg[ rnumc ] = regb & rega; break; // and 2 case 7: reg[ rnumc ] = regb | rega; break; // lor 2 case 8: reg[ rnumc ] = regb << (rega & 0xF); break; // sleft 2 case 9: reg[ rnumc ] = regb >> (rega & 0xF); break; // sright 2 case 10: reg[ rnumc ] = regb < rega; break; // lt 2 case 11: reg[ rnumc ] = regb <= rega; break; // lteq 2 case 12: reg[ rnumc ] = (regb) ? rega : regc; break; // cmove 3 case 13: reg[ rnumc ] = (regb) ? rega + regc : regc; break; // cadd 3 case 14: reg[ rnumc ] = (regc & 0xFF00) | data; break; // immlow 3 case 15: reg[ rnumc ] = (data << 8) | (regc & 0x00FF); break; // immhgh 3 default: break; } }