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