diff --git a/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala new file mode 100644 index 0000000..41ed391 --- /dev/null +++ b/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala @@ -0,0 +1,90 @@ +package vexriscv.plugin +import vexriscv._ +import vexriscv.VexRiscv +import spinal.core._ + +class MulSimplePlugin extends Plugin[VexRiscv]{ + object MUL_OPA extends Stageable(SInt(33 bits)) + object MUL_OPB extends Stageable(SInt(33 bits)) + object MUL extends Stageable(Bits(64 bits)) + + object IS_MUL extends Stageable(Bool) + + override def setup(pipeline: VexRiscv): Unit = { + import Riscv._ + import pipeline.config._ + + + val actions = List[(Stageable[_ <: BaseType],Any)]( + SRC1_CTRL -> Src1CtrlEnum.RS, + SRC2_CTRL -> Src2CtrlEnum.RS, + REGFILE_WRITE_VALID -> True, + BYPASSABLE_EXECUTE_STAGE -> False, + BYPASSABLE_MEMORY_STAGE -> False, + RS1_USE -> True, + RS2_USE -> True, + IS_MUL -> True + ) + + val decoderService = pipeline.service(classOf[DecoderService]) + decoderService.addDefault(IS_MUL, False) + decoderService.add(List( + MULX -> actions + )) + + } + + override def build(pipeline: VexRiscv): Unit = { + import pipeline._ + import pipeline.config._ + + // Prepare signed inputs for the multiplier in the next stage. + // This will map them best to an FPGA DSP. + execute plug new Area { + import execute._ + val aSigned,bSigned = Bool + val a,b = Bits(32 bit) + + a := input(SRC1) + b := input(SRC2) + switch(input(INSTRUCTION)(13 downto 12)) { + is(B"01") { + aSigned := True + bSigned := True + } + is(B"10") { + aSigned := True + bSigned := False + } + default { + aSigned := False + bSigned := False + } + } + + insert(MUL_OPA) := ((aSigned ? a.msb | False) ## a).asSInt + insert(MUL_OPB) := ((bSigned ? b.msb | False) ## b).asSInt + } + + memory plug new Area { + import memory._ + + insert(MUL) := (input(MUL_OPA) * input(MUL_OPB))(63 downto 0).asBits + } + + writeBack plug new Area { + import writeBack._ + + when(arbitration.isValid && input(IS_MUL)){ + switch(input(INSTRUCTION)(13 downto 12)){ + is(B"00"){ + output(REGFILE_WRITE_DATA) := input(MUL)(31 downto 0) + } + is(B"01",B"10",B"11"){ + output(REGFILE_WRITE_DATA) := input(MUL)(63 downto 32) + } + } + } + } + } +}