Added MMU support into cacheless DBus IBus plugins (for testing purposes)
Probably full of bugs, need testing
This commit is contained in:
parent
ffa489d211
commit
c490838202
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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)
|
||||
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
|
||||
} else {
|
||||
memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)
|
||||
memoryExceptionPort.code := 5
|
||||
when(input(ALIGNEMENT_FAULT)){
|
||||
}
|
||||
|
||||
if(catchAddressMisaligned) 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))){
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt //Drived by IntAluPlugin
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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.assignDontCare()
|
||||
decodeExceptionPort.badAddr := join.pc //TODO Should it be the physical address insted ?
|
||||
|
||||
if(catchAccessFault) when(join.valid && join.rsp.error){
|
||||
decodeExceptionPort.code := 1
|
||||
decodeExceptionPort.badAddr := join.pc
|
||||
when(join.valid && join.rsp.error && !issueDetected){
|
||||
issueDetected \= True
|
||||
decodeExceptionPort.valid := iBusRsp.readyForError
|
||||
}
|
||||
exceptionDetected := True
|
||||
}
|
||||
if(memoryTranslatorPortConfig != null) when(stages.last.input.valid && mmu.joinCtx.exception){
|
||||
decodeExceptionPort.code := 12
|
||||
exceptionDetected := True
|
||||
}
|
||||
decodeExceptionPort.valid := exceptionDetected && iBusRsp.readyForError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue