Instruction cache is now able to catch bus errors
This commit is contained in:
parent
95585b4d9a
commit
19fe998a52
|
@ -11,7 +11,8 @@ case class InstructionCacheConfig( cacheSize : Int,
|
||||||
wrappedMemAccess : Boolean,
|
wrappedMemAccess : Boolean,
|
||||||
addressWidth : Int,
|
addressWidth : Int,
|
||||||
cpuDataWidth : Int,
|
cpuDataWidth : Int,
|
||||||
memDataWidth : Int){
|
memDataWidth : Int,
|
||||||
|
catchAccessFault : Boolean){
|
||||||
def burstSize = bytePerLine*8/memDataWidth
|
def burstSize = bytePerLine*8/memDataWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +37,6 @@ class IBusCachedPlugin(catchAccessFault : Boolean, cacheConfig : InstructionCach
|
||||||
import pipeline._
|
import pipeline._
|
||||||
import pipeline.config._
|
import pipeline.config._
|
||||||
|
|
||||||
assert(catchAccessFault == false) //unimplemented
|
|
||||||
|
|
||||||
|
|
||||||
val cache = new InstructionCache(cacheConfig)
|
val cache = new InstructionCache(cacheConfig)
|
||||||
iBus = master(new InstructionCacheMemBus(cacheConfig)).setName("iBus")
|
iBus = master(new InstructionCacheMemBus(cacheConfig)).setName("iBus")
|
||||||
iBus <> cache.io.mem
|
iBus <> cache.io.mem
|
||||||
|
@ -59,13 +57,14 @@ class IBusCachedPlugin(catchAccessFault : Boolean, cacheConfig : InstructionCach
|
||||||
|
|
||||||
cache.io.flush.cmd.valid := False
|
cache.io.flush.cmd.valid := False
|
||||||
|
|
||||||
// fetch.insert(IBUS_ACCESS_ERROR) := iRsp.error
|
|
||||||
|
|
||||||
// if(catchAccessFault){
|
if(catchAccessFault){
|
||||||
// decodeExceptionPort.valid := decode.arbitration.isValid && decode.input(IBUS_ACCESS_ERROR)
|
fetch.insert(IBUS_ACCESS_ERROR) := cache.io.cpu.rsp.error
|
||||||
// decodeExceptionPort.code := 1
|
|
||||||
// decodeExceptionPort.badAddr := decode.input(PC)
|
decodeExceptionPort.valid := decode.arbitration.isValid && decode.input(IBUS_ACCESS_ERROR)
|
||||||
// }
|
decodeExceptionPort.code := 1
|
||||||
|
decodeExceptionPort.badAddr := decode.input(PC)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +88,12 @@ case class InstructionCacheCpuRsp(p : InstructionCacheConfig) extends Bundle wit
|
||||||
val isStuck = Bool
|
val isStuck = Bool
|
||||||
val address = UInt(p.addressWidth bit)
|
val address = UInt(p.addressWidth bit)
|
||||||
val data = Bits(32 bit)
|
val data = Bits(32 bit)
|
||||||
|
val error = if(p.catchAccessFault) Bool else null
|
||||||
|
|
||||||
override def asMaster(): Unit = {
|
override def asMaster(): Unit = {
|
||||||
out(isValid, isStuck, address)
|
out(isValid, isStuck, address)
|
||||||
in(haltIt, data)
|
in(haltIt, data)
|
||||||
|
if(p.catchAccessFault) in(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +108,24 @@ case class InstructionCacheCpuBus(p : InstructionCacheConfig) extends Bundle wit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class InstructionCacheTranslationBus(p : InstructionCacheConfig) extends Bundle with IMasterSlave{
|
||||||
|
val virtualAddress = UInt(32 bits)
|
||||||
|
val physicalAddress = UInt(32 bits)
|
||||||
|
val error = if(p.catchAccessFault) Bool else null
|
||||||
|
|
||||||
|
override def asMaster(): Unit = {
|
||||||
|
out(virtualAddress)
|
||||||
|
in(physicalAddress)
|
||||||
|
if(p.catchAccessFault) in(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 = if(p.catchAccessFault) Bool else null
|
||||||
}
|
}
|
||||||
|
|
||||||
case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle with IMasterSlave{
|
case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle with IMasterSlave{
|
||||||
|
@ -141,6 +154,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
assert(cpuDataWidth == memDataWidth)
|
assert(cpuDataWidth == memDataWidth)
|
||||||
val io = new Bundle{
|
val io = new Bundle{
|
||||||
val flush = slave(InstructionCacheFlushBus())
|
val flush = slave(InstructionCacheFlushBus())
|
||||||
|
// val translator = master(InstructionCacheTranslationBus(p))
|
||||||
val cpu = slave(InstructionCacheCpuBus(p))
|
val cpu = slave(InstructionCacheCpuBus(p))
|
||||||
val mem = master(InstructionCacheMemBus(p))
|
val mem = master(InstructionCacheMemBus(p))
|
||||||
}
|
}
|
||||||
|
@ -158,16 +172,22 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
val tagRange = addressWidth-1 downto log2Up(wayLineCount*bytePerLine)
|
val tagRange = addressWidth-1 downto log2Up(wayLineCount*bytePerLine)
|
||||||
val lineRange = tagRange.low-1 downto log2Up(bytePerLine)
|
val lineRange = tagRange.low-1 downto log2Up(bytePerLine)
|
||||||
val wordRange = log2Up(bytePerLine)-1 downto log2Up(bytePerWord)
|
val wordRange = log2Up(bytePerLine)-1 downto log2Up(bytePerWord)
|
||||||
|
val tagLineRange = tagRange.high downto lineRange.low
|
||||||
|
|
||||||
|
class LineInfo extends Bundle{
|
||||||
class LineInfo() extends Bundle{
|
|
||||||
val valid = Bool
|
val valid = Bool
|
||||||
|
val error = if(catchAccessFault) Bool else null
|
||||||
val address = UInt(tagRange.length bit)
|
val address = UInt(tagRange.length bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// class LineWord extends Bundle{
|
||||||
|
// val data = Bits(wordWidth bits)
|
||||||
|
// val error = Bool
|
||||||
|
// }
|
||||||
|
|
||||||
val ways = Array.fill(wayCount)(new Area{
|
val ways = Array.fill(wayCount)(new Area{
|
||||||
val tags = Mem(new LineInfo(),wayLineCount)
|
val tags = Mem(new LineInfo(),wayLineCount)
|
||||||
val datas = Mem(Bits(wordWidth bit),wayWordCount)
|
val datas = Mem(Bits(wordWidth bits),wayWordCount)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,7 +195,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
|
|
||||||
val lineLoader = new Area{
|
val lineLoader = new Area{
|
||||||
val requestIn = Stream(wrap(new Bundle{
|
val requestIn = Stream(wrap(new Bundle{
|
||||||
val addr = UInt(addressWidth bit)
|
val addr = UInt(addressWidth bits)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,46 +224,61 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
|
|
||||||
io.flush.rsp := flushCounter.msb.rise && flushFromInterface
|
io.flush.rsp := flushCounter.msb.rise && flushFromInterface
|
||||||
|
|
||||||
val lineInfoWrite = new LineInfo()
|
val loadingWithErrorReg = if(catchAccessFault) RegInit(False) else null
|
||||||
lineInfoWrite.valid := flushCounter.msb
|
val loadingWithError = if(catchAccessFault) loadingWithErrorReg else null
|
||||||
lineInfoWrite.address := requestIn.addr(tagRange)
|
if(catchAccessFault) loadingWithErrorReg := loadingWithError
|
||||||
when(requestIn.fire || !flushCounter.msb){
|
|
||||||
val tagsAddress = Mux(flushCounter.msb,requestIn.addr(lineRange),flushCounter(flushCounter.high-1 downto 0))
|
|
||||||
ways(0).tags(tagsAddress) := lineInfoWrite //TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val request = requestIn.haltWhen(!io.mem.cmd.ready).stage()
|
val request = requestIn.haltWhen(!io.mem.cmd.ready).stage()
|
||||||
|
|
||||||
|
val lineInfoWrite = new LineInfo()
|
||||||
|
lineInfoWrite.valid := flushCounter.msb
|
||||||
|
lineInfoWrite.address := request.addr(tagRange)
|
||||||
|
if(catchAccessFault) lineInfoWrite.error := loadingWithError
|
||||||
|
|
||||||
|
|
||||||
io.mem.cmd.valid := requestIn.valid && !request.isStall
|
io.mem.cmd.valid := requestIn.valid && !request.isStall
|
||||||
val wordIndex = Reg(UInt(log2Up(wordPerLine) bit))
|
val wordIndex = Reg(UInt(log2Up(wordPerLine) bit))
|
||||||
val loadedWordsNext = Bits(wordPerLine bit)
|
val loadedWordsNext = Bits(wordPerLine bit)
|
||||||
val loadedWords = RegNext(loadedWordsNext)
|
val loadedWords = RegNext(loadedWordsNext)
|
||||||
val loadedWordsReadable = RegNext(loadedWords)
|
val loadedWordsReadable = RegNext(loadedWords)
|
||||||
loadedWordsNext := loadedWords
|
loadedWordsNext := loadedWords
|
||||||
when(io.mem.rsp.fire){
|
when(io.mem.rsp.valid){
|
||||||
wordIndex := wordIndex + 1
|
wordIndex := wordIndex + 1
|
||||||
loadedWordsNext(wordIndex) := True
|
loadedWordsNext(wordIndex) := True
|
||||||
ways(0).datas(request.addr(lineRange) @@ wordIndex) := io.mem.rsp.data //TODO
|
ways(0).datas(request.addr(lineRange) @@ wordIndex) := io.mem.rsp.data //TODO
|
||||||
|
if(catchAccessFault) loadingWithError setWhen io.mem.rsp.error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val memRspLast = loadedWordsNext === B(loadedWordsNext.range -> true)
|
||||||
|
|
||||||
val readyDelay = Reg(UInt(1 bit))
|
val readyDelay = Reg(UInt(1 bit))
|
||||||
when(loadedWordsNext === B(loadedWordsNext.range -> true)){
|
when(memRspLast){
|
||||||
readyDelay := readyDelay + 1
|
readyDelay := readyDelay + 1
|
||||||
}
|
}
|
||||||
request.ready := readyDelay === 1
|
request.ready := readyDelay === 1
|
||||||
|
|
||||||
|
|
||||||
|
when((request.valid && memRspLast) || !flushCounter.msb){
|
||||||
|
val tagsAddress = Mux(flushCounter.msb,request.addr(lineRange),flushCounter(flushCounter.high-1 downto 0))
|
||||||
|
ways(0).tags(tagsAddress) := lineInfoWrite //TODO
|
||||||
|
}
|
||||||
|
|
||||||
when(requestIn.ready){
|
when(requestIn.ready){
|
||||||
wordIndex := io.mem.cmd.address(wordRange)
|
wordIndex := io.mem.cmd.address(wordRange)
|
||||||
loadedWords := 0
|
loadedWords := 0
|
||||||
loadedWordsReadable := 0
|
loadedWordsReadable := 0
|
||||||
readyDelay := 0
|
readyDelay := 0
|
||||||
|
if(catchAccessFault) loadingWithErrorReg := False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val task = new Area{
|
val task = new Area{
|
||||||
val waysHitValid = False
|
val waysHitValid = False
|
||||||
|
val waysHitError = Bool.assignDontCare()
|
||||||
val waysHitWord = Bits(wordWidth bit)
|
val waysHitWord = Bits(wordWidth bit)
|
||||||
waysHitWord.assignDontCare()
|
// waysHitWord.assignDontCare()
|
||||||
|
|
||||||
val waysRead = for(way <- ways) yield new Area{
|
val waysRead = for(way <- ways) yield new Area{
|
||||||
val readAddress = Mux(io.cpu.rsp.isStuck,io.cpu.rsp.address,io.cpu.cmd.address)
|
val readAddress = Mux(io.cpu.rsp.isStuck,io.cpu.rsp.address,io.cpu.cmd.address)
|
||||||
|
@ -254,18 +289,25 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
// val data = way.datas.readAsync(readAddress(lineRange.high downto wordRange.low))
|
// val data = way.datas.readAsync(readAddress(lineRange.high downto wordRange.low))
|
||||||
// way.tags.add(new AttributeString("ramstyle","no_rw_check"))
|
// way.tags.add(new AttributeString("ramstyle","no_rw_check"))
|
||||||
// way.datas.add(new AttributeString("ramstyle","no_rw_check"))
|
// way.datas.add(new AttributeString("ramstyle","no_rw_check"))
|
||||||
|
waysHitWord := data //Not applicable to multi way
|
||||||
when(tag.valid && tag.address === io.cpu.rsp.address(tagRange)) {
|
when(tag.valid && tag.address === io.cpu.rsp.address(tagRange)) {
|
||||||
waysHitValid := True
|
waysHitValid := True
|
||||||
waysHitWord := data
|
if(catchAccessFault) waysHitError := tag.error
|
||||||
|
}
|
||||||
|
|
||||||
|
when(lineLoader.request.valid && lineLoader.request.addr(lineRange) === io.cpu.rsp.address(lineRange)){
|
||||||
|
waysHitValid := False //Not applicable to multi way
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val loaderHitValid = lineLoader.request.valid && lineLoader.request.addr(tagRange) === io.cpu.rsp.address(tagRange)
|
|
||||||
|
val loaderHitValid = lineLoader.request.valid && lineLoader.request.addr(tagLineRange) === io.cpu.rsp.address(tagLineRange)
|
||||||
val loaderHitReady = lineLoader.loadedWordsReadable(io.cpu.rsp.address(wordRange))
|
val loaderHitReady = lineLoader.loadedWordsReadable(io.cpu.rsp.address(wordRange))
|
||||||
|
|
||||||
|
|
||||||
io.cpu.rsp.haltIt := io.cpu.rsp.isValid && !( waysHitValid && !(loaderHitValid && !loaderHitReady))
|
io.cpu.rsp.haltIt := io.cpu.rsp.isValid && !(waysHitValid || (loaderHitValid && loaderHitReady))
|
||||||
io.cpu.rsp.data := waysHitWord //TODO
|
io.cpu.rsp.data := waysHitWord //TODO
|
||||||
|
if(catchAccessFault) io.cpu.rsp.error := (waysHitValid && waysHitError) || (loaderHitValid && loaderHitReady && lineLoader.loadingWithErrorReg)
|
||||||
lineLoader.requestIn.valid := io.cpu.rsp.isValid && ! waysHitValid
|
lineLoader.requestIn.valid := io.cpu.rsp.isValid && ! waysHitValid
|
||||||
lineLoader.requestIn.addr := io.cpu.rsp.address
|
lineLoader.requestIn.addr := io.cpu.rsp.address
|
||||||
}
|
}
|
||||||
|
@ -274,30 +316,7 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
object InstructionCacheMain{
|
object InstructionCacheMain{
|
||||||
class TopLevel extends Component{
|
|
||||||
implicit val p = InstructionCacheConfig(
|
|
||||||
cacheSize =4096,
|
|
||||||
bytePerLine =32,
|
|
||||||
wayCount = 1,
|
|
||||||
wrappedMemAccess = true,
|
|
||||||
addressWidth = 32,
|
|
||||||
cpuDataWidth = 32,
|
|
||||||
memDataWidth = 32)
|
|
||||||
// val io = new Bundle{
|
|
||||||
// val cpu = slave(InstructionCacheCpuBus())
|
|
||||||
// val mem = master(InstructionCacheMemBus())
|
|
||||||
// }
|
|
||||||
val cache = new InstructionCache(p)
|
|
||||||
|
|
||||||
// cache.io.cpu.cmd <-< io.cpu.cmd
|
|
||||||
// cache.io.mem.cmd >-> io.mem.cmd
|
|
||||||
// cache.io.mem.rsp <-< io.mem.rsp
|
|
||||||
// cache.io.cpu.rsp >-> io.cpu.rsp
|
|
||||||
// when(cache.io.cpu.rsp.valid){
|
|
||||||
// cache.io.cpu.cmd.valid := RegNext(cache.io.cpu.cmd.valid)
|
|
||||||
// cache.io.cpu.cmd.address := RegNext(cache.io.cpu.cmd.address)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
def main(args: Array[String]) {
|
def main(args: Array[String]) {
|
||||||
implicit val p = InstructionCacheConfig(
|
implicit val p = InstructionCacheConfig(
|
||||||
cacheSize =4096,
|
cacheSize =4096,
|
||||||
|
@ -306,7 +325,8 @@ object InstructionCacheMain{
|
||||||
wrappedMemAccess = true,
|
wrappedMemAccess = true,
|
||||||
addressWidth = 32,
|
addressWidth = 32,
|
||||||
cpuDataWidth = 32,
|
cpuDataWidth = 32,
|
||||||
memDataWidth = 32)
|
memDataWidth = 32,
|
||||||
|
catchAccessFault = true)
|
||||||
// val io = new Bundle{
|
// val io = new Bundle{
|
||||||
// val cpu = slave(InstructionCacheCpuBus())
|
// val cpu = slave(InstructionCacheCpuBus())
|
||||||
// val mem = master(InstructionCacheMemBus())
|
// val mem = master(InstructionCacheMemBus())
|
||||||
|
|
|
@ -84,7 +84,7 @@ object TopLevel {
|
||||||
// catchAccessFault = true
|
// catchAccessFault = true
|
||||||
// ),
|
// ),
|
||||||
new IBusCachedPlugin(
|
new IBusCachedPlugin(
|
||||||
catchAccessFault = false,
|
catchAccessFault = true,//DUPLICATION
|
||||||
cacheConfig = InstructionCacheConfig(
|
cacheConfig = InstructionCacheConfig(
|
||||||
cacheSize =4096,
|
cacheSize =4096,
|
||||||
bytePerLine =32,
|
bytePerLine =32,
|
||||||
|
@ -92,7 +92,8 @@ object TopLevel {
|
||||||
wrappedMemAccess = true,
|
wrappedMemAccess = true,
|
||||||
addressWidth = 32,
|
addressWidth = 32,
|
||||||
cpuDataWidth = 32,
|
cpuDataWidth = 32,
|
||||||
memDataWidth = 32
|
memDataWidth = 32,
|
||||||
|
catchAccessFault = true //DUPLICATION
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new DecoderSimplePlugin(
|
new DecoderSimplePlugin(
|
||||||
|
@ -156,7 +157,9 @@ object TopLevel {
|
||||||
// )
|
// )
|
||||||
|
|
||||||
val toplevel = new VexRiscv(config)
|
val toplevel = new VexRiscv(config)
|
||||||
|
toplevel.decode.input(config.INSTRUCTION).addAttribute("verilator public")
|
||||||
|
toplevel.decode.input(config.PC).addAttribute("verilator public")
|
||||||
|
toplevel.decode.arbitration.isValid.addAttribute("verilator public")
|
||||||
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
|
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
|
||||||
|
|
||||||
toplevel
|
toplevel
|
||||||
|
|
|
@ -1,45 +1,50 @@
|
||||||
[*]
|
[*]
|
||||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||||
[*] Sat Mar 25 22:06:00 2017
|
[*] Thu Mar 30 15:00:10 2017
|
||||||
[*]
|
[*]
|
||||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3.vcd"
|
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3.vcd"
|
||||||
[dumpfile_mtime] "Sat Mar 25 22:05:31 2017"
|
[dumpfile_mtime] "Thu Mar 30 14:59:57 2017"
|
||||||
[dumpfile_size] 414222144
|
[dumpfile_size] 1227579722
|
||||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
|
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
|
||||||
[timestart] 60961
|
[timestart] 555551
|
||||||
[size] 1000 600
|
[size] 1776 953
|
||||||
[pos] -1 -1
|
[pos] -1 -1
|
||||||
*-7.000000 61271 -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
|
*-2.000000 555567 -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] 571
|
[sst_width] 378
|
||||||
|
[signals_width] 418
|
||||||
[sst_expanded] 1
|
[sst_expanded] 1
|
||||||
[sst_vpaned_height] 155
|
[sst_vpaned_height] 279
|
||||||
@28
|
@28
|
||||||
TOP.VexRiscv.decode_EXCEPTION
|
TOP.VexRiscv.clk
|
||||||
TOP.VexRiscv.execute_EXCEPTION
|
TOP.VexRiscv.decode_arbitration_isValid
|
||||||
TOP.VexRiscv.memory_EXCEPTION
|
|
||||||
TOP.VexRiscv.writeBack_EXCEPTION
|
|
||||||
TOP.VexRiscv.execute_arbitration_isValid
|
|
||||||
TOP.VexRiscv.execute_MEMORY_ENABLE
|
|
||||||
@22
|
@22
|
||||||
TOP.VexRiscv.execute_PC[31:0]
|
TOP.VexRiscv.decode_PC[31:0]
|
||||||
TOP.VexRiscv.RegFilePlugin_regFile(8)[31:0]
|
TOP.VexRiscv.decode_INSTRUCTION[31:0]
|
||||||
@28
|
@28
|
||||||
TOP.VexRiscv.writeBack_arbitration_isValid
|
TOP.VexRiscv.decode_LEGAL_INSTRUCTION
|
||||||
@23
|
|
||||||
TOP.VexRiscv.writeBack_PC[31:0]
|
|
||||||
@28
|
|
||||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid
|
|
||||||
@22
|
@22
|
||||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0]
|
TOP.VexRiscv.instructionCache_1.io_cpu_cmd_address[31:0]
|
||||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0]
|
|
||||||
TOP.VexRiscv.dCmd_payload_address[31:0]
|
|
||||||
TOP.VexRiscv.dCmd_payload_data[31:0]
|
|
||||||
@28
|
@28
|
||||||
TOP.VexRiscv.dCmd_payload_size[1:0]
|
TOP.VexRiscv.instructionCache_1.io_cpu_cmd_haltIt
|
||||||
TOP.VexRiscv.dCmd_payload_wr
|
@22
|
||||||
TOP.VexRiscv.dCmd_ready
|
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_address[31:0]
|
||||||
TOP.VexRiscv.dCmd_valid
|
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_data[31:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_haltIt
|
||||||
|
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_isStuck
|
||||||
|
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_isValid
|
||||||
|
TOP.VexRiscv.instructionCache_1.task_loaderHitReady
|
||||||
|
@29
|
||||||
|
TOP.VexRiscv.instructionCache_1.task_loaderHitValid
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.instructionCache_1.task_waysHitValid
|
||||||
|
@22
|
||||||
|
TOP.VexRiscv.instructionCache_1.task_waysHitWord[31:0]
|
||||||
|
TOP.VexRiscv.instructionCache_1.lineLoader_request_payload_addr[31:0]
|
||||||
|
@28
|
||||||
|
TOP.VexRiscv.instructionCache_1.lineLoader_request_ready
|
||||||
|
TOP.VexRiscv.instructionCache_1.lineLoader_request_valid
|
||||||
[pattern_trace] 1
|
[pattern_trace] 1
|
||||||
[pattern_trace] 0
|
[pattern_trace] 0
|
||||||
|
|
|
@ -342,6 +342,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
for(SimElement* simElement : simElements) simElement->preCycle();
|
for(SimElement* simElement : simElements) simElement->preCycle();
|
||||||
|
|
||||||
|
if(top->VexRiscv->decode_arbitration_isValid){
|
||||||
|
uint32_t expectedData;
|
||||||
|
bool dummy;
|
||||||
|
iBusAccess(top->VexRiscv->decode_PC, &expectedData, &dummy);
|
||||||
|
assertEq(top->VexRiscv->decode_INSTRUCTION,expectedData);
|
||||||
|
}
|
||||||
|
|
||||||
checks();
|
checks();
|
||||||
top->clk = 1;
|
top->clk = 1;
|
||||||
top->eval();
|
top->eval();
|
||||||
|
@ -459,10 +467,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void postCycle(){
|
virtual void postCycle(){
|
||||||
bool dummy;
|
bool error;
|
||||||
top->iBus_rsp_valid = 0;
|
top->iBus_rsp_valid = 0;
|
||||||
if(pendingCount != 0 && (!ws->iStall || VL_RANDOM_I(8) < 100)){
|
if(pendingCount != 0 && (!ws->iStall || VL_RANDOM_I(8) < 100)){
|
||||||
ws->iBusAccess(address,&top->iBus_rsp_payload_data,&dummy);
|
ws->iBusAccess(address,&top->iBus_rsp_payload_data,&error);
|
||||||
|
top->iBus_rsp_payload_error = error;
|
||||||
pendingCount--;
|
pendingCount--;
|
||||||
address = (address & ~0x1F) + ((address + 4) & 0x1F);
|
address = (address & ~0x1F) + ((address + 4) & 0x1F);
|
||||||
top->iBus_rsp_valid = 1;
|
top->iBus_rsp_valid = 1;
|
||||||
|
|
Loading…
Reference in New Issue