Skip to content

Commit

Permalink
wip, now need io support
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 25, 2024
1 parent 754d7ed commit 87ee467
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 61 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/vexiiriscv/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class ParamSimple(){
// Debug modifiers
val debugParam = sys.env.getOrElse("VEXIIRISCV_DEBUG_PARAM", "0").toInt.toBoolean
if(debugParam) {
decoders = 2
lanes = 2
decoders = 1
lanes = 1
regFileSync = false
withGShare = true
withBtb = true
Expand Down
108 changes: 78 additions & 30 deletions src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ object LsuL1 extends AreaObject{
val MIXED_ADDRESS = Payload(Global.MIXED_ADDRESS)
val PHYSICAL_ADDRESS = Payload(Global.PHYSICAL_ADDRESS)
val WRITE_DATA = Payload(Bits(Riscv.LSLEN bits))
val WRITE_MASK = Payload(Bits(Riscv.LSLEN/8 bits))
val MASK = Payload(Bits(Riscv.LSLEN/8 bits)) //Also needed for loads

// L1 ->
val READ_DATA = Payload(Bits(Riscv.LSLEN bits))
val REDO, MISS, FAULT = Payload(Bool())
val HAZARD, MISS, MISS_UNIQUE, FAULT = Payload(Bool())
}

class LsuL1Plugin(val lane : ExecuteLaneService,
Expand Down Expand Up @@ -85,6 +85,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
val lineRange = tagRange.low - 1 downto log2Up(lineSize)
val refillRange = tagRange.high downto lineRange.low
val hazardCheckRange = hazardCheckWidth+lineRange.low-1 downto lineRange.low
val notWordRange = tagRange.high downto log2Up(cpuDataWidth/8)

val bankCount = wayCount
val bankWidth = if (!reducedBankWidth) memDataWidth else Math.max(cpuWordWidth, memDataWidth / wayCount)
Expand Down Expand Up @@ -134,6 +135,11 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
val PROBE_ID = Payload(UInt(probeIdWidth bits))
val FLUSH = Payload(Bool())
val FLUSH_FREE = Payload(Bool())
val WRITE_TO_READ_HAZARDS = Payload(Bits(ctrlAt - bankReadAt bits))
val EVENT_WRITE_VALID = Payload(Bool())
val EVENT_WRITE_ADDRESS = Payload(PHYSICAL_ADDRESS)
val EVENT_WRITE_DATA = Payload(WRITE_DATA)
val EVENT_WRITE_MASK = Payload(MASK)

val BANKS_MUXES = Payload(Vec.fill(bankCount)(Bits(cpuWordWidth bits)))

Expand Down Expand Up @@ -680,6 +686,14 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
}


val weh = new Area {
val dst = lane.execute(ctrlAt-1)
for(id <- 0 until widthOf(WRITE_TO_READ_HAZARDS)) {
val src = lane.execute(bankReadAt+id)
dst(WRITE_TO_READ_HAZARDS)(id) := src(EVENT_WRITE_VALID) && src(EVENT_WRITE_ADDRESS)(notWordRange) === dst(PHYSICAL_ADDRESS)(notWordRange) && (src(EVENT_WRITE_MASK) & dst(MASK)).orR
}
}

// translatedStage(PHYSICAL_ADDRESS) := io.load.translated.physical
// translatedStage(ABORD) := io.load.translated.abord
//
Expand Down Expand Up @@ -741,49 +755,61 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
}

val reservation = tagsWriteArbiter.create(2)
val bankWriteReservation = bankWriteArbiter.create(2)
val refillWayWithoutUpdate = CombInit(plruLogic.core.io.evict.id)
// val refillWayWithoutUpdate = CombInit(wayRandom.value)
val refillWayNeedWriteback = WAYS_TAGS.map(w => w.loaded && withCoherency.mux(True, w.dirty)).read(refillWayWithoutUpdate)
// val refillHit = REFILL_HITS.orR
// val refillLoaded = (B(refill.slots.map(_.loaded)) & REFILL_HITS).orR
val lineBusy = isLineBusy(PHYSICAL_ADDRESS)
val bankBusy = (BANK_BUSY_REMAPPED & WAYS_HITS) =/= 0
val waysHitHazard = (WAYS_HITS & WAYS_HAZARD).orR
val hitUnique = withCoherency.mux((WAYS_HITS & WAYS_TAGS.map(_.unique).asBits).orR, True)
val uniqueMiss = NEED_UNIQUE && !hitUnique
// val waysHitHazard = (WAYS_HITS & WAYS_HAZARD).orR
val waysHazard = WAYS_HAZARD.orR
// val hitUnique = withCoherency.mux((WAYS_HITS & WAYS_TAGS.map(_.unique).asBits).orR, True)
// val uniqueMiss = NEED_UNIQUE && !hitUnique
val wasDirty = (B(WAYS_TAGS.map(_.dirty)) & WAYS_HITS).orR
val refillWayWasDirty = WAYS_TAGS.map(w => w.loaded && w.dirty).read(refillWayWithoutUpdate)
val loadBankHazard = LOAD && WRITE_TO_READ_HAZARDS.orR.mux(True, bankBusy)

//TODO !!! refill / writeback slots valid can go false faster than the main pipeline !freeze => need fix
REDO := !WAYS_HIT || waysHitHazard || bankBusy || lineBusy || LOCKED || uniqueMiss || (!LOAD && !wasDirty && !reservation.win)
MISS := !WAYS_HIT && !waysHitHazard && !lineBusy && !LOCKED
FAULT := (WAYS_HITS & WAYS_TAGS.map(_.fault).asBits).orR
val canRefill = !refill.full && !lineBusy && reservation.win && !(refillWayNeedWriteback && writeback.full) && !WAYS_HAZARD(refillWayWithoutUpdate)
HAZARD := waysHazard || loadBankHazard || lineBusy || LOCKED //TODO Line busy can likely be removed if single hart with no prefetch
MISS := !HAZARD && !WAYS_HIT
FAULT := !HAZARD && WAYS_HIT && (WAYS_HITS & WAYS_TAGS.map(_.fault).asBits).orR
MISS_UNIQUE := !HAZARD && WAYS_HIT && NEED_UNIQUE && withCoherency.mux((WAYS_HITS & WAYS_TAGS.map(e => !e.unique && !e.fault).asBits).orR, False)

val canRefill = reservation.win && !(refillWayNeedWriteback && writeback.full) && !refill.full
val canFlush = False //reservation.win && !writeback.full && !refill.slots.map(_.valid).orR && !(WAYS_HAZARD).orR

val askRefill = MISS && canRefill
val askUpgrade = !MISS && canRefill && uniqueMiss
val startRefill = SEL && askRefill
val startUpgrade = SEL && askUpgrade
val askUpgrade = MISS_UNIQUE && canRefill

val doRefill = SEL && askRefill
val doUpgrade = SEL && askUpgrade
val doFlush = False
val doWrite = SEL && !HAZARD && !LOAD && WAYS_HIT && this(WAYS_TAGS).reader(WAYS_HITS)(w => withCoherency.mux(w.unique, True) && !w.fault)
val doDirty = doWrite && !wasDirty

val wayId = OHToUInt(WAYS_HITS)
val writeCache = SEL && !LOAD && !REDO
val setDirty = writeCache && !wasDirty

val bankHitId = if(!reducedBankWidth) wayId else (wayId >> log2Up(bankCount/memToBankRatio)) @@ ((wayId + (PHYSICAL_ADDRESS(log2Up(bankWidth/8), log2Up(bankCount) bits))).resize(log2Up(bankCount/memToBankRatio)))

//Only valid for FLUSH === TRUE
val needFlushs = B(WAYS_TAGS.map(w => w.loaded && w.dirty))
val needFlushOh = OHMasking.firstV2(needFlushs)
val needFlushSel = OHToUInt(needFlushOh)
val needFlush = needFlushs.orR
val canFlush = reservation.win && !writeback.full && !refill.slots.map(_.valid).orR && !(WAYS_HAZARD).orR
val startFlush = isValid && FLUSH && needFlush && canFlush

val refillWay = (!MISS && uniqueMiss).mux(wayId, refillWayWithoutUpdate)
// val needFlushs = B(WAYS_TAGS.map(w => w.loaded && w.dirty))
// val needFlushOh = OHMasking.firstV2(needFlushs)
// val needFlushSel = OHToUInt(needFlushOh)
// val needFlush = needFlushs.orR
// val startFlush = isValid && FLUSH && needFlush && canFlush

val refillWay = askUpgrade.mux(wayId, refillWayWithoutUpdate)
val allowSideEffects = !ABORD

assert(!startFlush)
// assert(!startFlush)

val freezeIt = SEL && !LOAD && (!bankWriteReservation.win || !reservation.win)
lane.freezeWhen(freezeIt)

//TODO preset dirty if it come from a store
refill.push.valid := allowSideEffects && (startRefill || startUpgrade)
refill.push.valid := allowSideEffects && (doRefill || doUpgrade)
refill.push.address := PHYSICAL_ADDRESS
refill.push.unique := NEED_UNIQUE
refill.push.data := askRefill
Expand All @@ -796,22 +822,44 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
}


when(startRefill || startUpgrade || setDirty || startFlush) {
assert(!doUpgrade)
assert(!doFlush)

when(doRefill || doUpgrade || doDirty || doFlush) {
reservation.takeIt()
waysWrite.mask(refillWay) := allowSideEffects
waysWrite.address := MIXED_ADDRESS(lineRange)
}
when(setDirty){
when(doDirty){
waysWrite.tag.loaded := True
waysWrite.tag.address := PHYSICAL_ADDRESS(tagRange)
waysWrite.tag.fault := FAULT
waysWrite.tag.fault := FAULT
waysWrite.tag.dirty := True
if(withCoherency) waysWrite.tag.unique := True
}
when(startRefill || startUpgrade){
when(doRefill || doUpgrade){
waysWrite.tag.loaded := False
}

when(startRefill) {
when(doWrite) {
for ((bank, bankId) <- banks.zipWithIndex) when(WAYS_HITS(bankId)) {
bank.write.valid := bankId === bankHitId && allowSideEffects
bank.write.address := PHYSICAL_ADDRESS(lineRange.high downto log2Up(bankWidth / 8))
bank.write.data.subdivideIn(cpuWordWidth bits).foreach(_ := WRITE_DATA)
bank.write.mask := 0
bank.write.mask.subdivideIn(cpuWordWidth / 8 bits)(PHYSICAL_ADDRESS(bankWordToCpuWordRange)) := MASK
}
}

val brs = lane.execute(bankReadAt)
brs(EVENT_WRITE_VALID) := doWrite
brs(EVENT_WRITE_ADDRESS) := PHYSICAL_ADDRESS
brs(EVENT_WRITE_DATA) := WRITE_DATA
brs(EVENT_WRITE_MASK) := MASK



when(doRefill) {
writeback.push.valid := refillWayNeedWriteback && allowSideEffects
writeback.push.address := (WAYS_TAGS(refillWay).address @@ MIXED_ADDRESS(lineRange)) << lineRange.low
writeback.push.way := refillWay
Expand All @@ -826,7 +874,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
plruLogic.core.io.update.id := refillWay
}

when(SEL && !REDO && !MISS) {
when(SEL && !HAZARD && !MISS) {
plru.write.valid := allowSideEffects
plruLogic.core.io.update.id := wayId
}
Expand Down
34 changes: 18 additions & 16 deletions src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LsuPlugin(var layer : LaneLayer,
atsStorageLock.release()

val trapPort = ts.newTrap(layer.el.getAge(ctrlAt), Execute.LANE_AGE_WIDTH)
val flushPort = ss.newFlushPort(layer.el.getExecuteAge(addressAt), laneAgeWidth = Execute.LANE_AGE_WIDTH, withUopId = true)
val flushPort = ss.newFlushPort(layer.el.getExecuteAge(ctrlAt), laneAgeWidth = Execute.LANE_AGE_WIDTH, withUopId = true)
val frontend = new AguFrontend(layer, host)

// IntFormatPlugin specification
Expand All @@ -58,13 +58,13 @@ class LsuPlugin(var layer : LaneLayer,
case true => ifp.signExtend(iwb, op, spec.width)
}
op.mayFlushUpTo(ctrlAt) // page fault / trap
op.dontFlushFrom(ctrlAt+1)
op.dontFlushFrom(ctrlAt)
}

for(store <- frontend.writingMem ++ amos){
val op = layer(store)
op.mayFlushUpTo(ctrlAt)
op.dontFlushFrom(ctrlAt+1)
op.dontFlushFrom(ctrlAt)
op.addRsSpec(RS2, 0) //TODO
}

Expand Down Expand Up @@ -109,9 +109,9 @@ class LsuPlugin(var layer : LaneLayer,
}

FROM_LS := isValid && SEL
l1.SEL := isValid && SEL //TODO inibate SEL on cancel / throw
l1.SEL := isValid && SEL
l1.MIXED_ADDRESS := srcp.ADD_SUB.asUInt
l1.WRITE_MASK := AddressToMask(l1.MIXED_ADDRESS, SIZE, Riscv.LSLEN / 8)
l1.MASK := AddressToMask(l1.MIXED_ADDRESS, SIZE, Riscv.LSLEN / 8)
l1.WRITE_DATA := SIZE.muxListDc(mapping)
l1.LOAD := LOAD
l1.AMO := AMO
Expand Down Expand Up @@ -155,17 +155,19 @@ class LsuPlugin(var layer : LaneLayer,

val skip = False

when(l1.FAULT) {
skip := True
trapPort.exception := True
trapPort.code := CSR.MCAUSE_ENUM.LOAD_ACCESS_FAULT
trapPort.code(1) setWhen (!LOAD)
}

when(l1.REDO) {
skip := True
trapPort.exception := False
trapPort.code := TrapReason.REDO
when(!tpk.IO) {
when(l1.FAULT) {
skip := True
trapPort.exception := True
trapPort.code := CSR.MCAUSE_ENUM.LOAD_ACCESS_FAULT
trapPort.code(1) setWhen (!LOAD)
}

when(l1.HAZARD || l1.MISS || l1.MISS_UNIQUE) {
skip := True
trapPort.exception := False
trapPort.code := TrapReason.REDO
}
}

when(mmuPageFault) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexiiriscv/test/WhiteboxerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class WhiteboxerPlugin extends FiberPlugin{

val lp = host.get[LsuPlugin] map (p => new Area {
val c = p.logic.onWb
fire := c.down.isFiring && !c(AguPlugin.LOAD) && !c(p.logic.tpk.IO)
fire := c.down.isFiring && c(AguPlugin.SEL) && !c(AguPlugin.LOAD) && !c(p.logic.tpk.IO)
hartId := c(Global.HART_ID)
uopId := c(Decode.UOP_ID)
size := c(AguPlugin.SIZE)
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexiiriscv/tester/TestBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package vexiiriscv.tester
import rvls.spinal.{FileBackend, RvlsBackend}
import spinal.core._
import spinal.core.sim._
import spinal.lib.bus.tilelink.sim.{Checker, MemoryAgent}
import spinal.lib.bus.tilelink.sim.{Checker, MemoryAgent, TransactionA}
import spinal.lib.misc.Elf
import spinal.lib.misc.plugin.Hostable
import spinal.lib.misc.test.DualSimTracer
Expand Down Expand Up @@ -450,6 +450,7 @@ class TestOptions{
mem.randOffset = 0x80000000l
driver.driver.setFactor(dbusReadyFactor)
val checker = if (monitor.bus.p.withBCE) Checker(monitor)
override def delayOnA(a: TransactionA) = if(dbusReadyFactor < 1.0) super.delayOnA(a)
}
})

Expand Down
24 changes: 15 additions & 9 deletions src/test/scala/vexiiriscv/scratchpad/Synt.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,30 @@ object IntegrationSynthBench extends App{
add(p, postfix)
}

// add(""){ p =>
// p.regFileSync = false
// p.withMul = false
// p.withDiv = false
// }
add("") { p =>
add(""){ p =>
p.regFileSync = false
p.withMul = false
p.withDiv = false
p.allowBypassFrom = 0
}
add("") { p =>
p.regFileSync = false
p.withMul = false
p.withDiv = false
p.allowBypassFrom = 0
p.withLateAlu = true
p.withLsuL1 = true
}
// add("") { p =>
// p.regFileSync = false
// p.withMul = false
// p.withDiv = false
// p.allowBypassFrom = 0
// }
// add("") { p =>
// p.regFileSync = false
// p.withMul = false
// p.withDiv = false
// p.allowBypassFrom = 0
// p.withLateAlu = true
// }

// add("") { p =>
// p.regFileSync = false
Expand Down
5 changes: 3 additions & 2 deletions src/test/scala/vexiiriscv/tester/Regression.scala
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ class RegressionSingle(compiled : SimCompiled[VexiiRiscv],


val regulars = ArrayBuffer("dhrystone", "coremark_vexii", "machine_vexii")
priv.filter(_.p.withSupervisor).foreach(_ => regulars ++= List("supervisor", s"mmu_sv${if(xlen == 32) 32 else 39}"))
priv.filter(_.p.withSupervisor).foreach(_ => regulars ++= List("supervisor"))
if(mmu.nonEmpty) regulars ++= List(s"mmu_sv${if(xlen == 32) 32 else 39}")
for(name <- regulars){
val args = newArgs()
args.loadElf(new File(nsf, s"baremetal/$name/build/$arch/$name.elf"))
Expand Down Expand Up @@ -285,7 +286,7 @@ object RegressionSingle extends App{
}

def test(ps : ParamSimple, dutArgs : Seq[String] = Nil): Unit = {
test(ps.getName(), ps.plugins(), dutArgs)
test(ps.getName(), TestBench.paramToPlugins(ps), dutArgs)
}

def test(args : String) : Unit = test(args.split(" "))
Expand Down

0 comments on commit 87ee467

Please sign in to comment.