Skip to content

Commit

Permalink
lsu l1 nearly done
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 29, 2024
1 parent 274cbab commit 1919d69
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/vexiiriscv/Generate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import spinal.core._
import spinal.lib.LatencyAnalysis
import spinal.lib.misc.PathTracer
import vexiiriscv.compat.MultiPortWritesSymplifier
import vexiiriscv.execute.{LsuCachelessPlugin, SrcPlugin}
import vexiiriscv.execute.{SrcPlugin}

object Generate extends App {
val param = new ParamSimple()
Expand Down
16 changes: 11 additions & 5 deletions src/main/scala/vexiiriscv/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class ParamSimple(){
var performanceCounters = 0
var withFetchL1 = false
var withLsuL1 = false
var fetchL1Sets = 64
var fetchL1Ways = 1
var lsuL1Sets = 64
var lsuL1Ways = 1
var withLsuBypass = false
Expand All @@ -58,21 +60,23 @@ class ParamSimple(){
withRas = true
// withMul = false
// withDiv = false
// withLateAlu = true
withLateAlu = false
allowBypassFrom = 0
relaxedBranch = false
relaxedShift = false
relaxedSrc = true
performanceCounters = 4
privParam.withSupervisor = true
privParam.withUser = true
withMmu = false
withMmu = true
withRva = true
withRvc = false
withAlignerBuffer = withRvc
withFetchL1 = false
withFetchL1 = true
withLsuL1 = true
xlen = 32
fetchL1Sets = 64
fetchL1Ways = 4
lsuL1Sets = 64
lsuL1Ways = 4
withLsuBypass = true
Expand All @@ -92,7 +96,7 @@ class ParamSimple(){
r += s"d${decoders}"
r += s"l${lanes}"
r += regFileSync.mux("rfs","rfa")
if (withFetchL1) r += "fl1"
if (withFetchL1) r += s"fl1xW${lsuL1Ways}xS${lsuL1Sets}"
if (withLsuL1) r += s"lsul1xW${lsuL1Ways}xS${lsuL1Sets}${withLsuBypass.mux("xBp","")}"
if(allowBypassFrom < 100) r += s"bp$allowBypassFrom"
if (withBtb) r += "btb"
Expand Down Expand Up @@ -135,9 +139,11 @@ class ParamSimple(){
opt[Int]("performance-counters") action { (v, c) => performanceCounters = v }
opt[Unit]("with-fetch-l1") action { (v, c) => withFetchL1 = true }
opt[Unit]("with-lsu-l1") action { (v, c) => withLsuL1 = true }
opt[Int]("fetch-l1-sets") action { (v, c) => fetchL1Sets = v }
opt[Int]("fetch-l1-ways") action { (v, c) => fetchL1Ways = v }
opt[Int]("lsu-l1-sets") action { (v, c) => lsuL1Sets = v }
opt[Int]("lsu-l1-ways") action { (v, c) => lsuL1Ways = v }
opt[Unit]("lsu-l1-bypass") action { (v, c) => withLsuBypass = true }
opt[Unit]("with-lsu-bypass") action { (v, c) => withLsuBypass = true }
}

def plugins() = pluginsArea.plugins
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class LsuCachelessPlugin(var layer : LaneLayer,
val translationPort = ats.newTranslationPort(
nodes = Seq(forkCtrl.down),
rawAddress = RAW_ADDRESS,
allowRefill = insert(True),
forcePhysical = insert(False),
usage = AddressTranslationPortUsage.LOAD_STORE,
portSpec = translationPortParameter,
storageSpec = translationStorage
Expand Down
17 changes: 16 additions & 1 deletion src/main/scala/vexiiriscv/execute/lsu/LsuL1Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ object LsuL1 extends AreaObject{
val WRITEBACK_BUSY = blocking[Bits]
}

/*
List of hazard to take care of :
- store to load
- withBypass = false => redo when detected
- withBypass = true => data bypass
- dirty update
- bypass
- writeback/refill conflicting
- redo when detected
*/
class LsuL1Plugin(val lane : ExecuteLaneService,
var memDataWidth: Int,
var cpuDataWidth: Int,
Expand Down Expand Up @@ -792,6 +802,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,

val canRefill = reservation.win && !(refillWayNeedWriteback && writeback.full) && !refill.full
val canFlush = reservation.win && !writeback.full && !refill.slots.map(_.valid).orR
val canDirty = reservation.win
val needFlushs = B(WAYS_TAGS.map(w => w.loaded && w.dirty))
val needFlushOh = OHMasking.firstV2(needFlushs)
val needFlushSel = OHToUInt(needFlushOh)
Expand All @@ -804,7 +815,7 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
val doUpgrade = SEL && askUpgrade
val doFlush = SEL && askFlush
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 doDirty = doWrite && !wasDirty && canDirty

val wayId = OHToUInt(WAYS_HITS)

Expand All @@ -813,6 +824,10 @@ class LsuL1Plugin(val lane : ExecuteLaneService,
val targetWay = (askUpgrade || doDirty).mux(wayId, refillWayWithoutUpdate)
val allowSideEffects = !ABORD

when(SEL) {
assert(CountOne(WAYS_HITS) <= 1, "Multiple way hit ???")
}

// assert(!startFlush)

val freezeIt = SEL && !LOAD && (!bankWriteReservation.win || !reservation.win)
Expand Down
113 changes: 89 additions & 24 deletions src/main/scala/vexiiriscv/execute/lsu/LsuPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import vexiiriscv.execute._
import vexiiriscv.execute.lsu.AguPlugin._
import vexiiriscv.fetch.LsuL1Service

import scala.collection.mutable.ArrayBuffer


class LsuPlugin(var layer : LaneLayer,
var withRva : Boolean,
var translationStorageParameter: Any,
Expand Down Expand Up @@ -95,7 +98,8 @@ class LsuPlugin(var layer : LaneLayer,

accessRetainer.await()
val l1 = LsuL1
val FROM_LS = Payload(Bool())
val FROM_ACCESS = Payload(Bool())
val FROM_LSU = Payload(Bool())


invalidationRetainer.await()
Expand Down Expand Up @@ -133,35 +137,81 @@ class LsuPlugin(var layer : LaneLayer,
val translationPort = ats.newTranslationPort(
nodes = Seq(elp.execute(addressAt).down, elp.execute(addressAt+1).down),
rawAddress = l1.MIXED_ADDRESS,
allowRefill = insert(True),
forcePhysical = FROM_ACCESS,
usage = AddressTranslationPortUsage.LOAD_STORE,
portSpec = translationPortParameter,
storageSpec = translationStorage
)

FROM_LS := isValid && SEL
l1.SEL := isValid && SEL
l1.MIXED_ADDRESS := srcp.ADD_SUB.asUInt
l1.MASK := AddressToMask(l1.MIXED_ADDRESS, SIZE, Riscv.LSLEN / 8)
l1.LOAD := LOAD
l1.AMO := AMO
l1.SC := SC
l1.LR := LR
l1.FLUSH := False

when(flusher.isActive(flusher.CMD) && !flusher.cmdCounter.msb && !(isValid && SEL)) {
l1.SEL := True
l1.MIXED_ADDRESS(log2Up(l1.LINE_BYTES), log2Up(l1.SETS) bits) := flusher.cmdCounter.resized
l1.MASK := 0
l1.LOAD := False
l1.AMO := False
l1.SC := False
l1.LR := False
l1.FLUSH := True
when(!elp.isFreezed()) {
case class Cmd() extends Bundle {
val address = l1.MIXED_ADDRESS()
val mask = l1.MASK()
val load = Bool()
val amo = Bool()
val sc = Bool()
val lr = Bool()
val fromFlush = Bool()
val fromAccess = Bool()
}

val ports = ArrayBuffer[Stream[Cmd]]()

val ls = new Area {
val port = ports.addRet(Stream(Cmd()))
port.valid := isValid && SEL
port.address := srcp.ADD_SUB.asUInt
port.mask := AddressToMask(l1.MIXED_ADDRESS, SIZE, Riscv.LSLEN / 8)
port.load := LOAD
port.amo := AMO
port.sc := SC
port.lr := LR
port.fromFlush := False
port.fromAccess := False
}

val access = dbusAccesses.nonEmpty generate new Area {
assert(dbusAccesses.size == 1)
val cmd = dbusAccesses.head.cmd
val port = ports.addRet(Stream(Cmd()))
port.arbitrationFrom(cmd)
port.address := cmd.address
port.mask := AddressToMask(l1.MIXED_ADDRESS, cmd.size, Riscv.LSLEN / 8)
port.load := True
port.amo := False
port.sc := False
port.lr := False
port.fromFlush := False
port.fromAccess := True
}

val flush = new Area {
val port = ports.addRet(Stream(Cmd()))
port.valid := flusher.isActive(flusher.CMD) && !flusher.cmdCounter.msb
port.address := (flusher.cmdCounter << log2Up(l1.LINE_BYTES)).resized
port.mask := 0
port.load := False
port.amo := False
port.sc := False
port.lr := False
port.fromFlush := True
port.fromAccess := False
when(port.fire) {
flusher.cmdCounter := flusher.cmdCounter + 1
}
}

val arbiter = StreamArbiterFactory().noLock.lowerFirst.buildOn(ports)
arbiter.io.output.ready := !elp.isFreezed()
l1.SEL := arbiter.io.output.valid
l1.MIXED_ADDRESS := arbiter.io.output.address
l1.MASK := arbiter.io.output.mask
l1.LOAD := arbiter.io.output.load
l1.AMO := arbiter.io.output.amo
l1.SC := arbiter.io.output.sc
l1.LR := arbiter.io.output.lr
l1.FLUSH := arbiter.io.output.fromFlush
FROM_ACCESS := arbiter.io.output.fromAccess
FROM_LSU := !(arbiter.io.output.fromFlush || arbiter.io.output.fromAccess)
}

val tpk = onAddress0.translationPort.keys
Expand All @@ -176,6 +226,9 @@ class LsuPlugin(var layer : LaneLayer,
for(eid <- addressAt + 1 to ctrlAt) {
val e = elp.execute(eid)
e.up(l1.SEL).setAsReg().init(False)
when(e(FROM_LSU) && !e.isValid) {
e.bypass(l1.SEL) := False
}
}

val onCtrl = new elp.Execute(ctrlAt) {
Expand Down Expand Up @@ -247,7 +300,8 @@ class LsuPlugin(var layer : LaneLayer,
trapPort.code(1) setWhen (!LOAD)
}

when(!tpk.IO && (l1.HAZARD || l1.MISS || l1.MISS_UNIQUE)){
val l1Redo = !tpk.IO && (l1.HAZARD || l1.MISS || l1.MISS_UNIQUE)
when(l1Redo){
doTrap := True
trapPort.exception := False
trapPort.code := TrapReason.REDO
Expand Down Expand Up @@ -288,11 +342,22 @@ 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)
l1.ABORD := FROM_LSU && (!isValid || isCancel || tpk.IO || l1.FAULT || mmuPageFault || tpk.ACCESS_FAULT || tpk.REDO || MISS_ALIGNED)

when(l1.SEL && l1.FLUSH && (l1.FLUSH_HIT || l1.HAZARD)){
flusher.cmdCounter := l1.MIXED_ADDRESS(log2Up(l1.LINE_BYTES), log2Up(l1.SETS) bits).resized
}

val access = dbusAccesses.nonEmpty generate new Area {
assert(dbusAccesses.size == 1)
val rsp = dbusAccesses.head.rsp
rsp.valid := l1.SEL && FROM_ACCESS && !elp.isFreezed()
rsp.data := l1.READ_DATA
rsp.error := l1.FAULT
rsp.redo := l1Redo
rsp.waitSlot := 0
rsp.waitAny := False //TODO
}
}

val onWb = new elp.Execute(wbAt){
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexiiriscv/fetch/FetchCachelessPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class FetchCachelessPlugin(var wordWidth : Int,
val translationPort = ats.newTranslationPort(
nodes = Seq(down),
rawAddress = Fetch.WORD_PC,
allowRefill = insert(True),
forcePhysical = insert(False),
usage = AddressTranslationPortUsage.FETCH,
portSpec = translationPortParameter,
storageSpec = translationStorage
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexiiriscv/fetch/FetchL1Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class FetchL1Plugin(var translationStorageParameter: Any,
val translationPort = ats.newTranslationPort(
nodes = Seq(pp.fetch(readAt).down, pp.fetch(readAt+1).down),
rawAddress = Fetch.WORD_PC,
allowRefill = pp.fetch(readAt).insert(True),
forcePhysical = pp.fetch(readAt).insert(False),
usage = AddressTranslationPortUsage.FETCH,
portSpec = translationPortParameter,
storageSpec = translationStorage
Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/vexiiriscv/memory/MmuPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class MmuPlugin(var spec : MmuSpec,

case class PortSpec(stages: Seq[NodeBaseApi],
preAddress: Payload[UInt],
allowRefill : Payload[Bool],
forcePhysical : Payload[Bool],
usage : AddressTranslationPortUsage,
pp: MmuPortParameter,
ss : StorageSpec,
Expand Down Expand Up @@ -114,7 +114,7 @@ class MmuPlugin(var spec : MmuSpec,

override def newTranslationPort(stages: Seq[NodeBaseApi],
preAddress: Payload[UInt],
allowRefill : Payload[Bool],
forcePhysical : Payload[Bool],
usage : AddressTranslationPortUsage,
portSpec: Any,
storageSpec: Any) = {
Expand All @@ -124,7 +124,7 @@ class MmuPlugin(var spec : MmuSpec,
new PortSpec(
stages = stages,
preAddress = preAddress,
allowRefill = allowRefill,
forcePhysical = forcePhysical,
usage = usage,
pp = pp,
ss = ss,
Expand Down Expand Up @@ -283,6 +283,7 @@ class MmuPlugin(var spec : MmuSpec,
requireMmuLockup := False
}
}
requireMmuLockup clearWhen(ps.forcePhysical)

import ps.rsp.keys._
IO := ioRange(TRANSLATED)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexiiriscv/memory/Service.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ trait AddressTranslationService extends Area {

def newTranslationPort(nodes: Seq[NodeBaseApi],
rawAddress: Payload[UInt],
allowRefill: Payload[Bool],
forcePhysical: Payload[Bool],
usage: AddressTranslationPortUsage,
portSpec: Any,
storageSpec: Any): AddressTranslationRsp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class StaticTranslationPlugin(var physicalWidth: Int,

override def newTranslationPort(nodes: Seq[NodeBaseApi],
rawAddress: Payload[UInt],
allowRefill: Payload[Bool],
forcePhysical: Payload[Bool],
usage: AddressTranslationPortUsage,
portSpec: Any,
storageSpec: Any): AddressTranslationRsp = {
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/vexiiriscv/test/konata/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,14 @@ class Backend(f : File) {

def refresh(): Unit = {
val cycleEnd = threads.map(_.cycleLock).min
var skips = 0

while(cycle != cycleEnd && pendings.nonEmpty){
skips += 1
pendings.get(cycle) match {
case Some(instrs) => {
bf.write(s"C\t$skips\n")
skips = 0
for(instr <- instrs){
if(instr.first) {
instr.id = idAlloc
Expand All @@ -100,9 +104,9 @@ class Backend(f : File) {
}
case None =>
}
bf.write("C\t1\n")
cycle += 1
}
if (skips != 0) bf.write(s"C\t$skips\n")
}


Expand Down
Loading

0 comments on commit 1919d69

Please sign in to comment.