computer architecture: a constructive approach smips implementations arvind
DESCRIPTION
Computer Architecture: A Constructive Approach SMIPS Implementations Arvind Computer Science & Artificial Intelligence Lab. Massachusetts Institute of Technology. Single-Cycle SMIPS. Register File. PC. Execute. Decode. +4. Data Memory. Inst Memory. - PowerPoint PPT PresentationTRANSCRIPT
Computer Architecture: A Constructive Approach
SMIPS Implementations
ArvindComputer Science & Artificial Intelligence Lab.Massachusetts Institute of Technology
January 18, 2012 L7-1http://csg.csail.mit.edu/SNU
Single-Cycle SMIPS
PC
InstMemory
Decode
Register File
Execute
DataMemory
+4
Datapath is shown only for convenience; it will be derived automatically from the high-level textual description
January 18, 2012 L7-2http://csg.csail.mit.edu/SNU
decode
Decoding Instructions: input-output types
instructionbrComp
rDst
rSrc1
rSrc2
immext
aluFunc
iType31:26, 5:0
31:26
5:0
31:26
20:16
15:11
25:21
20:16
15:0
25:0
Typ
e D
eco
ded
Inst
Bit#(32)
IType
AluFunc
Rindex
Rindex
Rindex
BrType
Bit#(32)
Mux control logic not shown
immValidBool
January 18, 2012 L7-3http://csg.csail.mit.edu/SNU
Typedefstypedef enum {Alu, Ld, St, J, Jr, Jal, Jalr, Br} IType deriving(Bits, Eq);
typedef enum {Eq, Neq, Le, Lt, Ge, Gt} BrType deriving(Bits, Eq);
typedef enum {Add, Sub, And, Or, Xor, Nor, Slt, Sltu, LShift, RShift, Sra} AluFunc deriving(Bits, Eq);
typedef enum {RAlu, IAlu, LdSt, J, Jr, Br} InstDType deriving(Bits, Eq);
January 18, 2012 L7-4http://csg.csail.mit.edu/SNU
Instruction EncodingBit#(6) opADDIU = 6’b001001;Bit#(6) opSLTI = 6’b001010;Bit#(6) opLW = 6’b100011;Bit#(6) opSW = 6’b101011;Bit#(6) opJ = 6’b000010;Bit#(6) opBEQ = 6’b000100;…Bit#(6) opFUNC = 6’b000000;Bit#(6) fcADDU = 6’b100001;Bit#(6) fcAND = 6’b100100;Bit#(6) fcJR = 6’b001000;…Bit#(6) opRT = 6’b000001;Bit#(6) rtBLTZ = 5’b00000;Bit#(6) rtBGEZ = 5’b00100;
January 18, 2012 L7-5http://csg.csail.mit.edu/SNU
Instruction Groupingfunction InstDType getInstDType(Bit#(32) inst) return case (inst[31:26]) opADDIU, opSLTI, …: IAlu; opLW, opSW: LdSt; opJ, opJAL: J; opBEQ, opRT, …: Br; opFUNC: case (inst[5:0]) fcADDU, fcAND, …: RAlu; fcJR, fcJALR: Jr; endcase; endcase;endfunction
January 18, 2012 L7-6http://csg.csail.mit.edu/SNU
Decode Functionfunction DecodedInst decode(Bit#(32) inst); DecodedInst dInst = ?; let opcode = inst[ 31 : 26 ]; let rs = inst[ 25 : 21 ]; let rt = inst[ 20 : 16 ]; let rd = inst[ 15 : 11 ]; let funct = inst[ 5 : 0 ]; let imm = inst[ 15 : 0 ]; let target = inst[ 25 : 0 ]; case (getInstDType(inst)) ... endcase return dInst;endfunction
January 18, 2012 L7-7http://csg.csail.mit.edu/SNU
Decoding Instructions:R-Type ALU case (getInstDType(opcode)) … RAlu: begin dInst.iType = Alu; dInst.aluFunc = case (funct) fcADDU: Add; fcSUBU: Sub; ... endcase; dInst.rDst = rd; dInst.rSrc1 = rs; dInst.rSrc2 = rt;
dInst.immValid = False; end
January 18, 2012 L7-8http://csg.csail.mit.edu/SNU
Decoding Instructions:I-Type ALU case (getInstDType(opcode)) … IAlu: begin dInst.iType = Alu; dInst.aluFunc = case (opcode) opADDIU: Add; ... endcase; dInst.rDst = rt; dInst.rSrc1 = rs; dInst.imm = signedIAlu(opcode) ? signExtend(imm): zeroExtend(imm);
dInst.immValid = True; end
January 18, 2012 L7-9http://csg.csail.mit.edu/SNU
Decoding Instructions:Load & Store case (getInstDType(opcode)) … LdSt: begin dInst.iType = opcode==opLW ? Ld : St; dInst.aluFunc = Add; dInst.rDst = rt; dInst.rSrc1 = rs; dInst.rSrc2 = rt; dInst.imm = signExtned(imm);
dInst.immValid = True; end
January 18, 2012 L7-10http://csg.csail.mit.edu/SNU
Decoding Instructions:Jump case (getInstDType(opcode)) … J: begin dInst.iType = opcode==opJ ? J : Jal; dInst.rDst = 31; dInst.imm = zeroExtend({target, 2’b00});
dInst.immValid = False; end
Jr: begin dInst.iType = funct==fcJR ? Jr : Jalr; dInst.rDst = rd; dInst.rSrc1 = rs;
dInst.immValid = False; end
January 18, 2012 L7-11http://csg.csail.mit.edu/SNU
Decoding Instructions:Branch case (getInstDType(opcode)) … Br: begin dInst.iType = Br; dInst.brComp = case (opcode) opBEQ : EQ; opBLEZ: LE; ... endcase; dInst.rSrc1 = rs; dInst.rSrc2 = rt; dInst.imm = signExtend({imm, 2’b00});
dInst.immValid = False; end
January 18, 2012 L7-12http://csg.csail.mit.edu/SNU
Executing Instructions
execute
dInst
addr
brTaken
data
iType
rDst
ALU
BranchAddresspc
rVal2
rVal1
Pure combinational logic
either for memory reference or branch target
either for rf write or St
January 18, 2012 L7-13http://csg.csail.mit.edu/SNU
Some Useful Functionsfunction Bool memType (IType i) return (i==Ld || i == St);endfunction
function Bool regWriteType (IType i) return (i==Alu || i==Ld || i==Jal || i==Jalr);endfunction
function Bool controlType (IType i) return (i==J || i==Jr || i==Jal || i==Jalr || i==Br);endfunction
January 18, 2012 L7-14http://csg.csail.mit.edu/SNU
Execute Functionfunction ExecInst exec(DecodedInst dInst, Data rVal1, Data rVal2, Addr pc); Data aluVal2 = (dInst.immValid)? dInst.imm : rVal2 let aluRes = alu(rVal1, aluVal2, dInst.aluFunc); let brRes = aluBr(rVal1, aluVal2, dInst.brComp); let brAddr = brAddrCal(pc, rVal1, dInst.iType, dInst.imm); let addr = (memType(dInst.iType)? aluRes : br.addr; let data = dInst.iType==St ? rVal2 : aluRes; return ExecInst{iType: dInst.iType, brTaken: brRes, addr: adddr, data: data, rDst: dInst.rDst};endfunction
January 18, 2012 L7-15http://csg.csail.mit.edu/SNU
ALUfunction Data alu(Data a, Data b, Func func); Data res = case(func) Add : add(a, b); Sub : subtract(a, b); And : (a & b); Or : (a | b); Xor : (a ^ b); Nor : ~(a | b); Slt : setLessThan(a, b); Sltu : setLessThanUnsigned(a, b); LShift: logicalShiftLeft(a, b[4:0]); RShift: logicalShiftRight(a, b[4:0]); Sra : signedShiftRight(a, b[4:0]); endcase; return res;endfunction
January 18, 2012 L7-16http://csg.csail.mit.edu/SNU
Branch Resolutionfunction Bool aluBr(Data a, Data b, BrType brComp);
Bool brTaken = case(brComp) Eq : (a == b); Neq : (a != b); Le : signedLE(a, 0); Lt : signedLT(a, 0); Ge : signedGE(a, 0); Gt : signedGT(a, 0);endcase;
return brTaken;endfunction
January 18, 2012 L7-17http://csg.csail.mit.edu/SNU
Branch Address Calculationfunction Addr brAddrCalc(Address pc, Data val, IType iType, Data imm); let targetAddr = case (iType) J, Jal : {pc[31:28], imm[27:0]}; Jr, Jalr : val; default : pc + imm; endcase; return targetAddr;endfunction
January 18, 2012 L7-18http://csg.csail.mit.edu/SNU
Single-Cycle SMIPSmodule mkProc(Proc); Reg#(Addr) pc <- mkRegU; RFile rf <- mkRFile; Memory mem <- mkTwoPortedMemory; let iMem = mem.iport ; let dMem = mem.dport;
rule doProc; let inst <- iMem(MemReq{op: Ld, addr: pc, data: ?});
let dInst = decode(inst); Data rVal1 = rf.rd1(dInst.rSrc1); Data rVal2 = rf.rd2(dInst.rSrc2);
January 18, 2012 L7-19http://csg.csail.mit.edu/SNU
Single-Cycle SMIPS cont let eInst = exec(dInst, rVal1, rVal2, pc);
if(memType(eInst.iType)) eInst.data <- dMem(MemReq{ op: eInst.iType==Ld ? Ld : St, addr: eInst.addr, data: eInst.data});
pc <= eInst.brTaken ? eInst.addr : pc + 4;
if(regWriteType(eInst.iType)) rf.wr(eInst.rDst, eInst.data); endrule endmodule
January 18, 2012 L7-20http://csg.csail.mit.edu/SNU
SMIPS Princeton Architecture
PC
Memory
Decode
Register File
Execute+4fr
Epoch
January 18, 2012 L7-21http://csg.csail.mit.edu/SNU
Two-Cycle SMIPSmodule mkProc(Proc); Reg#(Addr) pc <- mkRegU; RFile rf <- mkRFile; Memory mem <- mkMemory; let uMem = mem.port ; PipeReg#(FBundle) fr <- mkPipeReg; Reg#(Bit#(1)) stage <- mkReg(0);
rule doProc; if(stage==0 && fr.notFull) begin let inst <- uMem(MemReq{op: Ld, addr: pc, data: ?}); fr.enq(FBundle{pc: pc, inst: inst}); stage <= 1; end
January 18, 2012 L7-22http://csg.csail.mit.edu/SNU
Two-Cycle SMIPS if(stage==1 && fr.notEmpty) begin let frpc = fr.first.pc; let inst = fr.first.inst; let dInst = decode(inst); Data rVal1 = rf.rd1(dInst.rSrc1); Data rVal2 = rf.rd2(dInst.rSrc2); let eInst = exec(dInst, rVal1, rVal2, frpc); if(memType(eInst.iType)) eInst.data <- uMem(MemReq{ op: eInst.iType==Ld ? Ld : St, addr: eInst.addr, data: eInst.data});
pc <= eInst.brTaken ? eInst.addr : pc + 4; if(regWriteType(eInst.iType)) rf.wr(eInst.rDst, eInst.data); fr.deq; stage <= 0; end endrule endmoduleJanuary 18, 2012 L7-23http://csg.csail.mit.edu/SNU
Two-Cycle SMIPS descriptions are the same for Harvard & Princeton
PC
InstMemory
Decode
Register File
Execute
DataMemory
+4fr
stage
January 18, 2012 L7-24http://csg.csail.mit.edu/SNU
Pipelined SMIPS (Princeton)
PC
Memory
Decode
Register File
Execute+4fr
Epoch
January 18, 2012 L7-25http://csg.csail.mit.edu/SNU
Pipelined SMIPS (Princeton)module mkProc(Proc); Reg#(Addr) pc <- mkRegU; Reg#(Bool) epoch <- mkReg(True); RFile rf <- mkRFile; Memory mem <- mkOnePortedMemory; let uMem = mem.port; PipeReg#(FBundle) fr <- mkPipeReg; Wire#(Bool) memAcc <- mkDWire(False); rule doProc; if(fr.notFull && !memAcc) begin let inst <- uMem(MemReq{op: Ld, addr: pc, data: ?}); fr.enq(FBundle{pc: pc, epoch: epoch, inst: inst}); end
January 18, 2012 L7-26http://csg.csail.mit.edu/SNU
Pipelined SMIPS (Princeton) Addr redirPC = ?; Bool redirPCvalid = False; if(fr.notEmpty) begin let frpc = fr.first.pc; let inst = fr.first.inst; if(fr.first.epoch==epoch) begin let dInst = decode(inst); Data rVal1 = rf.rd1(dInst.rSrc1); Data rVal2 = rf.rd2(dInst.rSrc2); let eInst = exec(dInst, rVal1, rVal2, frpc);
if(memType(eInst.iType)) begin eInst.data <- uMem(MemReq{ op: eInst.iType==Ld ? Ld : St, addr: eInst.addr, data: eInst.data}); memAcc = True; end
January 18, 2012 L7-27http://csg.csail.mit.edu/SNU
if(eInst.brTaken) begin redirPC = eInst.addr; redirPCvalid = True; end if(regWriteType(eInst.iType)) rf.wr(eInst.rDst, eInst.data); end fr.deq; end
pc <= redirPCvalid ? redirPC : !memAcc ? pc + 4 : pc; epoch <= redirPCvalid ? !epoch : epoch; endruleendmodule
Pipelined SMIPS (Princeton)
January 18, 2012 L7-28http://csg.csail.mit.edu/SNU
Two-Stage SMIPS (Harvard)
PC
InstMemory
Decode
Register File
Execute
DataMemory
+4fr
Epoch
January 18, 2012 L7-29http://csg.csail.mit.edu/SNU
Two-Stage SMIPS (Harvard)module mkProc(Proc); Reg#(Addr) pc <- mkRegU; Reg#(Bool) epoch <- mkRegU; RFile rf <- mkRFile; Memory mem <- mkTwoPortedMemory; let iMem = mem.iport; let dMem = mem.dport; PipeReg#(FBundle) fr <- mkPipeReg;
rule doProc; if(fr.notFull) begin let inst <- iMem(MemReq{op: Ld, addr: pc, data: ?}); fr.enq(FBundle{pc: pc, epoch: epoch, inst: inst}); end
January 18, 2012 L7-30http://csg.csail.mit.edu/SNU
Two-Stage SMIPS (Harvard) Addr redirPc = ?; Bool redirPCvalid = False; if(fr.notEmpty) begin let frpc = fr.first.pc; let inst = fr.first.inst; if(fr.first.epoch==epoch) begin let dInst = decode(inst); Data rVal1 = rf.rd1(dInst.rSrc1); Data rVal2 = rf.rd2(dInst.rSrc2); let eInst = exec(dInst, rVal1, rVal2, frpc);
if(memType(eInst.iType)) eInst.data <- dMem(MemReq{ op: eInst.iType==Ld ? Ld : St, addr: eInst.addr, data: eInst.data});
January 18, 2012 L7-31http://csg.csail.mit.edu/SNU
if(eInst.brTaken) begin redirPC = eInst.addr; redirPCvalid = True; end if(regWriteType(eInst.iType)) rf.wr(eInst.rDst, eInst.data); end fr.deq; end
pc <= redirPCvalid ? redirPC : pc + 4; epoch <= redirPCvalid ? !epoch : epoch; endruleendmodule
Two-Stage SMIPS (Harvard)
January 18, 2012 L7-32http://csg.csail.mit.edu/SNU