diff --git a/src/main/scala/vexriscv/VexRiscv.scala b/src/main/scala/vexriscv/VexRiscv.scala index aead240..c0da1d4 100644 --- a/src/main/scala/vexriscv/VexRiscv.scala +++ b/src/main/scala/vexriscv/VexRiscv.scala @@ -52,6 +52,7 @@ case class VexRiscvConfig(){ object SRC_LESS extends Stageable(Bool) object SRC_USE_SUB_LESS extends Stageable(Bool) object SRC_LESS_UNSIGNED extends Stageable(Bool) + object SRC_ADD_ZERO extends Stageable(Bool) object HAS_SIDE_EFFECT extends Stageable(Bool) @@ -72,7 +73,7 @@ case class VexRiscvConfig(){ } object Src2CtrlEnum extends SpinalEnum(binarySequential){ - val RS, IMI, IMS, PC = newElement() + val RS, IMI, IMS, PC = newElement() //TODO remplacing ZERO could avoid 32 muxes if SRC_ADD can be disabled } object SRC1_CTRL extends Stageable(Src1CtrlEnum()) object SRC2_CTRL extends Stageable(Src2CtrlEnum()) diff --git a/src/main/scala/vexriscv/demo/Linux.scala b/src/main/scala/vexriscv/demo/Linux.scala index f9cb68c..c274554 100644 --- a/src/main/scala/vexriscv/demo/Linux.scala +++ b/src/main/scala/vexriscv/demo/Linux.scala @@ -52,7 +52,8 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DH -make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LITEX=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/riscv-linux/vmlinux.bin DTB=/home/spinalvm/hdl/riscv-linux/rv32.dtb RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=yes0 FLOW_INFO=yes TRACE_START=9570000099 +make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/riscv-linux/vmlinux.bin DTB=/home/spinalvm/hdl/riscv-linux/rv32.dtb RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=yes0 FLOW_INFO=yes TRACE_START=9570000099 +make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/riscv-linux/vmlinux.bin DTB=/home/spinalvm/hdl/riscv-linux/rv32.dtb RAMDISK=/home/spinalvm/hdl/linux/fs/rootfs.ext2 TRACE=yes0 FLOW_INFO=yes TRACE_START=9570000099 make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/linux/linux-1c163f4c7b3f621efff9b28a47abb36f7378d783/vmlinux.bin DTB=/home/spinalvm/hdl/linux/linux-1c163f4c7b3f621efff9b28a47abb36f7378d783/rv32.dtb RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=yes0 FLOW_INFO=yes TRACE_START=9570000099 @@ -64,7 +65,9 @@ make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DH Other commands (Memo): cp litex_default_configuration .config ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc`; riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin +ARCH=riscv CROSS_COMPILE=riscv32-unknown-linux-gnu- make -j`nproc`; riscv32-unknown-linux-gnu-objcopy -O binary vmlinux vmlinux.bin riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm; split -b 1M vmlinux.asm +riscv32-unknown-linux-gnu-objdump -S -d vmlinux > vmlinux.asm; split -b 1M vmlinux.asm diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index 3dde6dc..e775767 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -276,7 +276,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, decoderService.add( key = LR, values = loadActions.filter(_._1 != SRC2_CTRL) ++ Seq( - SRC2_CTRL -> Src2CtrlEnum.RS, + SRC_ADD_ZERO -> True, MEMORY_ATOMIC -> True ) ) @@ -284,6 +284,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, decoderService.add( key = SC, values = storeActions.filter(_._1 != SRC2_CTRL) ++ Seq( + SRC_ADD_ZERO -> True, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, BYPASSABLE_MEMORY_STAGE -> False, @@ -373,7 +374,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, val atomic = genAtomic generate new Area{ - val address = input(SRC1).asUInt //TODO could avoid 32 muxes if SRC_ADD can be disabled + val address = input(SRC_ADD).asUInt case class AtomicEntry() extends Bundle{ val valid = Bool() val address = UInt(32 bits) @@ -400,9 +401,6 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, when(input(MEMORY_STORE) && input(MEMORY_ATOMIC) && !input(ATOMIC_HIT)){ skipCmd := True } - when(input(MEMORY_ATOMIC)){ - mmuBus.cmd.virtualAddress := address - } } } diff --git a/src/main/scala/vexriscv/plugin/IntAluPlugin.scala b/src/main/scala/vexriscv/plugin/IntAluPlugin.scala index 1b7467e..0520c2f 100644 --- a/src/main/scala/vexriscv/plugin/IntAluPlugin.scala +++ b/src/main/scala/vexriscv/plugin/IntAluPlugin.scala @@ -4,7 +4,7 @@ import vexriscv._ import spinal.core._ object IntAluPlugin{ object AluBitwiseCtrlEnum extends SpinalEnum(binarySequential){ - val XOR, OR, AND, SRC1 = newElement() + val XOR, OR, AND = newElement() } object AluCtrlEnum extends SpinalEnum(binarySequential){ val ADD_SUB, SLT_SLTU, BITWISE = newElement() @@ -70,7 +70,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{ )) decoderService.add(List( - LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.BITWISE, ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)), + LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC_USE_SUB_LESS -> False, SRC_ADD_ZERO -> True)), AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC)) )) } @@ -86,8 +86,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{ 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) + AluBitwiseCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)) ) // mux results diff --git a/src/main/scala/vexriscv/plugin/ShiftPlugins.scala b/src/main/scala/vexriscv/plugin/ShiftPlugins.scala index 086528d..6fa26d7 100644 --- a/src/main/scala/vexriscv/plugin/ShiftPlugins.scala +++ b/src/main/scala/vexriscv/plugin/ShiftPlugins.scala @@ -105,24 +105,30 @@ class LightShifterPlugin extends Plugin[VexRiscv]{ val immediateActions = List[(Stageable[_ <: BaseType],Any)]( SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.IMI, - ALU_CTRL -> AluCtrlEnum.BITWISE, - ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, - RS1_USE -> True + RS1_USE -> True, + + //Get SRC1 through the MMU to the RF write path + ALU_CTRL -> AluCtrlEnum.ADD_SUB, + SRC_USE_SUB_LESS -> False, + SRC_ADD_ZERO -> True ) val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)]( SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.RS, - ALU_CTRL -> AluCtrlEnum.BITWISE, - ALU_BITWISE_CTRL -> AluBitwiseCtrlEnum.SRC1, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, RS1_USE -> True, - RS2_USE -> True + RS2_USE -> True, + + //Get SRC1 through the MMU to the RF write path + ALU_CTRL -> AluCtrlEnum.ADD_SUB, + SRC_USE_SUB_LESS -> False, + SRC_ADD_ZERO -> True ) val decoderService = pipeline.service(classOf[DecoderService]) diff --git a/src/main/scala/vexriscv/plugin/SrcPlugin.scala b/src/main/scala/vexriscv/plugin/SrcPlugin.scala index 395c0a7..79bc763 100644 --- a/src/main/scala/vexriscv/plugin/SrcPlugin.scala +++ b/src/main/scala/vexriscv/plugin/SrcPlugin.scala @@ -1,13 +1,26 @@ package vexriscv.plugin -import vexriscv.{RVC_GEN, Riscv, VexRiscv} +import vexriscv._ import spinal.core._ class SrcPlugin(separatedAddSub : Boolean = false, executeInsertion : Boolean = false, decodeAddSub : Boolean = false) extends Plugin[VexRiscv]{ + object SRC2_FORCE_ZERO extends Stageable(Bool) + + + override def setup(pipeline: VexRiscv): Unit = { + import pipeline.config._ + + val decoderService = pipeline.service(classOf[DecoderService]) + decoderService.addDefault(SRC_ADD_ZERO, False) //TODO avoid this default to simplify decoding ? + } + override def build(pipeline: VexRiscv): Unit = { import pipeline._ import pipeline.config._ + + decode.insert(SRC2_FORCE_ZERO) := decode.input(SRC_ADD_ZERO) && !decode.input(SRC_USE_SUB_LESS) + val insertionStage = if(executeInsertion) execute else decode insertionStage plug new Area{ import insertionStage._ @@ -33,8 +46,9 @@ class SrcPlugin(separatedAddSub : Boolean = false, executeInsertion : Boolean = import addSubStage._ // ADD, SUB - val add = (input(SRC1).asUInt + input(SRC2).asUInt).asBits.addAttribute("keep") - val sub = (input(SRC1).asUInt - input(SRC2).asUInt).asBits.addAttribute("keep") + val add = (U(input(SRC1)) + U(input(SRC2))).asBits.addAttribute("keep") + val sub = (U(input(SRC1)) - U(input(SRC2))).asBits.addAttribute("keep") + when(input(SRC_ADD_ZERO)){ add := input(SRC1) } // SLT, SLTU val less = Mux(input(SRC1).msb === input(SRC2).msb, sub.msb, @@ -51,6 +65,8 @@ class SrcPlugin(separatedAddSub : Boolean = false, executeInsertion : Boolean = // ADD, SUB val addSub = (input(SRC1).asSInt + Mux(input(SRC_USE_SUB_LESS), ~input(SRC2), input(SRC2)).asSInt + Mux(input(SRC_USE_SUB_LESS), S(1), S(0))).asBits + when(input(SRC2_FORCE_ZERO)){ addSub := input(SRC1) } + // SLT, SLTU val less = Mux(input(SRC1).msb === input(SRC2).msb, addSub.msb,