Smaller and faster single stage instruction cache

Add fast two stage instruction cache
Remove useless address == 0 checks in the HazardPlugin
This commit is contained in:
Charles Papon 2017-04-13 18:27:03 +02:00
parent c83a157c64
commit 024e14ae58
10 changed files with 227 additions and 182 deletions

View File

@ -128,7 +128,7 @@ class BranchPlugin(earlyBranch : Boolean,
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
}
if(catchAddressMisaligned) {
if(catchAddressMisaligned) { //TODO conflict with instruction cache two stage
branchExceptionPort.valid := arbitration.isValid && input(BRANCH_DO) && jumpInterface.payload(1 downto 0) =/= 0
branchExceptionPort.code := 0
branchExceptionPort.badAddr := jumpInterface.payload
@ -180,7 +180,7 @@ class BranchPlugin(earlyBranch : Boolean,
}
if(catchAddressMisaligned) {
predictionExceptionPort.valid := input(PREDICTION_HAD_BRANCHED) && arbitration.isValid && predictionJumpInterface.payload(1 downto 0) =/= 0
predictionExceptionPort.valid := input(INSTRUCTION_READY) && input(PREDICTION_HAD_BRANCHED) && arbitration.isValid && predictionJumpInterface.payload(1 downto 0) =/= 0
predictionExceptionPort.code := 0
predictionExceptionPort.badAddr := predictionJumpInterface.payload
}
@ -236,7 +236,7 @@ class BranchPlugin(earlyBranch : Boolean,
}
if(catchAddressMisaligned) {
branchExceptionPort.valid := arbitration.isValid && input(BRANCH_DO) && jumpInterface.payload(1 downto 0) =/= 0
branchExceptionPort.valid := input(INSTRUCTION_READY) && arbitration.isValid && input(BRANCH_DO) && jumpInterface.payload(1 downto 0) =/= 0
branchExceptionPort.code := 0
branchExceptionPort.badAddr := jumpInterface.payload
}

View File

@ -131,7 +131,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean) extends Plugin[VexR
if(catchIllegalInstruction){
decodeExceptionPort.valid := arbitration.isValid && arbitration.haltIt && !input(LEGAL_INSTRUCTION) //HalitIt to alow decoder stage to wait valid data from 2 stages cache cache
decodeExceptionPort.valid := arbitration.isValid && arbitration.haltIt && input(INSTRUCTION_READY) && !input(LEGAL_INSTRUCTION) //HalitIt to alow decoder stage to wait valid data from 2 stages cache cache
decodeExceptionPort.code := 2
decodeExceptionPort.badAddr.assignDontCare()
}

View File

@ -82,12 +82,14 @@ class HazardSimplePlugin(bypassExecute : Boolean,
trackHazardWithStage(execute ,bypassExecute ,BYPASSABLE_EXECUTE_STAGE)
when(decode.input(INSTRUCTION)(rs1Range) === 0 || (if(pessimisticUseSrc) False else !decode.input(REG1_USE))){
if(!pessimisticUseSrc) {
when(!decode.input(REG1_USE)) {
src0Hazard := False
}
when(decode.input(INSTRUCTION)(rs2Range) === 0 || (if(pessimisticUseSrc) False else !decode.input(REG2_USE))){
when(!decode.input(REG2_USE)) {
src1Hazard := False
}
}
when(decode.arbitration.isValid && (src0Hazard || src1Hazard)){
decode.arbitration.haltIt := True

View File

@ -61,6 +61,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv]
fetch.arbitration.haltIt setWhen (cache.io.cpu.fetch.haltIt)
fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
decode.insert(INSTRUCTION_READY) := True
}
cache.io.flush.cmd.valid := False
@ -72,11 +73,13 @@ class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv]
cache.io.cpu.decode.address := decode.input(PC)
decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
decode.insert(INSTRUCTION_ANTICIPATED) := cache.io.cpu.decode.dataAnticipated
decode.insert(INSTRUCTION_READY) := !cache.io.cpu.decode.haltIt
}
if(catchAccessFault){
if(!twoStageLogic) fetch.insert(IBUS_ACCESS_ERROR) := cache.io.cpu.fetch.error
if( twoStageLogic) decode.insert(IBUS_ACCESS_ERROR) := cache.io.cpu.decode.error
decodeExceptionPort.valid := decode.arbitration.isValid && decode.input(IBUS_ACCESS_ERROR)
decodeExceptionPort.code := 1
@ -105,7 +108,7 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
val isStuck = Bool
val isStuckByOthers = if(!p.twoStageLogic) Bool else null
val address = UInt(p.addressWidth bit)
val data = Bits(32 bit) //If twoStageLogic == true, this signal is acurate only when there is the cache doesn't stall decode (Used for Sync regfile)
val data = if(!p.twoStageLogic) Bits(32 bit) else null
val error = if(!p.twoStageLogic && p.catchAccessFault) Bool else null
override def asMaster(): Unit = {
@ -209,13 +212,26 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val lineRange = tagRange.low-1 downto log2Up(bytePerLine)
val wordRange = log2Up(bytePerLine)-1 downto log2Up(bytePerWord)
val tagLineRange = tagRange.high downto lineRange.low
val lineWordRange = lineRange.high downto wordRange.low
class LineInfo extends Bundle{
val valid = Bool
val loading = Bool
val error = if(catchAccessFault) Bool else null
val address = UInt(tagRange.length bit)
}
class LineInfoWithHit extends LineInfo{
val hit = Bool
}
def LineInfoWithHit(lineInfo : LineInfo, testTag : UInt) = {
val ret = new LineInfoWithHit()
ret.assignSomeByName(lineInfo)
ret.hit := lineInfo.valid && lineInfo.address === testTag
ret
}
val ways = Array.fill(wayCount)(new Area{
val tags = Mem(new LineInfo(),wayLineCount)
@ -232,7 +248,6 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val flushCounter = Reg(UInt(log2Up(wayLineCount) + 1 bit)) init(0)
when(!flushCounter.msb){
io.cpu.prefetch.haltIt := True
@ -260,10 +275,6 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val request = requestIn.stage()
val lineInfoWrite = new LineInfo()
lineInfoWrite.valid := flushCounter.msb
lineInfoWrite.address := request.addr(tagRange)
if(catchAccessFault) lineInfoWrite.error := loadingWithError
//Send memory requests
val memCmdSended = RegInit(False) setWhen(io.mem.cmd.fire)
@ -279,10 +290,10 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val loadedWordsReadable = RegNext(loadedWords)
loadedWordsNext := loadedWords
val waysWritePort = ways(0).datas.writePort //Not multi ways
waysWritePort.valid := io.mem.rsp.valid
waysWritePort.address := request.addr(lineRange) @@ wordIndex
waysWritePort.data := io.mem.rsp.data
val waysDatasWritePort = ways(0).datas.writePort //Not multi ways
waysDatasWritePort.valid := io.mem.rsp.valid
waysDatasWritePort.address := request.addr(lineRange) @@ wordIndex
waysDatasWritePort.data := io.mem.rsp.data
when(io.mem.rsp.valid){
wordIndex := wordIndex + 1
loadedWordsNext(wordIndex) := True
@ -297,11 +308,14 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
}
request.ready := readyDelay === 1
val waysTagsWritePort = ways(0).tags.writePort //not multi way
waysTagsWritePort.valid := io.mem.rsp.valid || !flushCounter.msb
waysTagsWritePort.address := Mux(flushCounter.msb,request.addr(lineRange),flushCounter(flushCounter.high-1 downto 0))
waysTagsWritePort.data.valid := flushCounter.msb
waysTagsWritePort.data.address := request.addr(tagRange)
waysTagsWritePort.data.loading := !memRspLast
if(catchAccessFault) waysTagsWritePort.data.error := loadingWithError
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){
memCmdSended := False
@ -321,9 +335,9 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
val waysRead = for(way <- ways) yield new Area{
val readAddress = Mux(io.cpu.fetch.isStuck,io.cpu.fetch.address,io.cpu.prefetch.address) //TODO FMAX
val tag = if(asyncTagMemory)
way.tags.readAsync(io.cpu.fetch.address(lineRange))
way.tags.readAsync(io.cpu.fetch.address(lineRange),writeFirst)
else
way.tags.readSync(readAddress(lineRange))
way.tags.readSync(readAddress(lineRange),readUnderWrite = readFirst)
val data = way.datas.readSync(readAddress(lineRange.high downto wordRange.low))
waysHitWord := data //Not applicable to multi way
@ -332,102 +346,128 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
if(catchAccessFault) waysHitError := tag.error
}
when(lineLoader.request.valid && lineLoader.request.addr(lineRange) === io.cpu.fetch.address(lineRange)){
waysHitValid := False //Not applicable to multi way
}
// when(lineLoader.request.valid && lineLoader.request.addr(lineRange) === io.cpu.fetch.address(lineRange)){
// waysHitValid := False //Not applicable to multi way
// }
}
val loaderHitValid = lineLoader.request.valid && lineLoader.request.addr(tagLineRange) === io.cpu.fetch.address(tagLineRange)
val loaderHitReady = lineLoader.loadedWordsReadable(io.cpu.fetch.address(wordRange))
io.cpu.fetch.haltIt := io.cpu.fetch.isValid && !(waysHitValid || (loaderHitValid && loaderHitReady))
io.cpu.fetch.data := waysHitWord //TODO
if(catchAccessFault) io.cpu.fetch.error := (waysHitValid && waysHitError) || (loaderHitValid && loaderHitReady && lineLoader.loadingWithErrorReg)
lineLoader.requestIn.valid := io.cpu.fetch.isValid && !io.cpu.fetch.isStuckByOthers && !waysHitValid
val hit = waysHitValid && !(waysRead(0).tag.loading && !(if(asyncTagMemory) lineLoader.loadedWords else RegNext(lineLoader.loadedWords))(io.cpu.fetch.address(wordRange)))
io.cpu.fetch.haltIt := io.cpu.fetch.isValid && !hit
io.cpu.fetch.data := waysHitWord
if(catchAccessFault) io.cpu.fetch.error := waysRead(0).tag.error
lineLoader.requestIn.valid := io.cpu.fetch.isValid && !hit //TODO avoid duplicated request
lineLoader.requestIn.addr := io.cpu.fetch.address
// val loaderHitValid = lineLoader.request.valid && lineLoader.request.addr(tagLineRange) === io.cpu.fetch.address(tagLineRange)
// val loaderHitReady = lineLoader.loadedWordsReadable(io.cpu.fetch.address(wordRange))
//
//
// io.cpu.fetch.haltIt := io.cpu.fetch.isValid && !(waysHitValid || (loaderHitValid && loaderHitReady))
// io.cpu.fetch.data := waysHitWord //TODO
// if(catchAccessFault) io.cpu.fetch.error := (waysHitValid && waysHitError) || (loaderHitValid && loaderHitReady && lineLoader.loadingWithErrorReg)
// lineLoader.requestIn.valid := io.cpu.fetch.isValid && !io.cpu.fetch.isStuckByOthers && !waysHitValid
// lineLoader.requestIn.addr := io.cpu.fetch.address
} else new Area{
val waysHitValid = False
val waysHitError = Bool.assignDontCare()
val waysHitWord = Bits(wordWidth bit)
//Long readValidPath
// def writeFirstMemWrap[T <: Data](readValid : Bool, readAddress : UInt, lastAddress : UInt, readData : T,writeValid : Bool, writeAddress : UInt, writeData : T) : T = {
// val hit = writeValid && (readValid ? readAddress | lastAddress) === writeAddress
// val overrideValid = RegInit(False) clearWhen(readValid) setWhen(hit)
// val overrideValue = RegNextWhen(writeData,hit)
// overrideValid ? overrideValue | readData
// }
val waysRead = for(way <- ways) yield new Area{
//shot readValid path
def writeFirstMemWrap[T <: Data](readValid : Bool, readLastAddress : UInt, readData : T,writeValid : Bool, writeAddress : UInt, writeData : T) : T = {
val writeSample = readValid || (writeValid && writeAddress === readLastAddress)
val writeValidReg = RegNextWhen(writeValid,writeSample)
val writeAddressReg = RegNextWhen(writeAddress,writeSample)
val writeDataReg = RegNextWhen(writeData,writeSample)
(writeValidReg && writeAddressReg === readLastAddress) ? writeDataReg | readData
}
//Long sample path
// def writeFirstRegWrap[T <: Data](sample : Bool, sampleAddress : UInt,lastAddress : UInt, readData : T, writeValid : Bool, writeAddress : UInt, writeData : T) : (T,T) = {
// val hit = writeValid && (sample ? sampleAddress | lastAddress) === writeAddress
// val bypass = hit ? writeData | readData
// val reg = RegNextWhen(bypass,sample || hit)
// (reg,bypass)
// }
//Short sample path
def writeFirstRegWrap[T <: Data](sample : Bool, sampleAddress : UInt,sampleLastAddress : UInt, readData : T, writeValid : Bool, writeAddress : UInt, writeData : T) = {
val preWrite = (writeValid && sampleAddress === writeAddress)
val postWrite = (writeValid && sampleLastAddress === writeAddress)
val bypass = (!sample || preWrite) ? writeData | readData
val regEn = sample || postWrite
val reg = RegNextWhen(bypass,regEn)
(reg,bypass,regEn,preWrite,postWrite)
}
// def writeFirstRegWrap[T <: Data](sample : Bool, sampleAddress : UInt,sampleLastAddress : UInt, readData : T, writeValid : Bool, writeAddress : UInt, writeData : T) = {
// val bypass = (!sample || (writeValid && sampleAddress === writeAddress)) ? writeData | readData
// val regEn = sample || (writeValid && sampleLastAddress === writeAddress)
// val reg = RegNextWhen(bypass,regEn)
// (reg,bypass,regEn,False,False)
// }
require(wayCount == 1)
val memRead = new Area{
val way = ways(0)
val tag = if(asyncTagMemory)
way.tags.readAsync(io.cpu.fetch.address(lineRange))
way.tags.readAsync(io.cpu.fetch.address(lineRange),writeFirst)
else
way.tags.readSync(io.cpu.prefetch.address(lineRange),enable = !io.cpu.fetch.isStuck)
writeFirstMemWrap(
readValid = !io.cpu.fetch.isStuck,
// readAddress = io.cpu.prefetch.address(lineRange),
readLastAddress = io.cpu.fetch.address(lineRange),
readData = way.tags.readSync(io.cpu.prefetch.address(lineRange),enable = !io.cpu.fetch.isStuck),
writeValid = lineLoader.waysTagsWritePort.valid,
writeAddress = lineLoader.waysTagsWritePort.address,
writeData = lineLoader.waysTagsWritePort.data
)
val data = way.datas.readSync(io.cpu.prefetch.address(lineRange.high downto wordRange.low),enable = !io.cpu.fetch.isStuck)
waysHitWord := data //Not applicable to multi way
when(tag.valid && tag.address === io.cpu.fetch.address(tagRange)) {
waysHitValid := True
if(catchAccessFault) waysHitError := tag.error
}
when(lineLoader.request.valid && lineLoader.request.addr(lineRange) === io.cpu.fetch.address(lineRange)){
waysHitValid := False //Not applicable to multi way
}
val data = writeFirstMemWrap(
readValid = !io.cpu.fetch.isStuck,
// readAddress = io.cpu.prefetch.address(lineWordRange),
readLastAddress = io.cpu.fetch.address(lineWordRange),
readData = way.datas.readSync(io.cpu.prefetch.address(lineWordRange),enable = !io.cpu.fetch.isStuck),
writeValid = lineLoader.waysDatasWritePort.valid,
writeAddress = lineLoader.waysDatasWritePort.address,
writeData = lineLoader.waysDatasWritePort.data
)
}
val tag = writeFirstRegWrap(
sample = !io.cpu.decode.isStuck,
sampleAddress = io.cpu.fetch.address(lineRange),
sampleLastAddress = io.cpu.decode.address(lineRange),
readData = LineInfoWithHit(memRead.tag,io.cpu.fetch.address(tagRange)),
writeValid = lineLoader.waysTagsWritePort.valid,
writeAddress = lineLoader.waysTagsWritePort.address,
writeData = LineInfoWithHit(lineLoader.waysTagsWritePort.data,io.cpu.fetch.address(tagRange)) //TODO wrong address src
)._1
val loadedWord = new Area{
val valid = RegNext(lineLoader.waysWritePort.valid)
val address = RegNext(lineLoader.request.addr(tagLineRange) @@ lineLoader.wordIndex @@ U"00")
val data = RegNext(lineLoader.waysWritePort.data)
val wasLoaded = RegNext(lineLoader.loadedWords)
}
val (data,dataRegIn,dataRegEn,dataPreWrite,dataPostWrite) = writeFirstRegWrap(
sample = !io.cpu.decode.isStuck,
sampleAddress = io.cpu.fetch.address(lineWordRange),
sampleLastAddress = io.cpu.decode.address(lineWordRange),
readData = memRead.data,
writeValid = lineLoader.waysDatasWritePort.valid,
writeAddress = lineLoader.waysDatasWritePort.address,
writeData = lineLoader.waysDatasWritePort.data
)
val hit = tag.valid && tag.address === io.cpu.decode.address(tagRange) && !(tag.loading && !lineLoader.loadedWords(io.cpu.decode.address(wordRange)))
// val hit = tag.hit && !(tag.loading && !lineLoader.loadedWords(io.cpu.decode.address(wordRange)))
val fetchInstructionValid = Bool
val fetchInstructionValue = Bits(32 bits)
val fetchInstructionValidReg = Reg(Bool)
val fetchInstructionValueReg = Reg(Bits(32 bits))
io.cpu.decode.haltIt := io.cpu.decode.isValid && !hit //TODO PERF not halit it when removed, Should probably be applyed in many other places
io.cpu.decode.data := data
// io.cpu.decode.dataAnticipated := dataRegEn ? dataRegIn | data
io.cpu.decode.dataAnticipated := io.cpu.decode.isStuck ? Mux(dataPostWrite,lineLoader.waysDatasWritePort.data,data) | Mux(dataPreWrite,lineLoader.waysDatasWritePort.data,memRead.data)
if(catchAccessFault) io.cpu.decode.error := tag.error
when(fetchInstructionValidReg){
fetchInstructionValid := True
fetchInstructionValue := fetchInstructionValueReg
}.elsewhen(loadedWord.valid && (loadedWord.address >> 2) === (io.cpu.fetch.address >> 2)){
fetchInstructionValid := True
fetchInstructionValue := loadedWord.data
} otherwise{
fetchInstructionValid := waysHitValid || (loadedWord.address(tagLineRange) === io.cpu.fetch.address(tagLineRange) && loadedWord.wasLoaded(io.cpu.fetch.address(wordRange)))
fetchInstructionValue := waysHitWord //Not multi way (wasloaded)
}
when(io.cpu.fetch.isStuck){
fetchInstructionValidReg := fetchInstructionValid
fetchInstructionValueReg := fetchInstructionValue
} otherwise {
fetchInstructionValidReg := False
}
io.cpu.fetch.data := fetchInstructionValue
val decodeInstructionValid = Reg(Bool)
val decodeInstructionReg = Reg(Bits(32 bits))
val decodeInstructionRegIn = (!io.cpu.decode.isStuck) ? fetchInstructionValue | loadedWord.data
io.cpu.decode.dataAnticipated := decodeInstructionReg
when(!io.cpu.decode.isStuck){
decodeInstructionValid := fetchInstructionValid
decodeInstructionReg := decodeInstructionRegIn
io.cpu.decode.dataAnticipated := decodeInstructionRegIn
}.elsewhen(loadedWord.valid && (loadedWord.address >> 2) === (io.cpu.decode.address >> 2)){
decodeInstructionValid := True
decodeInstructionReg := decodeInstructionRegIn
io.cpu.decode.dataAnticipated := decodeInstructionRegIn
}
io.cpu.decode.haltIt := io.cpu.decode.isValid && !decodeInstructionValid
io.cpu.decode.data := decodeInstructionReg
lineLoader.requestIn.valid := io.cpu.decode.isValid && !decodeInstructionValid
lineLoader.requestIn.valid := io.cpu.decode.isValid && !hit //TODO avoid duplicated request
lineLoader.requestIn.addr := io.cpu.decode.address
}

View File

@ -61,6 +61,7 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
fetch.insert(IBUS_ACCESS_ERROR) := iBus.rsp.error
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
decode.insert(INSTRUCTION_READY) := True
if(catchAccessFault){
decodeExceptionPort.valid := decode.arbitration.isValid && decode.input(IBUS_ACCESS_ERROR)

View File

@ -79,22 +79,24 @@ object TopLevel {
configFull.plugins ++= List(
new PcManagerSimplePlugin(0x00000000l, false),
new IBusSimplePlugin(
interfaceKeepData = true,
catchAccessFault = true
),
// new IBusCachedPlugin(
// config = InstructionCacheConfig(
// cacheSize =4096,
// bytePerLine =32,
// wayCount = 1,
// wrappedMemAccess = true,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// new IBusSimplePlugin(
// interfaceKeepData = true,
// catchAccessFault = true
// )
// ),
new IBusCachedPlugin(
config = InstructionCacheConfig(
cacheSize = 4096,
bytePerLine =32,
wayCount = 1,
wrappedMemAccess = true,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchAccessFault = true,
asyncTagMemory = false,
twoStageLogic = true
)
),
new DBusSimplePlugin(
catchAddressMisaligned = true,
catchAccessFault = true
@ -269,9 +271,9 @@ object TopLevel {
)
)
// val toplevel = new VexRiscv(configFull)
val toplevel = new VexRiscv(configFull)
// val toplevel = new VexRiscv(configLight)
val toplevel = new VexRiscv(configTest)
// val toplevel = new VexRiscv(configTest)
toplevel.decode.input(toplevel.config.INSTRUCTION).addAttribute(Verilator.public)
toplevel.decode.input(toplevel.config.PC).addAttribute(Verilator.public)
toplevel.decode.arbitration.isValid.addAttribute(Verilator.public)

View File

@ -19,6 +19,7 @@ case class VexRiscvConfig(pcWidth : Int){
object PC extends Stageable(UInt(pcWidth bits))
object PC_CALC_WITHOUT_JUMP extends Stageable(UInt(pcWidth bits))
object INSTRUCTION extends Stageable(Bits(32 bits))
object INSTRUCTION_READY extends Stageable(Bool)
object INSTRUCTION_ANTICIPATED extends Stageable(Bits(32 bits))
object LEGAL_INSTRUCTION extends Stageable(Bool)
object REGFILE_WRITE_VALID extends Stageable(Bool)

View File

@ -1,52 +1,66 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Sun Apr 9 09:10:08 2017
[*] Wed Apr 12 17:13:59 2017
[*]
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-addi.vcd"
[dumpfile_mtime] "Sun Apr 9 09:08:48 2017"
[dumpfile_size] 136439
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3.vcd"
[dumpfile_mtime] "Wed Apr 12 17:05:50 2017"
[dumpfile_size] 476292557
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
[timestart] 274
[timestart] 602234
[size] 1776 953
[pos] -775 -353
*-2.774728 284 -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
[pos] -775 -1
*-3.626630 602285 -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.VexRiscv.
[sst_width] 201
[signals_width] 453
[signals_width] 518
[sst_expanded] 1
[sst_vpaned_height] 279
@800200
-prefetch
@28
TOP.VexRiscv.instructionCache_1.io_cpu_prefetch_haltIt
@22
TOP.VexRiscv.instructionCache_1.io_cpu_prefetch_address[31:0]
@1000200
-prefetch
@800200
-fetch
@28
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isValid
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isStuck
TOP.VexRiscv.instructionCache_1.io_cpu_prefetch_haltIt
@800200
-Fetch
@22
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_address[31:0]
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_data[31:0]
@1000200
-fetch
@800200
-decode
@28
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isValid
TOP.VexRiscv.instructionCache_1.io_cpu_decode_haltIt
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isStuck
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isStuck
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isValid
@1000200
-Fetch
@800200
-Decode
@22
TOP.VexRiscv.instructionCache_1.io_cpu_decode_address[31:0]
TOP.VexRiscv.instructionCache_1.io_cpu_decode_data[31:0]
@28
TOP.VexRiscv.instructionCache_1.io_cpu_decode_haltIt
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isStuck
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isValid
@1000200
-decode
-Decode
@800200
-ibus
-Task
@22
TOP.VexRiscv.instructionCache_1.task_memRead_data[31:0]
TOP.VexRiscv.instructionCache_1.task_memRead_tag_address[19:0]
@28
TOP.VexRiscv.instructionCache_1.task_memRead_tag_valid
@22
TOP.VexRiscv.instructionCache_1.task_tag_address[19:0]
@28
TOP.VexRiscv.instructionCache_1.task_tag_valid
@22
TOP.VexRiscv.instructionCache_1.task_dataRegIn[31:0]
TOP.VexRiscv.instructionCache_1.task_data[31:0]
@29
TOP.VexRiscv.instructionCache_1.task_cacheHit
@28
TOP.VexRiscv.instructionCache_1.task_hit
TOP.VexRiscv.instructionCache_1.task_loaderHit
@1000200
-Task
@22
TOP.VexRiscv.instructionCache_1.io_mem_cmd_payload_address[31:0]
@28
@ -56,32 +70,16 @@ TOP.VexRiscv.instructionCache_1.io_mem_cmd_valid
TOP.VexRiscv.instructionCache_1.io_mem_rsp_payload_data[31:0]
@28
TOP.VexRiscv.instructionCache_1.io_mem_rsp_valid
@1000200
-ibus
@28
TOP.VexRiscv.instructionCache_1.clk
@22
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_data[31:0]
TOP.VexRiscv.decode_RegFilePlugin_srcInstruction[31:0]
TOP.VexRiscv.instructionCache_1.io_cpu_decode_data[31:0]
@29
TOP.VexRiscv.decode_arbitration_isValid
TOP.VexRiscv.instructionCache_1.lineLoader_waysDatasWritePort_payload_address[9:0]
TOP.VexRiscv.instructionCache_1.lineLoader_waysDatasWritePort_payload_data[31:0]
@28
TOP.VexRiscv.decode_arbitration_isStuck
TOP.VexRiscv.instructionCache_1.lineLoader_waysDatasWritePort_valid
TOP.VexRiscv.clk
@22
TOP.VexRiscv.decode_PC[31:0]
TOP.VexRiscv.decode_REG1[31:0]
TOP.VexRiscv.decode_REG2[31:0]
TOP.VexRiscv.instructionCache_1.lineLoader_request_payload_addr[31:0]
@28
TOP.VexRiscv.decode_REG1_USE
TOP.VexRiscv.decode_REG2_USE
TOP.VexRiscv.decode_arbitration_isValid
TOP.VexRiscv.decode_arbitration_isStuck
@22
TOP.VexRiscv.decode_RegFilePlugin_regFileReadAddress1[4:0]
TOP.VexRiscv.decode_RegFilePlugin_regFileReadAddress2[4:0]
TOP.VexRiscv.decode_RegFilePlugin_rs1Data[31:0]
TOP.VexRiscv.decode_RegFilePlugin_rs2Data[31:0]
TOP.VexRiscv.decode_RegFilePlugin_srcInstruction[31:0]
TOP.VexRiscv.instructionCache_1.lineLoader_request_ready
TOP.VexRiscv.instructionCache_1.lineLoader_request_valid
[pattern_trace] 1
[pattern_trace] 0

View File

@ -681,11 +681,12 @@ public:
#endif
class Dhrystone : public Workspace{
public:
Dhrystone(string name,bool iStall, bool dStall) : Workspace(name) {
string hexName;
Dhrystone(string name,string hexName,bool iStall, bool dStall) : Workspace(name) {
setIStall(iStall);
setDStall(dStall);
loadHex("../../resources/hex/" + name + ".hex");
loadHex("../../resources/hex/" + hexName + ".hex");
this->hexName = hexName;
}
virtual void checks(){
@ -693,7 +694,7 @@ public:
}
virtual void pass(){
FILE *refFile = fopen((name + ".logRef").c_str(), "r");
FILE *refFile = fopen((hexName + ".logRef").c_str(), "r");
fseek(refFile, 0, SEEK_END);
uint32_t refSize = ftell(refFile);
fseek(refFile, 0, SEEK_SET);
@ -828,10 +829,10 @@ int main(int argc, char **argv, char **env) {
#ifdef DHRYSTONE
// Dhrystone("dhrystoneO3",false,false).run(0.05e6);
Dhrystone("dhrystoneO3",true,true).run(1.1e6);
Dhrystone("dhrystoneO3M",true,true).run(1.5e6);
Dhrystone("dhrystoneO3",false,false).run(1.5e6);
Dhrystone("dhrystoneO3M",false,false).run(1.2e6);
Dhrystone("dhrystoneO3_Stall","dhrystoneO3",true,true).run(1.1e6);
Dhrystone("dhrystoneO3M_Stall","dhrystoneO3M",true,true).run(1.5e6);
Dhrystone("dhrystoneO3","dhrystoneO3",false,false).run(1.5e6);
Dhrystone("dhrystoneO3M","dhrystoneO3M",false,false).run(1.2e6);
// Dhrystone("dhrystoneO3ML",false,false).run(8e6);
// Dhrystone("dhrystoneO3MLL",false,false).run(80e6);

View File

@ -1,4 +1,4 @@
IBUS=IBUS_SIMPLE
IBUS=IBUS_CACHED
DBUS=DBUS_SIMPLE
TRACE=no
TRACE_START=0