diff options
Diffstat (limited to 'VexRiscv/src/main/scala/vexriscv/demo/CustomInstruction.scala')
-rw-r--r-- | VexRiscv/src/main/scala/vexriscv/demo/CustomInstruction.scala | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/VexRiscv/src/main/scala/vexriscv/demo/CustomInstruction.scala b/VexRiscv/src/main/scala/vexriscv/demo/CustomInstruction.scala new file mode 100644 index 0000000..dc35997 --- /dev/null +++ b/VexRiscv/src/main/scala/vexriscv/demo/CustomInstruction.scala @@ -0,0 +1,75 @@ +package vexriscv.demo + +import spinal.core._ +import vexriscv.plugin.Plugin +import vexriscv.{Stageable, DecoderService, VexRiscv} + +//This plugin example will add a new instruction named SIMD_ADD which do the following : +// +//RD : Regfile Destination, RS : Regfile Source +//RD( 7 downto 0) = RS1( 7 downto 0) + RS2( 7 downto 0) +//RD(16 downto 8) = RS1(16 downto 8) + RS2(16 downto 8) +//RD(23 downto 16) = RS1(23 downto 16) + RS2(23 downto 16) +//RD(31 downto 24) = RS1(31 downto 24) + RS2(31 downto 24) +// +//Instruction encoding : +//0000011----------000-----0110011 +// |RS2||RS1| |RD | +// +//Note : RS1, RS2, RD positions follow the RISC-V spec and are common for all instruction of the ISA + +class SimdAddPlugin extends Plugin[VexRiscv]{ + //Define the concept of IS_SIMD_ADD signals, which specify if the current instruction is destined for ths plugin + object IS_SIMD_ADD extends Stageable(Bool) + + //Callback to setup the plugin and ask for different services + override def setup(pipeline: VexRiscv): Unit = { + import pipeline.config._ + + //Retrieve the DecoderService instance + val decoderService = pipeline.service(classOf[DecoderService]) + + //Specify the IS_SIMD_ADD default value when instruction are decoded + decoderService.addDefault(IS_SIMD_ADD, False) + + //Specify the instruction decoding which should be applied when the instruction match the 'key' parttern + decoderService.add( + //Bit pattern of the new SIMD_ADD instruction + key = M"0000011----------000-----0110011", + + //Decoding specification when the 'key' pattern is recognized in the instruction + List( + IS_SIMD_ADD -> True, + REGFILE_WRITE_VALID -> True, //Enable the register file write + BYPASSABLE_EXECUTE_STAGE -> True, //Notify the hazard management unit that the instruction result is already accessible in the EXECUTE stage (Bypass ready) + BYPASSABLE_MEMORY_STAGE -> True, //Same as above but for the memory stage + RS1_USE -> True, //Notify the hazard management unit that this instruction use the RS1 value + RS2_USE -> True //Same than above but for RS2. + ) + ) + } + + override def build(pipeline: VexRiscv): Unit = { + import pipeline._ + import pipeline.config._ + + //Add a new scope on the execute stage (used to give a name to signals) + execute plug new Area { + //Define some signals used internally to the plugin + val rs1 = execute.input(RS1).asUInt //32 bits UInt value of the regfile[RS1] + val rs2 = execute.input(RS2).asUInt + val rd = UInt(32 bits) + + //Do some computation + rd(7 downto 0) := rs1(7 downto 0) + rs2(7 downto 0) + rd(16 downto 8) := rs1(16 downto 8) + rs2(16 downto 8) + rd(23 downto 16) := rs1(23 downto 16) + rs2(23 downto 16) + rd(31 downto 24) := rs1(31 downto 24) + rs2(31 downto 24) + + //When the instruction is a SIMD_ADD one, then write the result into the register file data path. + when(execute.input(IS_SIMD_ADD)) { + execute.output(REGFILE_WRITE_DATA) := rd.asBits + } + } + } +} |