REG1/REG2 refractoring RS1/RS2
Add CustomeInstruction example
This commit is contained in:
parent
708a8f66de
commit
84bba3adf0
|
@ -39,8 +39,8 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||
SRC2_CTRL -> Src2CtrlEnum.RS,
|
||||
SRC_USE_SUB_LESS -> True,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
val jActions = List[(Stageable[_ <: BaseType],Any)](
|
||||
|
@ -55,7 +55,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC)
|
||||
decoderService.add(List(
|
||||
JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL, ALU_CTRL -> AluCtrlEnum.ADD_SUB)),
|
||||
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, ALU_CTRL -> AluCtrlEnum.ADD_SUB, REG1_USE -> True)),
|
||||
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, ALU_CTRL -> AluCtrlEnum.ADD_SUB, RS1_USE -> True)),
|
||||
BEQ -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BNE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BLT -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||
|
@ -108,7 +108,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
)
|
||||
|
||||
val imm = IMM(input(INSTRUCTION))
|
||||
val branch_src1 = (input(BRANCH_CTRL) === BranchCtrlEnum.JALR) ? input(REG1).asUInt | input(PC)
|
||||
val branch_src1 = (input(BRANCH_CTRL) === BranchCtrlEnum.JALR) ? input(RS1).asUInt | input(PC)
|
||||
val branch_src2 = input(BRANCH_CTRL).mux(
|
||||
BranchCtrlEnum.JAL -> imm.j_sext,
|
||||
BranchCtrlEnum.JALR -> imm.i_sext,
|
||||
|
@ -212,7 +212,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
val branch_src1,branch_src2 = UInt(32 bits)
|
||||
switch(input(BRANCH_CTRL)){
|
||||
is(BranchCtrlEnum.JALR){
|
||||
branch_src1 := input(REG1).asUInt
|
||||
branch_src1 := input(RS1).asUInt
|
||||
branch_src2 := imm.i_sext.asUInt
|
||||
}
|
||||
default{
|
||||
|
|
|
@ -188,7 +188,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
|
||||
val nonImmediatActions = defaultCsrActions ++ List(
|
||||
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
)
|
||||
|
||||
val immediatActions = defaultCsrActions
|
||||
|
|
|
@ -28,7 +28,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
|||
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||
SRC_USE_SUB_LESS -> False,
|
||||
MEMORY_ENABLE -> True,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
) ++ (if (catchUnaligned) List(IntAluPlugin.ALU_CTRL -> IntAluPlugin.AluCtrlEnum.ADD_SUB) else Nil) //Used for access fault bad address in memory stage
|
||||
|
||||
val loadActions = stdActions ++ List(
|
||||
|
@ -40,7 +40,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
|||
|
||||
val storeActions = stdActions ++ List(
|
||||
SRC2_CTRL -> Src2CtrlEnum.IMS,
|
||||
REG2_USE -> True
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
decoderService.addDefault(MEMORY_ENABLE, False)
|
||||
|
@ -52,7 +52,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
|||
def MANAGEMENT = M"-------00000-----101-----0001111"
|
||||
decoderService.add(MANAGEMENT, stdActions ++ List(
|
||||
SRC2_CTRL -> Src2CtrlEnum.RS,
|
||||
REG2_USE -> True
|
||||
RS2_USE -> True
|
||||
))
|
||||
|
||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,memoryTranslatorPortConfig)
|
||||
|
@ -104,9 +104,9 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
|||
cache.io.cpu.execute.args.wr := input(INSTRUCTION)(5)
|
||||
cache.io.cpu.execute.args.address := input(SRC_ADD).asUInt
|
||||
cache.io.cpu.execute.args.data := size.mux(
|
||||
U(0) -> input(REG2)( 7 downto 0) ## input(REG2)( 7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0),
|
||||
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
|
||||
default -> input(REG2)(31 downto 0)
|
||||
U(0) -> input(RS2)( 7 downto 0) ## input(RS2)( 7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0),
|
||||
U(1) -> input(RS2)(15 downto 0) ## input(RS2)(15 downto 0),
|
||||
default -> input(RS2)(31 downto 0)
|
||||
)
|
||||
cache.io.cpu.execute.args.size := size
|
||||
cache.io.cpu.execute.args.forceUncachedAccess := False
|
||||
|
|
|
@ -116,7 +116,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||
SRC_USE_SUB_LESS -> False,
|
||||
MEMORY_ENABLE -> True,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
) ++ (if(catchAccessFault || catchAddressMisaligned) List(IntAluPlugin.ALU_CTRL -> IntAluPlugin.AluCtrlEnum.ADD_SUB) else Nil) //Used for access fault bad address in memory stage
|
||||
|
||||
val loadActions = stdActions ++ List(
|
||||
|
@ -128,7 +128,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
|
||||
val storeActions = stdActions ++ List(
|
||||
SRC2_CTRL -> Src2CtrlEnum.IMS,
|
||||
REG2_USE -> True
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
decoderService.addDefault(MEMORY_ENABLE, False)
|
||||
|
@ -166,9 +166,9 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
dBus.cmd.address := input(SRC_ADD).asUInt
|
||||
dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt
|
||||
dBus.cmd.payload.data := dBus.cmd.size.mux (
|
||||
U(0) -> input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0),
|
||||
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
|
||||
default -> input(REG2)(31 downto 0)
|
||||
U(0) -> input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0),
|
||||
U(1) -> input(RS2)(15 downto 0) ## input(RS2)(15 downto 0),
|
||||
default -> input(RS2)(31 downto 0)
|
||||
)
|
||||
when(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.cmd.ready && !input(ALIGNEMENT_FAULT)){
|
||||
arbitration.haltIt := True
|
||||
|
|
|
@ -17,8 +17,8 @@ class DivPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True,
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True,
|
||||
IS_DIV -> True
|
||||
)
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ class HazardSimplePlugin(bypassExecute : Boolean,
|
|||
if (bypassable) {
|
||||
when(runtimeBypassableValue) {
|
||||
when(addr0Match) {
|
||||
decode.input(REG1) := stage.output(REGFILE_WRITE_DATA)
|
||||
decode.input(RS1) := stage.output(REGFILE_WRITE_DATA)
|
||||
}
|
||||
when(addr1Match) {
|
||||
decode.input(REG2) := stage.output(REGFILE_WRITE_DATA)
|
||||
decode.input(RS2) := stage.output(REGFILE_WRITE_DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,10 +62,10 @@ class HazardSimplePlugin(bypassExecute : Boolean,
|
|||
when(writeBackBuffer.valid) {
|
||||
if (bypassWriteBackBuffer) {
|
||||
when(addr0Match) {
|
||||
decode.input(REG1) := writeBackBuffer.data
|
||||
decode.input(RS1) := writeBackBuffer.data
|
||||
}
|
||||
when(addr1Match) {
|
||||
decode.input(REG2) := writeBackBuffer.data
|
||||
decode.input(RS2) := writeBackBuffer.data
|
||||
}
|
||||
} else {
|
||||
when(addr0Match) {
|
||||
|
@ -83,10 +83,10 @@ class HazardSimplePlugin(bypassExecute : Boolean,
|
|||
|
||||
|
||||
if(!pessimisticUseSrc) {
|
||||
when(!decode.input(REG1_USE)) {
|
||||
when(!decode.input(RS1_USE)) {
|
||||
src0Hazard := False
|
||||
}
|
||||
when(!decode.input(REG2_USE)) {
|
||||
when(!decode.input(RS2_USE)) {
|
||||
src1Hazard := False
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,13 +86,14 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
iBus = master(IBusSimpleBus(interfaceKeepData)).setName("iBus")
|
||||
prefetch plug new Area {
|
||||
val pendingCmd = RegInit(False) clearWhen (iBus.rsp.ready) setWhen (iBus.cmd.fire)
|
||||
|
||||
//Emit iBus.cmd request
|
||||
iBus.cmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers && !(pendingCmd && !iBus.rsp.ready) //prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers
|
||||
iBus.cmd.pc := prefetch.output(PC)
|
||||
prefetch.arbitration.haltIt setWhen (!iBus.cmd.ready || (pendingCmd && !iBus.rsp.ready))
|
||||
|
||||
}
|
||||
|
||||
//Bus rsp buffer
|
||||
val rspBuffer = if(!interfaceKeepData) new Area{
|
||||
|
|
|
@ -28,7 +28,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> True,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
)
|
||||
|
||||
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
|
||||
|
@ -37,8 +37,8 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> True,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
val otherAction = List[(Stageable[_ <: BaseType],Any)](
|
||||
|
|
|
@ -31,8 +31,8 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
|||
def TLBW1 = M"0000001----------111-----0001111"
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
decoderService.addDefault(IS_TLB, False)
|
||||
decoderService.add(TLBW0, List(IS_TLB -> True, REG1_USE -> True, SRC1_CTRL -> Src1CtrlEnum.RS))
|
||||
decoderService.add(TLBW1, List(IS_TLB -> True, REG1_USE -> True, REG2_USE -> True, SRC1_CTRL -> Src1CtrlEnum.RS))
|
||||
decoderService.add(TLBW0, List(IS_TLB -> True, RS1_USE -> True, SRC1_CTRL -> Src1CtrlEnum.RS))
|
||||
decoderService.add(TLBW1, List(IS_TLB -> True, RS1_USE -> True, RS2_USE -> True, SRC1_CTRL -> Src1CtrlEnum.RS))
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
|
@ -133,12 +133,12 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
|||
is(1){
|
||||
val line = CacheLine()
|
||||
line.virtualAddress := tlbWriteBuffer
|
||||
line.physicalAddress := input(REG2)(19 downto 0).asUInt
|
||||
line.allowUser := input(REG2)(27)
|
||||
line.allowRead := input(REG2)(28)
|
||||
line.allowWrite := input(REG2)(29)
|
||||
line.allowExecute := input(REG2)(30)
|
||||
line.valid := input(REG2)(31)
|
||||
line.physicalAddress := input(RS2)(19 downto 0).asUInt
|
||||
line.allowUser := input(RS2)(27)
|
||||
line.allowRead := input(RS2)(28)
|
||||
line.allowWrite := input(RS2)(29)
|
||||
line.allowExecute := input(RS2)(30)
|
||||
line.valid := input(RS2)(31)
|
||||
core.shared.cache(input(SRC1)(log2Up(tlbSize)-1 downto 0).asUInt) := line
|
||||
|
||||
core.ports.foreach(_.cache.foreach(_.valid := False)) //Invalidate all ports caches
|
||||
|
|
|
@ -24,8 +24,8 @@ class MulPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||
BYPASSABLE_MEMORY_STAGE -> False,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True,
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True,
|
||||
IS_MUL -> True
|
||||
)
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals
|
|||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
decoderService.addDefault(REG1_USE,False)
|
||||
decoderService.addDefault(REG2_USE,False)
|
||||
decoderService.addDefault(RS1_USE,False)
|
||||
decoderService.addDefault(RS2_USE,False)
|
||||
decoderService.addDefault(REGFILE_WRITE_VALID,False)
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,8 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals
|
|||
case `SYNC` => (global.regFile.readSync(regFileReadAddress1),global.regFile.readSync(regFileReadAddress2))
|
||||
}
|
||||
|
||||
insert(REG1) := rs1Data
|
||||
insert(REG2) := rs2Data
|
||||
insert(RS1) := rs1Data
|
||||
insert(RS2) := rs2Data
|
||||
}
|
||||
|
||||
//Write register file
|
||||
|
|
|
@ -26,7 +26,7 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
)
|
||||
|
||||
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
|
||||
|
@ -35,8 +35,8 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
|
@ -109,7 +109,7 @@ class LightShifterPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> True,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True
|
||||
RS1_USE -> True
|
||||
)
|
||||
|
||||
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
|
||||
|
@ -120,8 +120,8 @@ class LightShifterPlugin extends Plugin[VexRiscv]{
|
|||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> True,
|
||||
BYPASSABLE_MEMORY_STAGE -> True,
|
||||
REG1_USE -> True,
|
||||
REG2_USE -> True
|
||||
RS1_USE -> True,
|
||||
RS2_USE -> True
|
||||
)
|
||||
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
|
|
|
@ -14,12 +14,12 @@ class SrcPlugin(separatedAddSub : Boolean, executeInsertion : Boolean = false) e
|
|||
|
||||
val imm = Riscv.IMM(input(INSTRUCTION))
|
||||
insert(SRC1) := input(SRC1_CTRL).mux(
|
||||
Src1CtrlEnum.RS -> output(REG1),
|
||||
Src1CtrlEnum.RS -> output(RS1),
|
||||
Src1CtrlEnum.FOUR -> B(4),
|
||||
Src1CtrlEnum.IMU -> imm.u.resized
|
||||
)
|
||||
insert(SRC2) := input(SRC2_CTRL).mux(
|
||||
Src2CtrlEnum.RS -> output(REG2),
|
||||
Src2CtrlEnum.RS -> output(RS2),
|
||||
Src2CtrlEnum.IMI -> imm.i_sext.resized,
|
||||
Src2CtrlEnum.IMS -> imm.s_sext.resized,
|
||||
Src2CtrlEnum.PC -> output(PC).asBits
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package VexRiscv
|
||||
|
||||
import VexRiscv.Plugin._
|
||||
import VexRiscv.demo.SimdAddPlugin
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import VexRiscv.ip._
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
package VexRiscv
|
||||
|
||||
import VexRiscv.Plugin.Plugin
|
||||
import VexRiscv.Plugin._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
case class VexRiscvConfig(plugins : Seq[Plugin[VexRiscv]]){
|
||||
|
||||
//Default Stageables
|
||||
object BYPASSABLE_EXECUTE_STAGE extends Stageable(Bool)
|
||||
object BYPASSABLE_MEMORY_STAGE extends Stageable(Bool)
|
||||
object REG1 extends Stageable(Bits(32 bits))
|
||||
object REG2 extends Stageable(Bits(32 bits))
|
||||
object REG1_USE extends Stageable(Bool)
|
||||
object REG2_USE extends Stageable(Bool)
|
||||
object RS1 extends Stageable(Bits(32 bits))
|
||||
object RS2 extends Stageable(Bits(32 bits))
|
||||
object RS1_USE extends Stageable(Bool)
|
||||
object RS2_USE extends Stageable(Bool)
|
||||
object RESULT extends Stageable(UInt(32 bits))
|
||||
object PC extends Stageable(UInt(32 bits))
|
||||
object PC_CALC_WITHOUT_JUMP extends Stageable(UInt(32 bits))
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
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._
|
||||
|
||||
//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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue