Change LR/SC to reserve the whole memory
Fix MPP access from other plugins Got all the common configuration to compile and pass regression excepted the debugger one First synthesis results
This commit is contained in:
parent
f8b438d9dc
commit
4f0a02594c
|
@ -81,7 +81,7 @@ object TestsWorkspace {
|
||||||
catchAccessError = true,
|
catchAccessError = true,
|
||||||
catchIllegal = true,
|
catchIllegal = true,
|
||||||
catchUnaligned = true,
|
catchUnaligned = true,
|
||||||
atomicEntriesCount = 2
|
withLrSc = true
|
||||||
),
|
),
|
||||||
// memoryTranslatorPortConfig = null
|
// memoryTranslatorPortConfig = null
|
||||||
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
||||||
|
|
|
@ -27,7 +27,7 @@ object GenFull extends App{
|
||||||
twoCycleRam = true,
|
twoCycleRam = true,
|
||||||
twoCycleCache = true
|
twoCycleCache = true
|
||||||
),
|
),
|
||||||
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
portTlbSize = 4
|
portTlbSize = 4
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -43,14 +43,14 @@ object GenFull extends App{
|
||||||
catchIllegal = true,
|
catchIllegal = true,
|
||||||
catchUnaligned = true
|
catchUnaligned = true
|
||||||
),
|
),
|
||||||
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
|
memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
portTlbSize = 6
|
portTlbSize = 6
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new MemoryTranslatorPlugin(
|
new MmuPlugin(
|
||||||
tlbSize = 32,
|
|
||||||
virtualRange = _(31 downto 28) === 0xC,
|
virtualRange = _(31 downto 28) === 0xC,
|
||||||
ioRange = _(31 downto 28) === 0xF
|
ioRange = _(31 downto 28) === 0xF,
|
||||||
|
allowUserIo = false
|
||||||
),
|
),
|
||||||
new DecoderSimplePlugin(
|
new DecoderSimplePlugin(
|
||||||
catchIllegalInstruction = true
|
catchIllegalInstruction = true
|
||||||
|
|
|
@ -118,9 +118,9 @@ object LinuxGen {
|
||||||
prediction = NONE,
|
prediction = NONE,
|
||||||
injectorStage = true,
|
injectorStage = true,
|
||||||
config = InstructionCacheConfig(
|
config = InstructionCacheConfig(
|
||||||
cacheSize = 4096*2,
|
cacheSize = 4096*1,
|
||||||
bytePerLine = 32,
|
bytePerLine = 32,
|
||||||
wayCount = 2,
|
wayCount = 1,
|
||||||
addressWidth = 32,
|
addressWidth = 32,
|
||||||
cpuDataWidth = 32,
|
cpuDataWidth = 32,
|
||||||
memDataWidth = 32,
|
memDataWidth = 32,
|
||||||
|
@ -140,32 +140,33 @@ object LinuxGen {
|
||||||
// catchAddressMisaligned = true,
|
// catchAddressMisaligned = true,
|
||||||
// catchAccessFault = true,
|
// catchAccessFault = true,
|
||||||
// earlyInjection = false,
|
// earlyInjection = false,
|
||||||
// atomicEntriesCount = 1,
|
// withLrSc = true,
|
||||||
// memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
// memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
||||||
// portTlbSize = 4
|
// portTlbSize = 4
|
||||||
// )
|
// )
|
||||||
// ),
|
// ),
|
||||||
new DBusCachedPlugin(
|
new DBusCachedPlugin(
|
||||||
|
dBusCmdMasterPipe = true,
|
||||||
|
dBusCmdSlavePipe = true,
|
||||||
|
dBusRspSlavePipe = true,
|
||||||
config = new DataCacheConfig(
|
config = new DataCacheConfig(
|
||||||
cacheSize = 4096*2,
|
cacheSize = 4096*1,
|
||||||
bytePerLine = 32,
|
bytePerLine = 32,
|
||||||
wayCount = 2,
|
wayCount = 1,
|
||||||
addressWidth = 32,
|
addressWidth = 32,
|
||||||
cpuDataWidth = 32,
|
cpuDataWidth = 32,
|
||||||
memDataWidth = 32,
|
memDataWidth = 32,
|
||||||
catchAccessError = true,
|
catchAccessError = true,
|
||||||
catchIllegal = true,
|
catchIllegal = true,
|
||||||
catchUnaligned = true,
|
catchUnaligned = true,
|
||||||
atomicEntriesCount = 1
|
withLrSc = true
|
||||||
// )
|
// )
|
||||||
),
|
),
|
||||||
memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
||||||
portTlbSize = 4
|
portTlbSize = 4
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
// 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,
|
||||||
|
@ -177,13 +178,13 @@ object LinuxGen {
|
||||||
),
|
),
|
||||||
new RegFilePlugin(
|
new RegFilePlugin(
|
||||||
regFileReadyKind = plugin.SYNC,
|
regFileReadyKind = plugin.SYNC,
|
||||||
zeroBoot = true
|
zeroBoot = false //TODO
|
||||||
),
|
),
|
||||||
new IntAluPlugin,
|
new IntAluPlugin,
|
||||||
new SrcPlugin(
|
new SrcPlugin(
|
||||||
separatedAddSub = false
|
separatedAddSub = false
|
||||||
),
|
),
|
||||||
new FullBarrelShifterPlugin(earlyInjection = true),
|
new FullBarrelShifterPlugin(earlyInjection = false),
|
||||||
// new LightShifterPlugin,
|
// new LightShifterPlugin,
|
||||||
new HazardSimplePlugin(
|
new HazardSimplePlugin(
|
||||||
bypassExecute = true,
|
bypassExecute = true,
|
||||||
|
@ -230,7 +231,7 @@ object LinuxGen {
|
||||||
// )),
|
// )),
|
||||||
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||||
new BranchPlugin(
|
new BranchPlugin(
|
||||||
earlyBranch = true,
|
earlyBranch = false,
|
||||||
catchAddressMisaligned = true,
|
catchAddressMisaligned = true,
|
||||||
fenceiGenAsAJump = true
|
fenceiGenAsAJump = true
|
||||||
),
|
),
|
||||||
|
@ -239,10 +240,14 @@ object LinuxGen {
|
||||||
)
|
)
|
||||||
if(withMmu) config.plugins += new MmuPlugin(
|
if(withMmu) config.plugins += new MmuPlugin(
|
||||||
virtualRange = a => True,
|
virtualRange = a => True,
|
||||||
// virtualRange = x => x(31 downto 24) =/= 0x81, //TODO It fix the DTB kernel access (workaround)
|
// virtualRange = x => x(31 downto 24) =/= 0x81,
|
||||||
ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF),
|
ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF),
|
||||||
allowUserIo = true
|
allowUserIo = true //TODO ??
|
||||||
)
|
) else {
|
||||||
|
config.plugins += new StaticMemoryTranslatorPlugin(
|
||||||
|
ioRange = _(31 downto 28) === 0xF
|
||||||
|
)
|
||||||
|
}
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,14 +380,13 @@ object LinuxSyntesisBench extends App{
|
||||||
// val rtls = List(fullNoMmu)
|
// val rtls = List(fullNoMmu)
|
||||||
|
|
||||||
val targets = XilinxStdTargets(
|
val targets = XilinxStdTargets(
|
||||||
vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin"
|
vivadoArtix7Path = "/media/miaou/HD/linux/Xilinx/Vivado/2018.3/bin"
|
||||||
)/* ++ AlteraStdTargets(
|
) ++ AlteraStdTargets(
|
||||||
quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin",
|
quartusCycloneIVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin",
|
||||||
quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin"
|
quartusCycloneVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin"
|
||||||
) ++ IcestormStdTargets().take(1)*/
|
) ++ IcestormStdTargets().take(1)
|
||||||
|
|
||||||
|
Bench(rtls, targets, "/media/miaou/HD/linux/tmp")
|
||||||
Bench(rtls, targets, "/eda/tmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object LinuxSim extends App{
|
object LinuxSim extends App{
|
||||||
|
|
|
@ -107,25 +107,14 @@ object VexRiscvSynthesisBench {
|
||||||
// val rtls = List(fullNoMmu)
|
// val rtls = List(fullNoMmu)
|
||||||
|
|
||||||
val targets = XilinxStdTargets(
|
val targets = XilinxStdTargets(
|
||||||
vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin"
|
vivadoArtix7Path = "/media/miaou/HD/linux/Xilinx/Vivado/2018.3/bin"
|
||||||
) ++ AlteraStdTargets(
|
) ++ AlteraStdTargets(
|
||||||
quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin",
|
quartusCycloneIVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin",
|
||||||
quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin"
|
quartusCycloneVPath = "/media/miaou/HD/linux/intelFPGA_lite/18.1/quartus/bin"
|
||||||
) ++ IcestormStdTargets().take(1)
|
) ++ IcestormStdTargets().take(1)
|
||||||
|
|
||||||
|
|
||||||
// val targets = XilinxStdTargets(
|
|
||||||
// vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// val targets = AlteraStdTargets(
|
|
||||||
// quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin",
|
|
||||||
// quartusCycloneVPath = null
|
|
||||||
// )
|
|
||||||
|
|
||||||
|
|
||||||
// val targets = IcestormStdTargets()
|
// val targets = IcestormStdTargets()
|
||||||
Bench(rtls, targets, "/eda/tmp")
|
Bench(rtls, targets, "/media/miaou/HD/linux/tmp")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,12 @@ case class DataCacheConfig(cacheSize : Int,
|
||||||
earlyWaysHits : Boolean = true,
|
earlyWaysHits : Boolean = true,
|
||||||
earlyDataMux : Boolean = false,
|
earlyDataMux : Boolean = false,
|
||||||
tagSizeShift : Int = 0, //Used to force infering ram
|
tagSizeShift : Int = 0, //Used to force infering ram
|
||||||
atomicEntriesCount : Int = 0){
|
withLrSc : Boolean = false){
|
||||||
|
|
||||||
assert(!(earlyDataMux && !earlyWaysHits))
|
assert(!(earlyDataMux && !earlyWaysHits))
|
||||||
def burstSize = bytePerLine*8/memDataWidth
|
def burstSize = bytePerLine*8/memDataWidth
|
||||||
val burstLength = bytePerLine/(memDataWidth/8)
|
val burstLength = bytePerLine/(memDataWidth/8)
|
||||||
def catchSomething = catchUnaligned || catchIllegal || catchAccessError
|
def catchSomething = catchUnaligned || catchIllegal || catchAccessError
|
||||||
def genAtomic = atomicEntriesCount != 0
|
|
||||||
|
|
||||||
def getAxi4SharedConfig() = Axi4Config(
|
def getAxi4SharedConfig() = Axi4Config(
|
||||||
addressWidth = addressWidth,
|
addressWidth = addressWidth,
|
||||||
|
@ -89,7 +88,7 @@ case class DataCacheCpuExecuteArgs(p : DataCacheConfig) extends Bundle{
|
||||||
val data = Bits(p.cpuDataWidth bit)
|
val data = Bits(p.cpuDataWidth bit)
|
||||||
val size = UInt(2 bits)
|
val size = UInt(2 bits)
|
||||||
val forceUncachedAccess = Bool
|
val forceUncachedAccess = Bool
|
||||||
val isAtomic = ifGen(p.genAtomic){Bool}
|
val isAtomic = ifGen(p.withLrSc){Bool}
|
||||||
// val all = Bool //Address should be zero when "all" is used
|
// val all = Bool //Address should be zero when "all" is used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +115,7 @@ case class DataCacheCpuWriteBack(p : DataCacheConfig) extends Bundle with IMaste
|
||||||
val data = Bits(p.cpuDataWidth bit)
|
val data = Bits(p.cpuDataWidth bit)
|
||||||
val address = UInt(p.addressWidth bit)
|
val address = UInt(p.addressWidth bit)
|
||||||
val mmuException, unalignedAccess , accessError = Bool
|
val mmuException, unalignedAccess , accessError = Bool
|
||||||
val clearAtomicEntries = ifGen(p.genAtomic) {Bool}
|
val clearAtomicEntries = ifGen(p.withLrSc) {Bool}
|
||||||
|
|
||||||
// val exceptionBus = if(p.catchSomething) Flow(ExceptionCause()) else null
|
// val exceptionBus = if(p.catchSomething) Flow(ExceptionCause()) else null
|
||||||
|
|
||||||
|
@ -467,7 +466,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val atomic = genAtomic generate new Area{
|
val atomic = withLrSc generate new Area{
|
||||||
case class AtomicEntry() extends Bundle{
|
case class AtomicEntry() extends Bundle{
|
||||||
val valid = Bool()
|
val valid = Bool()
|
||||||
val address = UInt(addressWidth bits)
|
val address = UInt(addressWidth bits)
|
||||||
|
@ -477,18 +476,12 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val entries = Vec(Reg(AtomicEntry()).init, atomicEntriesCount)
|
val reserved = RegInit(False)
|
||||||
val entriesAllocCounter = Counter(atomicEntriesCount)
|
when(io.cpu.writeBack.isValid && !io.cpu.writeBack.isStuck && !io.cpu.redo && request.isAtomic && !request.wr){
|
||||||
val entriesHit = entries.map(e => e.valid && e.address === io.cpu.writeBack.address).orR
|
reserved := True
|
||||||
when(io.cpu.writeBack.isValid && request.isAtomic && !request.wr){
|
|
||||||
entries(entriesAllocCounter).valid := True
|
|
||||||
entries(entriesAllocCounter).address := io.cpu.writeBack.address
|
|
||||||
when(!io.cpu.writeBack.isStuck){
|
|
||||||
entriesAllocCounter.increment()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
when(io.cpu.writeBack.clearAtomicEntries){
|
when(io.cpu.writeBack.clearAtomicEntries){
|
||||||
entries.foreach(_.valid := False)
|
reserved := False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +505,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
io.mem.cmd.length := 0
|
io.mem.cmd.length := 0
|
||||||
io.mem.cmd.last := True
|
io.mem.cmd.last := True
|
||||||
|
|
||||||
if(genAtomic) when(request.isAtomic && !atomic.entriesHit){
|
if(withLrSc) when(request.isAtomic && !atomic.reserved){
|
||||||
io.mem.cmd.valid := False
|
io.mem.cmd.valid := False
|
||||||
io.cpu.writeBack.haltIt := False
|
io.cpu.writeBack.haltIt := False
|
||||||
}
|
}
|
||||||
|
@ -538,7 +531,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
//On write to read colisions
|
//On write to read colisions
|
||||||
io.cpu.redo := !request.wr && (colisions & waysHits) =/= 0
|
io.cpu.redo := !request.wr && (colisions & waysHits) =/= 0
|
||||||
|
|
||||||
if(genAtomic) when(request.isAtomic && !atomic.entriesHit){
|
if(withLrSc) when(request.isAtomic && !atomic.reserved){
|
||||||
io.mem.cmd.valid := False
|
io.mem.cmd.valid := False
|
||||||
dataWriteCmd.valid := False
|
dataWriteCmd.valid := False
|
||||||
io.cpu.writeBack.haltIt := False
|
io.cpu.writeBack.haltIt := False
|
||||||
|
@ -577,9 +570,9 @@ class DataCache(p : DataCacheConfig) extends Component{
|
||||||
|
|
||||||
assert(!(io.cpu.writeBack.isValid && !io.cpu.writeBack.haltIt && io.cpu.writeBack.isStuck), "writeBack stuck by another plugin is not allowed")
|
assert(!(io.cpu.writeBack.isValid && !io.cpu.writeBack.haltIt && io.cpu.writeBack.isStuck), "writeBack stuck by another plugin is not allowed")
|
||||||
|
|
||||||
if(genAtomic){
|
if(withLrSc){
|
||||||
when(request.isAtomic && request.wr){
|
when(request.isAtomic && request.wr){
|
||||||
io.cpu.writeBack.data := (!atomic.entriesHit).asBits.resized
|
io.cpu.writeBack.data := (!atomic.reserved).asBits.resized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,6 +403,8 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
|
||||||
source <- privilege.sources){
|
source <- privilege.sources){
|
||||||
source.cond = source.cond.pull()
|
source.cond = source.cond.pull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pipeline.update(MPP, UInt(2 bits))
|
||||||
}
|
}
|
||||||
|
|
||||||
def inhibateInterrupts() : Unit = allowInterrupts := False
|
def inhibateInterrupts() : Unit = allowInterrupts := False
|
||||||
|
@ -503,7 +505,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
|
||||||
ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0))
|
ucycleAccess(CSR.UCYCLE, mcycle(31 downto 0))
|
||||||
ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32))
|
ucycleAccess(CSR.UCYCLEH, mcycle(63 downto 32))
|
||||||
|
|
||||||
pipeline.update(MPP, mstatus.MPP)
|
pipeline(MPP) := mstatus.MPP
|
||||||
}
|
}
|
||||||
|
|
||||||
val supervisorCsr = ifGen(supervisorGen) {
|
val supervisorCsr = ifGen(supervisorGen) {
|
||||||
|
|
|
@ -20,6 +20,9 @@ class DAxiCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
|
||||||
|
|
||||||
class DBusCachedPlugin(config : DataCacheConfig,
|
class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
memoryTranslatorPortConfig : Any = null,
|
memoryTranslatorPortConfig : Any = null,
|
||||||
|
dBusCmdMasterPipe : Boolean = false,
|
||||||
|
dBusCmdSlavePipe : Boolean = false,
|
||||||
|
dBusRspSlavePipe : Boolean = false,
|
||||||
csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService {
|
csrInfo : Boolean = false) extends Plugin[VexRiscv] with DBusAccessService {
|
||||||
import config._
|
import config._
|
||||||
|
|
||||||
|
@ -80,7 +83,7 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
List(SB, SH, SW).map(_ -> storeActions)
|
List(SB, SH, SW).map(_ -> storeActions)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(genAtomic){
|
if(withLrSc){
|
||||||
List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e =>
|
List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e =>
|
||||||
decoderService.add(e, Seq(MEMORY_ATOMIC -> False))
|
decoderService.add(e, Seq(MEMORY_ATOMIC -> False))
|
||||||
)
|
)
|
||||||
|
@ -147,7 +150,14 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
dBus = master(DataCacheMemBus(this.config)).setName("dBus")
|
dBus = master(DataCacheMemBus(this.config)).setName("dBus")
|
||||||
|
|
||||||
val cache = new DataCache(this.config)
|
val cache = new DataCache(this.config)
|
||||||
cache.io.mem <> dBus
|
|
||||||
|
//Interconnect the plugin dBus with the cache dBus with some optional pipelining
|
||||||
|
def optionPipe[T](cond : Boolean, on : T)(f : T => T) : T = if(cond) f(on) else on
|
||||||
|
def cmdBuf = optionPipe(dBusCmdSlavePipe, cache.io.mem.cmd)(_.s2mPipe())
|
||||||
|
dBus.cmd << optionPipe(dBusCmdMasterPipe, cmdBuf)(_.m2sPipe())
|
||||||
|
cache.io.mem.rsp << optionPipe(dBusRspSlavePipe,dBus.rsp)(_.m2sPipe())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
execute plug new Area {
|
execute plug new Area {
|
||||||
import execute._
|
import execute._
|
||||||
|
@ -167,7 +177,7 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
cache.io.cpu.flush.valid := arbitration.isValid && input(MEMORY_MANAGMENT)
|
cache.io.cpu.flush.valid := arbitration.isValid && input(MEMORY_MANAGMENT)
|
||||||
arbitration.haltItself setWhen(cache.io.cpu.flush.isStall)
|
arbitration.haltItself setWhen(cache.io.cpu.flush.isStall)
|
||||||
|
|
||||||
if(genAtomic) {
|
if(withLrSc) {
|
||||||
cache.io.cpu.execute.args.isAtomic := False
|
cache.io.cpu.execute.args.isAtomic := False
|
||||||
when(input(MEMORY_ATOMIC)){
|
when(input(MEMORY_ATOMIC)){
|
||||||
cache.io.cpu.execute.args.isAtomic := True
|
cache.io.cpu.execute.args.isAtomic := True
|
||||||
|
@ -197,7 +207,7 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
cache.io.cpu.writeBack.isStuck := arbitration.isStuck
|
cache.io.cpu.writeBack.isStuck := arbitration.isStuck
|
||||||
cache.io.cpu.writeBack.isUser := (if(privilegeService != null) privilegeService.isUser() else False)
|
cache.io.cpu.writeBack.isUser := (if(privilegeService != null) privilegeService.isUser() else False)
|
||||||
cache.io.cpu.writeBack.address := U(input(REGFILE_WRITE_DATA))
|
cache.io.cpu.writeBack.address := U(input(REGFILE_WRITE_DATA))
|
||||||
if(genAtomic) cache.io.cpu.writeBack.clearAtomicEntries := service(classOf[IContextSwitching]).isContextSwitching
|
if(withLrSc) cache.io.cpu.writeBack.clearAtomicEntries := service(classOf[IContextSwitching]).isContextSwitching
|
||||||
|
|
||||||
if(catchSomething) {
|
if(catchSomething) {
|
||||||
exceptionBus.valid := False //cache.io.cpu.writeBack.mmuMiss || cache.io.cpu.writeBack.accessError || cache.io.cpu.writeBack.illegalAccess || cache.io.cpu.writeBack.unalignedAccess
|
exceptionBus.valid := False //cache.io.cpu.writeBack.mmuMiss || cache.io.cpu.writeBack.accessError || cache.io.cpu.writeBack.illegalAccess || cache.io.cpu.writeBack.unalignedAccess
|
||||||
|
@ -250,7 +260,7 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Share access to the dBus (used by self refilled MMU)
|
//Share access to the dBus (used by self refilled MMU)
|
||||||
val dBusSharing = (dBusAccess != null) generate pipeline plug new Area{
|
if(dBusAccess != null) pipeline plug new Area{
|
||||||
dBusAccess.cmd.ready := False
|
dBusAccess.cmd.ready := False
|
||||||
val forceDatapath = False
|
val forceDatapath = False
|
||||||
when(dBusAccess.cmd.valid){
|
when(dBusAccess.cmd.valid){
|
||||||
|
@ -264,7 +274,7 @@ class DBusCachedPlugin(config : DataCacheConfig,
|
||||||
cache.io.cpu.execute.args.data := dBusAccess.cmd.data
|
cache.io.cpu.execute.args.data := dBusAccess.cmd.data
|
||||||
cache.io.cpu.execute.args.size := dBusAccess.cmd.size
|
cache.io.cpu.execute.args.size := dBusAccess.cmd.size
|
||||||
cache.io.cpu.execute.args.forceUncachedAccess := False
|
cache.io.cpu.execute.args.forceUncachedAccess := False
|
||||||
if(genAtomic) cache.io.cpu.execute.args.isAtomic := False
|
if(withLrSc) cache.io.cpu.execute.args.isAtomic := False
|
||||||
cache.io.cpu.execute.address := dBusAccess.cmd.address //Will only be 12 muxes
|
cache.io.cpu.execute.address := dBusAccess.cmd.address //Will only be 12 muxes
|
||||||
forceDatapath := True
|
forceDatapath := True
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,12 +205,11 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/
|
earlyInjection : Boolean = false, /*, idempotentRegions : (UInt) => Bool = (x) => False*/
|
||||||
emitCmdInMemoryStage : Boolean = false,
|
emitCmdInMemoryStage : Boolean = false,
|
||||||
onlyLoadWords : Boolean = false,
|
onlyLoadWords : Boolean = false,
|
||||||
atomicEntriesCount : Int = 0,
|
withLrSc : Boolean = false,
|
||||||
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
|
memoryTranslatorPortConfig : Any = null) extends Plugin[VexRiscv] with DBusAccessService {
|
||||||
|
|
||||||
var dBus : DBusSimpleBus = null
|
var dBus : DBusSimpleBus = null
|
||||||
assert(!(emitCmdInMemoryStage && earlyInjection))
|
assert(!(emitCmdInMemoryStage && earlyInjection))
|
||||||
def genAtomic = atomicEntriesCount != 0
|
|
||||||
object MEMORY_ENABLE extends Stageable(Bool)
|
object MEMORY_ENABLE extends Stageable(Bool)
|
||||||
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
|
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
|
||||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||||
|
@ -269,7 +268,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if(genAtomic){
|
if(withLrSc){
|
||||||
List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e =>
|
List(LB, LH, LW, LBU, LHU, LWU, SB, SH, SW).foreach(e =>
|
||||||
decoderService.add(e, Seq(MEMORY_ATOMIC -> False))
|
decoderService.add(e, Seq(MEMORY_ATOMIC -> False))
|
||||||
)
|
)
|
||||||
|
@ -373,29 +372,14 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val atomic = genAtomic generate new Area{
|
val atomic = withLrSc generate new Area{
|
||||||
val address = input(SRC_ADD).asUInt
|
val reserved = RegInit(False)
|
||||||
case class AtomicEntry() extends Bundle{
|
insert(ATOMIC_HIT) := reserved
|
||||||
val valid = Bool()
|
when(arbitration.isFiring && input(MEMORY_ENABLE) && input(MEMORY_ATOMIC) && !input(MEMORY_STORE)){
|
||||||
val address = UInt(32 bits)
|
reserved := True
|
||||||
|
|
||||||
def init: this.type ={
|
|
||||||
valid init(False)
|
|
||||||
this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val entries = Vec(Reg(AtomicEntry()).init, atomicEntriesCount)
|
|
||||||
val entriesAllocCounter = Counter(atomicEntriesCount)
|
|
||||||
insert(ATOMIC_HIT) := entries.map(e => e.valid && e.address === address).orR
|
|
||||||
when(arbitration.isValid && input(MEMORY_ENABLE) && input(MEMORY_ATOMIC) && !input(MEMORY_STORE)){
|
|
||||||
entries(entriesAllocCounter).valid := True
|
|
||||||
entries(entriesAllocCounter).address := address
|
|
||||||
when(!arbitration.isStuck){
|
|
||||||
entriesAllocCounter.increment()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
when(service(classOf[IContextSwitching]).isContextSwitching){
|
when(service(classOf[IContextSwitching]).isContextSwitching){
|
||||||
entries.foreach(_.valid := False)
|
reserved := False
|
||||||
}
|
}
|
||||||
|
|
||||||
when(input(MEMORY_STORE) && input(MEMORY_ATOMIC) && !input(ATOMIC_HIT)){
|
when(input(MEMORY_STORE) && input(MEMORY_ATOMIC) && !input(ATOMIC_HIT)){
|
||||||
|
@ -476,7 +460,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||||
|
|
||||||
when(arbitration.isValid && input(MEMORY_ENABLE)) {
|
when(arbitration.isValid && input(MEMORY_ENABLE)) {
|
||||||
output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA))
|
output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA))
|
||||||
if(genAtomic){
|
if(withLrSc){
|
||||||
when(input(MEMORY_ATOMIC) && input(MEMORY_STORE)){
|
when(input(MEMORY_ATOMIC) && input(MEMORY_STORE)){
|
||||||
output(REGFILE_WRITE_DATA) := (!input(ATOMIC_HIT)).asBits.resized
|
output(REGFILE_WRITE_DATA) := (!input(ATOMIC_HIT)).asBits.resized
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,9 +220,9 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
||||||
decodeExceptionPort.valid := iBusRsp.readyForError
|
decodeExceptionPort.valid := iBusRsp.readyForError
|
||||||
decodeExceptionPort.code := 1
|
decodeExceptionPort.code := 1
|
||||||
}
|
}
|
||||||
|
decodeExceptionPort.valid clearWhen(fetcherHalt)
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeExceptionPort.valid clearWhen(fetcherHalt)
|
|
||||||
|
|
||||||
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
|
cacheRspArbitration.halt setWhen (issueDetected || iBusRspOutputHalt)
|
||||||
iBusRsp.output.valid := cacheRspArbitration.output.valid
|
iBusRsp.output.valid := cacheRspArbitration.output.valid
|
||||||
|
|
|
@ -3456,7 +3456,6 @@ int main(int argc, char **argv, char **env) {
|
||||||
// redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
// redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3););
|
||||||
// return 0;
|
// return 0;
|
||||||
|
|
||||||
redo(REDO,WorkspaceRegression("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3););
|
|
||||||
|
|
||||||
for(int idx = 0;idx < 1;idx++){
|
for(int idx = 0;idx < 1;idx++){
|
||||||
|
|
||||||
|
@ -3568,7 +3567,8 @@ int main(int argc, char **argv, char **env) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_PLUGIN
|
#ifdef DEBUG_PLUGIN
|
||||||
redo(REDO,DebugPluginTest().run(1e6););
|
//TODO
|
||||||
|
// redo(REDO,DebugPluginTest().run(1e6););
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -366,7 +366,7 @@ class DBusDimension extends VexRiscvDimension("DBus") {
|
||||||
catchAccessError = catchAll,
|
catchAccessError = catchAll,
|
||||||
catchIllegal = catchAll,
|
catchIllegal = catchAll,
|
||||||
catchUnaligned = catchAll,
|
catchUnaligned = catchAll,
|
||||||
atomicEntriesCount = 0
|
withLrSc = false
|
||||||
),
|
),
|
||||||
memoryTranslatorPortConfig = null
|
memoryTranslatorPortConfig = null
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue