Reintroduce MMU feature (pass tests)
This commit is contained in:
parent
35fbf177e2
commit
7ffbfab312
|
@ -56,20 +56,22 @@ case class MemoryTranslatorRsp() extends Bundle{
|
||||||
val isIoAccess = Bool
|
val isIoAccess = Bool
|
||||||
val allowRead, allowWrite, allowExecute, allowUser = Bool
|
val allowRead, allowWrite, allowExecute, allowUser = Bool
|
||||||
val miss = Bool
|
val miss = Bool
|
||||||
|
val hit = Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
case class MemoryTranslatorBus() extends Bundle with IMasterSlave{
|
case class MemoryTranslatorBus() extends Bundle with IMasterSlave{
|
||||||
val cmd = MemoryTranslatorCmd()
|
val cmd = MemoryTranslatorCmd()
|
||||||
val rsp = MemoryTranslatorRsp()
|
val rsp = MemoryTranslatorRsp()
|
||||||
|
val end = Bool
|
||||||
|
|
||||||
override def asMaster() : Unit = {
|
override def asMaster() : Unit = {
|
||||||
out(cmd)
|
out(cmd, end)
|
||||||
in(rsp)
|
in(rsp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MemoryTranslator{
|
trait MemoryTranslator{
|
||||||
def newTranslationPort(stage : Stage, args : Any) : MemoryTranslatorBus
|
def newTranslationPort(priority : Int, args : Any) : MemoryTranslatorBus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ object TestsWorkspace {
|
||||||
// ),
|
// ),
|
||||||
new IBusCachedPlugin(
|
new IBusCachedPlugin(
|
||||||
resetVector = 0x80000000l,
|
resetVector = 0x80000000l,
|
||||||
|
compressedGen = true,
|
||||||
config = InstructionCacheConfig(
|
config = InstructionCacheConfig(
|
||||||
cacheSize = 1024*16,
|
cacheSize = 1024*16,
|
||||||
bytePerLine = 32,
|
bytePerLine = 32,
|
||||||
|
@ -54,10 +55,10 @@ object TestsWorkspace {
|
||||||
asyncTagMemory = false,
|
asyncTagMemory = false,
|
||||||
twoCycleRam = false,
|
twoCycleRam = false,
|
||||||
twoCycleCache = true
|
twoCycleCache = true
|
||||||
)//,
|
),
|
||||||
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
// portTlbSize = 4
|
portTlbSize = 4
|
||||||
// )
|
)
|
||||||
),
|
),
|
||||||
// new DBusSimplePlugin(
|
// new DBusSimplePlugin(
|
||||||
// catchAddressMisaligned = true,
|
// catchAddressMisaligned = true,
|
||||||
|
|
|
@ -511,6 +511,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid && request.kind === MEMORY //TODO filter request kind
|
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid && request.kind === MEMORY //TODO filter request kind
|
||||||
io.cpu.memory.mmuBus.cmd.virtualAddress := request.address
|
io.cpu.memory.mmuBus.cmd.virtualAddress := request.address
|
||||||
io.cpu.memory.mmuBus.cmd.bypassTranslation := request.way
|
io.cpu.memory.mmuBus.cmd.bypassTranslation := request.way
|
||||||
|
io.cpu.memory.mmuBus.end := !io.cpu.memory.isStuck || io.cpu.memory.isRemoved
|
||||||
cpuMemoryStageNeedReadData := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr
|
cpuMemoryStageNeedReadData := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ trait InstructionCacheCommons{
|
||||||
val isValid : Bool
|
val isValid : Bool
|
||||||
val isStuck : Bool
|
val isStuck : Bool
|
||||||
val pc : UInt
|
val pc : UInt
|
||||||
|
val physicalAddress : UInt
|
||||||
val data : Bits
|
val data : Bits
|
||||||
val cacheMiss, error, mmuMiss, illegalAccess,isUser : Bool
|
val cacheMiss, error, mmuMiss, illegalAccess,isUser : Bool
|
||||||
}
|
}
|
||||||
|
@ -70,14 +71,16 @@ trait InstructionCacheCommons{
|
||||||
case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle with IMasterSlave with InstructionCacheCommons {
|
case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle with IMasterSlave with InstructionCacheCommons {
|
||||||
val isValid = Bool
|
val isValid = Bool
|
||||||
val isStuck = Bool
|
val isStuck = Bool
|
||||||
|
val isRemoved = Bool
|
||||||
val pc = UInt(p.addressWidth bits)
|
val pc = UInt(p.addressWidth bits)
|
||||||
val data = Bits(p.cpuDataWidth bits)
|
val data = Bits(p.cpuDataWidth bits)
|
||||||
val mmuBus = MemoryTranslatorBus()
|
val mmuBus = MemoryTranslatorBus()
|
||||||
|
val physicalAddress = UInt(p.addressWidth bits)
|
||||||
val cacheMiss, error, mmuMiss, illegalAccess,isUser = ifGen(!p.twoCycleCache)(Bool)
|
val cacheMiss, error, mmuMiss, illegalAccess,isUser = ifGen(!p.twoCycleCache)(Bool)
|
||||||
|
|
||||||
override def asMaster(): Unit = {
|
override def asMaster(): Unit = {
|
||||||
out(isValid, isStuck, pc)
|
out(isValid, isStuck, isRemoved, pc)
|
||||||
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss)
|
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss,physicalAddress)
|
||||||
outWithNull(isUser)
|
outWithNull(isUser)
|
||||||
slaveWithNull(mmuBus)
|
slaveWithNull(mmuBus)
|
||||||
}
|
}
|
||||||
|
@ -88,13 +91,14 @@ case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle
|
||||||
val isValid = Bool
|
val isValid = Bool
|
||||||
val isStuck = Bool
|
val isStuck = Bool
|
||||||
val pc = UInt(p.addressWidth bits)
|
val pc = UInt(p.addressWidth bits)
|
||||||
|
val physicalAddress = UInt(p.addressWidth bits)
|
||||||
val data = Bits(p.cpuDataWidth bits)
|
val data = Bits(p.cpuDataWidth bits)
|
||||||
val cacheMiss, error, mmuMiss, illegalAccess, isUser = ifGen(p.twoCycleCache)(Bool)
|
val cacheMiss, error, mmuMiss, illegalAccess, isUser = ifGen(p.twoCycleCache)(Bool)
|
||||||
|
|
||||||
override def asMaster(): Unit = {
|
override def asMaster(): Unit = {
|
||||||
out(isValid, isStuck, pc)
|
out(isValid, isStuck, pc)
|
||||||
outWithNull(isUser)
|
outWithNull(isUser)
|
||||||
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss)
|
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss, physicalAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +332,8 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
io.cpu.fetch.mmuBus.cmd.isValid := io.cpu.fetch.isValid
|
io.cpu.fetch.mmuBus.cmd.isValid := io.cpu.fetch.isValid
|
||||||
io.cpu.fetch.mmuBus.cmd.virtualAddress := io.cpu.fetch.pc
|
io.cpu.fetch.mmuBus.cmd.virtualAddress := io.cpu.fetch.pc
|
||||||
io.cpu.fetch.mmuBus.cmd.bypassTranslation := False
|
io.cpu.fetch.mmuBus.cmd.bypassTranslation := False
|
||||||
|
io.cpu.fetch.mmuBus.end := !io.cpu.fetch.isStuck || io.cpu.fetch.isRemoved
|
||||||
|
io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuBus.rsp.physicalAddress
|
||||||
|
|
||||||
val resolution = ifGen(!twoCycleCache)( new Area{
|
val resolution = ifGen(!twoCycleCache)( new Area{
|
||||||
def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck)
|
def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck)
|
||||||
|
@ -371,6 +377,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
io.cpu.decode.error := hit.error
|
io.cpu.decode.error := hit.error
|
||||||
io.cpu.decode.mmuMiss := mmuRsp.miss
|
io.cpu.decode.mmuMiss := mmuRsp.miss
|
||||||
io.cpu.decode.illegalAccess := !mmuRsp.allowExecute || (io.cpu.decode.isUser && !mmuRsp.allowUser)
|
io.cpu.decode.illegalAccess := !mmuRsp.allowExecute || (io.cpu.decode.isUser && !mmuRsp.allowUser)
|
||||||
|
io.cpu.decode.physicalAddress := mmuRsp.physicalAddress
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
||||||
MEMORY_MANAGMENT -> True
|
MEMORY_MANAGMENT -> True
|
||||||
))
|
))
|
||||||
|
|
||||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,memoryTranslatorPortConfig)
|
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_DATA ,memoryTranslatorPortConfig)
|
||||||
|
|
||||||
if(catchSomething)
|
if(catchSomething)
|
||||||
exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack)
|
exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack)
|
||||||
|
@ -171,6 +171,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
||||||
arbitration.haltItself setWhen(cache.io.cpu.memory.haltIt)
|
arbitration.haltItself setWhen(cache.io.cpu.memory.haltIt)
|
||||||
|
|
||||||
cache.io.cpu.memory.mmuBus <> mmuBus
|
cache.io.cpu.memory.mmuBus <> mmuBus
|
||||||
|
arbitration.haltItself setWhen (mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeBack plug new Area{
|
writeBack plug new Area{
|
||||||
|
|
|
@ -200,11 +200,12 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
val iBusRsp = new Area {
|
val iBusRsp = new Area {
|
||||||
val input = Stream(UInt(32 bits))
|
val input = Stream(UInt(32 bits))
|
||||||
val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
|
val inputPipeline = Vec(Stream(UInt(32 bits)), cmdToRspStageCount)
|
||||||
|
val inputPipelineHalt = Vec(False, cmdToRspStageCount-1)
|
||||||
for(i <- 0 until cmdToRspStageCount) {
|
for(i <- 0 until cmdToRspStageCount) {
|
||||||
// val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush
|
// val doFlush = if(i == cmdToRspStageCount- 1 && ???) killLastStage else flush
|
||||||
inputPipeline(i) << {i match {
|
inputPipeline(i) << {i match {
|
||||||
case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation, collapsBubble = false)
|
case 0 => input.m2sPipeWithFlush(flush, relaxedPcCalculation, collapsBubble = false)
|
||||||
case _ => inputPipeline(i-1)/*.haltWhen(fetcherHalt)*/.m2sPipeWithFlush(flush,collapsBubble = false)
|
case _ => inputPipeline(i-1).haltWhen(inputPipelineHalt(i-1)).m2sPipeWithFlush(flush,collapsBubble = false)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,8 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
|
decodeExceptionPort = exceptionService.newExceptionPort(pipeline.decode,1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(pipeline.serviceExist(classOf[MemoryTranslator]))
|
if(pipeline.serviceExist(classOf[MemoryTranslator]))
|
||||||
// ??? //TODO
|
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(MemoryTranslatorPort.PRIORITY_INSTRUCTION, memoryTranslatorPortConfig)
|
||||||
//mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.fetch, memoryTranslatorPortConfig)
|
|
||||||
|
|
||||||
if(pipeline.serviceExist(classOf[PrivilegeService]))
|
if(pipeline.serviceExist(classOf[PrivilegeService]))
|
||||||
privilegeService = pipeline.service(classOf[PrivilegeService])
|
privilegeService = pipeline.service(classOf[PrivilegeService])
|
||||||
|
@ -105,6 +104,22 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
cache.io.cpu.prefetch.pc := fetchPc.output.payload
|
cache.io.cpu.prefetch.pc := fetchPc.output.payload
|
||||||
iBusRsp.input << fetchPc.output.haltWhen(cache.io.cpu.prefetch.haltIt)
|
iBusRsp.input << fetchPc.output.haltWhen(cache.io.cpu.prefetch.haltIt)
|
||||||
|
|
||||||
|
|
||||||
|
cache.io.cpu.fetch.isRemoved := flush
|
||||||
|
if (mmuBus != null) {
|
||||||
|
cache.io.cpu.fetch.mmuBus <> mmuBus
|
||||||
|
iBusRsp.inputPipelineHalt(0) setWhen(mmuBus.cmd.isValid && !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
|
||||||
|
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
//Connect fetch cache side
|
//Connect fetch cache side
|
||||||
cache.io.cpu.fetch.isValid := iBusRsp.inputPipeline(0).valid
|
cache.io.cpu.fetch.isValid := iBusRsp.inputPipeline(0).valid
|
||||||
cache.io.cpu.fetch.isStuck := !iBusRsp.input.ready
|
cache.io.cpu.fetch.isStuck := !iBusRsp.input.ready
|
||||||
|
@ -123,17 +138,6 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mmuBus != null) {
|
|
||||||
cache.io.cpu.fetch.mmuBus <> mmuBus
|
|
||||||
} else {
|
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress //- debugAddressOffset
|
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
|
// val missHalt = cache.io.cpu.fetch.isValid && cache.io.cpu.fetch.cacheMiss
|
||||||
val cacheRsp = if(twoCycleCache) cache.io.cpu.decode else cache.io.cpu.fetch
|
val cacheRsp = if(twoCycleCache) cache.io.cpu.decode else cache.io.cpu.fetch
|
||||||
|
@ -148,13 +152,17 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
redoBranch.valid := redoFetch
|
redoBranch.valid := redoFetch
|
||||||
assert(decodePcGen == compressedGen)
|
assert(decodePcGen == compressedGen)
|
||||||
redoBranch.payload := (if(decodePcGen) decode.input(PC) else cacheRsp.pc)
|
redoBranch.payload := (if(decodePcGen) decode.input(PC) else cacheRsp.pc)
|
||||||
cache.io.cpu.fill.payload := cacheRsp.pc
|
cache.io.cpu.fill.payload := cacheRsp.physicalAddress
|
||||||
|
|
||||||
if(catchSomething){
|
if(catchSomething){
|
||||||
|
val accessFault = if (catchAccessFault) cacheRsp.error else False
|
||||||
|
val mmuMiss = if (catchMemoryTranslationMiss) cacheRsp.mmuMiss else False
|
||||||
|
val illegalAccess = if (catchIllegalAccess) cacheRsp.illegalAccess else False
|
||||||
|
|
||||||
decodeExceptionPort.valid := False
|
decodeExceptionPort.valid := False
|
||||||
decodeExceptionPort.code := 1
|
decodeExceptionPort.code := mmuMiss ? U(14) | 1
|
||||||
decodeExceptionPort.badAddr := cacheRsp.pc
|
decodeExceptionPort.badAddr := cacheRsp.pc
|
||||||
when(cacheRsp.isValid && cacheRsp.error && !issueDetected){
|
when(cacheRsp.isValid && (accessFault || mmuMiss || illegalAccess) && !issueDetected){
|
||||||
issueDetected \= True
|
issueDetected \= True
|
||||||
decodeExceptionPort.valid := iBusRsp.readyForError
|
decodeExceptionPort.valid := iBusRsp.readyForError
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,12 @@ import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
case class MemoryTranslatorPort(bus : MemoryTranslatorBus, stage : Stage, args : MemoryTranslatorPortConfig/*, exceptionBus: Flow[ExceptionCause]*/)
|
|
||||||
|
object MemoryTranslatorPort{
|
||||||
|
val PRIORITY_DATA = 1
|
||||||
|
val PRIORITY_INSTRUCTION = 0
|
||||||
|
}
|
||||||
|
case class MemoryTranslatorPort(bus : MemoryTranslatorBus, priority : Int, args : MemoryTranslatorPortConfig/*, exceptionBus: Flow[ExceptionCause]*/)
|
||||||
|
|
||||||
case class MemoryTranslatorPortConfig(portTlbSize : Int)
|
case class MemoryTranslatorPortConfig(portTlbSize : Int)
|
||||||
|
|
||||||
|
@ -16,9 +21,9 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
||||||
|
|
||||||
val portsInfo = ArrayBuffer[MemoryTranslatorPort]()
|
val portsInfo = ArrayBuffer[MemoryTranslatorPort]()
|
||||||
|
|
||||||
override def newTranslationPort(stage : Stage,args : Any): MemoryTranslatorBus = {
|
override def newTranslationPort(priority : Int,args : Any): MemoryTranslatorBus = {
|
||||||
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
||||||
val port = MemoryTranslatorPort(MemoryTranslatorBus(),stage,args.asInstanceOf[MemoryTranslatorPortConfig]/*,exceptionBus*/)
|
val port = MemoryTranslatorPort(MemoryTranslatorBus(),priority,args.asInstanceOf[MemoryTranslatorPortConfig]/*,exceptionBus*/)
|
||||||
portsInfo += port
|
portsInfo += port
|
||||||
port.bus
|
port.bus
|
||||||
}
|
}
|
||||||
|
@ -41,7 +46,7 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
||||||
import Riscv._
|
import Riscv._
|
||||||
|
|
||||||
//Sorted by priority
|
//Sorted by priority
|
||||||
val sortedPortsInfo = portsInfo.sortWith((a,b) => indexOf(a.stage) > indexOf(b.stage))
|
val sortedPortsInfo = portsInfo.sortWith((a,b) => a.priority > b.priority)
|
||||||
|
|
||||||
case class CacheLine() extends Bundle {
|
case class CacheLine() extends Bundle {
|
||||||
val valid = Bool
|
val valid = Bool
|
||||||
|
@ -94,7 +99,7 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedMiss.setWhen(sharedIterator >= tlbSize && sharedAccessed === B"00")
|
sharedMiss.setWhen(sharedIterator >= tlbSize && sharedAccessed === B"00")
|
||||||
when(!port.stage.arbitration.isStuck){
|
when(port.bus.end){
|
||||||
sharedIterator := 0
|
sharedIterator := 0
|
||||||
sharedMiss.clear()
|
sharedMiss.clear()
|
||||||
sharedAccessAsked.clear()
|
sharedAccessAsked.clear()
|
||||||
|
@ -108,13 +113,15 @@ class MemoryTranslatorPlugin(tlbSize : Int,
|
||||||
port.bus.rsp.allowWrite := cacheLine.allowWrite
|
port.bus.rsp.allowWrite := cacheLine.allowWrite
|
||||||
port.bus.rsp.allowExecute := cacheLine.allowExecute
|
port.bus.rsp.allowExecute := cacheLine.allowExecute
|
||||||
port.bus.rsp.allowUser := cacheLine.allowUser
|
port.bus.rsp.allowUser := cacheLine.allowUser
|
||||||
port.stage.arbitration.haltItself setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss)
|
port.bus.rsp.hit := cacheHit
|
||||||
|
// port.stage.arbitration.haltItself setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss)
|
||||||
} otherwise {
|
} otherwise {
|
||||||
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
|
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
|
||||||
port.bus.rsp.allowRead := True
|
port.bus.rsp.allowRead := True
|
||||||
port.bus.rsp.allowWrite := True
|
port.bus.rsp.allowWrite := True
|
||||||
port.bus.rsp.allowExecute := True
|
port.bus.rsp.allowExecute := True
|
||||||
port.bus.rsp.allowUser := True
|
port.bus.rsp.allowUser := True
|
||||||
|
port.bus.rsp.hit := True
|
||||||
}
|
}
|
||||||
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
||||||
port.bus.rsp.miss := sharedMiss
|
port.bus.rsp.miss := sharedMiss
|
||||||
|
|
|
@ -5,14 +5,14 @@ import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
case class StaticMemoryTranslatorPort(bus : MemoryTranslatorBus, stage : Stage)
|
case class StaticMemoryTranslatorPort(bus : MemoryTranslatorBus, priority : Int)
|
||||||
|
|
||||||
class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
||||||
val portsInfo = ArrayBuffer[StaticMemoryTranslatorPort]()
|
val portsInfo = ArrayBuffer[StaticMemoryTranslatorPort]()
|
||||||
|
|
||||||
override def newTranslationPort(stage : Stage,args : Any): MemoryTranslatorBus = {
|
override def newTranslationPort(priority : Int,args : Any): MemoryTranslatorBus = {
|
||||||
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
||||||
val port = StaticMemoryTranslatorPort(MemoryTranslatorBus(),stage)
|
val port = StaticMemoryTranslatorPort(MemoryTranslatorBus(),priority)
|
||||||
portsInfo += port
|
portsInfo += port
|
||||||
port.bus
|
port.bus
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRis
|
||||||
port.bus.rsp.allowUser := True
|
port.bus.rsp.allowUser := True
|
||||||
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
||||||
port.bus.rsp.miss := False
|
port.bus.rsp.miss := False
|
||||||
|
port.bus.rsp.hit := True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue