Fix multi port MMU design
Change machineCSR to handle exceptions from the writeBack stage Change the DBusCachedPlugin to emit miss exception
This commit is contained in:
parent
2ed33106d6
commit
889a040f90
|
@ -12,20 +12,23 @@ case class DataCacheConfig( cacheSize : Int,
|
|||
addressWidth : Int,
|
||||
cpuDataWidth : Int,
|
||||
memDataWidth : Int,
|
||||
catchAccessFault : Boolean = false,
|
||||
catchAccessFault : Boolean,
|
||||
catchMemoryTranslationMiss : Boolean,
|
||||
tagSizeShift : Int = 0){ //Used to force infering ram
|
||||
def burstSize = bytePerLine*8/memDataWidth
|
||||
val burstLength = bytePerLine/(memDataWidth/8)
|
||||
assert(catchAccessFault == false)
|
||||
def catchSomething = catchAccessFault || catchMemoryTranslationMiss
|
||||
}
|
||||
|
||||
case class DataMmuConfig(dTlbSize : Int)
|
||||
|
||||
|
||||
class DBusCachedPlugin(config : DataCacheConfig, mmuConfig : DataMmuConfig = null) extends Plugin[VexRiscv]{
|
||||
|
||||
class DBusCachedPlugin(config : DataCacheConfig, askMemoryTranslation : Boolean = false, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv]{
|
||||
import config._
|
||||
var dBus : DataCacheMemBus = null
|
||||
var mmuBus : MemoryTranslatorBus = null
|
||||
var exceptionBus : Flow[ExceptionCause] = null
|
||||
object MEMORY_ENABLE extends Stageable(Bool)
|
||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||
|
||||
|
@ -60,8 +63,11 @@ class DBusCachedPlugin(config : DataCacheConfig, mmuConfig : DataMmuConfig = nul
|
|||
List(SB, SH, SW).map(_ -> storeActions)
|
||||
)
|
||||
|
||||
if(mmuConfig != null)
|
||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,mmuConfig.dTlbSize)
|
||||
if(askMemoryTranslation != null)
|
||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,memoryTranslatorPortConfig)
|
||||
|
||||
if(catchSomething)
|
||||
exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(pipeline.writeBack)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
|
@ -119,6 +125,7 @@ class DBusCachedPlugin(config : DataCacheConfig, mmuConfig : DataMmuConfig = nul
|
|||
import writeBack._
|
||||
cache.io.cpu.writeBack.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
||||
cache.io.cpu.writeBack.isStuck := arbitration.isStuck
|
||||
if(catchSomething) cache.io.cpu.writeBack.exceptionBus <> exceptionBus
|
||||
arbitration.haltIt.setWhen(cache.io.cpu.writeBack.haltIt)
|
||||
|
||||
val rspShifted = Bits(32 bits)
|
||||
|
@ -266,10 +273,12 @@ case class DataCacheCpuWriteBack(p : DataCacheConfig) extends Bundle with IMaste
|
|||
val isStuck = Bool
|
||||
val haltIt = Bool
|
||||
val data = Bits(p.cpuDataWidth bit)
|
||||
val exceptionBus = if(p.catchSomething) Flow(ExceptionCause()) else null
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(isValid,isStuck)
|
||||
in(haltIt, data)
|
||||
slaveWithNull(exceptionBus)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,6 +319,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
|
||||
class DataCache(p : DataCacheConfig) extends Component{
|
||||
import p._
|
||||
import DataCacheCpuCmdKind._
|
||||
assert(wayCount == 1)
|
||||
assert(cpuDataWidth == memDataWidth)
|
||||
|
||||
|
@ -531,7 +541,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
|
||||
val stageA = new Area{
|
||||
val request = RegNextWhen(io.cpu.execute.args, !io.cpu.memory.isStuck)
|
||||
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid //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
|
||||
}
|
||||
|
||||
|
@ -565,7 +575,12 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
val victimNotSent = RegInit(False) clearWhen(victim.requestIn.ready) setWhen(!io.cpu.memory.isStuck)
|
||||
val loadingNotDone = RegInit(False) clearWhen(loaderReady) setWhen(!io.cpu.memory.isStuck)
|
||||
|
||||
import DataCacheCpuCmdKind._
|
||||
if(catchSomething){
|
||||
io.cpu.writeBack.exceptionBus.valid := False
|
||||
io.cpu.writeBack.exceptionBus.code := 13
|
||||
io.cpu.writeBack.exceptionBus.badAddr := request.address
|
||||
}
|
||||
|
||||
when(requestValid) {
|
||||
switch(request.kind) {
|
||||
is(EVICT){
|
||||
|
@ -631,41 +646,47 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
// }
|
||||
// }
|
||||
is(MEMORY) {
|
||||
when(request.bypass) {
|
||||
val memCmdSent = RegInit(False)
|
||||
when(!victim.request.valid) { //Avoid mixing memory request while victim is pending
|
||||
io.mem.cmd.wr := request.wr
|
||||
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0,wordRange.low bit)
|
||||
io.mem.cmd.mask := request.mask
|
||||
io.mem.cmd.data := request.data
|
||||
io.mem.cmd.length := 1
|
||||
if (catchMemoryTranslationMiss) {
|
||||
io.cpu.writeBack.exceptionBus.valid := mmuRsp.miss
|
||||
}
|
||||
when(Bool(!catchMemoryTranslationMiss) || !mmuRsp.miss) {
|
||||
when(request.bypass) {
|
||||
val memCmdSent = RegInit(False)
|
||||
when(!victim.request.valid) {
|
||||
//Avoid mixing memory request while victim is pending
|
||||
io.mem.cmd.wr := request.wr
|
||||
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0, wordRange.low bit)
|
||||
io.mem.cmd.mask := request.mask
|
||||
io.mem.cmd.data := request.data
|
||||
io.mem.cmd.length := 1
|
||||
|
||||
when(!memCmdSent) {
|
||||
io.mem.cmd.valid := True
|
||||
memCmdSent setWhen(io.mem.cmd.ready)
|
||||
when(!memCmdSent) {
|
||||
io.mem.cmd.valid := True
|
||||
memCmdSent setWhen (io.mem.cmd.ready)
|
||||
}
|
||||
|
||||
io.cpu.writeBack.haltIt.clearWhen(memCmdSent && (io.mem.rsp.fire || request.wr)) //Cut mem.cmd.ready path but insert one cycle stall when write
|
||||
}
|
||||
|
||||
io.cpu.writeBack.haltIt.clearWhen(memCmdSent && (io.mem.rsp.fire || request.wr)) //Cut mem.cmd.ready path but insert one cycle stall when write
|
||||
}
|
||||
memCmdSent clearWhen(!io.cpu.writeBack.isStuck)
|
||||
} otherwise {
|
||||
when(waysHit || !loadingNotDone){
|
||||
io.cpu.writeBack.haltIt := False
|
||||
dataWriteCmd.valid := request.wr
|
||||
dataWriteCmd.address := mmuRsp.physicalAddress(lineRange.high downto wordRange.low)
|
||||
dataWriteCmd.data := request.data
|
||||
dataWriteCmd.mask := request.mask
|
||||
|
||||
tagsWriteCmd.valid := !loadingNotDone || request.wr
|
||||
tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange)
|
||||
tagsWriteCmd.data.used := True
|
||||
tagsWriteCmd.data.dirty := request.wr
|
||||
tagsWriteCmd.data.address := mmuRsp.physicalAddress(tagRange)
|
||||
memCmdSent clearWhen (!io.cpu.writeBack.isStuck)
|
||||
} otherwise {
|
||||
val victimRequired = way.tagReadRspTwo.used && way.tagReadRspTwo.dirty
|
||||
loaderValid := loadingNotDone && !(victimNotSent && victim.request.isStall) //Additional condition used to be sure of that all previous victim are written into the RAM
|
||||
victim.requestIn.valid := victimRequired && victimNotSent
|
||||
victim.requestIn.address := way.tagReadRspTwo.address @@ mmuRsp.physicalAddress(lineRange) @@ U((lineRange.low - 1 downto 0) -> false)
|
||||
when(waysHit || !loadingNotDone) {
|
||||
io.cpu.writeBack.haltIt := False
|
||||
dataWriteCmd.valid := request.wr
|
||||
dataWriteCmd.address := mmuRsp.physicalAddress(lineRange.high downto wordRange.low)
|
||||
dataWriteCmd.data := request.data
|
||||
dataWriteCmd.mask := request.mask
|
||||
|
||||
tagsWriteCmd.valid := !loadingNotDone || request.wr
|
||||
tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange)
|
||||
tagsWriteCmd.data.used := True
|
||||
tagsWriteCmd.data.dirty := request.wr
|
||||
tagsWriteCmd.data.address := mmuRsp.physicalAddress(tagRange)
|
||||
} otherwise {
|
||||
val victimRequired = way.tagReadRspTwo.used && way.tagReadRspTwo.dirty
|
||||
loaderValid := loadingNotDone && !(victimNotSent && victim.request.isStall) //Additional condition used to be sure of that all previous victim are written into the RAM
|
||||
victim.requestIn.valid := victimRequired && victimNotSent
|
||||
victim.requestIn.address := way.tagReadRspTwo.address @@ mmuRsp.physicalAddress(lineRange) @@ U((lineRange.low - 1 downto 0) -> false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -717,17 +738,17 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
|
||||
object DataCacheMain{
|
||||
def main(args: Array[String]) {
|
||||
|
||||
SpinalVhdl({
|
||||
implicit val p = DataCacheConfig(
|
||||
cacheSize =4096,
|
||||
bytePerLine =32,
|
||||
wayCount = 1,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
memDataWidth = 32)
|
||||
new WrapWithReg.Wrapper(new DataCache(p)).setDefinitionName("TopLevel")
|
||||
})
|
||||
//
|
||||
// SpinalVhdl({
|
||||
// implicit val p = DataCacheConfig(
|
||||
// cacheSize =4096,
|
||||
// bytePerLine =32,
|
||||
// wayCount = 1,
|
||||
// addressWidth = 32,
|
||||
// cpuDataWidth = 32,
|
||||
// memDataWidth = 32)
|
||||
// new WrapWithReg.Wrapper(new DataCache(p)).setDefinitionName("TopLevel")
|
||||
// })
|
||||
// SpinalVhdl({
|
||||
// implicit val p = DataCacheConfig(
|
||||
// cacheSize =512,
|
||||
|
|
|
@ -245,7 +245,6 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
pipelineLiberator.enable setWhen(pipelineHasException)
|
||||
|
||||
val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => {
|
||||
assert(s != writeBack)
|
||||
val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority)
|
||||
val stagePort = stagePortsInfos.length match{
|
||||
case 1 => stagePortsInfos.head.port
|
||||
|
@ -309,8 +308,8 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
True -> ((mip.MEIP && mie.MEIE) ? U(11) | ((mip.MSIP && mie.MSIE) ? U(3) | U(7))),
|
||||
False -> (if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionContext.code else U(0))
|
||||
)
|
||||
when(exception){
|
||||
mbadaddr := exceptionPortCtrl.exceptionContext.badAddr
|
||||
when(RegNext(exception)){
|
||||
mbadaddr := (if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionContext.badAddr else U(0))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,17 +342,22 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
|
||||
val imm = IMM(input(INSTRUCTION))
|
||||
|
||||
val writeEnable = arbitration.isValid && !arbitration.isStuckByOthers && !arbitration.removeIt && input(IS_CSR) &&
|
||||
(!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
|
||||
|
||||
|
||||
val writeSrc = input(INSTRUCTION)(14) ? imm.z.asBits.resized | input(SRC1)
|
||||
val readData = B(0, 32 bits)
|
||||
val readDataReg = RegNext(readData)
|
||||
val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid) clearWhen(!arbitration.isStuck)
|
||||
val writeData = input(INSTRUCTION)(13).mux(
|
||||
False -> writeSrc,
|
||||
True -> Mux(input(INSTRUCTION)(12), readData & ~writeSrc, readData | writeSrc)
|
||||
True -> Mux(input(INSTRUCTION)(12), readDataReg & ~writeSrc, readDataReg | writeSrc)
|
||||
)
|
||||
val writeInstruction = arbitration.isValid && input(IS_CSR)
|
||||
(!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
|
||||
|
||||
arbitration.haltIt setWhen(writeInstruction && !readDataRegValid)
|
||||
val writeEnable = writeInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt && readDataRegValid
|
||||
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
output(REGFILE_WRITE_DATA) := readData
|
||||
|
@ -361,21 +365,21 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
|
||||
|
||||
//Translation of the csrMapping into real logic
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
switch(input(INSTRUCTION)(csrRange)) {
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
is(address) {
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
when(csrAddress === address) {
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,18 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
case class MemoryTranslatorPort(bus : MemoryTranslatorBus, stage : Stage, cacheSize : Int, exceptionBus: Flow[ExceptionCause])
|
||||
case class MemoryTranslatorPort(bus : MemoryTranslatorBus, stage : Stage, args : MemoryTranslatorPortConfig/*, exceptionBus: Flow[ExceptionCause]*/)
|
||||
|
||||
class MemoryTranslatorPlugin(tlbSize : Int, exceptionCode : Int, mmuRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
||||
case class MemoryTranslatorPortConfig(portTlbSize : Int)
|
||||
|
||||
class MemoryTranslatorPlugin(tlbSize : Int, mmuRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
||||
assert(isPow2(tlbSize))
|
||||
|
||||
val portsInfo = ArrayBuffer[MemoryTranslatorPort]()
|
||||
|
||||
override def newTranslationPort(stage : Stage,cacheSize : Int): MemoryTranslatorBus = {
|
||||
val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
||||
val port = MemoryTranslatorPort(MemoryTranslatorBus(),stage,cacheSize,exceptionBus)
|
||||
override def newTranslationPort(stage : Stage,args : Any): MemoryTranslatorBus = {
|
||||
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
||||
val port = MemoryTranslatorPort(MemoryTranslatorBus(),stage,args.asInstanceOf[MemoryTranslatorPortConfig]/*,exceptionBus*/)
|
||||
portsInfo += port
|
||||
port.bus
|
||||
}
|
||||
|
@ -54,76 +56,64 @@ class MemoryTranslatorPlugin(tlbSize : Int, exceptionCode : Int, mmuRange : UInt
|
|||
val core = pipeline plug new Area {
|
||||
val shared = new Area {
|
||||
val cache = Mem(CacheLine(), tlbSize)
|
||||
val cmd = Stream(UInt(log2Up(sortedPortsInfo.length) bits))
|
||||
val rsp = new Bundle {
|
||||
val portId = UInt()
|
||||
val hit = Bool
|
||||
val line = CacheLine()
|
||||
}
|
||||
|
||||
val cmdVirtualAddress = RegNext(sortedPortsInfo.map(_.bus).read(cmd.payload).cmd.virtualAddress(31 downto 12))
|
||||
val ptr = Counter(tlbSize)
|
||||
val setup = RegNext(False) init (False)
|
||||
val last = RegNext(ptr.willOverflowIfInc)
|
||||
rsp.portId := RegNext(cmd.payload)
|
||||
rsp.line := cache.readSync(ptr)
|
||||
rsp.hit := rsp.line.valid && rsp.line.virtualAddress === cmdVirtualAddress
|
||||
cmd.ready := !setup && (rsp.hit || last)
|
||||
|
||||
when(cmd.valid) {
|
||||
ptr.increment()
|
||||
}
|
||||
|
||||
when(!cmd.valid || cmd.ready || sortedPortsInfo.map(_.stage.arbitration.removeIt).read(cmd.payload)) {
|
||||
ptr.clear()
|
||||
last := False
|
||||
setup := True
|
||||
}
|
||||
var free = True
|
||||
val readAddr = cache.addressType.assignDontCare()
|
||||
val readData = RegNext(cache.readSync(readAddr))
|
||||
}
|
||||
|
||||
|
||||
val ports = for ((port, portId) <- sortedPortsInfo.zipWithIndex) yield new Area {
|
||||
val cache = Vec(Reg(CacheLine()) init, port.cacheSize)
|
||||
val entryToReplace = Counter(port.cacheSize)
|
||||
|
||||
val sharedMiss = RegInit(False)
|
||||
when(shared.cmd.fire && shared.rsp.portId === portId) {
|
||||
cache(entryToReplace) := shared.rsp.line //TODO FMAX pipelining
|
||||
sharedMiss := !shared.rsp.hit
|
||||
entryToReplace.increment()
|
||||
}
|
||||
sharedMiss clearWhen (!port.stage.arbitration.isStuck)
|
||||
|
||||
val sharedRequest = Stream(UInt(log2Up(sortedPortsInfo.length) bits))
|
||||
sharedRequest.valid := False
|
||||
sharedRequest.payload := portId
|
||||
|
||||
port.exceptionBus.valid := False
|
||||
port.exceptionBus.code := exceptionCode
|
||||
port.exceptionBus.badAddr := port.bus.cmd.virtualAddress
|
||||
|
||||
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))
|
||||
val cacheHit = cacheHits.asBits.orR
|
||||
val cacheLine = MuxOH(cacheHits, cache)
|
||||
val isInMmuRange = mmuRange(port.bus.cmd.virtualAddress)
|
||||
|
||||
val sharedMiss = RegInit(False)
|
||||
val sharedIterator = Reg(UInt(log2Up(tlbSize + 1) bits))
|
||||
val sharedAccessed = RegInit(B"00")
|
||||
val entryToReplace = Counter(port.args.portTlbSize)
|
||||
|
||||
val sharedAccessAsked = RegNext(port.bus.cmd.isValid && !cacheHit && sharedIterator < tlbSize && isInMmuRange)
|
||||
val sharedAccessGranted = sharedAccessAsked && shared.free
|
||||
when(sharedAccessGranted) {
|
||||
shared.readAddr := sharedIterator.resized
|
||||
sharedIterator := sharedIterator + 1
|
||||
}
|
||||
sharedAccessed := (sharedAccessed ## sharedAccessGranted).resized
|
||||
when(sharedAccessAsked){
|
||||
shared.free \= False
|
||||
}
|
||||
|
||||
when(sharedAccessed.msb){
|
||||
when(shared.readData.virtualAddress === port.bus.cmd.virtualAddress(31 downto 12)){
|
||||
cache(entryToReplace) := shared.readData
|
||||
entryToReplace.increment()
|
||||
}
|
||||
}
|
||||
|
||||
sharedMiss.setWhen(sharedIterator >= tlbSize && sharedAccessed === B"00")
|
||||
when(!port.stage.arbitration.isStuck){
|
||||
sharedIterator := 0
|
||||
sharedMiss.clear()
|
||||
sharedAccessAsked.clear()
|
||||
sharedAccessed := 0
|
||||
}
|
||||
|
||||
|
||||
when(isInMmuRange) {
|
||||
port.bus.rsp.physicalAddress := cacheLine.physicalAddress @@ port.bus.cmd.virtualAddress(11 downto 0)
|
||||
port.bus.rsp.allowRead := cacheLine.allowRead
|
||||
port.bus.rsp.allowWrite := cacheLine.allowWrite
|
||||
port.bus.rsp.allowExecute := cacheLine.allowExecute
|
||||
port.stage.arbitration.haltIt setWhen (port.bus.cmd.isValid && !cacheHit)
|
||||
port.exceptionBus.valid := sharedMiss
|
||||
sharedRequest.valid := port.bus.cmd.isValid && !cacheHit && !sharedMiss
|
||||
port.stage.arbitration.haltIt setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss)
|
||||
} otherwise {
|
||||
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
|
||||
port.bus.rsp.allowRead := True
|
||||
port.bus.rsp.allowWrite := True
|
||||
port.bus.rsp.allowExecute := True
|
||||
}
|
||||
port.bus.rsp.miss := sharedMiss
|
||||
}
|
||||
|
||||
shared.cmd << StreamArbiterFactory.lowerFirst.noLock.on(ports.map(_.sharedRequest))
|
||||
}
|
||||
|
||||
//Manage TLBW0 and TLBW1 instructions
|
||||
|
|
|
@ -29,6 +29,7 @@ case class MemoryTranslatorCmd() extends Bundle{
|
|||
case class MemoryTranslatorRsp() extends Bundle{
|
||||
val physicalAddress = UInt(32 bits)
|
||||
val allowRead, allowWrite, allowExecute = Bool
|
||||
val miss = Bool
|
||||
}
|
||||
|
||||
case class MemoryTranslatorBus() extends Bundle with IMasterSlave{
|
||||
|
@ -42,5 +43,5 @@ case class MemoryTranslatorBus() extends Bundle with IMasterSlave{
|
|||
}
|
||||
|
||||
trait MemoryTranslator{
|
||||
def newTranslationPort(stage : Stage, cacheSize : Int) : MemoryTranslatorBus
|
||||
def newTranslationPort(stage : Stage, args : Any) : MemoryTranslatorBus
|
||||
}
|
||||
|
|
|
@ -60,22 +60,43 @@ object TopLevel {
|
|||
wfiGen = true
|
||||
)
|
||||
|
||||
// val csrConfig = MachineCsrConfig(
|
||||
// mvendorid = null,
|
||||
// marchid = null,
|
||||
// mimpid = null,
|
||||
// mhartid = null,
|
||||
// misaExtensionsInit = 66,
|
||||
// misaAccess = CsrAccess.NONE,
|
||||
// mtvecAccess = CsrAccess.NONE,
|
||||
// mtvecInit = 0x00000020l,
|
||||
// mepcAccess = CsrAccess.READ_ONLY,
|
||||
// mscratchGen = false,
|
||||
// mcauseAccess = CsrAccess.READ_ONLY,
|
||||
// mbadaddrAccess = CsrAccess.NONE,
|
||||
// mcycleAccess = CsrAccess.NONE,
|
||||
// minstretAccess = CsrAccess.NONE
|
||||
// )
|
||||
val csrConfigSmall = MachineCsrConfig(
|
||||
mvendorid = null,
|
||||
marchid = null,
|
||||
mimpid = null,
|
||||
mhartid = null,
|
||||
misaExtensionsInit = 66,
|
||||
misaAccess = CsrAccess.NONE,
|
||||
mtvecAccess = CsrAccess.NONE,
|
||||
mtvecInit = 0x00000020l,
|
||||
mepcAccess = CsrAccess.READ_WRITE,
|
||||
mscratchGen = false,
|
||||
mcauseAccess = CsrAccess.READ_ONLY,
|
||||
mbadaddrAccess = CsrAccess.READ_ONLY,
|
||||
mcycleAccess = CsrAccess.NONE,
|
||||
minstretAccess = CsrAccess.NONE,
|
||||
ecallGen = false,
|
||||
wfiGen = false
|
||||
)
|
||||
|
||||
val csrConfigSmallest = MachineCsrConfig(
|
||||
mvendorid = null,
|
||||
marchid = null,
|
||||
mimpid = null,
|
||||
mhartid = null,
|
||||
misaExtensionsInit = 66,
|
||||
misaAccess = CsrAccess.NONE,
|
||||
mtvecAccess = CsrAccess.NONE,
|
||||
mtvecInit = 0x00000020l,
|
||||
mepcAccess = CsrAccess.READ_ONLY,
|
||||
mscratchGen = false,
|
||||
mcauseAccess = CsrAccess.READ_ONLY,
|
||||
mbadaddrAccess = CsrAccess.NONE,
|
||||
mcycleAccess = CsrAccess.NONE,
|
||||
minstretAccess = CsrAccess.NONE,
|
||||
ecallGen = false,
|
||||
wfiGen = false
|
||||
)
|
||||
|
||||
configFull.plugins ++= List(
|
||||
new PcManagerSimplePlugin(0x00000000l, false),
|
||||
|
@ -109,7 +130,8 @@ object TopLevel {
|
|||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
memDataWidth = 32,
|
||||
catchAccessFault = false
|
||||
catchAccessFault = false,
|
||||
catchMemoryTranslationMiss = false
|
||||
)
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
|
@ -246,19 +268,20 @@ object TopLevel {
|
|||
cpuDataWidth = 32,
|
||||
memDataWidth = 32,
|
||||
catchAccessFault = false,
|
||||
catchMemoryTranslationMiss = true,
|
||||
tagSizeShift = 2
|
||||
),
|
||||
mmuConfig = DataMmuConfig(
|
||||
dTlbSize = 6
|
||||
askMemoryTranslation = true,
|
||||
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||
portTlbSize = 6
|
||||
)
|
||||
),
|
||||
|
||||
new MemoryTranslatorPlugin(
|
||||
tlbSize = 32,
|
||||
exceptionCode = 13,
|
||||
mmuRange = _(31 downto 28) === 0xC
|
||||
),
|
||||
new MachineCsr(csrConfigAll),
|
||||
new MachineCsr(csrConfigSmall),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
|
@ -275,10 +298,10 @@ object TopLevel {
|
|||
// new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
bypassExecute = false,
|
||||
bypassMemory = false,
|
||||
bypassWriteBack = false,
|
||||
bypassWriteBackBuffer = false,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
|
|
Loading…
Reference in New Issue