VexRiscv/src/main/scala/SpinalRiscv/Plugin/IntAluPlugin.scala
Charles Papon efb27390a7 Better IntAluPlugin
Better SrcPlugin
Better DBusCachedPlugin
2017-04-06 01:28:52 +02:00

101 lines
4.1 KiB
Scala

package SpinalRiscv.Plugin
import SpinalRiscv._
import spinal.core._
object IntAluPlugin{
object AluBitwiseCtrlEnum extends SpinalEnum(binarySequential){
val XOR, OR, AND, SRC1 = newElement()
}
object AluCtrlEnum extends SpinalEnum(binarySequential){
val ADD_SUB, SLT_SLTU, BITWISE = newElement()
}
object ALU_BITWISE_CTRL extends Stageable(AluBitwiseCtrlEnum())
object ALU_CTRL extends Stageable(AluCtrlEnum())
}
class IntAluPlugin extends Plugin[VexRiscv]{
import IntAluPlugin._
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
val immediateActions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
REG1_USE -> True,
REG2_USE -> True
)
val otherAction = List[(Stageable[_ <: BaseType],Any)](
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True
)
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.add(List(
ADD -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
SUB -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> True)),
SLT -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
SLTU -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)),
XOR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.XOR)),
OR -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.OR)),
AND -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.AND))
))
decoderService.add(List(
ADDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
SLTI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
SLTIU -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)),
XORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.XOR)),
ORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.OR)),
ANDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.AND))
))
decoderService.add(List(
LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)),
AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC))
))
}
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
val bitwise = input(ALU_BITWISE_CTRL).mux(
AluBitwiseCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
AluBitwiseCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
AluBitwiseCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
AluBitwiseCtrlEnum.SRC1 -> input(SRC1)
)
// mux results
insert(REGFILE_WRITE_DATA) := input(ALU_CTRL).mux(
AluCtrlEnum.BITWISE -> bitwise,
AluCtrlEnum.SLT_SLTU -> input(SRC_LESS).asBits(32 bit),
AluCtrlEnum.ADD_SUB -> input(SRC_ADD_SUB)
)
}
}
}