diff --git a/src/main/scala/vexriscv/demo/GenFullNoMmuNoCacheSimpleMul.scala b/src/main/scala/vexriscv/demo/GenFullNoMmuNoCacheSimpleMul.scala new file mode 100644 index 0000000..f1e9874 --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenFullNoMmuNoCacheSimpleMul.scala @@ -0,0 +1,63 @@ +package vexriscv.demo + +import vexriscv.plugin._ +import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig} +import vexriscv.{plugin, VexRiscv, VexRiscvConfig} +import spinal.core._ + +/** + * Created by spinalvm on 15.06.17. + */ +object GenFullNoMmuNoCacheSimpleMul extends App{ + def cpu() = new VexRiscv( + config = VexRiscvConfig( + plugins = List( + new IBusSimplePlugin( + resetVector = 0x80000000l, + cmdForkOnSecondStage = false, + cmdForkPersistence = false, + prediction = STATIC, + catchAccessFault = false, + compressedGen = false + ), + new DBusSimplePlugin( + catchAddressMisaligned = false, + catchAccessFault = false + ), + new DecoderSimplePlugin( + catchIllegalInstruction = true + ), + new RegFilePlugin( + regFileReadyKind = plugin.SYNC, + zeroBoot = false + ), + new IntAluPlugin, + new SrcPlugin( + separatedAddSub = false, + executeInsertion = true + ), + new FullBarrelShifterPlugin, + new HazardSimplePlugin( + bypassExecute = true, + bypassMemory = true, + bypassWriteBack = true, + bypassWriteBackBuffer = true, + pessimisticUseSrc = false, + pessimisticWriteRegFile = false, + pessimisticAddressMatch = false + ), + new MulSimplePlugin, + new DivPlugin, + new CsrPlugin(CsrPluginConfig.small), + new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))), + new BranchPlugin( + earlyBranch = false, + catchAddressMisaligned = true + ), + new YamlPlugin("cpu0.yaml") + ) + ) + ) + + SpinalVerilog(cpu()) +} 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) + } + } + } + } + } +}