Skip to content

Commit

Permalink
Merge pull request #21 from SpinalHDL/prefetch
Browse files Browse the repository at this point in the history
Add D$ prefetch support
  • Loading branch information
Dolu1990 authored Jul 10, 2024
2 parents 7b50ac8 + 4d3cd06 commit ee92608
Show file tree
Hide file tree
Showing 25 changed files with 1,373 additions and 252 deletions.
2 changes: 1 addition & 1 deletion ext/rvls
6 changes: 5 additions & 1 deletion src/main/scala/vexiiriscv/Generate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ import scala.collection.mutable.ArrayBuffer
object Generate extends App {
val param = new ParamSimple()
val sc = SpinalConfig()
val regions = ArrayBuffer[PmaRegion]()

assert(new scopt.OptionParser[Unit]("VexiiRiscv") {
help("help").text("prints this usage text")
param.addOptions(this)
ParamSimple.addptionRegion(this, regions)
}.parse(args, Unit).nonEmpty)

if(regions.isEmpty) regions ++= ParamSimple.defaultPma

val report = sc.generateVerilog {
val plugins = param.plugins()
ParamSimple.setPma(plugins)
ParamSimple.setPma(plugins, regions)
VexiiRiscv(plugins)
}
}
Expand Down
97 changes: 66 additions & 31 deletions src/main/scala/vexiiriscv/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,48 @@ import vexiiriscv.test.WhiteboxerPlugin
import scala.collection.mutable.ArrayBuffer

object ParamSimple{
def setPma(plugins : Seq[Hostable]) = {
val regions = ArrayBuffer[PmaRegion](
new PmaRegionImpl(
mapping = SizeMapping(0x80000000l, 0x80000000l),
isMain = true,
isExecutable = true,
transfers = M2sTransfers(
get = SizeRange.all,
putFull = SizeRange.all
)
),
new PmaRegionImpl(
mapping = SizeMapping(0x10000000l, 0x10000000l),
isMain = false,
isExecutable = true,
transfers = M2sTransfers(
get = SizeRange.all,
putFull = SizeRange.all
)

def addptionRegion(parser: scopt.OptionParser[Unit], regions : ArrayBuffer[PmaRegion]): Unit = {
import parser._
opt[Map[String, String]]("region") unbounded() action { (v, c) =>
regions += PmaRegionImpl(
mapping = SizeMapping(BigInt(v("base"), 16), BigInt(v("size"), 16)),
transfers = M2sTransfers.all,
isMain = v("main") == "1",
isExecutable = v("exe") == "1"
)
} text ("Specify a memory region, for instance : --region base=80000000,size=80000000,main=1,exe=1 --region base=10000000,size=10000000,main=0,exe=0")
}

val defaultPma = List[PmaRegion](
new PmaRegionImpl(
mapping = SizeMapping(0x80000000l, 0x80000000l),
isMain = true,
isExecutable = true,
transfers = M2sTransfers(
get = SizeRange.all,
putFull = SizeRange.all
)
),
new PmaRegionImpl(
mapping = SizeMapping(0x10000000l, 0x10000000l),
isMain = false,
isExecutable = true,
transfers = M2sTransfers(
get = SizeRange.all,
putFull = SizeRange.all
)
)
)

def setPma(plugins : Seq[Hostable], regions : Seq[PmaRegion] = defaultPma) = {
val array = ArrayBuffer(regions :_*)
plugins.foreach {
case p: FetchCachelessPlugin => p.regions.load(regions)
case p: LsuCachelessPlugin => p.regions.load(regions)
case p: FetchL1Plugin => p.regions.load(regions)
case p: LsuPlugin => p.ioRegions.load(regions)
case p: LsuL1Plugin => p.regions.load(regions)
case p: FetchCachelessPlugin => p.regions.load(array)
case p: LsuCachelessPlugin => p.regions.load(array)
case p: FetchL1Plugin => p.regions.load(array)
case p: LsuPlugin => p.ioRegions.load(array)
case p: LsuL1Plugin => p.regions.load(array)
case _ =>
}
plugins
Expand Down Expand Up @@ -98,6 +113,8 @@ class ParamSimple(){
var fetchL1Ways = 1
var fetchL1ReducedBank = false
var fetchMemDataWidthMin = 32
var lsuSoftwarePrefetch = false
var lsuHardwarePrefetch = "none"
var lsuStoreBufferSlots = 0
var lsuStoreBufferOps = 0
var lsuL1Enable = false
Expand Down Expand Up @@ -142,36 +159,42 @@ class ParamSimple(){
fetchL1Sets = 64
fetchL1Ways = 4
fetchL1ReducedBank = true
fetchMemDataWidthMin = 256
fetchMemDataWidthMin = 64
lsuL1Enable = true
lsuMemDataWidthMin = 64
lsuL1Sets = 64
lsuL1Ways = 4
lsuL1RefillCount = 2
lsuL1WritebackCount = 2
lsuL1RefillCount = 4
lsuL1WritebackCount = 4
lsuL1Coherency = false
lsuStoreBufferSlots = 2
// lsuStoreBufferSlots = 2
// lsuStoreBufferOps = 32
lsuStoreBufferSlots = 4
lsuStoreBufferOps = 32
withLsuBypass = true
// lsuSoftwarePrefetch = true
lsuHardwarePrefetch = "rpt"

// lsuForkAt = 1
divArea = false
divRadix = 2
// decoders = 2
// lanes = 2
// storeRs2Late = true
withLateAlu = true
// withLateAlu = true
withMul = true
withDiv = true
withDispatcherBuffer = true
withAlignerBuffer = true
// withRvc = true
withRva = true
withRvf = true
withRvd = true
// withRvf = true
// withRvd = true
withMmu = true
privParam.withSupervisor = true
privParam.withUser = true
xlen = 64
physicalWidth = 38


privParam.withDebug = true
Expand Down Expand Up @@ -307,6 +330,8 @@ class ParamSimple(){
opt[Int]("lsu-l1-ways") unbounded() action { (v, c) => lsuL1Ways = v }
opt[Int]("lsu-l1-store-buffer-slots") action { (v, c) => lsuStoreBufferSlots = v }
opt[Int]("lsu-l1-store-buffer-ops") action { (v, c) => lsuStoreBufferOps = v }
opt[String]("lsu-hardware-prefetch") action { (v, c) => lsuHardwarePrefetch = v }
opt[Unit]("lsu-software-prefetch") action { (v, c) => lsuSoftwarePrefetch = true }
opt[Int]("lsu-l1-refill-count") action { (v, c) => lsuL1RefillCount = v }
opt[Int]("lsu-l1-writeback-count") action { (v, c) => lsuL1WritebackCount = v }
opt[Int]("lsu-l1-mem-data-width-min") action { (v, c) => lsuMemDataWidthMin = v }
Expand Down Expand Up @@ -534,6 +559,7 @@ class ParamSimple(){
storeRs2At = storeRs2Late.mux(2, 0),
storeBufferSlots = lsuStoreBufferSlots,
storeBufferOps = lsuStoreBufferOps,
softwarePrefetch = lsuSoftwarePrefetch,
translationStorageParameter = MmuStorageParameter(
levels = List(
MmuStorageLevel(
Expand Down Expand Up @@ -571,6 +597,15 @@ class ParamSimple(){
withCoherency = lsuL1Coherency,
bootMemClear = bootMemClear
)

lsuHardwarePrefetch match {
case "none" =>
case "nl" => plugins += new lsu.PrefetchNextLinePlugin
case "rpt" => plugins += new lsu.PrefetchRptPlugin(
sets = 128,
bootMemClear = bootMemClear
)
}
}

if(withMul) {
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/vexiiriscv/decode/DecoderPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DecoderPlugin(var decodeAt : Int) extends FiberPlugin with DecoderService
}

override def addMicroOpDecoding(microOp: MicroOp, decoding: DecodeListType) = {
val op = Masked(microOp.key)
val op = microOp.keysMasked
for ((key, value) <- decoding) {
getDecodingSpec(key).addNeeds(op, Masked(value))
}
Expand All @@ -44,7 +44,7 @@ class DecoderPlugin(var decodeAt : Int) extends FiberPlugin with DecoderService

override def covers() = {
elaborationLock.await()
host.list[ExecuteLaneService].flatMap(_.getUops()).map(e => Masked(e.key))
host.list[ExecuteLaneService].flatMap(_.getUops().flatMap(_.keysMasked))
}


Expand Down Expand Up @@ -107,14 +107,14 @@ class DecoderPlugin(var decodeAt : Int) extends FiberPlugin with DecoderService
val rfAccessDec = rfAccesses.map(rfa => rfa -> new RfAccessDecoding(rfa)).toMapLinked()

for (e <- singleDecodings) {
val key = Masked(e.key)
all += key
val keys = e.keysMasked
all ++= keys

e.resources.foreach {
case r: RfResource => {
val dec = rfAccessDec(r.access)
dec.read.addNeeds(key, one)
dec.rfid.addNeeds(key, Masked(dec.rfaKey.idOf(r.rf), (1 << dec.rfaKey.rfIdWidth)-1))
dec.read.addNeeds(keys, one)
dec.rfid.addNeeds(keys, Masked(dec.rfaKey.idOf(r.rf), (1 << dec.rfaKey.rfIdWidth)-1))
}
case PC_READ =>
case INSTRUCTION_SIZE =>
Expand Down Expand Up @@ -144,8 +144,8 @@ class DecoderPlugin(var decodeAt : Int) extends FiberPlugin with DecoderService
}

val predictionSpec = new Area {
val branchKeys = List(Rvi.BEQ, Rvi.BNE, Rvi.BLT, Rvi.BGE, Rvi.BLTU, Rvi.BGEU).map(e => Masked(e.key))
val jalKeys = List(Rvi.JAL, Rvi.JALR).map(e => Masked(e.key))
val branchKeys = List(Rvi.BEQ, Rvi.BNE, Rvi.BLT, Rvi.BGE, Rvi.BLTU, Rvi.BGEU).flatMap(_.keysMasked)
val jalKeys = List(Rvi.JAL, Rvi.JALR).flatMap(_.keysMasked)
val any = new DecodingSpec(Bool()).setDefault(Masked.zero)
any.addNeeds(branchKeys ++ jalKeys, Masked.one)
}
Expand Down
8 changes: 5 additions & 3 deletions src/main/scala/vexiiriscv/execute/EnvPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ class EnvPlugin(layer : LaneLayer,
}

is(EnvPluginOp.WFI) {
commit := True
trapPort.exception := False
trapPort.code := TrapReason.WFI
when(privilege === 3 || !ps.logic.harts(0).m.status.tw && (Bool(!ps.implementSupervisor) || privilege === 1)) {
commit := True
trapPort.exception := False
trapPort.code := TrapReason.WFI
}
}

is(EnvPluginOp.FENCE_I) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/vexiiriscv/execute/ExecuteLanePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,11 @@ class ExecuteLanePlugin(override val laneName : String,
val implSelMask = ((BigInt(1) << log2Up(layers.size))-1) << Decode.UOP_WIDTH
val decoding = new decodeCtrl.Area {
def implToMasked(impl : UopLayerSpec) = {
val uop = Masked(impl.uop.key)
val uop = impl.uop.keysMasked
val sel = Masked(BigInt(getLayerId(impl.elImpl)) << Decode.UOP_WIDTH, implSelMask)
uop fuse sel
uop.map(_ fuse sel)
}
val coverAll = getUopLayerSpec().map(implToMasked)
val coverAll = getUopLayerSpec().flatMap(implToMasked)
val decodingSpecs = mutable.LinkedHashMap[Payload[_ <: BaseType], DecodingSpec[_ <: BaseType]]()
def ds(key : Payload[_ <: BaseType]) = decodingSpecs.getOrElseUpdate(key, new DecodingSpec(key))
for((key, default) <- decodingDefaults) ds(key).setDefault(Masked(default))
Expand Down
7 changes: 6 additions & 1 deletion src/main/scala/vexiiriscv/execute/IntAluPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import spinal.lib.Flow
import spinal.lib.misc.pipeline._
import vexiiriscv.Global
import vexiiriscv.decode._
import vexiiriscv.execute.lsu.CmoService
import vexiiriscv.riscv.{Riscv, Rvi}

object IntAluPlugin extends AreaObject {
Expand Down Expand Up @@ -37,6 +38,10 @@ class IntAluPlugin(var layer: LaneLayer,
val abce = AluBitwiseCtrlEnum

val wb = newWriteback(ifp, formatAt)
val ORI = Rvi.ORI(host.get[CmoService] match {
case Some(s) => s.withSoftwarePrefetch
case None => false
})

add(Rvi.ADD ).srcs(Op.ADD , SRC1.RF, SRC2.RF).decode(ALU_CTRL -> ace.ADD_SUB )
add(Rvi.SUB ).srcs(Op.SUB , SRC1.RF, SRC2.RF).decode(ALU_CTRL -> ace.ADD_SUB )
Expand All @@ -50,7 +55,7 @@ class IntAluPlugin(var layer: LaneLayer,
add(Rvi.SLTI ).srcs(Op.LESS , SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.SLT_SLTU)
add(Rvi.SLTIU).srcs(Op.LESS_U, SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.SLT_SLTU)
add(Rvi.XORI ).srcs( SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.BITWISE , ALU_BITWISE_CTRL -> abce.XOR )
add(Rvi.ORI ).srcs( SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.BITWISE , ALU_BITWISE_CTRL -> abce.OR )
add( ORI ).srcs( SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.BITWISE , ALU_BITWISE_CTRL -> abce.OR )
add(Rvi.ANDI ).srcs( SRC1.RF, SRC2.I).decode(ALU_CTRL -> ace.BITWISE , ALU_BITWISE_CTRL -> abce.AND )

add(Rvi.LUI ).srcs(Op.SRC1, SRC1.U ).decode(ALU_CTRL -> ace.ADD_SUB)
Expand Down
Loading

0 comments on commit ee92608

Please sign in to comment.