Data cache pass dhrystone benchmark.
Data cache todo -> bus error handling
This commit is contained in:
parent
2f384364d8
commit
a9f7177181
|
@ -1,25 +1,138 @@
|
|||
package SpinalRiscv.Plugin
|
||||
|
||||
import SpinalRiscv.Riscv._
|
||||
import SpinalRiscv.{Stageable, DecoderService, Riscv, VexRiscv}
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
|
||||
|
||||
class DBusCachedPlugin {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
case class DataCacheConfig( cacheSize : Int,
|
||||
bytePerLine : Int,
|
||||
wayCount : Int,
|
||||
addressWidth : Int,
|
||||
cpuDataWidth : Int,
|
||||
memDataWidth : Int){
|
||||
memDataWidth : Int,
|
||||
catchAccessFault : Boolean = false){
|
||||
def burstSize = bytePerLine*8/memDataWidth
|
||||
val burstLength = bytePerLine/(memDataWidth/8)
|
||||
assert(catchAccessFault == false)
|
||||
}
|
||||
|
||||
|
||||
class DBusCachedPlugin(config : DataCacheConfig) extends Plugin[VexRiscv]{
|
||||
import config._
|
||||
var dBus : DataCacheMemBus = null
|
||||
|
||||
object MEMORY_ENABLE extends Stageable(Bool)
|
||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import Riscv._
|
||||
import pipeline.config._
|
||||
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
|
||||
val stdActions = List[(Stageable[_ <: BaseType],Any)](
|
||||
LEGAL_INSTRUCTION -> True,
|
||||
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||
SRC_USE_SUB_LESS -> False,
|
||||
MEMORY_ENABLE -> True,
|
||||
REG1_USE -> True
|
||||
) ++ (if (catchAccessFault) List(IntAluPlugin.ALU_CTRL -> IntAluPlugin.AluCtrlEnum.ADD_SUB) else Nil) //Used for access fault bad address in memory stage
|
||||
|
||||
val loadActions = stdActions ++ List(
|
||||
SRC2_CTRL -> Src2CtrlEnum.IMI,
|
||||
REGFILE_WRITE_VALID -> True,
|
||||
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||
BYPASSABLE_MEMORY_STAGE -> False
|
||||
)
|
||||
|
||||
val storeActions = stdActions ++ List(
|
||||
SRC2_CTRL -> Src2CtrlEnum.IMS,
|
||||
REG2_USE -> True
|
||||
)
|
||||
|
||||
decoderService.addDefault(MEMORY_ENABLE, False)
|
||||
decoderService.add(
|
||||
List(LB, LH, LW, LBU, LHU, LWU).map(_ -> loadActions) ++
|
||||
List(SB, SH, SW).map(_ -> storeActions)
|
||||
)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
dBus = master(DataCacheMemBus(this.config)).setName("dBus")
|
||||
|
||||
val cache = new DataCache(this.config)
|
||||
cache.io.mem <> dBus
|
||||
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
//TODO manage removeIt
|
||||
|
||||
val size = input(INSTRUCTION)(13 downto 12).asUInt
|
||||
cache.io.cpu.execute.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
||||
cache.io.cpu.execute.isStuck := arbitration.isStuck
|
||||
arbitration.haltIt.setWhen(cache.io.cpu.execute.haltIt)
|
||||
cache.io.cpu.execute.args.wr := input(INSTRUCTION)(5)
|
||||
cache.io.cpu.execute.args.address := input(SRC_ADD_SUB).asUInt
|
||||
cache.io.cpu.execute.args.data := size.mux(
|
||||
U(0) -> input(REG2)( 7 downto 0) ## input(REG2)( 7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0),
|
||||
U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0),
|
||||
default -> input(REG2)(31 downto 0)
|
||||
)
|
||||
cache.io.cpu.execute.args.mask := (size.mux (
|
||||
U(0) -> B"0001",
|
||||
U(1) -> B"0011",
|
||||
default -> B"1111"
|
||||
) << cache.io.cpu.execute.args.address(1 downto 0)).resized
|
||||
cache.io.cpu.execute.args.bypass := cache.io.cpu.execute.args.address(31 downto 28) === 0xF
|
||||
cache.io.cpu.execute.args.all := False
|
||||
cache.io.cpu.execute.args.kind := DataCacheCpuCmdKind.MEMORY
|
||||
|
||||
insert(MEMORY_ADDRESS_LOW) := cache.io.cpu.execute.args.address(1 downto 0)
|
||||
}
|
||||
|
||||
memory plug new Area{
|
||||
import memory._
|
||||
cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
||||
cache.io.cpu.memory.isStuck := arbitration.isStuck
|
||||
arbitration.haltIt.setWhen(cache.io.cpu.memory.haltIt)
|
||||
}
|
||||
|
||||
writeBack plug new Area{
|
||||
import writeBack._
|
||||
|
||||
cache.io.cpu.writeBack.isValid := arbitration.isValid && input(MEMORY_ENABLE)
|
||||
arbitration.haltIt.setWhen(cache.io.cpu.writeBack.haltIt)
|
||||
|
||||
val rspShifted = Bits(32 bits)
|
||||
rspShifted := cache.io.cpu.writeBack.data
|
||||
switch(input(MEMORY_ADDRESS_LOW)){
|
||||
is(1){rspShifted(7 downto 0) := cache.io.cpu.writeBack.data(15 downto 8)}
|
||||
is(2){rspShifted(15 downto 0) := cache.io.cpu.writeBack.data(31 downto 16)}
|
||||
is(3){rspShifted(7 downto 0) := cache.io.cpu.writeBack.data(31 downto 24)}
|
||||
}
|
||||
|
||||
val rspFormated = input(INSTRUCTION)(13 downto 12).mux(
|
||||
0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)),
|
||||
1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)),
|
||||
default -> rspShifted //W
|
||||
)
|
||||
|
||||
when(arbitration.isValid && input(MEMORY_ENABLE)) {
|
||||
input(REGFILE_WRITE_DATA) := rspFormated
|
||||
}
|
||||
|
||||
assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
object DataCacheCpuCmdKind extends SpinalEnum{
|
||||
val MEMORY,FLUSH,EVICT = newElement()
|
||||
}
|
||||
|
@ -52,11 +165,11 @@ case class DataCacheCpuExecuteArgs(p : DataCacheConfig) extends Bundle{
|
|||
|
||||
case class DataCacheCpuMemory(p : DataCacheConfig) extends Bundle with IMasterSlave{
|
||||
val isValid = Bool
|
||||
val isStall = Bool
|
||||
val isStuck = Bool
|
||||
val haltIt = Bool
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(isValid, isStall)
|
||||
out(isValid, isStuck)
|
||||
in(haltIt)
|
||||
}
|
||||
}
|
||||
|
@ -264,11 +377,10 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
val manager = new Area {
|
||||
io.flushDone := False
|
||||
|
||||
io.cpu.execute.haltIt := False
|
||||
val request = RegNextWhen(io.cpu.execute.args, !io.cpu.execute.isStuck)
|
||||
|
||||
//Evict the cache after reset
|
||||
val requestValid = io.cpu.memory.isValid || RegNextWhen(False, !io.cpu.memory.isStall, True)
|
||||
val requestValid = io.cpu.memory.isValid || RegNextWhen(False, !io.cpu.memory.isStuck, True)
|
||||
request.kind.getDrivingReg.init(DataCacheCpuCmdKind.EVICT)
|
||||
request.all.getDrivingReg.init(True)
|
||||
request.address.getDrivingReg.init(0)
|
||||
|
@ -281,11 +393,11 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
val waysHitInfo = new LineInfo().assignDontCare()
|
||||
|
||||
//delayedXX are used to relax logic timings in flush and evict modes
|
||||
val delayedValid = RegNext(io.cpu.memory.isStall) init(False)
|
||||
val delayedValid = RegNext(io.cpu.memory.isStuck) init(False)
|
||||
val delayedWaysHitValid = RegNext(waysHitValid)
|
||||
val delayedWaysHitId = RegNext(waysHitId)
|
||||
|
||||
val waysReadAddress = Mux(io.cpu.memory.isStall, request.address, io.cpu.execute.address)
|
||||
val waysReadAddress = Mux(io.cpu.memory.isStuck, request.address, io.cpu.execute.address)
|
||||
tagsReadCmd := waysReadAddress(lineRange)
|
||||
dataReadCmd := waysReadAddress(lineRange.high downto wordRange.low)
|
||||
when(victim.dataReadCmdOccure){
|
||||
|
@ -322,8 +434,8 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
val loaderReady = False
|
||||
val loadingDone = RegNext(loaderValid && loaderReady) init(False) //one cycle pulse
|
||||
|
||||
val victimSent = RegInit(False)
|
||||
victimSent := (victimSent || victim.requestIn.fire) && io.cpu.memory.isStall
|
||||
val victimSent = RegInit(False) //TODO manage "removeIt"
|
||||
victimSent := (victimSent || victim.requestIn.fire) && io.cpu.memory.isStuck
|
||||
|
||||
val flushAllState = RegInit(False) //Used to keep logic timings fast
|
||||
val flushAllDone = RegNext(False) init(False)
|
||||
|
@ -458,7 +570,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
|
||||
//The whole life of a loading task, the corresponding manager request is present
|
||||
val loader = new Area{
|
||||
val valid = RegNext(manager.loaderValid)
|
||||
val valid = RegNext(manager.loaderValid) init(False)
|
||||
val wayId = RegNext(manager.writebackWayId)
|
||||
val baseAddress = manager.request.address
|
||||
|
||||
|
|
|
@ -36,12 +36,8 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
|
||||
var dBus : DBusSimpleBus = null
|
||||
|
||||
object MemoryCtrlEnum extends SpinalEnum{
|
||||
val WR, RD = newElement()
|
||||
}
|
||||
|
||||
object MEMORY_ENABLE extends Stageable(Bool)
|
||||
object MEMORY_CTRL extends Stageable(MemoryCtrlEnum())
|
||||
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
|
||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||
|
||||
|
@ -74,17 +70,10 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
)
|
||||
|
||||
decoderService.addDefault(MEMORY_ENABLE, False)
|
||||
decoderService.add(List(
|
||||
LB -> (loadActions),
|
||||
LH -> (loadActions),
|
||||
LW -> (loadActions),
|
||||
LBU -> (loadActions),
|
||||
LHU -> (loadActions),
|
||||
LWU -> (loadActions),
|
||||
SB -> (storeActions),
|
||||
SH -> (storeActions),
|
||||
SW -> (storeActions)
|
||||
))
|
||||
decoderService.add(
|
||||
List(LB, LH, LW, LBU, LHU, LWU).map(_ -> loadActions) ++
|
||||
List(SB, SH, SW).map(_ -> storeActions)
|
||||
)
|
||||
|
||||
if(catchAddressMisaligned) {
|
||||
val exceptionService = pipeline.service(classOf[ExceptionService])
|
||||
|
@ -170,7 +159,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
|
|||
input(REGFILE_WRITE_DATA) := rspFormated
|
||||
}
|
||||
|
||||
assert(!(input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
|
||||
assert(!(arbitration.isValid && input(MEMORY_ENABLE) && !input(INSTRUCTION)(5) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,37 +79,48 @@ object TopLevel {
|
|||
|
||||
config.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,
|
||||
// catchAccessFault = true
|
||||
// )
|
||||
// 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
|
||||
)
|
||||
),
|
||||
// new DBusSimplePlugin(
|
||||
// catchAddressMisaligned = true,
|
||||
// catchAccessFault = true
|
||||
// ),
|
||||
new DBusCachedPlugin(
|
||||
config = new DataCacheConfig(
|
||||
cacheSize = 4096,
|
||||
bytePerLine = 32,
|
||||
wayCount = 1,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
memDataWidth = 32,
|
||||
catchAccessFault = false
|
||||
)
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = true
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.SYNC,
|
||||
zeroBoot = false
|
||||
zeroBoot = true
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin,
|
||||
new FullBarrielShifterPlugin,
|
||||
// new LightShifterPlugin,
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = true,
|
||||
catchAccessFault = true
|
||||
),
|
||||
new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
// new HazardSimplePlugin(false, false, false, false),
|
||||
|
@ -159,6 +170,7 @@ object TopLevel {
|
|||
toplevel.decode.input(config.INSTRUCTION).addAttribute("verilator public")
|
||||
toplevel.decode.input(config.PC).addAttribute("verilator public")
|
||||
toplevel.decode.arbitration.isValid.addAttribute("verilator public")
|
||||
// toplevel.writeBack.input(config.PC).addAttribute("verilator public")
|
||||
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
|
||||
|
||||
toplevel
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,50 +1,130 @@
|
|||
[*]
|
||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||
[*] Thu Mar 30 15:00:10 2017
|
||||
[*] Sat Apr 1 14:47:34 2017
|
||||
[*]
|
||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3.vcd"
|
||||
[dumpfile_mtime] "Thu Mar 30 14:59:57 2017"
|
||||
[dumpfile_size] 1227579722
|
||||
[dumpfile_mtime] "Sat Apr 1 14:46:24 2017"
|
||||
[dumpfile_size] 1846070138
|
||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
|
||||
[timestart] 555551
|
||||
[timestart] 48127
|
||||
[size] 1776 953
|
||||
[pos] -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
|
||||
*-3.000000 48140 48755 -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] 378
|
||||
[signals_width] 418
|
||||
[sst_width] 313
|
||||
[signals_width] 558
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 279
|
||||
[sst_vpaned_height] 374
|
||||
@28
|
||||
TOP.clk
|
||||
TOP.reset
|
||||
@22
|
||||
TOP.dBus_cmd_payload_address[31:0]
|
||||
TOP.dBus_cmd_payload_data[31:0]
|
||||
TOP.dBus_cmd_payload_length[3:0]
|
||||
TOP.dBus_cmd_payload_mask[3:0]
|
||||
@28
|
||||
TOP.dBus_cmd_payload_wr
|
||||
TOP.dBus_cmd_ready
|
||||
TOP.dBus_cmd_valid
|
||||
@22
|
||||
TOP.dBus_rsp_payload_data[31:0]
|
||||
@28
|
||||
TOP.dBus_rsp_valid
|
||||
TOP.VexRiscv.dataCache_1.victim_bufferReaded_valid
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_isValid
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_memory_isValid
|
||||
TOP.VexRiscv.dataCache_1.loader_valid
|
||||
TOP.VexRiscv.writeBack_arbitration_isValid
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_writeBack_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_writeBack_haltIt
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_memory_haltIt
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_memory_isStuck
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_memory_isValid
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_payload_fromBypass
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_ready
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_valid
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port0_address[9:0]
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port0_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port0_enable
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port0_mask[3:0]
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port1_address[9:0]
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port1_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.ways_0_data_port1_enable
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.dataReadedValue_0[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_payload_fromBypass
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_ready
|
||||
TOP.VexRiscv.dataCache_1.manager_cpuRsp_valid
|
||||
TOP.VexRiscv.writeBack_REGFILE_WRITE_VALID
|
||||
@22
|
||||
TOP.VexRiscv.writeBack_REGFILE_WRITE_DATA[31:0]
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0]
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid
|
||||
@800200
|
||||
-cache_mem
|
||||
@23
|
||||
TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_address[31:0]
|
||||
@22
|
||||
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_valid
|
||||
TOP.VexRiscv.dataCache_1.io_mem_cmd_ready
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.io_mem_rsp_payload_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.io_mem_rsp_valid
|
||||
@1000200
|
||||
-cache_mem
|
||||
@28
|
||||
TOP.VexRiscv.clk
|
||||
TOP.VexRiscv.decode_arbitration_isValid
|
||||
@22
|
||||
TOP.VexRiscv.decode_PC[31:0]
|
||||
TOP.VexRiscv.decode_INSTRUCTION[31:0]
|
||||
TOP.VexRiscv.writeBack_PC[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.decode_LEGAL_INSTRUCTION
|
||||
TOP.VexRiscv.writeBack_arbitration_isValid
|
||||
TOP.VexRiscv.decode_arbitration_haltIt
|
||||
TOP.VexRiscv.execute_arbitration_haltIt
|
||||
TOP.VexRiscv.fetch_arbitration_haltIt
|
||||
TOP.VexRiscv.memory_arbitration_haltIt
|
||||
TOP.VexRiscv.prefetch_arbitration_haltIt
|
||||
TOP.VexRiscv.writeBack_arbitration_haltIt
|
||||
TOP.VexRiscv.MachineCsr_exceptionPortCtrl_pipelineHasException
|
||||
@800200
|
||||
-cache_cpu
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_cmd_address[31:0]
|
||||
TOP.VexRiscv.execute_PC[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_cmd_haltIt
|
||||
TOP.VexRiscv.execute_arbitration_removeIt
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_address[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_rsp_data[31:0]
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_address[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
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_all
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_bypass
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.task_waysHitWord[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.lineLoader_request_payload_addr[31:0]
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.instructionCache_1.lineLoader_request_ready
|
||||
TOP.VexRiscv.instructionCache_1.lineLoader_request_valid
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_kind[1:0]
|
||||
@22
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_mask[3:0]
|
||||
@28
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_args_wr
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_haltIt
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_isStuck
|
||||
TOP.VexRiscv.dataCache_1.io_cpu_execute_isValid
|
||||
@1000200
|
||||
-cache_cpu
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
class Memory{
|
||||
|
@ -200,7 +201,7 @@ public:
|
|||
| (mem[addr + 3] << 24));
|
||||
*error = addr == 0xF00FFF60u;
|
||||
}
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint32_t *data, bool *error) {
|
||||
virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) {
|
||||
*error = addr == 0xF00FFF60u;
|
||||
if(wr){
|
||||
memTraces <<
|
||||
|
@ -214,7 +215,8 @@ public:
|
|||
" : WRITE mem" << (1 << size) << "[" << addr << "] = " << *data << endl;
|
||||
for(uint32_t b = 0;b < (1 << size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
*mem.get(addr + b) = *data >> (offset*8);
|
||||
if((mask >> offset) & 1 == 1)
|
||||
*mem.get(addr + b) = *data >> (offset*8);
|
||||
}
|
||||
|
||||
switch(addr){
|
||||
|
@ -332,7 +334,7 @@ public:
|
|||
#ifdef TRACE_WITH_TIME
|
||||
currentTime <<
|
||||
#endif
|
||||
" : reg[" << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
|
||||
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
|
||||
}
|
||||
|
||||
for(SimElement* simElement : simElements) simElement->preCycle();
|
||||
|
@ -484,10 +486,10 @@ public:
|
|||
}
|
||||
|
||||
virtual void preCycle(){
|
||||
if (top->dBus_cmd_valid && top->dBus_cmd_ready && !pending) {
|
||||
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
|
||||
pending = true;
|
||||
data_next = top->dBus_cmd_payload_data;
|
||||
ws->dBusAccess(top->dBus_cmd_payload_address,top->dBus_cmd_payload_wr,top->dBus_cmd_payload_size,&data_next,&error_next);
|
||||
ws->dBusAccess(top->dBus_cmd_payload_address,top->dBus_cmd_payload_wr,top->dBus_cmd_payload_size,0xF,&data_next,&error_next);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,9 +509,60 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef DBUS_CACHED
|
||||
class DBusCached : public SimElement{
|
||||
public:
|
||||
uint32_t address;
|
||||
bool error_next = false;
|
||||
uint32_t pendingCount = 0;
|
||||
bool wr;
|
||||
|
||||
Workspace *ws;
|
||||
VVexRiscv* top;
|
||||
DBusCached(Workspace* ws){
|
||||
this->ws = ws;
|
||||
this->top = ws->top;
|
||||
}
|
||||
|
||||
virtual void onReset(){
|
||||
top->dBus_cmd_ready = 1;
|
||||
top->dBus_rsp_valid = 0;
|
||||
}
|
||||
|
||||
virtual void preCycle(){
|
||||
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
|
||||
if(pendingCount == 0){
|
||||
pendingCount = top->dBus_cmd_payload_length;
|
||||
address = top->dBus_cmd_payload_address;
|
||||
wr = top->dBus_cmd_payload_wr;
|
||||
}
|
||||
if(top->dBus_cmd_payload_wr){
|
||||
ws->dBusAccess(address,top->dBus_cmd_payload_wr,2,top->dBus_cmd_payload_mask,&top->dBus_cmd_payload_data,&error_next);
|
||||
address += 4;
|
||||
pendingCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void postCycle(){
|
||||
if(pendingCount != 0 && !wr && (!ws->dStall || VL_RANDOM_I(7) < 100)){
|
||||
ws->dBusAccess(address,0,2,0,&top->dBus_rsp_payload_data,&error_next);
|
||||
top->dBus_rsp_valid = 1;
|
||||
address += 4;
|
||||
pendingCount--;
|
||||
} else{
|
||||
top->dBus_rsp_valid = 0;
|
||||
top->dBus_rsp_payload_data = VL_RANDOM_I(32);
|
||||
}
|
||||
|
||||
top->dBus_cmd_ready = (ws->dStall ? VL_RANDOM_I(7) < 100 : 1) && (pendingCount == 0 || wr);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void Workspace::fillSimELements(){
|
||||
|
||||
#ifdef IBUS_SIMPLE
|
||||
simElements.push_back(new IBusSimple(this));
|
||||
#endif
|
||||
|
@ -519,6 +572,9 @@ void Workspace::fillSimELements(){
|
|||
#ifdef DBUS_SIMPLE
|
||||
simElements.push_back(new DBusSimple(this));
|
||||
#endif
|
||||
#ifdef DBUS_CACHED
|
||||
simElements.push_back(new DBusCached(this));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -768,10 +824,12 @@ 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("dhrystoneO3ML",false,false).run(8e6);
|
||||
// Dhrystone("dhrystoneO3MLL",false,false).run(80e6);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
IBUS=IBUS_SIMPLE
|
||||
DBUS=DBUS_SIMPLE
|
||||
IBUS=IBUS_CACHED
|
||||
DBUS=DBUS_CACHED
|
||||
TRACE=no
|
||||
TRACE_START=0
|
||||
CSR=yes
|
||||
|
|
Loading…
Reference in New Issue