Parcourir la source

Add special handlers for shift instructions.

master
peteraa il y a 6 ans
Parent
révision
8e2d686b5c
8 fichiers modifiés avec 84 ajouts et 62 suppressions
  1. +4
    -0
      .jvmopts
  2. +1
    -1
      src/main/scala/IF.scala
  3. +6
    -3
      src/test/scala/RISCV/Ops.scala
  4. +9
    -9
      src/test/scala/RISCV/Parser.scala
  5. +18
    -10
      src/test/scala/RISCV/VM.scala
  6. +32
    -26
      src/test/scala/RISCV/assembler.scala
  7. +11
    -10
      src/test/scala/RISCV/printUtils.scala
  8. +3
    -3
      src/test/scala/TestUtils.scala

+ 4
- 0
.jvmopts Voir le fichier

@@ -0,0 +1,4 @@
-Xms512M
-Xmx4096M
-Xss32M
-XX:MaxMetaspaceSize=1024M

+ 1
- 1
src/main/scala/IF.scala Voir le fichier

@@ -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")
}
}

+ 6
- 3
src/test/scala/RISCV/Ops.scala Voir le fichier

@@ -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


+ 9
- 9
src/test/scala/RISCV/Parser.scala Voir le fichier

@@ -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]),


+ 18
- 10
src/test/scala/RISCV/VM.scala Voir le fichier

@@ -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)


+ 32
- 26
src/test/scala/RISCV/assembler.scala Voir le fichier

@@ -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)


+ 11
- 10
src/test/scala/RISCV/printUtils.scala Voir le fichier

@@ -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"
}




+ 3
- 3
src/test/scala/TestUtils.scala Voir le fichier

@@ -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)


Chargement…
Annuler
Enregistrer