| @@ -0,0 +1,4 @@ | |||||
| -Xms512M | |||||
| -Xmx4096M | |||||
| -Xss32M | |||||
| -XX:MaxMetaspaceSize=1024M | |||||
| @@ -61,6 +61,6 @@ class InstructionFetch extends MultiIOModule { | |||||
| when(testHarness.IMEMsetup.setup) { | when(testHarness.IMEMsetup.setup) { | ||||
| PC := 0.U | PC := 0.U | ||||
| // TODO: You should probably set the instruction to Instruction.NOP here. | // 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 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 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 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 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 sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU) | ||||
| def nop = add(0, 0, 0) | 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 LUI(rd: Reg, imm: Imm) extends Op with UType | ||||
| case class AUIPC(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("xori") ~> arithImm.mapN{ArithImm.xor}, | ||||
| stringWs("andi") ~> arithImm.mapN{ArithImm.and}, | 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("slti") ~> arithImm.mapN{ArithImm.slt}, | ||||
| stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu}, | stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu}, | ||||
| @@ -160,16 +160,16 @@ object Parser { | |||||
| SW(placeHolder, 0, 2048), | SW(placeHolder, 0, 2048), | ||||
| LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)), | LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)), | ||||
| LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4), | 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), | Arith.add(rd, rd, placeHolder), | ||||
| LW(placeHolder, 0, 2048)).reverse | LW(placeHolder, 0, 2048)).reverse | ||||
| } | } | ||||
| case (rd, offset, rs1) if (offset % 4 == 2) => { | case (rd, offset, rs1) if (offset % 4 == 2) => { | ||||
| List( | List( | ||||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | LW(rd, rs1, (offset & 0xFFFFFF1C)), | ||||
| ArithImm.sra(rd, rd, 16) | |||||
| ArithImmShift.sra(rd, rd, 16) | |||||
| ).reverse | ).reverse | ||||
| } | } | ||||
| @@ -177,8 +177,8 @@ object Parser { | |||||
| val leftShift = if((offset % 4) == 0) 16 else 8 | val leftShift = if((offset % 4) == 0) 16 else 8 | ||||
| List( | List( | ||||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | 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 | ).reverse | ||||
| } | } | ||||
| }.map(_.widen[Op]), | }.map(_.widen[Op]), | ||||
| @@ -23,16 +23,17 @@ case class VM( | |||||
| def stepInstruction: Either[Finished, ExecutionTrace[VM]] = { | def stepInstruction: Either[Finished, ExecutionTrace[VM]] = { | ||||
| if (pc.value == 0xEB1CEB1C) Left(Success) | if (pc.value == 0xEB1CEB1C) Left(Success) | ||||
| else getOp flatMap { | 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) = { | private def executeLUI(op: LUI) = { | ||||
| val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12)) | val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12)) | ||||
| val nextVM = this.copy(regs = nextRegs) | 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) | def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode) | ||||
| @@ -142,16 +147,17 @@ object assembler { | |||||
| def setOpCode(op: Op): Int => Int = op match { | 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 { | def setComparisonFunct(cmp: Comparison): Int => Int = cmp match { | ||||
| @@ -195,7 +201,6 @@ object assembler { | |||||
| setRs1(op.rs1.value) | setRs1(op.rs1.value) | ||||
| def assembleSType(op: SType): Int => Int = { | def assembleSType(op: SType): Int => Int = { | ||||
| // say("stype") | |||||
| instruction => | instruction => | ||||
| (setRs1(op.rs1.value) andThen | (setRs1(op.rs1.value) andThen | ||||
| setRs2(op.rs2.value))(instruction) | 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 { | 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 | val addressDistance = labelMap | ||||
| .lift(op.dst).toRight(s"label ${op.dst} not found", addr) | .lift(op.dst).toRight(s"label ${op.dst} not found", addr) | ||||
| .map(absoluteAddr => absoluteAddr - addr) | .map(absoluteAddr => absoluteAddr - addr) | ||||
| @@ -81,16 +81,17 @@ object PrintUtils { | |||||
| val UNKNOWN = "UNKNOWN" | val UNKNOWN = "UNKNOWN" | ||||
| def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match { | 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"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"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"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"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))) | (s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm))) | ||||
| (rd, choices.shuffle(r).head) | (rd, choices.shuffle(r).head) | ||||