Add ICache and DCache axi bridges functions
Add StaticMemoryTranslationPlugin
This commit is contained in:
parent
ac16558b6b
commit
1e18daecc0
|
@ -8,7 +8,7 @@ import spinal.lib._
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DBusCachedPlugin(config : DataCacheConfig, askMemoryTranslation : Boolean = false, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv]{
|
class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv]{
|
||||||
import config._
|
import config._
|
||||||
var dBus : DataCacheMemBus = null
|
var dBus : DataCacheMemBus = null
|
||||||
var mmuBus : MemoryTranslatorBus = null
|
var mmuBus : MemoryTranslatorBus = null
|
||||||
|
@ -55,7 +55,6 @@ class DBusCachedPlugin(config : DataCacheConfig, askMemoryTranslation : Boolean
|
||||||
REG2_USE -> True
|
REG2_USE -> True
|
||||||
))
|
))
|
||||||
|
|
||||||
if(askMemoryTranslation)
|
|
||||||
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,memoryTranslatorPortConfig)
|
mmuBus = pipeline.service(classOf[MemoryTranslator]).newTranslationPort(pipeline.memory,memoryTranslatorPortConfig)
|
||||||
|
|
||||||
if(catchSomething)
|
if(catchSomething)
|
||||||
|
@ -104,15 +103,9 @@ class DBusCachedPlugin(config : DataCacheConfig, askMemoryTranslation : Boolean
|
||||||
cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
||||||
cache.io.cpu.memory.isStuck := arbitration.isStuck
|
cache.io.cpu.memory.isStuck := arbitration.isStuck
|
||||||
cache.io.cpu.memory.isRemoved := arbitration.removeIt
|
cache.io.cpu.memory.isRemoved := arbitration.removeIt
|
||||||
if(mmuBus != null){
|
arbitration.haltIt setWhen(cache.io.cpu.memory.haltIt)
|
||||||
|
|
||||||
cache.io.cpu.memory.mmuBus <> mmuBus
|
cache.io.cpu.memory.mmuBus <> mmuBus
|
||||||
} else {
|
|
||||||
cache.io.cpu.memory.mmuBus.rsp.physicalAddress := cache.io.cpu.memory.mmuBus.cmd.virtualAddress
|
|
||||||
cache.io.cpu.memory.mmuBus.rsp.allowExecute := True
|
|
||||||
cache.io.cpu.memory.mmuBus.rsp.allowRead := True
|
|
||||||
cache.io.cpu.memory.mmuBus.rsp.allowWrite := True
|
|
||||||
cache.io.cpu.memory.mmuBus.rsp.allowUser := True
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeBack plug new Area{
|
writeBack plug new Area{
|
||||||
|
|
|
@ -74,6 +74,9 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
|
cache.io.cpu.fetch.mmuBus.rsp.allowRead := True
|
||||||
cache.io.cpu.fetch.mmuBus.rsp.allowWrite := 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package SpinalRiscv.Plugin
|
||||||
|
|
||||||
|
import SpinalRiscv.{VexRiscv, _}
|
||||||
|
import spinal.core._
|
||||||
|
import spinal.lib._
|
||||||
|
|
||||||
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
case class StaticMemoryTranslatorPort(bus : MemoryTranslatorBus, stage : Stage)
|
||||||
|
|
||||||
|
class StaticMemoryTranslatorPlugin(ioRange : UInt => Bool) extends Plugin[VexRiscv] with MemoryTranslator {
|
||||||
|
val portsInfo = ArrayBuffer[StaticMemoryTranslatorPort]()
|
||||||
|
|
||||||
|
override def newTranslationPort(stage : Stage,args : Any): MemoryTranslatorBus = {
|
||||||
|
// val exceptionBus = pipeline.service(classOf[ExceptionService]).newExceptionPort(stage)
|
||||||
|
val port = StaticMemoryTranslatorPort(MemoryTranslatorBus(),stage)
|
||||||
|
portsInfo += port
|
||||||
|
port.bus
|
||||||
|
}
|
||||||
|
|
||||||
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def build(pipeline: VexRiscv): Unit = {
|
||||||
|
import pipeline._
|
||||||
|
import pipeline.config._
|
||||||
|
import Riscv._
|
||||||
|
|
||||||
|
val core = pipeline plug new Area {
|
||||||
|
val ports = for ((port, portId) <- portsInfo.zipWithIndex) yield new Area {
|
||||||
|
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.allowUser := True
|
||||||
|
port.bus.rsp.isIoAccess := ioRange(port.bus.rsp.physicalAddress)
|
||||||
|
port.bus.rsp.miss := False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,52 +105,55 @@ object TopLevel {
|
||||||
val configFull = VexRiscvConfig(
|
val configFull = VexRiscvConfig(
|
||||||
plugins = List(
|
plugins = List(
|
||||||
new PcManagerSimplePlugin(0x00000000l, false),
|
new PcManagerSimplePlugin(0x00000000l, false),
|
||||||
new IBusSimplePlugin(
|
// new IBusSimplePlugin(
|
||||||
interfaceKeepData = true,
|
// interfaceKeepData = true,
|
||||||
catchAccessFault = true
|
// catchAccessFault = true
|
||||||
),
|
|
||||||
// new IBusCachedPlugin(
|
|
||||||
// config = InstructionCacheConfig(
|
|
||||||
// cacheSize = 4096,
|
|
||||||
// bytePerLine =32,
|
|
||||||
// wayCount = 1,
|
|
||||||
// wrappedMemAccess = true,
|
|
||||||
// addressWidth = 32,
|
|
||||||
// cpuDataWidth = 32,
|
|
||||||
// memDataWidth = 32,
|
|
||||||
// catchIllegalAccess = true,
|
|
||||||
// catchAccessFault = true,
|
|
||||||
// catchMemoryTranslationMiss = true,
|
|
||||||
// asyncTagMemory = false,
|
|
||||||
// twoStageLogic = true
|
|
||||||
// ),
|
// ),
|
||||||
|
new IBusCachedPlugin(
|
||||||
|
config = InstructionCacheConfig(
|
||||||
|
cacheSize = 4096,
|
||||||
|
bytePerLine =32,
|
||||||
|
wayCount = 1,
|
||||||
|
wrappedMemAccess = true,
|
||||||
|
addressWidth = 32,
|
||||||
|
cpuDataWidth = 32,
|
||||||
|
memDataWidth = 32,
|
||||||
|
catchIllegalAccess = true,
|
||||||
|
catchAccessFault = true,
|
||||||
|
catchMemoryTranslationMiss = true,
|
||||||
|
asyncTagMemory = false,
|
||||||
|
twoStageLogic = true
|
||||||
|
)
|
||||||
// askMemoryTranslation = true,
|
// askMemoryTranslation = true,
|
||||||
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
// portTlbSize = 4
|
// portTlbSize = 4
|
||||||
// )
|
// )
|
||||||
// ),
|
|
||||||
new DBusSimplePlugin(
|
|
||||||
catchAddressMisaligned = true,
|
|
||||||
catchAccessFault = true
|
|
||||||
),
|
),
|
||||||
// new DBusCachedPlugin(
|
// new DBusSimplePlugin(
|
||||||
// config = new DataCacheConfig(
|
// catchAddressMisaligned = true,
|
||||||
// cacheSize = 4096,
|
// catchAccessFault = true
|
||||||
// bytePerLine = 32,
|
|
||||||
// wayCount = 1,
|
|
||||||
// addressWidth = 32,
|
|
||||||
// cpuDataWidth = 32,
|
|
||||||
// memDataWidth = 32,
|
|
||||||
// catchAccessError = true,
|
|
||||||
// catchIllegal = true,
|
|
||||||
// catchUnaligned = true,
|
|
||||||
// catchMemoryTranslationMiss = true
|
|
||||||
// ),
|
// ),
|
||||||
// askMemoryTranslation = true,
|
new DBusCachedPlugin(
|
||||||
|
config = new DataCacheConfig(
|
||||||
|
cacheSize = 4096,
|
||||||
|
bytePerLine = 32,
|
||||||
|
wayCount = 1,
|
||||||
|
addressWidth = 32,
|
||||||
|
cpuDataWidth = 32,
|
||||||
|
memDataWidth = 32,
|
||||||
|
catchAccessError = true,
|
||||||
|
catchIllegal = true,
|
||||||
|
catchUnaligned = true,
|
||||||
|
catchMemoryTranslationMiss = true
|
||||||
|
),
|
||||||
|
memoryTranslatorPortConfig = null
|
||||||
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
// portTlbSize = 6
|
// portTlbSize = 6
|
||||||
// )
|
// )
|
||||||
// ),
|
),
|
||||||
|
new StaticMemoryTranslatorPlugin(
|
||||||
|
ioRange = _(31 downto 28) === 0xF
|
||||||
|
),
|
||||||
// new MemoryTranslatorPlugin(
|
// new MemoryTranslatorPlugin(
|
||||||
// tlbSize = 32,
|
// tlbSize = 32,
|
||||||
// virtualRange = _(31 downto 28) === 0xC,
|
// virtualRange = _(31 downto 28) === 0xC,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package SpinalRiscv.demo
|
||||||
|
|
||||||
import SpinalRiscv.Plugin._
|
import SpinalRiscv.Plugin._
|
||||||
import SpinalRiscv._
|
import SpinalRiscv._
|
||||||
|
import SpinalRiscv.ip.{DataCacheConfig, InstructionCacheConfig}
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
import spinal.lib.bus.amba3.apb._
|
import spinal.lib.bus.amba3.apb._
|
||||||
|
@ -124,14 +125,55 @@ class Briey(config: BrieyConfig) extends Component{
|
||||||
val configLight = VexRiscvConfig(
|
val configLight = VexRiscvConfig(
|
||||||
plugins = List(
|
plugins = List(
|
||||||
new PcManagerSimplePlugin(0x00000000l, false),
|
new PcManagerSimplePlugin(0x00000000l, false),
|
||||||
new IBusSimplePlugin(
|
// new IBusSimplePlugin(
|
||||||
interfaceKeepData = false,
|
// interfaceKeepData = false,
|
||||||
catchAccessFault = false
|
// catchAccessFault = false
|
||||||
|
// ),
|
||||||
|
new IBusCachedPlugin(
|
||||||
|
config = InstructionCacheConfig(
|
||||||
|
cacheSize = 4096,
|
||||||
|
bytePerLine =32,
|
||||||
|
wayCount = 1,
|
||||||
|
wrappedMemAccess = true,
|
||||||
|
addressWidth = 32,
|
||||||
|
cpuDataWidth = 32,
|
||||||
|
memDataWidth = 32,
|
||||||
|
catchIllegalAccess = false,
|
||||||
|
catchAccessFault = false,
|
||||||
|
catchMemoryTranslationMiss = false,
|
||||||
|
asyncTagMemory = false,
|
||||||
|
twoStageLogic = true
|
||||||
|
)
|
||||||
|
// askMemoryTranslation = true,
|
||||||
|
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
|
// portTlbSize = 4
|
||||||
|
// )
|
||||||
),
|
),
|
||||||
new DBusSimplePlugin(
|
new DBusSimplePlugin(
|
||||||
catchAddressMisaligned = false,
|
catchAddressMisaligned = false,
|
||||||
catchAccessFault = false
|
catchAccessFault = false
|
||||||
),
|
),
|
||||||
|
// new DBusCachedPlugin(
|
||||||
|
// config = new DataCacheConfig(
|
||||||
|
// cacheSize = 4096,
|
||||||
|
// bytePerLine = 32,
|
||||||
|
// wayCount = 1,
|
||||||
|
// addressWidth = 32,
|
||||||
|
// cpuDataWidth = 32,
|
||||||
|
// memDataWidth = 32,
|
||||||
|
// catchAccessError = false,
|
||||||
|
// catchIllegal = false,
|
||||||
|
// catchUnaligned = false,
|
||||||
|
// catchMemoryTranslationMiss = false
|
||||||
|
// ),
|
||||||
|
// memoryTranslatorPortConfig = null
|
||||||
|
// // memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
|
// // portTlbSize = 6
|
||||||
|
// // )
|
||||||
|
// ),
|
||||||
|
// new StaticMemoryTranslatorPlugin(
|
||||||
|
// ioRange = _(31 downto 28) === 0xF
|
||||||
|
// ),
|
||||||
new DecoderSimplePlugin(
|
new DecoderSimplePlugin(
|
||||||
catchIllegalInstruction = false
|
catchIllegalInstruction = false
|
||||||
),
|
),
|
||||||
|
@ -168,7 +210,9 @@ class Briey(config: BrieyConfig) extends Component{
|
||||||
var debugBus : Apb3 = null
|
var debugBus : Apb3 = null
|
||||||
for(plugin <- configLight.plugins) plugin match{
|
for(plugin <- configLight.plugins) plugin match{
|
||||||
case plugin : IBusSimplePlugin => iBus = plugin.iBus.toAxi4ReadOnly()
|
case plugin : IBusSimplePlugin => iBus = plugin.iBus.toAxi4ReadOnly()
|
||||||
|
case plugin : IBusCachedPlugin => iBus = plugin.iBus.toAxi4ReadOnly()
|
||||||
case plugin : DBusSimplePlugin => dBus = plugin.dBus.toAxi4Shared()
|
case plugin : DBusSimplePlugin => dBus = plugin.dBus.toAxi4Shared()
|
||||||
|
case plugin : DBusCachedPlugin => dBus = plugin.dBus.toAxi4Shared()
|
||||||
case plugin : DebugPlugin => {
|
case plugin : DebugPlugin => {
|
||||||
resetCtrl.coreResetUnbuffered setWhen(plugin.io.resetOut)
|
resetCtrl.coreResetUnbuffered setWhen(plugin.io.resetOut)
|
||||||
debugBus = plugin.io.bus.toApb3()
|
debugBus = plugin.io.bus.toApb3()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package SpinalRiscv.ip
|
||||||
import SpinalRiscv._
|
import SpinalRiscv._
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.amba4.axi.{Axi4Shared, Axi4Config}
|
||||||
|
|
||||||
|
|
||||||
case class DataCacheConfig( cacheSize : Int,
|
case class DataCacheConfig( cacheSize : Int,
|
||||||
|
@ -20,6 +21,16 @@ case class DataCacheConfig( cacheSize : Int,
|
||||||
def burstSize = bytePerLine*8/memDataWidth
|
def burstSize = bytePerLine*8/memDataWidth
|
||||||
val burstLength = bytePerLine/(memDataWidth/8)
|
val burstLength = bytePerLine/(memDataWidth/8)
|
||||||
def catchSomething = catchUnaligned || catchMemoryTranslationMiss || catchIllegal || catchAccessError
|
def catchSomething = catchUnaligned || catchMemoryTranslationMiss || catchIllegal || catchAccessError
|
||||||
|
|
||||||
|
def getAxi4SharedConfig() = Axi4Config(
|
||||||
|
addressWidth = addressWidth,
|
||||||
|
dataWidth = memDataWidth,
|
||||||
|
useId = false,
|
||||||
|
useRegion = false,
|
||||||
|
useBurst = false,
|
||||||
|
useLock = false,
|
||||||
|
useQos = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,10 +141,12 @@ case class DataCacheCpuMemory(p : DataCacheConfig) extends Bundle with IMasterSl
|
||||||
val isValid = Bool
|
val isValid = Bool
|
||||||
val isStuck = Bool
|
val isStuck = Bool
|
||||||
val isRemoved = Bool
|
val isRemoved = Bool
|
||||||
|
val haltIt = Bool
|
||||||
val mmuBus = MemoryTranslatorBus()
|
val mmuBus = MemoryTranslatorBus()
|
||||||
|
|
||||||
override def asMaster(): Unit = {
|
override def asMaster(): Unit = {
|
||||||
out(isValid, isStuck, isRemoved)
|
out(isValid, isStuck, isRemoved)
|
||||||
|
in(haltIt)
|
||||||
slave(mmuBus)
|
slave(mmuBus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +186,7 @@ case class DataCacheMemCmd(p : DataCacheConfig) extends Bundle{
|
||||||
val address = UInt(p.addressWidth bit)
|
val address = UInt(p.addressWidth bit)
|
||||||
val data = Bits(p.memDataWidth bits)
|
val data = Bits(p.memDataWidth bits)
|
||||||
val mask = Bits(p.memDataWidth/8 bits)
|
val mask = Bits(p.memDataWidth/8 bits)
|
||||||
val length = UInt(log2Up(p.burstLength+1) bit)
|
val length = UInt(log2Up(p.burstLength) bits)
|
||||||
}
|
}
|
||||||
case class DataCacheMemRsp(p : DataCacheConfig) extends Bundle{
|
case class DataCacheMemRsp(p : DataCacheConfig) extends Bundle{
|
||||||
val data = Bits(p.memDataWidth bit)
|
val data = Bits(p.memDataWidth bit)
|
||||||
|
@ -188,6 +201,50 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
||||||
master(cmd)
|
master(cmd)
|
||||||
slave(rsp)
|
slave(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def toAxi4Shared(stageCmd : Boolean = false): Axi4Shared = {
|
||||||
|
val axi = Axi4Shared(p.getAxi4SharedConfig())
|
||||||
|
val pendingWritesMax = 7
|
||||||
|
val pendingWrites = CounterUpDown(
|
||||||
|
stateCount = pendingWritesMax + 1,
|
||||||
|
incWhen = axi.sharedCmd.fire && axi.sharedCmd.write,
|
||||||
|
decWhen = axi.writeRsp.fire
|
||||||
|
)
|
||||||
|
|
||||||
|
val cmdPreFork = if (stageCmd) cmd.stage.stage().s2mPipe() else cmd
|
||||||
|
val (cmdFork, dataFork) = StreamFork2(cmdPreFork.haltWhen((pendingWrites =/= 0 && !cmdPreFork.wr) || pendingWrites === pendingWritesMax))
|
||||||
|
axi.sharedCmd.arbitrationFrom(cmdFork)
|
||||||
|
axi.sharedCmd.write := cmdFork.wr
|
||||||
|
axi.sharedCmd.prot := "010"
|
||||||
|
axi.sharedCmd.cache := "1111"
|
||||||
|
axi.sharedCmd.size := log2Up(p.memDataWidth/8)
|
||||||
|
axi.sharedCmd.addr := cmdFork.address
|
||||||
|
axi.sharedCmd.len := cmdFork.length.resized
|
||||||
|
|
||||||
|
val dataStage = dataFork.throwWhen(!dataFork.wr)
|
||||||
|
axi.writeData.arbitrationFrom(dataStage)
|
||||||
|
axi.writeData.last := True
|
||||||
|
axi.writeData.data := dataStage.data
|
||||||
|
axi.writeData.strb := dataStage.mask
|
||||||
|
|
||||||
|
|
||||||
|
rsp.valid := axi.r.valid
|
||||||
|
rsp.error := !axi.r.isOKAY()
|
||||||
|
rsp.data := axi.r.data
|
||||||
|
|
||||||
|
axi.r.ready := True
|
||||||
|
axi.b.ready := True
|
||||||
|
|
||||||
|
|
||||||
|
//TODO remove
|
||||||
|
val axi2 = cloneOf(axi)
|
||||||
|
// axi.arw >/-> axi2.arw
|
||||||
|
// axi.w >/-> axi2.w
|
||||||
|
// axi.r <-/< axi2.r
|
||||||
|
// axi.b <-/< axi2.b
|
||||||
|
axi2 << axi
|
||||||
|
axi2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -349,10 +406,8 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
when(!dataReadRestored) {
|
when(!dataReadRestored) {
|
||||||
dataReadCmd.valid := True
|
dataReadCmd.valid := True
|
||||||
dataReadCmd.payload := way.dataReadRspOneAddress //Restore stage one readed value
|
dataReadCmd.payload := way.dataReadRspOneAddress //Restore stage one readed value
|
||||||
assert(io.cpu.memory.isStuck,"Should not issue instructions when a victim line is not entirly in the victim cache",FAILURE)
|
|
||||||
}
|
}
|
||||||
dataReadRestored := True
|
dataReadRestored := True
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +438,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
io.mem.cmd.valid := True
|
io.mem.cmd.valid := True
|
||||||
io.mem.cmd.wr := True
|
io.mem.cmd.wr := True
|
||||||
io.mem.cmd.address := request.address(tagRange.high downto lineRange.low) @@ U(0,lineRange.low bit)
|
io.mem.cmd.address := request.address(tagRange.high downto lineRange.low) @@ U(0,lineRange.low bit)
|
||||||
io.mem.cmd.length := p.burstLength
|
io.mem.cmd.length := p.burstLength-1
|
||||||
io.mem.cmd.data := bufferReaded.payload
|
io.mem.cmd.data := bufferReaded.payload
|
||||||
io.mem.cmd.mask := (1<<(wordWidth/8))-1
|
io.mem.cmd.mask := (1<<(wordWidth/8))-1
|
||||||
|
|
||||||
|
@ -412,6 +467,8 @@ 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.haltIt := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr && victim.request.valid && !victim.dataReadRestored
|
||||||
}
|
}
|
||||||
|
|
||||||
val stageB = new Area {
|
val stageB = new Area {
|
||||||
|
@ -498,7 +555,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0, wordRange.low bit)
|
io.mem.cmd.address := mmuRsp.physicalAddress(tagRange.high downto wordRange.low) @@ U(0, wordRange.low bit)
|
||||||
io.mem.cmd.mask := writeMask
|
io.mem.cmd.mask := writeMask
|
||||||
io.mem.cmd.data := request.data
|
io.mem.cmd.data := request.data
|
||||||
io.mem.cmd.length := 1
|
io.mem.cmd.length := 0
|
||||||
|
|
||||||
when(!memCmdSent) {
|
when(!memCmdSent) {
|
||||||
io.mem.cmd.valid := True
|
io.mem.cmd.valid := True
|
||||||
|
@ -548,7 +605,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
io.mem.cmd.valid := True
|
io.mem.cmd.valid := True
|
||||||
io.mem.cmd.wr := False
|
io.mem.cmd.wr := False
|
||||||
io.mem.cmd.address := baseAddress(tagRange.high downto lineRange.low) @@ U(0,lineRange.low bit)
|
io.mem.cmd.address := baseAddress(tagRange.high downto lineRange.low) @@ U(0,lineRange.low bit)
|
||||||
io.mem.cmd.length := p.burstLength
|
io.mem.cmd.length := p.burstLength-1
|
||||||
}
|
}
|
||||||
|
|
||||||
when(valid && io.mem.cmd.ready){
|
when(valid && io.mem.cmd.ready){
|
||||||
|
|
|
@ -3,6 +3,7 @@ package SpinalRiscv.ip
|
||||||
import SpinalRiscv._
|
import SpinalRiscv._
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.amba4.axi.{Axi4ReadOnly, Axi4Config}
|
||||||
|
|
||||||
|
|
||||||
case class InstructionCacheConfig( cacheSize : Int,
|
case class InstructionCacheConfig( cacheSize : Int,
|
||||||
|
@ -20,6 +21,15 @@ case class InstructionCacheConfig( cacheSize : Int,
|
||||||
def burstSize = bytePerLine*8/memDataWidth
|
def burstSize = bytePerLine*8/memDataWidth
|
||||||
def catchSomething = catchAccessFault || catchMemoryTranslationMiss || catchIllegalAccess
|
def catchSomething = catchAccessFault || catchMemoryTranslationMiss || catchIllegalAccess
|
||||||
|
|
||||||
|
def getAxi4Config() = Axi4Config(
|
||||||
|
addressWidth = addressWidth,
|
||||||
|
dataWidth = memDataWidth,
|
||||||
|
useId = false,
|
||||||
|
useRegion = false,
|
||||||
|
useLock = false,
|
||||||
|
useQos = false,
|
||||||
|
useSize = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +99,7 @@ case class InstructionCacheCpuBus(p : InstructionCacheConfig) extends Bundle wit
|
||||||
case class InstructionCacheMemCmd(p : InstructionCacheConfig) extends Bundle{
|
case class InstructionCacheMemCmd(p : InstructionCacheConfig) extends Bundle{
|
||||||
val address = UInt(p.addressWidth bit)
|
val address = UInt(p.addressWidth bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class InstructionCacheMemRsp(p : InstructionCacheConfig) extends Bundle{
|
case class InstructionCacheMemRsp(p : InstructionCacheConfig) extends Bundle{
|
||||||
val data = Bits(32 bit)
|
val data = Bits(32 bit)
|
||||||
val error = Bool
|
val error = Bool
|
||||||
|
@ -102,7 +113,29 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit
|
||||||
master(cmd)
|
master(cmd)
|
||||||
slave(rsp)
|
slave(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def toAxi4ReadOnly(): Axi4ReadOnly = {
|
||||||
|
val axiConfig = p.getAxi4Config()
|
||||||
|
val mm = Axi4ReadOnly(axiConfig)
|
||||||
|
|
||||||
|
mm.readCmd.valid := cmd.valid
|
||||||
|
mm.readCmd.len := p.burstSize-1
|
||||||
|
mm.readCmd.addr := cmd.address
|
||||||
|
mm.readCmd.prot := "110"
|
||||||
|
mm.readCmd.cache := "1111"
|
||||||
|
if(p.wrappedMemAccess)
|
||||||
|
mm.readCmd.setBurstWRAP()
|
||||||
|
else
|
||||||
|
mm.readCmd.setBurstINCR()
|
||||||
|
cmd.ready := mm.readCmd.ready
|
||||||
|
rsp.valid := mm.readRsp.valid
|
||||||
|
rsp.data := mm.readRsp.data
|
||||||
|
rsp.error := !mm.readRsp.isOKAY()
|
||||||
|
mm.readRsp.ready := True
|
||||||
|
mm
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case class InstructionCacheFlushBus() extends Bundle with IMasterSlave{
|
case class InstructionCacheFlushBus() extends Bundle with IMasterSlave{
|
||||||
val cmd = Event
|
val cmd = Event
|
||||||
|
|
|
@ -1,47 +1,56 @@
|
||||||
[*]
|
[*]
|
||||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||||
[*] Sun May 28 13:48:58 2017
|
[*] Wed May 31 17:28:39 2017
|
||||||
[*]
|
[*]
|
||||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/regression/debugPluginExternal.vcd"
|
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/regression/debugPluginExternal.vcd"
|
||||||
[dumpfile_mtime] "Sun May 28 12:59:45 2017"
|
[dumpfile_mtime] "Wed May 31 17:28:23 2017"
|
||||||
[dumpfile_size] 905973760
|
[dumpfile_size] 285487729
|
||||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/regression/fail.gtkw"
|
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/regression/fail.gtkw"
|
||||||
[timestart] 1181704
|
[timestart] 1754228
|
||||||
[size] 1776 953
|
[size] 1776 953
|
||||||
[pos] -1 -353
|
[pos] -775 -353
|
||||||
*-6.000000 1181914 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
*-5.000000 1754292 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||||
[treeopen] TOP.
|
[treeopen] TOP.
|
||||||
[sst_width] 201
|
[treeopen] TOP.VexRiscv.
|
||||||
[signals_width] 392
|
[sst_width] 264
|
||||||
|
[signals_width] 416
|
||||||
[sst_expanded] 1
|
[sst_expanded] 1
|
||||||
[sst_vpaned_height] 279
|
[sst_vpaned_height] 279
|
||||||
@22
|
|
||||||
TOP.VexRiscv.DebugPlugin_busReadDataReg[31:0]
|
|
||||||
@28
|
@28
|
||||||
TOP.VexRiscv.DebugPlugin_firstCycle
|
|
||||||
TOP.VexRiscv.DebugPlugin_haltIt
|
TOP.VexRiscv.DebugPlugin_haltIt
|
||||||
TOP.VexRiscv.DebugPlugin_haltedByBreak
|
|
||||||
TOP.VexRiscv.DebugPlugin_insertDecodeInstruction
|
TOP.VexRiscv.DebugPlugin_insertDecodeInstruction
|
||||||
TOP.VexRiscv.DebugPlugin_isPipActive
|
TOP.VexRiscv.DebugPlugin_isPipActive
|
||||||
TOP.VexRiscv.DebugPlugin_isPipBusy
|
TOP.VexRiscv.DebugPlugin_isPipBusy
|
||||||
TOP.VexRiscv.DebugPlugin_resetIt
|
|
||||||
TOP.VexRiscv.DebugPlugin_stepIt
|
|
||||||
TOP.VexRiscv.debugReset
|
|
||||||
@22
|
|
||||||
TOP.VexRiscv.debug_bus_cmd_payload_address[7:0]
|
|
||||||
TOP.VexRiscv.debug_bus_cmd_payload_data[31:0]
|
|
||||||
@28
|
|
||||||
TOP.VexRiscv.debug_bus_cmd_payload_wr
|
|
||||||
@29
|
|
||||||
TOP.VexRiscv.debug_bus_cmd_ready
|
|
||||||
@28
|
|
||||||
TOP.VexRiscv.debug_bus_cmd_valid
|
|
||||||
@22
|
|
||||||
TOP.VexRiscv.debug_bus_rsp_data[31:0]
|
|
||||||
@28
|
|
||||||
TOP.VexRiscv.debug_resetOut
|
|
||||||
TOP.VexRiscv.decode_LEGAL_INSTRUCTION
|
|
||||||
TOP.VexRiscv.CsrPlugin_exception
|
|
||||||
TOP.VexRiscv.clk
|
TOP.VexRiscv.clk
|
||||||
|
@22
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_address[31:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_clean
|
||||||
|
@22
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_data[31:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_forceUncachedAccess
|
||||||
|
@29
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_invalidate
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_kind[0]
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_size[1:0]
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_way
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_wr
|
||||||
|
TOP.VexRiscv.dataCache_1.io_cpu_execute_isValid
|
||||||
|
@22
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_address[31:0]
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_data[31:0]
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_length[3:0]
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_mask[3:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_wr
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_ready
|
||||||
|
TOP.VexRiscv.dataCache_1.io_mem_cmd_valid
|
||||||
|
@22
|
||||||
|
TOP.VexRiscv.dataCache_1.victim_request_payload_address[31:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.dataCache_1.victim_request_ready
|
||||||
|
TOP.VexRiscv.dataCache_1.victim_request_valid
|
||||||
[pattern_trace] 1
|
[pattern_trace] 1
|
||||||
[pattern_trace] 0
|
[pattern_trace] 0
|
||||||
|
|
|
@ -591,7 +591,7 @@ public:
|
||||||
virtual void preCycle(){
|
virtual void preCycle(){
|
||||||
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
|
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
|
||||||
if(pendingCount == 0){
|
if(pendingCount == 0){
|
||||||
pendingCount = top->dBus_cmd_payload_length;
|
pendingCount = top->dBus_cmd_payload_length+1;
|
||||||
address = top->dBus_cmd_payload_address;
|
address = top->dBus_cmd_payload_address;
|
||||||
wr = top->dBus_cmd_payload_wr;
|
wr = top->dBus_cmd_payload_wr;
|
||||||
}
|
}
|
||||||
|
@ -1214,7 +1214,7 @@ int main(int argc, char **argv, char **env) {
|
||||||
w.loadHex("../../resources/hex/debugPluginExternal.hex");
|
w.loadHex("../../resources/hex/debugPluginExternal.hex");
|
||||||
w.noInstructionReadCheck();
|
w.noInstructionReadCheck();
|
||||||
#if defined(TRACE) || defined(TRACE_ACCESS)
|
#if defined(TRACE) || defined(TRACE_ACCESS)
|
||||||
//w.setCyclesPerSecond(5e3);
|
w.setCyclesPerSecond(5e3);
|
||||||
printf("Speed reduced 5Khz\n");
|
printf("Speed reduced 5Khz\n");
|
||||||
#endif
|
#endif
|
||||||
w.run(1e9);
|
w.run(1e9);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
IBUS=IBUS_SIMPLE
|
IBUS=IBUS_CACHED
|
||||||
DBUS=DBUS_SIMPLE
|
DBUS=DBUS_CACHED
|
||||||
TRACE?=no
|
TRACE?=no
|
||||||
TRACE_ACCESS?=no
|
TRACE_ACCESS?=no
|
||||||
TRACE_START=0
|
TRACE_START=0
|
||||||
CSR=yes
|
CSR=yes
|
||||||
MMU=no
|
MMU=yes
|
||||||
DEBUG_PLUGIN=yes
|
DEBUG_PLUGIN=yes
|
||||||
DEBUG_PLUGIN_EXTERNAL?=no
|
DEBUG_PLUGIN_EXTERNAL?=no
|
||||||
DHRYSTONE=yes
|
DHRYSTONE=yes
|
||||||
|
|
Loading…
Reference in New Issue