From c490838202880c6781d72be64450367973fd4227 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 18 Mar 2019 12:17:43 +0100 Subject: [PATCH] Added MMU support into cacheless DBus IBus plugins (for testing purposes) Probably full of bugs, need testing --- src/main/scala/vexriscv/ip/DataCache.scala | 6 +- .../scala/vexriscv/ip/InstructionCache.scala | 4 +- .../vexriscv/plugin/DBusCachedPlugin.scala | 2 +- .../vexriscv/plugin/DBusSimplePlugin.scala | 129 +++++++++++++++--- src/main/scala/vexriscv/plugin/Fetcher.scala | 6 + .../vexriscv/plugin/IBusCachedPlugin.scala | 7 +- .../vexriscv/plugin/IBusSimplePlugin.scala | 74 +++++++--- .../plugin/MemoryTranslatorPlugin.scala | 9 +- .../scala/vexriscv/plugin/MmuPlugin.scala | 12 +- .../plugin/StaticMemoryTranslatorPlugin.scala | 5 +- 10 files changed, 198 insertions(+), 56 deletions(-) diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 5e4f9b7..21f1c38 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -684,11 +684,11 @@ class DataCache(p : DataCacheConfig) extends Component{ when(io.cpu.writeBack.isValid) { if (catchMemoryTranslationMiss) { - io.cpu.writeBack.mmuMiss := mmuRsp.miss + io.cpu.writeBack.mmuMiss := ??? //TODO mmuRsp.miss } switch(request.kind) { is(MANAGMENT) { - when(delayedIsStuck && !mmuRsp.miss) { + when(delayedIsStuck && ???){ //TODO!mmuRsp.miss) { when(delayedWaysHitValid || (request.way && way.tagReadRspTwo.used)) { io.cpu.writeBack.haltIt.clearWhen(!(victim.requestIn.valid && !victim.requestIn.ready)) victim.requestIn.valid := request.clean && way.tagReadRspTwo.dirty @@ -708,7 +708,7 @@ class DataCache(p : DataCacheConfig) extends Component{ val unaligned = if(catchUnaligned) ((request.size === 2 && mmuRsp.physicalAddress(1 downto 0) =/= 0) || (request.size === 1 && mmuRsp.physicalAddress(0 downto 0) =/= 0)) else False io.cpu.writeBack.illegalAccess := illegal io.cpu.writeBack.unalignedAccess := unaligned - when((Bool(!catchMemoryTranslationMiss) || !mmuRsp.miss) && !illegal && !unaligned) { + when((Bool(!catchMemoryTranslationMiss) || ???) && !illegal && !unaligned) { //TODO !mmuRsp.miss when(request.forceUncachedAccess || mmuRsp.isIoAccess) { val memCmdSent = RegInit(False) when(!victim.request.valid) { diff --git a/src/main/scala/vexriscv/ip/InstructionCache.scala b/src/main/scala/vexriscv/ip/InstructionCache.scala index 26d1caa..e7afa73 100644 --- a/src/main/scala/vexriscv/ip/InstructionCache.scala +++ b/src/main/scala/vexriscv/ip/InstructionCache.scala @@ -411,7 +411,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ io.cpu.fetch.cacheMiss := !hit.valid io.cpu.fetch.error := hit.error - io.cpu.fetch.mmuMiss := mmuRsp.miss + io.cpu.fetch.mmuMiss := ??? //TODO mmuRsp.miss io.cpu.fetch.illegalAccess := !mmuRsp.allowExecute || (io.cpu.fetch.isUser && !mmuRsp.allowUser) }) } @@ -441,7 +441,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{ io.cpu.decode.cacheMiss := !hit.valid io.cpu.decode.error := hit.error - io.cpu.decode.mmuMiss := mmuRsp.miss + io.cpu.decode.mmuMiss := ??? //TODO mmuRsp.miss io.cpu.decode.illegalAccess := !mmuRsp.allowExecute || (io.cpu.decode.isUser && !mmuRsp.allowUser) io.cpu.decode.physicalAddress := mmuRsp.physicalAddress }) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 752552a..8a9d3fd 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -173,7 +173,7 @@ class DBusCachedPlugin(config : DataCacheConfig, arbitration.haltItself setWhen(cache.io.cpu.memory.haltIt) cache.io.cpu.memory.mmuBus <> mmuBus - arbitration.haltItself setWhen (mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss) + arbitration.haltItself setWhen (mmuBus.cmd.isValid && ???) //TODO !mmuBus.rsp.hit && !mmuBus.rsp.miss } writeBack plug new Area{ diff --git a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala index eb4ce46..ed3a1b9 100644 --- a/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusSimplePlugin.scala @@ -9,6 +9,8 @@ import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig} import spinal.lib.bus.simple._ import vexriscv.ip.DataCacheMemCmd +import scala.collection.mutable.ArrayBuffer + case class DBusSimpleCmd() extends Bundle{ val wr = Bool @@ -202,7 +204,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, catchAccessFault : Boolean = false, earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/ emitCmdInMemoryStage : Boolean = false, - onlyLoadWords : Boolean = false) extends Plugin[VexRiscv]{ + onlyLoadWords : Boolean = false, + memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService { var dBus : DBusSimpleBus = null assert(!(emitCmdInMemoryStage && earlyInjection)) @@ -211,9 +214,20 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, object MEMORY_READ_DATA extends Stageable(Bits(32 bits)) object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits)) object ALIGNEMENT_FAULT extends Stageable(Bool) + object MMU_RSP extends Stageable(MemoryTranslatorRsp()) var memoryExceptionPort : Flow[ExceptionCause] = null var rspStage : Stage = null + var mmuBus : MemoryTranslatorBus = null + var redoBranch : Flow[UInt] = null + val catchSomething = catchAccessFault || catchAddressMisaligned || memoryTranslatorPortConfig != null + + var dBusAccess : DBusAccess = null + override def newDBusAccess(): DBusAccess = { + assert(dBusAccess == null) + dBusAccess = DBusAccess() + dBusAccess + } override def setup(pipeline: VexRiscv): Unit = { import Riscv._ @@ -250,10 +264,15 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, rspStage = if(stages.last == execute) execute else (if(emitCmdInMemoryStage) writeBack else memory) - if(catchAccessFault || catchAddressMisaligned) { + if(catchSomething) { val exceptionService = pipeline.service(classOf[ExceptionService]) memoryExceptionPort = exceptionService.newExceptionPort(rspStage) } + + if(memoryTranslatorPortConfig != null) { + mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig) + redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.memory) + } } override def build(pipeline: VexRiscv): Unit = { @@ -262,7 +281,6 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, dBus = master(DBusSimpleBus()).setName("dBus") - //Emit dBus.cmd request val cmdStage = if(emitCmdInMemoryStage) memory else execute cmdStage plug new Area{ @@ -279,7 +297,6 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, dBus.cmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers && !arbitration.isFlushed && !input(ALIGNEMENT_FAULT) && !cmdSent dBus.cmd.wr := input(INSTRUCTION)(5) - 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(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0) ## input(RS2)(7 downto 0), @@ -302,6 +319,25 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, insert(FORMAL_MEM_WMASK) := (dBus.cmd.valid && dBus.cmd.wr) ? formalMask | B"0000" insert(FORMAL_MEM_RMASK) := (dBus.cmd.valid && !dBus.cmd.wr) ? formalMask | B"0000" insert(FORMAL_MEM_WDATA) := dBus.cmd.payload.data + + val mmu = (mmuBus != null) generate new Area { + mmuBus.cmd.isValid := arbitration.isValid && input(MEMORY_ENABLE) + mmuBus.cmd.virtualAddress := input(SRC_ADD).asUInt + mmuBus.cmd.bypassTranslation := False + dBus.cmd.address := mmuBus.rsp.physicalAddress + + //do not emit memory request if MMU miss + when(mmuBus.cmd.isValid && (mmuBus.rsp.exception || mmuBus.rsp.refilling)){ + dBus.cmd.valid := False + arbitration.haltItself := False + } + + insert(MMU_RSP) := mmuBus.rsp + } + + val mmuLess = (mmuBus == null) generate new Area{ + dBus.cmd.address := input(SRC_ADD).asUInt + } } //Collect dBus.rsp read responses @@ -312,26 +348,38 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, insert(MEMORY_READ_DATA) := dBus.rsp.data arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && !dBus.rsp.ready) - 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 && !input(INSTRUCTION)(5) - memoryExceptionPort.code := 5 - } else { - memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5) - 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) && (if(cmdStage == rspStage) !arbitration.isStuckByOthers else True))){ - memoryExceptionPort.valid := False + if(catchSomething) { + memoryExceptionPort.valid := False + memoryExceptionPort.code.assignDontCare() + memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt + + if(catchAccessFault) when(dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)) { + memoryExceptionPort.valid := True + memoryExceptionPort.code := 5 } - memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt //Drived by IntAluPlugin + if(catchAddressMisaligned) when(input(ALIGNEMENT_FAULT)){ + memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized + memoryExceptionPort.valid := True + } + + if(memoryTranslatorPortConfig != null) { + redoBranch.valid := False + redoBranch.payload := input(PC) + + when(input(MMU_RSP).refilling){ + redoBranch.valid := True + memoryExceptionPort.valid := False + } elsewhen(input(MMU_RSP).exception) { + memoryExceptionPort.valid := True + memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(15) | U(13)).resized + } + } + + when(!(arbitration.isValid && input(MEMORY_ENABLE) && (Bool(cmdStage != rspStage) || !arbitration.isStuckByOthers))){ + memoryExceptionPort.valid := False + redoBranch.valid := False + } } @@ -368,5 +416,42 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, //formal insert(FORMAL_MEM_RDATA) := input(MEMORY_READ_DATA) } + + //Share access to the dBus (used by self refilled MMU) + val dBusSharing = (dBusAccess != null) generate new Area{ + val state = Reg(UInt(2 bits)) init(0) + dBusAccess.rsp.valid := False + dBusAccess.rsp.data := dBus.rsp.data + dBusAccess.rsp.error := dBus.rsp.error + + switch(state){ + is(0){ + when(dBusAccess.cmd.valid){ + decode.arbitration.haltItself := True + when(!stages.dropWhile(_ != execute).map(_.arbitration.isValid).orR){ + state := 1 + } + } + } + is(1){ + decode.arbitration.haltItself := True + dBus.cmd.valid := True + dBus.cmd.address := dBusAccess.cmd.address + dBus.cmd.wr := dBusAccess.cmd.write + dBus.cmd.data := dBusAccess.cmd.data + dBus.cmd.size := dBusAccess.cmd.size + when(dBus.cmd.ready){ + state := (dBusAccess.cmd.write ? U(0) | U(2)) + } + } + is(2){ + decode.arbitration.haltItself := True + when(dBus.rsp.ready){ + dBusAccess.rsp.valid := True + state := 0 + } + } + } + } } } diff --git a/src/main/scala/vexriscv/plugin/Fetcher.scala b/src/main/scala/vexriscv/plugin/Fetcher.scala index 27a22e0..a6c166a 100644 --- a/src/main/scala/vexriscv/plugin/Fetcher.scala +++ b/src/main/scala/vexriscv/plugin/Fetcher.scala @@ -605,5 +605,11 @@ abstract class IBusFetcherImpl(val resetVector : BigInt, }) } } + + def stageXToIBusRsp[T <: Data](stage : Any, input : T): (T) ={ + iBusRsp.stages.dropWhile(_ != stage).foldLeft(input)((data,stage) => RegNextWhen(data, stage.output.ready)) + + } + } } \ No newline at end of file diff --git a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala index 03285f0..027a015 100644 --- a/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusCachedPlugin.scala @@ -223,7 +223,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l, if (mmuBus != null) { cache.io.cpu.fetch.mmuBus <> mmuBus - (if (twoCycleCache) stages(1).halt else rsp.iBusRspOutputHalt) setWhen (mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss) + (if (twoCycleCache) stages(1).halt else rsp.iBusRspOutputHalt) setWhen (mmuBus.cmd.isValid && ???) //TODO !mmuBus.rsp.hit && !mmuBus.rsp.miss } else { cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True @@ -231,8 +231,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l, cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True cache.io.cpu.fetch.mmuBus.rsp.allowUser := True cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False - cache.io.cpu.fetch.mmuBus.rsp.miss := False - cache.io.cpu.fetch.mmuBus.rsp.hit := False + ??? //TODO +// cache.io.cpu.fetch.mmuBus.rsp.miss := False +// cache.io.cpu.fetch.mmuBus.rsp.hit := False } val flushStage = if(memory != null) memory else execute diff --git a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala index 636b193..cc0a66d 100644 --- a/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala @@ -166,7 +166,8 @@ class IBusSimplePlugin(resetVector : BigInt, pendingMax : Int = 7, injectorStage : Boolean = true, rspHoldValue : Boolean = false, - singleInstructionPipeline : Boolean = false + singleInstructionPipeline : Boolean = false, + memoryTranslatorPortConfig : Any = null ) extends IBusFetcherImpl( resetVector = resetVector, keepPcPlus4 = keepPcPlus4, @@ -181,15 +182,23 @@ class IBusSimplePlugin(resetVector : BigInt, var iBus : IBusSimpleBus = null var decodeExceptionPort : Flow[ExceptionCause] = null + val catchSomething = memoryTranslatorPortConfig != null || catchAccessFault + var mmuBus : MemoryTranslatorBus = null + var redoBranch : Flow[UInt] = null + if(rspHoldValue) assert(busLatencyMin <= 1) override def setup(pipeline: VexRiscv): Unit = { super.setup(pipeline) iBus = master(IBusSimpleBus(false)).setName("iBus") - if(catchAccessFault) { - val exceptionService = pipeline.service(classOf[ExceptionService]) - decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1) + if(catchSomething) { + decodeExceptionPort = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.decode,1) + } + + if(memoryTranslatorPortConfig != null) { + mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig) + redoBranch = pipeline.service(classOf[JumpService]).createJumpInterface(pipeline.decode, priority = 1) //Priority 1 will win against branch predictor } } @@ -206,9 +215,12 @@ class IBusSimplePlugin(resetVector : BigInt, val pendingCmdNext = pendingCmd + cmd.fire.asUInt - iBus.rsp.fire.asUInt pendingCmd := pendingCmdNext + def cmdForkStage = if(!cmdForkPersistence || !cmdForkOnSecondStage) iBusRsp.stages(if(cmdForkOnSecondStage) 1 else 0) else iBusRsp.stages(1) + + val cmdFork = if(!cmdForkPersistence || !cmdForkOnSecondStage) new Area { //This implementation keep the cmd on the bus until it's executed or the the pipeline is flushed - def stage = iBusRsp.stages(if(cmdForkOnSecondStage) 1 else 0) + def stage = cmdForkStage stage.halt setWhen(stage.input.valid && (!cmd.valid || !cmd.ready)) if(singleInstructionPipeline) { cmd.valid := stage.input.valid && pendingCmd =/= pendingMax && !stages.map(_.arbitration.isValid).orR @@ -217,16 +229,33 @@ class IBusSimplePlugin(resetVector : BigInt, }else { cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax } - cmd.pc := stage.input.payload(31 downto 2) @@ "00" } else new Area{ //This implementation keep the cmd on the bus until it's executed, even if the pipeline is flushed - def stage = iBusRsp.stages(1) + def stage = cmdForkStage val pendingFull = pendingCmd === pendingMax val cmdKeep = RegInit(False) setWhen(cmd.valid) clearWhen(cmd.ready) val cmdFired = RegInit(False) setWhen(cmd.fire) clearWhen(stage.input.ready) stage.halt setWhen(cmd.isStall || (pendingFull && !cmdFired)) cmd.valid := (stage.input.valid || cmdKeep) && !pendingFull && !cmdFired - cmd.pc := stage.input.payload(31 downto 2) @@ "00" + } + + val mmu = (mmuBus != null) generate new Area { + mmuBus.cmd.isValid := cmdForkStage.input.valid + mmuBus.cmd.virtualAddress := cmdForkStage.input.payload + mmuBus.cmd.bypassTranslation := False + cmd.pc := mmuBus.rsp.physicalAddress(31 downto 2) @@ "00" + + //do not emit memory request if MMU miss + when(mmuBus.rsp.exception || mmuBus.rsp.refilling){ + cmdForkStage.halt := False + cmd.valid := False + } + + val joinCtx = stageXToIBusRsp(cmdForkStage, mmuBus.rsp) + } + + val mmuLess = (mmuBus == null) generate new Area{ + cmd.pc := cmdForkStage.input.payload(31 downto 2) @@ "00" } val rspJoin = new Area { @@ -261,22 +290,35 @@ class IBusSimplePlugin(resetVector : BigInt, fetchRsp.rsp.error.clearWhen(!rspBufferOutput.valid) //Avoid interference with instruction injection from the debug plugin - var issueDetected = False val join = Stream(FetchRsp()) + val exceptionDetected = False + val redoRequired = False join.valid := stages.last.output.valid && rspBufferOutput.valid join.payload := fetchRsp stages.last.output.ready := stages.last.output.valid ? join.fire | join.ready rspBufferOutput.ready := join.fire - output << join.haltWhen(issueDetected) + output << join.haltWhen(exceptionDetected || redoRequired) - if(catchAccessFault){ + if(memoryTranslatorPortConfig != null){ + redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling) + redoBranch.valid := redoRequired && iBusRsp.readyForError + redoBranch.payload := stages.last.input.payload + } + + if(catchSomething){ decodeExceptionPort.valid := False - decodeExceptionPort.code := 1 - decodeExceptionPort.badAddr := join.pc - when(join.valid && join.rsp.error && !issueDetected){ - issueDetected \= True - decodeExceptionPort.valid := iBusRsp.readyForError + decodeExceptionPort.code.assignDontCare() + decodeExceptionPort.badAddr := join.pc //TODO Should it be the physical address insted ? + + if(catchAccessFault) when(join.valid && join.rsp.error){ + decodeExceptionPort.code := 1 + exceptionDetected := True } + if(memoryTranslatorPortConfig != null) when(stages.last.input.valid && mmu.joinCtx.exception){ + decodeExceptionPort.code := 12 + exceptionDetected := True + } + decodeExceptionPort.valid := exceptionDetected && iBusRsp.readyForError } } } diff --git a/src/main/scala/vexriscv/plugin/MemoryTranslatorPlugin.scala b/src/main/scala/vexriscv/plugin/MemoryTranslatorPlugin.scala index db31022..c5da539 100644 --- a/src/main/scala/vexriscv/plugin/MemoryTranslatorPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MemoryTranslatorPlugin.scala @@ -113,7 +113,8 @@ class MemoryTranslatorPlugin(tlbSize : Int, port.bus.rsp.allowWrite := cacheLine.allowWrite port.bus.rsp.allowExecute := cacheLine.allowExecute port.bus.rsp.allowUser := cacheLine.allowUser - port.bus.rsp.hit := cacheHit + ??? +// port.bus.rsp.hit := cacheHit // port.stage.arbitration.haltItself setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss) } otherwise { port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress @@ -121,10 +122,12 @@ class MemoryTranslatorPlugin(tlbSize : Int, port.bus.rsp.allowWrite := True port.bus.rsp.allowExecute := True port.bus.rsp.allowUser := True - port.bus.rsp.hit := True + ??? +// port.bus.rsp.hit := True } port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) - port.bus.rsp.miss := sharedMiss + ??? +// port.bus.rsp.miss := sharedMiss } } diff --git a/src/main/scala/vexriscv/plugin/MmuPlugin.scala b/src/main/scala/vexriscv/plugin/MmuPlugin.scala index 42a99cc..bbd206d 100644 --- a/src/main/scala/vexriscv/plugin/MmuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/MmuPlugin.scala @@ -6,11 +6,15 @@ import spinal.lib._ import scala.collection.mutable.ArrayBuffer +trait DBusAccessService{ + def newDBusAccess() : DBusAccess +} + case class DBusAccessCmd() extends Bundle { val address = UInt(32 bits) val size = UInt(2 bits) val write = Bool - val writeData = Bits(32 bits) + val data = Bits(32 bits) val writeMask = Bits(4 bits) } @@ -56,7 +60,7 @@ class MmuPlugin(virtualRange : UInt => Bool, decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA -> True)) - dBus = ??? + dBus = pipeline.service(classOf[DBusAccessService]).newDBusAccess() } override def build(pipeline: VexRiscv): Unit = { @@ -81,7 +85,7 @@ class MmuPlugin(virtualRange : UInt => Bool, } val core = pipeline plug new Area { - val ports = for (port <- sortedPortsInfo yield new Area { + val ports = for (port <- sortedPortsInfo) yield new Area { val id = port.id val cache = Vec(Reg(CacheLine()) init, port.args.portTlbSize) val cacheHits = cache.map(line => line.valid && line.virtualAddress === port.bus.cmd.virtualAddress(31 downto 12)) @@ -144,7 +148,7 @@ class MmuPlugin(virtualRange : UInt => Bool, dBus.cmd.write := False dBus.cmd.size := 2 dBus.cmd.address.assignDontCare() - dBus.cmd.writeData.assignDontCare() + dBus.cmd.data.assignDontCare() dBus.cmd.writeMask.assignDontCare() switch(state){ is(State.IDLE){ diff --git a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala index 71d2312..d190ef0 100644 --- a/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala +++ b/src/main/scala/vexriscv/plugin/StaticMemoryTranslatorPlugin.scala @@ -33,8 +33,9 @@ class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRis port.bus.rsp.allowExecute := True port.bus.rsp.allowUser := True port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress) - port.bus.rsp.miss := False - port.bus.rsp.hit := True + ??? +// port.bus.rsp.miss := False +// port.bus.rsp.hit := True } } }