| @@ -0,0 +1,4 @@ | |||
| -Xms512M | |||
| -Xmx4096M | |||
| -Xss32M | |||
| -XX:MaxMetaspaceSize=1024M | |||
| @@ -61,6 +61,6 @@ class InstructionFetch extends MultiIOModule { | |||
| when(testHarness.IMEMsetup.setup) { | |||
| PC := 0.U | |||
| // TODO: You should probably set the instruction to Instruction.NOP here. | |||
| throw new Exception("Just making sure you're seeing the line above.\nYou can delete this exception now, it's found at line 64 at IF.scala") | |||
| // throw new Exception("Just making sure you're seeing the line above.\nYou can delete this exception now, it's found at line 64 at IF.scala") | |||
| } | |||
| } | |||
| @@ -93,14 +93,17 @@ object Ops { | |||
| def or( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), OR) | |||
| def xor( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), XOR) | |||
| def and( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), AND) | |||
| def sll( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLL) | |||
| def srl( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRL) | |||
| def sra( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRA) | |||
| def slt( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLT) | |||
| def sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU) | |||
| def nop = add(0, 0, 0) | |||
| } | |||
| case class ArithImmShift(imm11: Imm, rd: Reg, rs1: Reg, shamt: Imm, op: ArithOp) extends Op with IType | |||
| object ArithImmShift { | |||
| def sll( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(0), Reg(rd), Reg(rs1), Imm(imm), SLL) | |||
| def srl( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(0), Reg(rd), Reg(rs1), Imm(imm), SRL) | |||
| def sra( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(32), Reg(rd), Reg(rs1), Imm(imm), SRA) | |||
| } | |||
| case class LUI(rd: Reg, imm: Imm) extends Op with UType | |||
| case class AUIPC(rd: Reg, imm: Imm) extends Op with UType | |||
| @@ -84,9 +84,9 @@ object Parser { | |||
| stringWs("xori") ~> arithImm.mapN{ArithImm.xor}, | |||
| stringWs("andi") ~> arithImm.mapN{ArithImm.and}, | |||
| stringWs("slli") ~> arithImm.mapN{ArithImm.sll}, | |||
| stringWs("srli") ~> arithImm.mapN{ArithImm.srl}, | |||
| stringWs("srai") ~> arithImm.mapN{ArithImm.sra}, | |||
| stringWs("slli") ~> arithImm.mapN{ArithImmShift.sll}, | |||
| stringWs("srli") ~> arithImm.mapN{ArithImmShift.srl}, | |||
| stringWs("srai") ~> arithImm.mapN{ArithImmShift.sra}, | |||
| stringWs("slti") ~> arithImm.mapN{ArithImm.slt}, | |||
| stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu}, | |||
| @@ -160,16 +160,16 @@ object Parser { | |||
| SW(placeHolder, 0, 2048), | |||
| LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)), | |||
| LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4), | |||
| ArithImm.sra(placeHolder, placeHolder, 24), | |||
| ArithImm.sll(rd.value, rd.value, 24), | |||
| ArithImm.sra(rd.value, rd.value, 16), | |||
| ArithImmShift.sra(placeHolder, placeHolder, 24), | |||
| ArithImmShift.sll(rd.value, rd.value, 24), | |||
| ArithImmShift.sra(rd.value, rd.value, 16), | |||
| Arith.add(rd, rd, placeHolder), | |||
| LW(placeHolder, 0, 2048)).reverse | |||
| } | |||
| case (rd, offset, rs1) if (offset % 4 == 2) => { | |||
| List( | |||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | |||
| ArithImm.sra(rd, rd, 16) | |||
| ArithImmShift.sra(rd, rd, 16) | |||
| ).reverse | |||
| } | |||
| @@ -177,8 +177,8 @@ object Parser { | |||
| val leftShift = if((offset % 4) == 0) 16 else 8 | |||
| List( | |||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | |||
| ArithImm.sll(rd, rd, leftShift), | |||
| ArithImm.sra(rd, rd, 16), | |||
| ArithImmShift.sll(rd, rd, leftShift), | |||
| ArithImmShift.sra(rd, rd, 16), | |||
| ).reverse | |||
| } | |||
| }.map(_.widen[Op]), | |||
| @@ -23,16 +23,17 @@ case class VM( | |||
| def stepInstruction: Either[Finished, ExecutionTrace[VM]] = { | |||
| if (pc.value == 0xEB1CEB1C) Left(Success) | |||
| else getOp flatMap { | |||
| case op: Branch => executeBranch(op) | |||
| case op: Arith => executeArith(op) | |||
| case op: ArithImm => executeArithImm(op) | |||
| case op: AUIPC => executeAUIPC(op) | |||
| case op: LUI => executeLUI(op) | |||
| case op: JALR => executeJALR(op) | |||
| case op: JAL => executeJAL(op) | |||
| case op: LW => executeLW(op) | |||
| case op: SW => executeSW(op) | |||
| case DONE => Left(Success) | |||
| case op: Branch => executeBranch(op) | |||
| case op: Arith => executeArith(op) | |||
| case op: ArithImm => executeArithImm(op) | |||
| case op: ArithImmShift => executeArithImmShift(op) | |||
| case op: AUIPC => executeAUIPC(op) | |||
| case op: LUI => executeLUI(op) | |||
| case op: JALR => executeJALR(op) | |||
| case op: JAL => executeJAL(op) | |||
| case op: LW => executeLW(op) | |||
| case op: SW => executeSW(op) | |||
| case DONE => Left(Success) | |||
| } | |||
| } | |||
| @@ -75,6 +76,13 @@ case class VM( | |||
| } | |||
| private def executeArithImmShift(op: ArithImmShift) = { | |||
| val (regUpdate, nextRegs) = regs.arithImm(op.rd, op.rs1, op.shamt, op.op.run) | |||
| val nextVM = this.copy(regs = nextRegs) | |||
| Right(step(nextVM, regUpdate.toList:_*)) | |||
| } | |||
| private def executeLUI(op: LUI) = { | |||
| val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12)) | |||
| val nextVM = this.copy(regs = nextRegs) | |||
| @@ -125,12 +125,17 @@ object assembler { | |||
| } | |||
| /** | |||
| * Currently not used, thus we allow too larg shifts. | |||
| * Used by SRI, SRAI, SLLI | |||
| */ | |||
| def setShiftTypeImmediate(instruction: Int, immediate: Int): Int = { | |||
| val points = List((24, 5)) | |||
| val withField = applyImmediate(5, immediate, points)(instruction) | |||
| withField | |||
| def setShiftTypeImmediate(funct7: Int, shamt: Int, addr: Addr): Int => InstructionFragment = { | |||
| val shamtPoints = List((24, 5)) | |||
| val funct7Points = List((31, 6)) | |||
| base => { | |||
| val withF7 = applyImmediateU(funct7, funct7Points, addr)(base) | |||
| val withShamt = withF7.flatMap(base2 => applyImmediateU(shamt, shamtPoints, addr)(base2)) | |||
| withShamt | |||
| } | |||
| } | |||
| def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode) | |||
| @@ -142,16 +147,17 @@ object assembler { | |||
| def setOpCode(op: Op): Int => Int = op match { | |||
| case x: Branch => setOpCode("1100011".binary) | |||
| case x: Arith => setOpCode("0110011".binary) | |||
| case x: ArithImm => setOpCode("0010011".binary) | |||
| case x: LW => setOpCode("0000011".binary) | |||
| case x: SW => setOpCode("0100011".binary) | |||
| case x: JALR => setOpCode("1100111".binary) | |||
| case x: JAL => setOpCode("1101111".binary) | |||
| case x: AUIPC => setOpCode("0110111".binary) | |||
| case x: LUI => setOpCode("0010111".binary) | |||
| case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler. | |||
| case x: Branch => setOpCode("1100011".binary) | |||
| case x: Arith => setOpCode("0110011".binary) | |||
| case x: ArithImm => setOpCode("0010011".binary) | |||
| case x: ArithImmShift => setOpCode("0010011".binary) | |||
| case x: LW => setOpCode("0000011".binary) | |||
| case x: SW => setOpCode("0100011".binary) | |||
| case x: JALR => setOpCode("1100111".binary) | |||
| case x: JAL => setOpCode("1101111".binary) | |||
| case x: AUIPC => setOpCode("0110111".binary) | |||
| case x: LUI => setOpCode("0010111".binary) | |||
| case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler. | |||
| } | |||
| def setComparisonFunct(cmp: Comparison): Int => Int = cmp match { | |||
| @@ -195,7 +201,6 @@ object assembler { | |||
| setRs1(op.rs1.value) | |||
| def assembleSType(op: SType): Int => Int = { | |||
| // say("stype") | |||
| instruction => | |||
| (setRs1(op.rs1.value) andThen | |||
| setRs2(op.rs2.value))(instruction) | |||
| @@ -214,16 +219,17 @@ object assembler { | |||
| def assembleImmediate(op: Op, addr: Addr, labelMap: Map[Label, Addr]): Int => Either[(String, Addr), Int] = op match { | |||
| case DONE => instruction => Right(instruction) | |||
| case op: Arith => instruction => Right(instruction) | |||
| case op: ArithImm => setItypeImmediate(op.imm.value, addr) | |||
| case op: Branch => setBranchDestination(labelMap, op, addr) | |||
| case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction)) | |||
| case op: AUIPC => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LUI => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LW => setItypeImmediate(op.offset.value, addr) | |||
| case op: SW => setStypeImmediate(op.offset.value, addr) | |||
| case op: JAL => instruction => { | |||
| case DONE => instruction => Right(instruction) | |||
| case op: Arith => instruction => Right(instruction) | |||
| case op: ArithImm => setItypeImmediate(op.imm.value, addr) | |||
| case op: ArithImmShift => setShiftTypeImmediate(op.imm11.value, op.shamt.value, addr) | |||
| case op: Branch => setBranchDestination(labelMap, op, addr) | |||
| case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction)) | |||
| case op: AUIPC => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LUI => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LW => setItypeImmediate(op.offset.value, addr) | |||
| case op: SW => setStypeImmediate(op.offset.value, addr) | |||
| case op: JAL => instruction => { | |||
| val addressDistance = labelMap | |||
| .lift(op.dst).toRight(s"label ${op.dst} not found", addr) | |||
| .map(absoluteAddr => absoluteAddr - addr) | |||
| @@ -81,16 +81,17 @@ object PrintUtils { | |||
| val UNKNOWN = "UNKNOWN" | |||
| def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match { | |||
| case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}" | |||
| case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}" | |||
| case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}" | |||
| case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}" | |||
| case DONE => s"DONE" | |||
| case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}" | |||
| case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}" | |||
| case op: ArithImmShift => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.shamt.show}" | |||
| case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}" | |||
| case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}" | |||
| case DONE => s"DONE" | |||
| } | |||
| @@ -136,9 +136,9 @@ object TestUtils { | |||
| (s"ori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.or(rd, rs1, imm)), | |||
| (s"xori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.xor(rd, rs1, imm)), | |||
| (s"andi ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.and(rd, rs1, imm)), | |||
| (s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sll(rd, rs1, shift)), | |||
| (s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.srl(rd, rs1, shift)), | |||
| (s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sra(rd, rs1, shift)), | |||
| (s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.sll(rd, rs1, shift % 32)), | |||
| (s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.srl(rd, rs1, shift % 32)), | |||
| (s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.sra(rd, rs1, shift % 32)), | |||
| (s"slti ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.slt(rd, rs1, imm)), | |||
| (s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm))) | |||
| (rd, choices.shuffle(r).head) | |||