diff --git a/.jvmopts b/.jvmopts new file mode 100644 index 0000000..03918b6 --- /dev/null +++ b/.jvmopts @@ -0,0 +1,4 @@ +-Xms512M +-Xmx4096M +-Xss32M +-XX:MaxMetaspaceSize=1024M \ No newline at end of file diff --git a/src/main/scala/IF.scala b/src/main/scala/IF.scala index 2195819..232442f 100644 --- a/src/main/scala/IF.scala +++ b/src/main/scala/IF.scala @@ -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") } } diff --git a/src/test/scala/RISCV/Ops.scala b/src/test/scala/RISCV/Ops.scala index e627d90..9158312 100644 --- a/src/test/scala/RISCV/Ops.scala +++ b/src/test/scala/RISCV/Ops.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 diff --git a/src/test/scala/RISCV/Parser.scala b/src/test/scala/RISCV/Parser.scala index 7bd5a45..c00bcd2 100644 --- a/src/test/scala/RISCV/Parser.scala +++ b/src/test/scala/RISCV/Parser.scala @@ -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]), diff --git a/src/test/scala/RISCV/VM.scala b/src/test/scala/RISCV/VM.scala index fe545bd..203161f 100644 --- a/src/test/scala/RISCV/VM.scala +++ b/src/test/scala/RISCV/VM.scala @@ -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) diff --git a/src/test/scala/RISCV/assembler.scala b/src/test/scala/RISCV/assembler.scala index 298a85b..7c4f943 100644 --- a/src/test/scala/RISCV/assembler.scala +++ b/src/test/scala/RISCV/assembler.scala @@ -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) diff --git a/src/test/scala/RISCV/printUtils.scala b/src/test/scala/RISCV/printUtils.scala index 77fe516..4c18a8a 100644 --- a/src/test/scala/RISCV/printUtils.scala +++ b/src/test/scala/RISCV/printUtils.scala @@ -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" } diff --git a/src/test/scala/TestUtils.scala b/src/test/scala/TestUtils.scala index 5943fd7..0a671d1 100644 --- a/src/test/scala/TestUtils.scala +++ b/src/test/scala/TestUtils.scala @@ -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)