Fix CsrPlugin case issue

Better DBusSimplePlugin FMax with catch enables
SrcPlugin can now insert SRC1 and SRC2 in the execute mode for lower area usage and combinatorial path balancing
This commit is contained in:
Charles Papon 2017-06-27 19:37:46 +02:00
parent e9ab3d71d5
commit 8d34c04425
7 changed files with 58 additions and 36 deletions

View File

@ -64,7 +64,8 @@ object GenFull extends App{
),
new IntAluPlugin,
new SrcPlugin(
separatedAddSub = false
separatedAddSub = false,
executeInsertion = true
),
new FullBarrielShifterPlugin,
new HazardSimplePlugin(

View File

@ -31,7 +31,7 @@ object CsrAccess {
}
case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int)
case class csrPluginConfig(
case class CsrPluginConfig(
catchIllegalAccess : Boolean,
mvendorid : BigInt,
marchid : BigInt,
@ -55,7 +55,7 @@ case class csrPluginConfig(
}
object CsrPluginConfig{
val all = csrPluginConfig(
val all = CsrPluginConfig(
catchIllegalAccess = true,
mvendorid = 11,
marchid = 22,
@ -76,7 +76,7 @@ object CsrPluginConfig{
ucycleAccess = CsrAccess.READ_ONLY
)
val small = csrPluginConfig(
val small = CsrPluginConfig(
catchIllegalAccess = false,
mvendorid = null,
marchid = null,
@ -97,7 +97,7 @@ object CsrPluginConfig{
ucycleAccess = CsrAccess.NONE
)
val smallest = csrPluginConfig(
val smallest = CsrPluginConfig(
catchIllegalAccess = false,
mvendorid = null,
marchid = null,
@ -140,7 +140,7 @@ case class CsrMapping(){
class CsrPlugin(config : csrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor{
class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor{
import config._
import CsrAccess._

View File

@ -103,8 +103,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
object MEMORY_ENABLE extends Stageable(Bool)
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
object ALIGNEMENT_FAULT extends Stageable(Bool)
var executeExceptionPort : Flow[ExceptionCause] = null
var memoryExceptionPort : Flow[ExceptionCause] = null
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
@ -117,7 +117,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
SRC_USE_SUB_LESS -> False,
MEMORY_ENABLE -> True,
REG1_USE -> True
) ++ (if(catchAccessFault) 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(
SRC2_CTRL -> Src2CtrlEnum.IMI,
@ -137,12 +137,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
List(SB, SH, SW).map(_ -> storeActions)
)
if(catchAddressMisaligned) {
val exceptionService = pipeline.service(classOf[ExceptionService])
executeExceptionPort = exceptionService.newExceptionPort(pipeline.execute)
}
if(catchAccessFault) {
if(catchAccessFault || catchAddressMisaligned) {
val exceptionService = pipeline.service(classOf[ExceptionService])
memoryExceptionPort = exceptionService.newExceptionPort(pipeline.memory)
}
@ -158,7 +154,14 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
execute plug new Area{
import execute._
dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.removeIt
insert(ALIGNEMENT_FAULT) := {
if (catchAddressMisaligned)
(dBus.cmd.size === 2 && dBus.cmd.address(1 downto 0) =/= 0) || (dBus.cmd.size === 1 && dBus.cmd.address(0 downto 0) =/= 0)
else
False
}
dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.removeIt && !input(ALIGNEMENT_FAULT)
dBus.cmd.wr := input(INSTRUCTION)(5)
dBus.cmd.address := input(SRC_ADD).asUInt
dBus.cmd.size := input(INSTRUCTION)(13 downto 12).asUInt
@ -167,18 +170,11 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
default -> input(REG2)(31 downto 0)
)
when(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.cmd.ready){
when(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.cmd.ready && !input(ALIGNEMENT_FAULT)){
arbitration.haltIt := True
}
insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0)
if(catchAddressMisaligned){
executeExceptionPort.code := (dBus.cmd.wr ? U(6) | U(4)).resized
executeExceptionPort.badAddr := dBus.cmd.address
executeExceptionPort.valid := (arbitration.isValid && input(MEMORY_ENABLE)
&& ((dBus.cmd.size === 2 && dBus.cmd.address(1 downto 0) =/= 0) || (dBus.cmd.size === 1 && dBus.cmd.address(0 downto 0) =/= 0)))
}
}
//Collect dBus.rsp read responses
@ -189,12 +185,28 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
insert(MEMORY_READ_DATA) := dBus.rsp.data
arbitration.haltIt setWhen(arbitration.isValid && input(MEMORY_ENABLE) && input(REGFILE_WRITE_VALID) && !dBus.rsp.ready)
if(catchAccessFault){
memoryExceptionPort.valid := arbitration.isValid && input(MEMORY_ENABLE) && dBus.rsp.ready && dBus.rsp.error
if(catchAccessFault || catchAddressMisaligned){
if(!catchAccessFault){
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized
memoryExceptionPort.valid := input(ALIGNEMENT_FAULT)
} else if(!catchAddressMisaligned){
memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error
memoryExceptionPort.code := 5
} else {
memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error
memoryExceptionPort.code := 5
when(input(ALIGNEMENT_FAULT)){
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized
memoryExceptionPort.valid := True
}
}
when(!(arbitration.isValid && input(MEMORY_ENABLE))){
memoryExceptionPort.valid := False
}
memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt //Drived by IntAluPlugin
}
assert(!(dBus.rsp.ready && input(MEMORY_ENABLE) && arbitration.isValid && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
}

View File

@ -80,6 +80,15 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{
}
}
class LightShifterPlugin extends Plugin[VexRiscv]{
object ShiftCtrlEnum extends SpinalEnum(binarySequential){
val DISABLE, SLL, SRL, SRA = newElement()

View File

@ -4,13 +4,13 @@ import VexRiscv.{Riscv, VexRiscv}
import spinal.core._
class SrcPlugin(separatedAddSub : Boolean) extends Plugin[VexRiscv]{
class SrcPlugin(separatedAddSub : Boolean, executeInsertion : Boolean = false) extends Plugin[VexRiscv]{
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
decode plug new Area{
import decode._
val insertionStage = if(executeInsertion) execute else decode
insertionStage plug new Area{
import insertionStage._
val imm = Riscv.IMM(input(INSTRUCTION))
insert(SRC1) := input(SRC1_CTRL).mux(

View File

@ -208,10 +208,10 @@ class Briey(config: BrieyConfig) extends Component{
// portTlbSize = 4
// )
),
// new DBusSimplePlugin(
// catchAddressMisaligned = false,
// catchAccessFault = false
// ),
// new DBusSimplePlugin(
// catchAddressMisaligned = true,
// catchAccessFault = true
// ),
new DBusCachedPlugin(
config = new DataCacheConfig(
cacheSize = 4096,
@ -242,7 +242,8 @@ class Briey(config: BrieyConfig) extends Component{
),
new IntAluPlugin,
new SrcPlugin(
separatedAddSub = false
separatedAddSub = false,
executeInsertion = true
),
new FullBarrielShifterPlugin,
new MulPlugin,
@ -263,7 +264,7 @@ class Briey(config: BrieyConfig) extends Component{
prediction = STATIC
),
new CsrPlugin(
config = csrPluginConfig(
config = CsrPluginConfig(
catchIllegalAccess = false,
mvendorid = null,
marchid = null,

View File

@ -412,7 +412,6 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val mmuRsp = RegNextWhen(io.cpu.fetch.mmuBus.rsp,!io.cpu.decode.isStuck)
val hit = tag.valid && tag.address === mmuRsp.physicalAddress(tagRange) && !(tag.loading && !lineLoader.loadedWords(mmuRsp.physicalAddress(wordRange)))
// val hit = tag.hit && !(tag.loading && !lineLoader.loadedWords(mmuRsp.physicalAddress(wordRange)))
io.cpu.decode.haltIt := io.cpu.decode.isValid && !hit //TODO PERF not halit it when removed, Should probably be applyed in many other places
io.cpu.decode.data := data