// ************************************************************************** // // // // 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; // ************************************************************************** // macros for implementing the behavior // ************************************************************************** macro OpCode(i) = i{15:10}; // opcode of instruction i macro DestReg(i) = i{9:7}; // register index of destination macro SrcLReg(i) = i{6:4}; // register index of left operand macro SrcRReg(i) = i{3:1}; // register index of right operand macro VctFlag(i) = i{0}; // register index of right operand macro ConstOp(i) = i{3:0}; // constant operand of instruction i macro JumpAdr(i) = i{9:0}; // address of jump instruction macro FctCode(i) = i{6:0}; // function code of instruction i macro DataWidth = 8; // bit-width of registers macro One = {true::DataWidth}; // bitvector consisting of 1s macro Zero = {false::DataWidth}; // bitvector consisting of 0s macro UpperWord(r) = r{2*DataWidth-1:DataWidth}; // upper half of double word macro LowerWord(r) = r{DataWidth-1:0}; // lower half of double word // sign and zero extensions macro zext4(b) = {false::DataWidth-sizeOf(b)}@b; macro zext7(b) = {false::DataWidth-sizeOf(b)}@b; macro sext4(b) = {b{-1}::DataWidth-sizeOf(b)}@b; macro sext7(b) = {b{-1}::DataWidth-sizeOf(b)}@b; // ---------------------------------------------------------------------------- // decode stage of the structural implementation // ---------------------------------------------------------------------------- module Decode( bv{16} ?instr, // instruction to be performed now [8]bv{DataWidth} ?Reg, // scalar registers bv{DataWidth} ?overflw, // overflw register (completing result) bv{6} opc, // opcode of instr bv{7} fnc, // constant operand of S-type instructions bv{10} !adr, // jump address of J-type instruction nat{8} rd, // register destination index bv{DataWidth} !opS,!opL,!opR // ALU operands and the value to be stored ) { // local variables nat{8} rs1,rs2; // register indices taken from instr bv{4} cst; // constant operand of I-type instructions // -------------------------------------------------------------------- // extract parts of the instruction word // -------------------------------------------------------------------- opc = OpCode(instr); rd = bv2nat(DestReg(instr)); rs1 = bv2nat(SrcLReg(instr)); rs2 = bv2nat(SrcRReg(instr)); cst = ConstOp(instr); fnc = FctCode(instr); adr = JumpAdr(instr); // -------------------------------------------------------------------- // determine the first operand // -------------------------------------------------------------------- case (opc==MOV | opc==MOVU | opc==J | opc==OVF) do opL = Reg[0]; (opc==JMP) do opL = Reg[rd]; default opL = Reg[rs1]; // -------------------------------------------------------------------- // determine the second operand // -------------------------------------------------------------------- case // signed arithmetic instruction with immediate operand (opc{5:4}==0b00 & opc{1} & !opc{0}) do opR = sext4(cst); // unsigned arithmetic instruction with immediate operand (opc{5:4}==0b00 & opc{1} & opc{0}) do opR = zext4(cst); (opc==LD | opc==LL | opc==ST | opc==SC) do opR = zext4(cst); (opc==BEZ | opc==BNZ) do opR = sext4(cst); (opc==MOV | opc==JMP) do opR = sext7(fnc); (opc==MOVU) do opR = zext7(fnc); (opc==OVF) do opR = overflw; (opc==J) do opR = Reg[0]; default opR = Reg[rs2]; // -------------------------------------------------------------------- // determine the third operand of store instructions // -------------------------------------------------------------------- opS = Reg[rd]; }