// ************************************************************************** // // // // eses eses // // eses eses // // eses eseses esesese eses Embedded Systems Group // // ese ese ese ese ese // // ese eseseses eseseses ese Department of Computer Science // // eses eses ese eses // // eses eseses eseseses eses University of Kaiserslautern // // eses eses // // // // ************************************************************************** // // ---------------------------------------------------------------------------- // opcodes of the instructions // ---------------------------------------------------------------------------- macro ADD = 0b000000; macro ADDU = 0b000001; macro ADDI = 0b000010; macro ADDIU = 0b000011; macro SUB = 0b000100; macro SUBU = 0b000101; macro SUBI = 0b000110; macro SUBIU = 0b000111; macro MUL = 0b001000; macro MULU = 0b001001; macro MULI = 0b001010; macro MULIU = 0b001011; macro DIV = 0b001100; macro DIVU = 0b001101; macro DIVI = 0b001110; macro DIVIU = 0b001111; macro SLT = 0b010000; macro SLTU = 0b010001; macro SLE = 0b010010; macro SLEU = 0b010011; macro SEQ = 0b010100; macro SNE = 0b010101; macro AND = 0b010110; macro OR = 0b010111; macro NAND = 0b011000; macro NOR = 0b011001; macro LD = 0b011010; macro ST = 0b011011; macro LVWS = 0b011100; macro SVWS = 0b011101; macro LL = 0b011110; macro SC = 0b011111; macro MOV = 0b100000; macro MOVU = 0b100001; macro BEZ = 0b100010; macro BNZ = 0b100011; macro JMP = 0b100100; macro J = 0b100101; macro SYNC = 0b100111; // note that this group of instructions share the same macro OVF = 0b100111; // opcode, and differ in the additional function code macro MVTM = 0b100111; // listed below macro MVFM = 0b100111; macro MVTL = 0b100111; macro MVFL = 0b100111; macro fn_SYNC = 0b0000000; macro fn_OVF = 0b0000001; macro fn_MVTM = 0b0000010; macro fn_MVFM = 0b0000011; macro fn_MVTL = 0b0000100; macro fn_MVFL = 0b0000101; // -------------------------------------------------------------------------- // special macros for this stage // -------------------------------------------------------------------------- macro DataWidth = 8; // bit-width of registers // -------------------------------------------------------------------------- // memory access stage // -------------------------------------------------------------------------- module MemAccess( nat pc, // program counter bv{6} ?opc_MA, // opcode of instr bv{7} ?fnc_MA, // constant operand of S-type instructions bv{10} ?adr_MA, // jump address of J-type instruction nat{8} ?rd_MA, // register destination index bv{DataWidth} ?opS_MA, // value to be stored in case of store op. bv{2*DataWidth} ?alu_MA, // ALU results (immediate and delayed) bool ?cnd_MA, // result of branch condition bv{6} !opc_WB, // opcode of instr bv{7} !fnc_WB, // function code bv{10} !adr_WB, // jump address of J-type instruction nat{8} !rd_WB, // register destination index bv{2*DataWidth} !alu_WB, // ALU result (contains memory address) bool !cnd_WB, // result of branch condition bv{DataWidth} ld_MA,!ld_WB, // load result event nat !adrBus, // address for memory access event bv{DataWidth} dataBus, // data for memory access event readMem,writeMem, // whether data is read or written to memory event reqMem,ackMem,doneMem // signals for memory transaction ) { // -------------------------------------------------------------------- // memory access takes only place for load/store instructions: // -------------------------------------------------------------------- if(opc_MA==LD | opc_MA==LL | opc_MA==ST | opc_MA==SC | opc_MA==SYNC & fnc_MA==fn_SYNC) { // apply for memory access by emitting reqMem until // ackMem holds; may take time on multiprocessors weak immediate abort { loop { emit(reqMem); if(!ackMem) next(pc) = pc; waitMem1: pause; } } when(ackMem); // provide address and read/write request signal // until memory transaction is done weak immediate abort { loop { adrBus = bv2nat(alu_MA); case (opc_MA==LD | opc_MA==LL) do emit(readMem); (opc_MA==ST | opc_MA==SC) do { emit(writeMem); dataBus = opS_MA; } (opc_MA==SYNC) do { emit(readMem); emit(writeMem); } default nothing; if(!doneMem) next(pc) = pc; waitMem2: pause; } } when(doneMem); // in case of load, transfer dataBus to LoadRes if(opc_MA==LD | opc_MA==LL) ld_MA = dataBus; } // -------------------------------------------------------------------- // forwarding values to WriteBack stage // -------------------------------------------------------------------- next(opc_WB) = opc_MA; next(fnc_WB) = fnc_MA; next(adr_WB) = adr_MA; next(rd_WB) = rd_MA; next(alu_WB) = alu_MA; next(cnd_WB) = cnd_MA; next(ld_WB) = ld_MA; }