diff --git a/src/main/scala/VexRiscv/GenFull.scala b/src/main/scala/VexRiscv/GenFull.scala index 131780f..4f1baea 100644 --- a/src/main/scala/VexRiscv/GenFull.scala +++ b/src/main/scala/VexRiscv/GenFull.scala @@ -64,7 +64,8 @@ object GenFull extends App{ ), new IntAluPlugin, new SrcPlugin( - separatedAddSub = false + separatedAddSub = false, + executeInsertion = true ), new FullBarrielShifterPlugin, new HazardSimplePlugin( diff --git a/src/main/scala/VexRiscv/Plugin/CsrPlugin.scala b/src/main/scala/VexRiscv/Plugin/CsrPlugin.scala index fee202b..4393b37 100644 --- a/src/main/scala/VexRiscv/Plugin/CsrPlugin.scala +++ b/src/main/scala/VexRiscv/Plugin/CsrPlugin.scala @@ -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._ diff --git a/src/main/scala/VexRiscv/Plugin/DBusSimplePlugin.scala b/src/main/scala/VexRiscv/Plugin/DBusSimplePlugin.scala index 5746ea4..8ff8cd5 100644 --- a/src/main/scala/VexRiscv/Plugin/DBusSimplePlugin.scala +++ b/src/main/scala/VexRiscv/Plugin/DBusSimplePlugin.scala @@ -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 - memoryExceptionPort.code := 5 + 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") } diff --git a/src/main/scala/VexRiscv/Plugin/ShiftPlugins.scala b/src/main/scala/VexRiscv/Plugin/ShiftPlugins.scala index c73d151..bbf100a 100644 --- a/src/main/scala/VexRiscv/Plugin/ShiftPlugins.scala +++ b/src/main/scala/VexRiscv/Plugin/ShiftPlugins.scala @@ -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() diff --git a/src/main/scala/VexRiscv/Plugin/SrcPlugin.scala b/src/main/scala/VexRiscv/Plugin/SrcPlugin.scala index 3a0b02a..7b2d5d9 100644 --- a/src/main/scala/VexRiscv/Plugin/SrcPlugin.scala +++ b/src/main/scala/VexRiscv/Plugin/SrcPlugin.scala @@ -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( diff --git a/src/main/scala/VexRiscv/demo/Briey.scala b/src/main/scala/VexRiscv/demo/Briey.scala index b19b72f..0abbe83 100644 --- a/src/main/scala/VexRiscv/demo/Briey.scala +++ b/src/main/scala/VexRiscv/demo/Briey.scala @@ -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, diff --git a/src/main/scala/VexRiscv/ip/InstructionCache.scala b/src/main/scala/VexRiscv/ip/InstructionCache.scala index 85b3ab0..eb70afd 100644 --- a/src/main/scala/VexRiscv/ip/InstructionCache.scala +++ b/src/main/scala/VexRiscv/ip/InstructionCache.scala @@ -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