/* Author : Rick van der Zwet * S-number : 0433373 * Version : $Id: control.c 366 2007-12-04 18:29:07Z rick $ * Copyright : FreeBSD Licence * Description : Memory unit */ #include #include #include #include "control.h" #include "memory.h" #include "datapath.h" /* fcode, ocode, target */ #define DECODE2_SIZE 17 const decode_t decode2[DECODE2_SIZE] = { { 8, 0, 18}, /* ADDI */ { 9, 0, 18}, /* ADDIU */ {10, 0, 39}, /* SLTI */ {11, 0, 39}, /* SLTIU */ {12, 0, 19}, /* ANDI */ {13, 0, 21}, /* ORI */ {14, 0, 23}, /* XORI */ {15, 0, 36}, /* LUI */ {32, 0, 59}, /* LB */ {33, 0, 65}, /* LH */ {35, 0, 71}, /* LW */ {36, 0, 62}, /* LBU */ {37, 0, 68}, /* LHU */ {40, 0, 44}, /* SB */ {41, 0, 50}, /* SH */ {43, 0, 56}, /* SW */ }; /* fcode, ocode, target */ #define DECODE3_SIZE 20 const decode_t decode3[DECODE3_SIZE] = { { 0, 0, 27}, /* SLL */ { 2, 0, 28}, /* SRL */ { 3, 0, 29}, /* SRA */ { 4, 0, 30}, /* SLLV */ { 6, 0, 32}, /* SRLV */ { 7, 0, 34}, /* SRAV */ { 8, 0, 42}, /* JR */ { 9, 0, 37}, /* JALR */ {13, 0, 43}, /* BREAK */ {32, 0, 18}, /* ADD */ {33, 0, 18}, /* ADDU */ {34, 0, 26}, /* SUB */ {35, 0, 26}, /* SUBU */ {36, 0, 20}, /* AND */ {37, 0, 22}, /* OR */ {38, 0, 24}, /* XOR */ {39, 0, 25}, /* NOR */ {42, 0, 39}, /* SLT */ {43, 0, 39}, /* SLTU */ }; /* * address, s1, s2, mux, constant, imm, alu, memory, a, b, c, temp, temp2, pc, * mar, mdr, ir, reg, register_address_a, register_address_b, * register_address_c, cond, jump * XXX: Needs more pretty writing, the enums defined should be used * XXX: More flexible input */ microcode_t microprogram[75] = { { 0, {5, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0}, 2, 0}, { 1, {5, 8, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0}, 3, 0}, { 2, {1, 9, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 0, 0}, { 3, {6, 8, 0, 3, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, { 4, {6, 8, 0,12, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 0, 0}, { 5, {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 2, 5}, { 6, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 0}, { 7, {1, 2, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6,10}, { 8, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0}, { 9, {1, 2, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 0}, {10, {5, 9, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 1, 0}, {11, {5, 8, 0, 5, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,31}, 0, 0}, {13, {5, 8, 0, 9, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {14, {9, 8, 0, 2, 3, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {15, {5, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 1, 0}, {16, {0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 5, 0}, {17, {0, 9, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 0}, {18, {3, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {19, {0, 9, 0, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {20, {1, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {21, {0, 9, 0, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {22, {1, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {23, {0, 9, 0, 0, 4, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {24, {1, 3, 0, 0, 0,11, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {25, {1, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {26, {1, 3, 0, 0, 0,10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {27, {3, 9, 0, 0, 2, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {28, {3, 9, 0, 0, 2, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {29, {3, 9, 0, 0, 2, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {30, {1, 8, 0, 8, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {31, {3, 4, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {32, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {33, {3, 4, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {34, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {35, {3, 4, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {36, {3, 8, 0, 6, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {37, {5, 8, 0, 5, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {38, {1, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {39, {1, 3, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 7,41}, {40, {0, 8, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {41, {0, 8, 0, 1, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {42, {1, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, 1, 0}, {43, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,43}, {44, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {45, {2, 8, 0, 7, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {46, {3, 4, 0, 0, 0, 9, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {47, {8, 4, 0,11, 0, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {48, {7, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 0, 0}, {49, {3, 7, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 1,57}, {50, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {51, {2, 8, 0, 6, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {52, {3, 4, 0, 0, 0, 9, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {53, {8, 4, 0,10, 0, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {54, {7, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 0, 0}, {55, {3, 7, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 1,57}, {56, {2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, 0, 0}, {57, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,57}, {58, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0}, {59, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {60, {7, 3, 0, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {61, {3, 8, 0, 7, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {62, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {63, {7, 3, 0, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {64, {3, 8, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {65, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {66, {7, 3, 0, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {67, {3, 8, 0, 6, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {68, {3, 8, 0, 3, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {69, {7, 3, 0, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {70, {3, 8, 0, 6, 0, 9, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 1,72}, {71, {7, 0, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}, {72, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8,74}, {73, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}, 1, 0}, {74, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0}, 1, 0}, }; void control_init() { int i = 0; /* Loop counter */ mpc = 0; a = 0; b = 0; c = 0; temp = 0; temp2 = 0; pc = 0; mar = 0; mdr = 0; ir = 0; imm = 0; constant = 0; for (i = 0; i < 32; i++) reg[i] = 0; } void find_new_mPC() { word tcode = 0; int i; /* Loop counter */ micro_address_t next_mpc; switch (microprogram[mpc].cond) { case NEXT: next_mpc = mpc + 1; break; case UNCOND: next_mpc = microprogram[mpc].jump; break; case MEMBUSY: if (mem_busy == FALSE) next_mpc = mpc + 1; else next_mpc = microprogram[mpc].jump; break; case DECODE1: /* XXX: Hardcoded, need something better */ tcode = ir >> 26; /* O-code */ if (tcode >= 32) /* MEM */ next_mpc = 2; else if (tcode >= 8) /* IMM */ next_mpc = 17; else if (tcode == 5) /* BNQ */ next_mpc = 9; else if (tcode == 4) /* BEQ */ next_mpc = 7; else if (tcode == 3) /* JAL */ next_mpc = 11; else if (tcode == 2) /* J */ next_mpc = 13; else if (tcode == 0) /* REG */ next_mpc = 16; break; case DECODE2: tcode = ir >> 26; /* O-code */ for (i = 0; i < DECODE2_SIZE; i++) { if (decode2[i].ocode == tcode) { next_mpc = decode2[i].target; break; } } break; case DECODE3: tcode = (ir << 26) >> 26; /* F-code */ for (i = 0; i < DECODE3_SIZE; i++) { if (decode3[i].fcode == tcode) { next_mpc = decode2[i].target; break; } } break; case ZEROVALUE: if (zero == TRUE) next_mpc = microprogram[mpc].jump; else next_mpc = mpc + 1; break; case NEGVALUE: if (negative == TRUE) next_mpc = microprogram[mpc].jump; else next_mpc = mpc + 1; break; case RTYPEIR: if ((ir >> 26) == 0) next_mpc = microprogram[mpc].jump; else next_mpc = mpc + 1; break; default: fprintf(stderr, "Control action '%i' not implemented\n", microprogram[mpc].cond); exit(EX_SOFTWARE); break; }; mpc = next_mpc; } void set_signals() { /* * XXX: Something like memory_busy or something like it * XXX: Dirty hacking, we better off creating a sperate control * struct which we 'feed' to datapath */ switch (mpc) { case 1: mem_busy = TRUE; microprogram[mpc].control.register_address_a = (ir << 6) >> 26; microprogram[mpc].control.register_address_b = (ir << 11) >> 26; break; case 12: microprogram[mpc].control.register_address_c = 31; break; case 73: microprogram[mpc].control.register_address_c = (ir << 11) >> 26; break; case 74: microprogram[mpc].control.register_address_c = (ir << 16) >> 26; break; } update_state(microprogram[mpc].control); }