Skip to content

Commit

Permalink
LsuL1 non coherent LR/SC implemented and pass tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 26, 2024
1 parent ac29bd9 commit d77e716
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/main/scala/vexiiriscv/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,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 All @@ -67,7 +67,7 @@ class ParamSimple(){
privParam.withSupervisor = true
privParam.withUser = true
withMmu = false
withRva = false
withRva = true
withRvc = false
withAlignerBuffer = withRvc
withFetchL1 = false
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/vexiiriscv/execute/lsu/Agu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class AguFrontend(
if (XLEN.get == 64) writingRf ++= List(Rvi.LD, Rvi.LWU)
if (RVF) writingRf ++= List(Rvfd.FLW)
if (RVD) writingRf ++= List(Rvfd.FLD)
for (op <- writingRf) add(op).srcs(sk.Op.ADD, sk.SRC1.RF, sk.SRC2.I).decode(LR -> False, LOAD -> True)
for (op <- writingRf) add(op).srcs(sk.Op.ADD, sk.SRC1.RF, sk.SRC2.I).decode(LOAD -> True, LR -> False, SC -> False, AMO -> False)

// Store stuff
val storeOps = List(sk.Op.ADD, sk.SRC1.RF, sk.SRC2.S)
Expand All @@ -62,11 +62,11 @@ class AguFrontend(
for (amo <- uops) add(amo).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(AMO -> True, SC -> False, LOAD -> False, FLOAT -> False)
writingMem += add(Rvi.SCW).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(AMO -> False, SC -> True, LOAD -> False, FLOAT -> False).uop
writingRf += Rvi.SCW
writingRf += add(Rvi.LRW).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(LR -> True, LOAD -> True).uop
writingRf += add(Rvi.LRW).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(LR -> True, LOAD -> True, SC -> False, AMO -> False).uop
if(XLEN.get == 64){
writingMem += add(Rvi.SCD).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(AMO -> False, SC -> True, LOAD -> False, FLOAT -> False).uop
writingRf += Rvi.SCD
writingRf += add(Rvi.LRD).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(LR -> True, LOAD -> True).uop
writingRf += add(Rvi.LRD).srcs(sk.Op.SRC1, sk.SRC1.RF).decode(LR -> True, LOAD -> True, SC -> False, AMO -> False).uop
}
// assert(false, "Rvi.LR and atomic may need reformat info, CachelessPlugin may use loads list for it, need to add to loads. Also store completion need to be handled")
}
Expand Down
56 changes: 48 additions & 8 deletions src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import spinal.lib.misc.pipeline._
import spinal.lib.misc.plugin.FiberPlugin
import vexiiriscv.Global
import vexiiriscv.misc.Reservation
import vexiiriscv.riscv.Riscv
import vexiiriscv.riscv.{AtomicAlu, Riscv}
import vexiiriscv.execute._
import vexiiriscv.fetch.InitService
import vexiiriscv.riscv.Riscv.{RVA, RVC}

object LsuL1 extends AreaObject{
// -> L1
Expand All @@ -20,10 +21,15 @@ object LsuL1 extends AreaObject{
val PHYSICAL_ADDRESS = Payload(Global.PHYSICAL_ADDRESS)
val WRITE_DATA = Payload(Bits(Riscv.LSLEN bits))
val MASK = Payload(Bits(Riscv.LSLEN/8 bits)) //Also needed for loads
val AMO_OP = Payload(Bits(3 bits))
val AMO_SWAP = Payload(Bool())
val AMO_WORD = Payload(Bool())

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

class LsuL1Plugin(val lane : ExecuteLaneService,
Expand Down Expand Up @@ -122,7 +128,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,

// val STATUS = Payload(Vec.fill(wayCount)(Status()))
val BANKS_WORDS = Payload(Vec.fill(bankCount)(bankWord()))
val MUXED_DATA = Payload(Bits(cpuDataWidth bits))
val MUXED_DATA, BYPASSED_DATA = Payload(Bits(cpuDataWidth bits))
val WAYS_TAGS = Payload(Vec.fill(wayCount)(Tag()))
val WAYS_HITS = Payload(Bits(wayCount bits))
val WAYS_HIT = Payload(Bool())
Expand All @@ -142,7 +148,6 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
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)))

val tagsWriteArbiter = new Reservation()
Expand Down Expand Up @@ -844,11 +849,12 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
waysWrite.tag.loaded := False
}

WRITE_DATA_FINAL := WRITE_DATA
when(doWrite) {
for ((bank, bankId) <- banks.zipWithIndex) when(WAYS_HITS(bankId)) {
bank.write.valid := bankId === bankHitId && allowSideEffects
bank.write.valid := bankId === bankHitId && allowSideEffects && !(SC && SC_MISS)
bank.write.address := PHYSICAL_ADDRESS(lineRange.high downto log2Up(bankWidth / 8))
bank.write.data.subdivideIn(cpuWordWidth bits).foreach(_ := WRITE_DATA)
bank.write.data.subdivideIn(cpuWordWidth bits).foreach(_ := WRITE_DATA_FINAL)
bank.write.mask := 0
bank.write.mask.subdivideIn(cpuWordWidth / 8 bits)(PHYSICAL_ADDRESS(bankWordToCpuWordRange)) := MASK
}
Expand All @@ -857,7 +863,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
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_DATA) := WRITE_DATA_FINAL
brs(EVENT_WRITE_MASK) := MASK


Expand All @@ -882,21 +888,55 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
plruLogic.core.io.update.id := wayId
}

READ_DATA := MUXED_DATA
BYPASSED_DATA := MUXED_DATA
val bypasser = if(withBypass) new Area {
for (b <- widthOf(WRITE_TO_READ_HAZARDS) - 1 downto 0) {
when(WRITE_TO_READ_HAZARDS(b)) {
for (i <- 0 until cpuDataWidth / 8) {
val range = i * 8 + 7 downto i * 8
val src = lane.execute(bankReadAt+1+b)
when(src(EVENT_WRITE_MASK)(i)) {
READ_DATA(range) := src(EVENT_WRITE_DATA)(range)
BYPASSED_DATA(range) := src(EVENT_WRITE_DATA)(range)
}
}
}
}
}
READ_DATA := BYPASSED_DATA

if (!RVA.get) {
SC_MISS := False
}
val rva = RVA.get generate new Area{
val srcBuffer = RegNext[Bits](READ_DATA)
val alu = new AtomicAlu(
op = AMO_OP,
swap = AMO_SWAP,
mem = srcBuffer,
rf = WRITE_DATA,
isWord = AMO_WORD
)
val aluBuffer = RegNext(alu.result)
when(AMO) {
WRITE_DATA_FINAL := aluBuffer
// READ_DATA := aluBuffer
}

val delay = History(!lane.isFreezed(), 1 to 2)
val freezeIt = SEL && AMO && delay.orR
lane.freezeWhen(freezeIt) //Note that if the refill is faster than 2 cycle, it may create issues

assert(Global.HART_COUNT.get == 1)
assert(!withCoherency)
val nc = !withCoherency generate new Area{
val reserved = RegInit(False)
when(!lane.isFreezed() && SEL && !ABORD){
reserved setWhen(LR)
reserved clearWhen(!LOAD)
}
SC_MISS := !reserved
}
}

// REFILL_SLOT_FULL := MISS && !refillHit && refill.full
// REFILL_SLOT := REFILL_HITS.andMask(!refillLoaded) | refill.free.andMask(askRefill)
Expand Down
18 changes: 9 additions & 9 deletions src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,15 @@ class LsuPlugin(var layer : LaneLayer,

val freezeIt = doIt && !rsp.valid
elp.freezeWhen(freezeIt)

assert(!withRva)
}

val READ_DATA = insert(io.doIt.mux[Bits](io.rsp.data, l1.READ_DATA))
val SC_MISS = insert(io.doIt.mux[Bool](io.rsp.scMiss, l1.SC_MISS))


l1.AMO_OP := UOP(29, 3 bits)
l1.AMO_SWAP := UOP(27)
l1.AMO_WORD := SIZE === 2

flushPort.valid := False
flushPort.hartId := Global.HART_ID
Expand All @@ -187,8 +191,6 @@ class LsuPlugin(var layer : LaneLayer,
trapPort.arg.allowOverride() := 0

val doTrap = False


when(tpk.IO.mux[Bool](io.rsp.valid && io.rsp.error, l1.FAULT)) {
doTrap := True
trapPort.exception := True
Expand Down Expand Up @@ -237,7 +239,6 @@ class LsuPlugin(var layer : LaneLayer,
bypass(Global.COMMIT) := False
}


l1.ABORD := FROM_LS && (!isValid || isCancel || tpk.IO || l1.FAULT || mmuPageFault || tpk.ACCESS_FAULT || tpk.REDO || MISS_ALIGNED)
}

Expand All @@ -259,10 +260,9 @@ class LsuPlugin(var layer : LaneLayer,
iwb.valid := SEL
iwb.payload := rspShifted

if (withRva) when(!LOAD && SC) {
???
// iwb.payload(0) := onJoin.SC_MISS
// iwb.payload(7 downto 1) := 0
if (withRva) when(SC) {
iwb.payload(0) := onCtrl.SC_MISS
iwb.payload(7 downto 1) := 0
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/main/scala/vexiiriscv/test/WhiteboxerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class WhiteboxerPlugin extends FiberPlugin{
uopId := c(Decode.UOP_ID)
size := c(AguPlugin.SIZE)
address := c(p.logic.tpk.TRANSLATED)
data := c(LsuL1.WRITE_DATA)
data := c(LsuL1.WRITE_DATA_FINAL)
})
}

Expand All @@ -201,7 +201,11 @@ class WhiteboxerPlugin extends FiberPlugin{
miss := c(p.logic.onJoin.SC_MISS)
})
val lp = host.get[LsuPlugin] map (p => new Area {
fire := False
val c = p.logic.onWb
fire := c.down.isFiring && c(AguPlugin.SEL) && (c(AguPlugin.SC)) && !c(TRAP)
hartId := c(Global.HART_ID)
uopId := c(Decode.UOP_ID)
miss := c(p.logic.onCtrl.SC_MISS)
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/vexiiriscv/tester/Regression.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ class RegressionSingle(compiled : SimCompiled[VexiiRiscv],
args.name(s"freertos/$name")
}

if(withBuildroot && rvm && rva) priv.filter(_.p.withSupervisor).foreach{ _ =>
if(withBuildroot && rvm && rva && mmu.nonEmpty) priv.filter(_.p.withSupervisor).foreach{ _ =>
val path = s"ext/NaxSoftware/buildroot/images/$archLinux"
val args = newArgs()
args.failAfter(10000000000l)
Expand Down

0 comments on commit d77e716

Please sign in to comment.