Add branch
This commit is contained in:
parent
23abdb7f95
commit
cb1b73bc2b
|
@ -20,6 +20,7 @@ package SpinalRiscv
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
import SpinalRiscv.Riscv.IMM
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
|
||||||
|
@ -81,6 +82,17 @@ object Riscv{
|
||||||
def SB = M"-----------------000-----0100011"
|
def SB = M"-----------------000-----0100011"
|
||||||
def SH = M"-----------------001-----0100011"
|
def SH = M"-----------------001-----0100011"
|
||||||
def SW = M"-----------------010-----0100011"
|
def SW = M"-----------------010-----0100011"
|
||||||
|
|
||||||
|
def BEQ = M"-----------------000-----1100011"
|
||||||
|
def BNE = M"-----------------001-----1100011"
|
||||||
|
def BLT = M"-----------------100-----1100011"
|
||||||
|
def BGE = M"-----------------101-----1100011"
|
||||||
|
def BLTU = M"-----------------110-----1100011"
|
||||||
|
def BGEU = M"-----------------111-----1100011"
|
||||||
|
def JALR = M"-----------------000-----1100111"
|
||||||
|
def JAL = M"-------------------------1101111"
|
||||||
|
def LUI = M"-------------------------0110111"
|
||||||
|
def AUIPC = M"-------------------------0010111"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +124,7 @@ case class VexRiscvConfig(pcWidth : Int){
|
||||||
|
|
||||||
|
|
||||||
object Src1CtrlEnum extends SpinalEnum(binarySequential){
|
object Src1CtrlEnum extends SpinalEnum(binarySequential){
|
||||||
val RS, IMU, IMZ, IMJB = newElement()
|
val RS, IMU, FOUR = newElement() //IMU, IMZ IMJB
|
||||||
}
|
}
|
||||||
|
|
||||||
object Src2CtrlEnum extends SpinalEnum(binarySequential){
|
object Src2CtrlEnum extends SpinalEnum(binarySequential){
|
||||||
|
@ -184,17 +196,106 @@ class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoPredictionBranchPlugin extends Plugin[VexRiscv]{
|
||||||
|
object BranchCtrlEnum extends SpinalEnum(binarySequential){
|
||||||
|
val INC,B,JAL,JALR = newElement()
|
||||||
|
}
|
||||||
|
|
||||||
|
object BRANCH_CTRL extends Stageable(BranchCtrlEnum())
|
||||||
|
object BRANCH_SOLVED extends Stageable(BranchCtrlEnum())
|
||||||
|
|
||||||
|
var jumpInterface : Flow[UInt] = null
|
||||||
|
|
||||||
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
|
import pipeline.config._
|
||||||
|
import Riscv._
|
||||||
|
|
||||||
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
|
|
||||||
|
val bActions = List[(Stageable[_ <: Data],Any)](
|
||||||
|
LEGAL_INSTRUCTION -> True,
|
||||||
|
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||||
|
SRC2_CTRL -> Src2CtrlEnum.RS,
|
||||||
|
SRC_USE_SUB_LESS -> True,
|
||||||
|
SRC1_USE -> True,
|
||||||
|
SRC2_USE -> True
|
||||||
|
)
|
||||||
|
|
||||||
|
val jActions = List[(Stageable[_ <: Data],Any)](
|
||||||
|
LEGAL_INSTRUCTION -> True,
|
||||||
|
SRC1_CTRL -> Src1CtrlEnum.FOUR,
|
||||||
|
SRC2_CTRL -> Src2CtrlEnum.PC,
|
||||||
|
SRC_USE_SUB_LESS -> False,
|
||||||
|
REGFILE_WRITE_VALID -> True,
|
||||||
|
SRC2_USE -> True
|
||||||
|
)
|
||||||
|
|
||||||
|
decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC)
|
||||||
|
decoderService.add(List(
|
||||||
|
JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL)),
|
||||||
|
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR)),
|
||||||
|
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)),
|
||||||
|
BGE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||||
|
BLTU -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> True)),
|
||||||
|
BGEU -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> True))
|
||||||
|
))
|
||||||
|
|
||||||
|
jumpInterface = pipeline.service(classOf[PcManagerService]).createJumpInterface(pipeline.execute)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override def build(pipeline: VexRiscv): Unit = {
|
||||||
|
import pipeline._
|
||||||
|
import pipeline.config._
|
||||||
|
|
||||||
|
execute plug new Area {
|
||||||
|
import execute._
|
||||||
|
|
||||||
|
val less = input(SRC_LESS)
|
||||||
|
val eq = input(SRC1) === input(SRC2)
|
||||||
|
|
||||||
|
insert(BRANCH_SOLVED) := input(BRANCH_CTRL).mux[BranchCtrlEnum.C](
|
||||||
|
BranchCtrlEnum.INC -> BranchCtrlEnum.INC,
|
||||||
|
BranchCtrlEnum.JAL -> BranchCtrlEnum.JAL,
|
||||||
|
BranchCtrlEnum.JALR -> BranchCtrlEnum.JALR,
|
||||||
|
BranchCtrlEnum.B -> input(INSTRUCTION)(14 downto 12).mux(
|
||||||
|
B"000" -> Mux( eq , BranchCtrlEnum.B, BranchCtrlEnum.INC),
|
||||||
|
B"001" -> Mux(!eq , BranchCtrlEnum.B, BranchCtrlEnum.INC),
|
||||||
|
M"1-1" -> Mux(!less, BranchCtrlEnum.B, BranchCtrlEnum.INC),
|
||||||
|
default -> Mux( less, BranchCtrlEnum.B, BranchCtrlEnum.INC)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val imm = IMM(input(INSTRUCTION))
|
||||||
|
jumpInterface.valid := arbitration.isFiring && input(BRANCH_SOLVED) =/= BranchCtrlEnum.INC
|
||||||
|
jumpInterface.payload := input(BRANCH_SOLVED).mux(
|
||||||
|
BranchCtrlEnum.JAL -> (input(PC) + imm.j_sext.asUInt),
|
||||||
|
BranchCtrlEnum.JALR -> (input(REG1).asUInt + imm.i_sext.asUInt),
|
||||||
|
default -> (input(PC) + imm.b_sext.asUInt) //B
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
trait PcManagerService{
|
trait PcManagerService{
|
||||||
def jumpTo(pc : UInt,cond : Bool,stage : Stage) : Unit
|
def createJumpInterface(stage : Stage) : Flow[UInt]
|
||||||
}
|
}
|
||||||
|
|
||||||
class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boolean) extends Plugin[VexRiscv] with PcManagerService{
|
class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boolean) extends Plugin[VexRiscv] with PcManagerService{
|
||||||
|
|
||||||
|
|
||||||
//FetchService interface
|
//FetchService interface
|
||||||
case class JumpInfo(pc: UInt, cond: Bool, stage: Stage)
|
case class JumpInfo(interface : Flow[UInt], stage: Stage)
|
||||||
val jumpInfos = ArrayBuffer[JumpInfo]()
|
val jumpInfos = ArrayBuffer[JumpInfo]()
|
||||||
override def jumpTo(pc: UInt, cond: Bool, stage: Stage): Unit = jumpInfos += JumpInfo(pc,cond,stage)
|
override def createJumpInterface(stage: Stage): Flow[UInt] = {
|
||||||
|
val interface = Flow(UInt(32 bits))
|
||||||
|
jumpInfos += JumpInfo(interface,stage)
|
||||||
|
interface
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override def build(pipeline: VexRiscv): Unit = {
|
override def build(pipeline: VexRiscv): Unit = {
|
||||||
|
@ -217,11 +318,11 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo
|
||||||
//FetchService hardware implementation
|
//FetchService hardware implementation
|
||||||
val jump = if(jumpInfos.length != 0) {
|
val jump = if(jumpInfos.length != 0) {
|
||||||
val sortedByStage = jumpInfos.sortWith((a, b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
val sortedByStage = jumpInfos.sortWith((a, b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
||||||
val valids = sortedByStage.map(_.cond)
|
val valids = sortedByStage.map(_.interface.valid)
|
||||||
val pcs = sortedByStage.map(_.pc)
|
val pcs = sortedByStage.map(_.interface.payload)
|
||||||
|
|
||||||
val pcLoad = Flow(UInt(pcWidth bits))
|
val pcLoad = Flow(UInt(pcWidth bits))
|
||||||
pcLoad.valid := jumpInfos.foldLeft(False)(_ || _.cond)
|
pcLoad.valid := jumpInfos.foldLeft(False)(_ || _.interface.valid)
|
||||||
pcLoad.payload := MuxOH(valids, pcs)
|
pcLoad.payload := MuxOH(valids, pcs)
|
||||||
|
|
||||||
//Register managments
|
//Register managments
|
||||||
|
@ -506,10 +607,11 @@ class SrcPlugin extends Plugin[VexRiscv]{
|
||||||
|
|
||||||
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(REG1),
|
||||||
Src1CtrlEnum.IMU -> imm.u.resized,
|
Src1CtrlEnum.FOUR -> B(4),
|
||||||
Src1CtrlEnum.IMZ -> imm.z.resized,
|
Src1CtrlEnum.IMU -> imm.u.resized
|
||||||
Src1CtrlEnum.IMJB -> B(0) //TODO
|
// Src1CtrlEnum.IMZ -> imm.z.resized,
|
||||||
|
// Src1CtrlEnum.IMJB -> B(0)
|
||||||
)
|
)
|
||||||
insert(SRC2) := input(SRC2_CTRL).mux(
|
insert(SRC2) := input(SRC2_CTRL).mux(
|
||||||
Src2CtrlEnum.RS -> output(REG2),
|
Src2CtrlEnum.RS -> output(REG2),
|
||||||
|
@ -538,7 +640,7 @@ class SrcPlugin extends Plugin[VexRiscv]{
|
||||||
class IntAluPlugin extends Plugin[VexRiscv]{
|
class IntAluPlugin extends Plugin[VexRiscv]{
|
||||||
|
|
||||||
object AluCtrlEnum extends SpinalEnum(binarySequential){
|
object AluCtrlEnum extends SpinalEnum(binarySequential){
|
||||||
val ADD_SUB, SLT_SLTU, XOR, OR, AND = newElement()
|
val ADD_SUB, SLT_SLTU, XOR, OR, AND, SRC1 = newElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
object ALU_CTRL extends Stageable(AluCtrlEnum())
|
object ALU_CTRL extends Stageable(AluCtrlEnum())
|
||||||
|
@ -568,7 +670,17 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
||||||
SRC2_USE -> True
|
SRC2_USE -> True
|
||||||
)
|
)
|
||||||
|
|
||||||
pipeline.service(classOf[DecoderService]).add(List(
|
val otherAction = List(
|
||||||
|
LEGAL_INSTRUCTION -> True,
|
||||||
|
REGFILE_WRITE_VALID -> True,
|
||||||
|
BYPASSABLE_EXECUTE_STAGE -> True,
|
||||||
|
BYPASSABLE_MEMORY_STAGE -> True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
|
decoderService.add(List(
|
||||||
ADD -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
|
ADD -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
|
||||||
SUB -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> True)),
|
SUB -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> True)),
|
||||||
SLT -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
|
SLT -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
|
||||||
|
@ -578,7 +690,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
||||||
AND -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND))
|
AND -> (nonImmediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND))
|
||||||
))
|
))
|
||||||
|
|
||||||
pipeline.service(classOf[DecoderService]).add(List(
|
decoderService.add(List(
|
||||||
ADDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
|
ADDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False)),
|
||||||
SLTI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
|
SLTI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> False)),
|
||||||
SLTIU -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)),
|
SLTIU -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.SLT_SLTU, SRC_USE_SUB_LESS -> True, SRC_LESS_UNSIGNED -> True)),
|
||||||
|
@ -586,6 +698,11 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
||||||
ORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.OR)),
|
ORI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.OR)),
|
||||||
ANDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND))
|
ANDI -> (immediateActions ++ List(ALU_CTRL -> AluCtrlEnum.AND))
|
||||||
))
|
))
|
||||||
|
|
||||||
|
decoderService.add(List(
|
||||||
|
LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1)),
|
||||||
|
AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC))
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
override def build(pipeline: VexRiscv): Unit = {
|
override def build(pipeline: VexRiscv): Unit = {
|
||||||
|
@ -601,6 +718,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{
|
||||||
AluCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
|
AluCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
|
||||||
AluCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
|
AluCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
|
||||||
AluCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
|
AluCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
|
||||||
|
AluCtrlEnum.SRC1 -> input(SRC1),
|
||||||
AluCtrlEnum.SLT_SLTU -> input(SRC_LESS).asBits(32 bit),
|
AluCtrlEnum.SLT_SLTU -> input(SRC_LESS).asBits(32 bit),
|
||||||
AluCtrlEnum.ADD_SUB -> input(SRC_ADD_SUB)
|
AluCtrlEnum.ADD_SUB -> input(SRC_ADD_SUB)
|
||||||
)
|
)
|
||||||
|
@ -706,6 +824,8 @@ object TopLevel {
|
||||||
new FullBarrielShifterPlugin,
|
new FullBarrielShifterPlugin,
|
||||||
new DBusSimplePlugin,
|
new DBusSimplePlugin,
|
||||||
new HazardSimplePlugin(true,true,true,true),
|
new HazardSimplePlugin(true,true,true,true),
|
||||||
|
// new HazardSimplePlugin(false,false,false,false),
|
||||||
|
new NoPredictionBranchPlugin,
|
||||||
new OutputAluResult
|
new OutputAluResult
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue