diff options
Diffstat (limited to 'VexRiscv/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala')
-rw-r--r-- | VexRiscv/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/VexRiscv/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala b/VexRiscv/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala new file mode 100644 index 0000000..3b407e1 --- /dev/null +++ b/VexRiscv/src/main/scala/vexriscv/plugin/MulSimplePlugin.scala @@ -0,0 +1,92 @@ +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 -> Bool(pipeline.stages.last == pipeline.execute), + BYPASSABLE_MEMORY_STAGE -> Bool(pipeline.stages.last == pipeline.memory), + 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 + } + + val injectionStage = if(pipeline.memory != null) pipeline.memory else pipeline.execute + injectionStage plug new Area { + import injectionStage._ + + insert(MUL) := (input(MUL_OPA) * input(MUL_OPB))(63 downto 0).asBits + } + + val memStage = stages.last + memStage plug new Area { + import memStage._ + + 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) + } + } + } + } + } +} |