#60 Got instruction cache running linux :D

This commit is contained in:
Charles Papon 2019-04-01 11:59:04 +02:00
parent 1dff9aff8a
commit bc0af02c97
17 changed files with 74 additions and 73 deletions

View File

@ -56,7 +56,6 @@ object TestsWorkspace {
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = false,
twoCycleCache = true

View File

@ -65,7 +65,6 @@ object BrieyConfig{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -23,7 +23,6 @@ object GenFull extends App{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -27,7 +27,6 @@ object GenFullNoMmu extends App{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -28,7 +28,6 @@ object GenFullNoMmuMaxPerf extends App{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = false,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -26,7 +26,6 @@ object GenSmallAndProductiveICache extends App{
memDataWidth = 32,
catchIllegalAccess = false,
catchAccessFault = false,
catchMemoryTranslationMiss = false,
asyncTagMemory = false,
twoCycleRam = false,
twoCycleCache = true

View File

@ -40,13 +40,13 @@ cd VexRiscv
Run regressions =>
sbt "runMain vexriscv.demo.LinuxGen -r"
cd src/test/cpp/regression
make run DBUS=SIMPLE IBUS=SIMPLE DHRYSTONE=yes SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=10 TRACE=no
make run IBUS=CACHED DBUS=SIMPLE DEBUG_PLUGIN=no DHRYSTONE=yes SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=10 TRACE=no
Run linux in simulation (Require the machime mode emulator compiled in SIM mode) =>
sbt "runMain vexriscv.demo.LinuxGen"
cd src/test/cpp/regression
export BUILDROOT=/home/miaou/pro/riscv/buildrootSpinal
make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=../../../main/c/emulator/build/emulator.bin VMLINUX=$BUILDROOT/output/images/vmlinux.bin DTB=$BUILDROOT/board/spinal/vexriscv_sim/rv32.dtb RAMDISK=$BUILDROOT/output/images/rootfs.cpio TRACE=no FLOW_INFO=no
make run IBUS=CACHED DBUS=SIMPLE DEBUG_PLUGIN=no SUPERVISOR=yes CSR=yes COMPRESSED=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=../../../main/c/emulator/build/emulator.bin VMLINUX=$BUILDROOT/output/images/vmlinux.bin DTB=$BUILDROOT/board/spinal/vexriscv_sim/rv32.dtb RAMDISK=$BUILDROOT/output/images/rootfs.cpio TRACE=no FLOW_INFO=no
Run linux with QEMU (Require the machime mode emulator compiled in QEMU mode)
export BUILDROOT=/home/miaou/pro/riscv/buildrootSpinal
@ -94,43 +94,46 @@ object LinuxGen {
val config = VexRiscvConfig(
plugins = List(
new DummyFencePlugin(), //TODO should be removed for design with caches
new IBusSimplePlugin(
//Uncomment the whole IBusSimplePlugin and comment IBusCachedPlugin if you want uncached iBus config
// new IBusSimplePlugin(
// resetVector = 0x80000000l,
// cmdForkOnSecondStage = false,
// cmdForkPersistence = false,
// prediction = NONE,
// historyRamSizeLog2 = 10,
// catchAccessFault = true,
// compressedGen = true,
// busLatencyMin = 1,
// injectorStage = true,
// memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
// portTlbSize = 4
// )
// ),
//Uncomment the whole IBusCachedPlugin and comment IBusSimplePlugin if you want cached iBus config
new IBusCachedPlugin(
resetVector = 0x80000000l,
cmdForkOnSecondStage = false,
cmdForkPersistence = false,
prediction = NONE,
historyRamSizeLog2 = 10,
catchAccessFault = true,
compressedGen = true,
busLatencyMin = 1,
prediction = NONE,
injectorStage = true,
memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
config = InstructionCacheConfig(
cacheSize = 4096,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
asyncTagMemory = false,
twoCycleRam = false,
twoCycleCache = true
),
memoryTranslatorPortConfig = MmuPortConfig(
portTlbSize = 4
)
),
// new IBusCachedPlugin(
// resetVector = 0x80000000l,
// compressedGen = false,
// prediction = NONE,
// injectorStage = true,
// config = InstructionCacheConfig(
// cacheSize = 4096,
// bytePerLine = 32,
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = true,
// catchAccessFault = true,
// catchMemoryTranslationMiss = true,
// asyncTagMemory = false,
// twoCycleRam = false,
// twoCycleCache = true
// ),
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
// ),
// ).newTightlyCoupledPort(TightlyCoupledPortParameter("iBusTc", a => a(30 downto 28) === 0x0 && a(5))),
new DBusSimplePlugin(
catchAddressMisaligned = true,
@ -225,7 +228,7 @@ object LinuxGen {
// wfiGenAsNop = true,
// ucycleAccess = CsrAccess.NONE
// )),
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = true,
catchAddressMisaligned = true,

View File

@ -48,7 +48,6 @@ object VexRiscvAvalonForSim{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true
)

View File

@ -44,7 +44,6 @@ object VexRiscvAvalonWithIntegratedJtag{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -45,7 +45,6 @@ object VexRiscvAxi4WithIntegratedJtag{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true,
twoCycleCache = true

View File

@ -44,7 +44,6 @@ object VexRiscvCachedWishboneForSim{
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = true
)

View File

@ -17,7 +17,6 @@ case class InstructionCacheConfig( cacheSize : Int,
memDataWidth : Int,
catchIllegalAccess : Boolean,
catchAccessFault : Boolean,
catchMemoryTranslationMiss : Boolean,
asyncTagMemory : Boolean,
twoCycleCache : Boolean = true,
twoCycleRam : Boolean = false,
@ -26,7 +25,7 @@ case class InstructionCacheConfig( cacheSize : Int,
assert(!(twoCycleRam && !twoCycleCache))
def burstSize = bytePerLine*8/memDataWidth
def catchSomething = catchAccessFault || catchMemoryTranslationMiss || catchIllegalAccess
def catchSomething = catchAccessFault || catchIllegalAccess
def getAxi4Config() = Axi4Config(
addressWidth = addressWidth,
@ -86,7 +85,7 @@ trait InstructionCacheCommons{
val pc : UInt
val physicalAddress : UInt
val data : Bits
val cacheMiss, error, mmuMiss, illegalAccess, isUser : Bool
val cacheMiss, error, mmuRefilling, mmuException, isUser : Bool
}
case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle with IMasterSlave with InstructionCacheCommons {
@ -99,11 +98,11 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
val dataBypass = Bits(p.cpuDataWidth bits)
val mmuBus = MemoryTranslatorBus()
val physicalAddress = UInt(p.addressWidth bits)
val cacheMiss, error, mmuMiss, illegalAccess,isUser = ifGen(!p.twoCycleCache)(Bool)
val cacheMiss, error, mmuRefilling, mmuException, isUser = ifGen(!p.twoCycleCache)(Bool)
override def asMaster(): Unit = {
out(isValid, isStuck, isRemoved, pc)
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss,physicalAddress)
inWithNull(error,mmuRefilling,mmuException,data, cacheMiss,physicalAddress)
outWithNull(isUser, dataBypass, dataBypassValid)
slaveWithNull(mmuBus)
}
@ -116,12 +115,12 @@ case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle
val pc = UInt(p.addressWidth bits)
val physicalAddress = UInt(p.addressWidth bits)
val data = Bits(p.cpuDataWidth bits)
val cacheMiss, error, mmuMiss, illegalAccess, isUser = ifGen(p.twoCycleCache)(Bool)
val cacheMiss, error, mmuRefilling, mmuException, isUser = ifGen(p.twoCycleCache)(Bool)
override def asMaster(): Unit = {
out(isValid, isStuck, pc)
outWithNull(isUser)
inWithNull(error,mmuMiss,illegalAccess,data, cacheMiss, physicalAddress)
inWithNull(error, mmuRefilling, mmuException,data, cacheMiss, physicalAddress)
}
}
@ -411,8 +410,8 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
io.cpu.fetch.cacheMiss := !hit.valid
io.cpu.fetch.error := hit.error
io.cpu.fetch.mmuMiss := ??? //TODO mmuRsp.miss
io.cpu.fetch.illegalAccess := !mmuRsp.allowExecute || (io.cpu.fetch.isUser && !mmuRsp.allowUser)
io.cpu.fetch.mmuRefilling := mmuRsp.refilling
io.cpu.fetch.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.fetch.isUser)) //TODO Do not allow supervisor if it's a user page ?
})
}
@ -441,8 +440,8 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
io.cpu.decode.cacheMiss := !hit.valid
io.cpu.decode.error := hit.error
io.cpu.decode.mmuMiss := ??? //TODO mmuRsp.miss
io.cpu.decode.illegalAccess := !mmuRsp.allowExecute || (io.cpu.decode.isUser && !mmuRsp.allowUser)
io.cpu.decode.mmuRefilling := mmuRsp.refilling
io.cpu.decode.mmuException := !mmuRsp.refilling && (mmuRsp.exception || !mmuRsp.allowExecute || (!mmuRsp.allowUser && io.cpu.decode.isUser)) //TODO Do not allow supervisor if it's a user page ?
io.cpu.decode.physicalAddress := mmuRsp.physicalAddress
})
}

View File

@ -807,7 +807,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
import lastStage._
//Manage MRET / SRET instructions
when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) {
when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { //TODO do not allow user mode already implemented somewhere else ?
fetcher.haltIt()
jumpInterface.valid := True
beforeLastStage.arbitration.flushAll := True

View File

@ -74,11 +74,11 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
super.setup(pipeline)
def MANAGEMENT = M"-----------------100-----0001111"
//def MANAGEMENT = M"-----------------100-----0001111"
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(FLUSH_ALL, False)
decoderService.add(MANAGEMENT, List(
decoderService.add(FENCE_I, List(
FLUSH_ALL -> True
))
@ -101,7 +101,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
val e = new BusReport()
val c = new CacheReport()
e.kind = "cached"
e.flushInstructions.add(0x400F) //invalid instruction cache
e.flushInstructions.add(0x100F) //FENCE.I
e.flushInstructions.add(0x13)
e.flushInstructions.add(0x13)
e.flushInstructions.add(0x13)
@ -187,7 +187,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
val cacheRspArbitration = stages(if (twoCycleCache) 2 else 1)
var issueDetected = False
val redoFetch = False //RegNext(False) init(False)
when(cacheRsp.isValid && cacheRsp.cacheMiss && !issueDetected) {
when(cacheRsp.isValid && (cacheRsp.cacheMiss || cacheRsp.mmuRefilling) && !issueDetected) {
issueDetected \= True
redoFetch := iBusRsp.readyForError
}
@ -201,19 +201,25 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
redoBranch.payload := (if (decodePcGen) decode.input(PC) else cacheRsp.pc)
if (catchSomething) {
val accessFault = if (catchAccessFault) cacheRsp.error else False
val mmuMiss = if (catchMemoryTranslationMiss) cacheRsp.mmuMiss else False
val illegalAccess = if (catchIllegalAccess) cacheRsp.illegalAccess else False
decodeExceptionPort.valid := False
decodeExceptionPort.code := mmuMiss ? U(14) | 1
decodeExceptionPort.code.assignDontCare()
decodeExceptionPort.badAddr := cacheRsp.pc
when(cacheRsp.isValid && (accessFault || mmuMiss || illegalAccess) && !issueDetected) {
if(catchIllegalAccess) when(cacheRsp.isValid && cacheRsp.mmuException && !issueDetected) {
issueDetected \= True
decodeExceptionPort.valid := iBusRsp.readyForError
decodeExceptionPort.code := 12
}
if(catchAccessFault) when(cacheRsp.isValid && cacheRsp.error && !issueDetected) {
issueDetected \= True
decodeExceptionPort.valid := iBusRsp.readyForError
decodeExceptionPort.code := 1
}
}
decodeExceptionPort.valid clearWhen(fetcherHalt)
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
iBusRsp.output.valid := cacheRspArbitration.output.valid
cacheRspArbitration.output.ready := iBusRsp.output.ready
@ -223,7 +229,6 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
if (mmuBus != null) {
cache.io.cpu.fetch.mmuBus <> mmuBus
(if (twoCycleCache) stages(1).halt else rsp.iBusRspOutputHalt) setWhen (mmuBus.cmd.isValid && ???) //TODO !mmuBus.rsp.hit && !mmuBus.rsp.miss
} else {
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
@ -231,9 +236,8 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
cache.io.cpu.fetch.mmuBus.rsp.allowWrite := True
cache.io.cpu.fetch.mmuBus.rsp.allowUser := True
cache.io.cpu.fetch.mmuBus.rsp.isIoAccess := False
??? //TODO
// cache.io.cpu.fetch.mmuBus.rsp.miss := False
// cache.io.cpu.fetch.mmuBus.rsp.hit := False
cache.io.cpu.fetch.mmuBus.rsp.exception := False
cache.io.cpu.fetch.mmuBus.rsp.refilling := False
}
val flushStage = if(memory != null) memory else execute

View File

@ -232,6 +232,7 @@ class success : public std::exception { };
class RiscvGolden {
public:
int32_t pc, lastPc;
uint32_t lastInstruction;
int32_t regs[32];
uint32_t mscratch, sscratch;
@ -706,6 +707,7 @@ public:
return;
}
}
lastInstruction = i;
currentInstruction = i;
if ((i & 0x3) == 0x3) {
//32 bit
@ -1584,7 +1586,11 @@ public:
staticMutex.unlock();
} catch (const std::exception& e) {
staticMutex.lock();
cout << "FAIL " << name << " at PC=" << hex << setw(8) << top->VexRiscv->writeBack_PC << dec << endl; //<< " seed : " << seed <<
cout << "FAIL " << name << " at PC=" << hex << setw(8) << top->VexRiscv->writeBack_PC << dec; //<< " seed : " << seed <<
if(riscvRefEnable) cout << hex << " REF PC=" << riscvRef.lastPc << " REF I=" << riscvRef.lastInstruction << dec;
cout << endl;
cycles += instanceCycles;
staticMutex.unlock();
failed = true;

View File

@ -27,7 +27,7 @@ REDO?=10
REF=no
TRACE_WITH_TIME=no
REF_TIME=no
THREAD_COUNT?=4
THREAD_COUNT?=$(shell nproc)
MTIME_INSTR_FACTOR?=no
COMPRESSED?=no
SUPERVISOR?=no

View File

@ -315,7 +315,6 @@ class IBusDimension extends VexRiscvDimension("IBus") {
memDataWidth = 32,
catchIllegalAccess = catchAll,
catchAccessFault = catchAll,
catchMemoryTranslationMiss = catchAll,
asyncTagMemory = false,
twoCycleRam = twoCycleRam,
twoCycleCache = twoCycleCache