Skip to content

Commit

Permalink
FetchL1 pass generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 19, 2024
1 parent a994872 commit de25137
Show file tree
Hide file tree
Showing 4 changed files with 662 additions and 9 deletions.
53 changes: 45 additions & 8 deletions src/main/scala/vexiiriscv/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,20 @@ class ParamSimple(){
var privParam = PrivilegedParam.base
var relaxedBranch = false
var relaxedShift = false
var relaxedSrc = false
var relaxedSrc = true
var allowBypassFrom = 100 //100 => disabled
var performanceCounters = 0
var withFetchL1 = false

// 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
withRas = true
withGShare = false
withBtb = false
withRas = false
// withMul = false
// withDiv = false
withLateAlu = true
Expand All @@ -63,6 +64,7 @@ class ParamSimple(){
withMmu = true
withRva = true
withRvc = false
withFetchL1 = true
xlen = 32
}

Expand All @@ -80,6 +82,7 @@ class ParamSimple(){
r += s"d${decoders}"
r += s"l${lanes}"
r += regFileSync.mux("rfs","rfa")
if (withFetchL1) r += "fl1"
if(allowBypassFrom < 100) r += s"bp$allowBypassFrom"
if (withBtb) r += "btb"
if (withRas) r += "ras"
Expand Down Expand Up @@ -119,6 +122,7 @@ class ParamSimple(){
opt[Unit]("regfile-sync") action { (v, c) => regFileSync = true }
opt[Int]("allow-bypass-from") action { (v, c) => allowBypassFrom = v }
opt[Int]("performance-counters") action { (v, c) => performanceCounters = v }
opt[Unit]("with-fetch-l1") action { (v, c) => withFetchL1 = true }
}

def plugins() = pluginsArea.plugins
Expand Down Expand Up @@ -170,7 +174,7 @@ class ParamSimple(){

plugins += new fetch.PcPlugin(resetVector)
plugins += new fetch.FetchPipelinePlugin()
plugins += new fetch.FetchCachelessPlugin(
if(!withFetchL1) plugins += new fetch.FetchCachelessPlugin(
forkAt = 0,
joinAt = 1, //You can for instance allow the external memory to have more latency by changing this
wordWidth = 32*decoders,
Expand Down Expand Up @@ -199,10 +203,43 @@ class ParamSimple(){
)
}
)
if(withFetchL1) plugins += new fetch.FetchL1Plugin(
cacheSize = 1024,
wayCount = 1,
fetchDataWidth = 32*decoders,
memDataWidth = 32*decoders,
reducedBankWidth = false,
hitsWithTranslationWays = true,
tagsReadAsync = false,
translationStorageParameter = MmuStorageParameter(
levels = List(
MmuStorageLevel(
id = 0,
ways = 4,
depth = 32
),
MmuStorageLevel(
id = 1,
ways = 2,
depth = 32
)
),
priority = 0
),
translationPortParameter = withMmu match {
case false => null
case true => MmuPortParameter(
readAt = 1,
hitsAt = 1,
ctrlAt = 1,
rspAt = 1
)
}
)

plugins += new decode.DecodePipelinePlugin()
plugins += new decode.AlignerPlugin2(
fetchAt = 1,
fetchAt = withFetchL1.mux(2, 1),
lanes = decoders,
withBuffer = withAlignerBuffer
)
Expand Down
1 change: 0 additions & 1 deletion src/main/scala/vexiiriscv/fetch/FetchCachelessPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ class FetchCachelessPlugin(var wordWidth : Int,
trapPort.code := CSR.MCAUSE_ENUM.INSTRUCTION_ACCESS_FAULT
}


trapPort.arg(0, 2 bits) := TrapArg.FETCH
trapPort.arg(2, ats.getStorageIdWidth() bits) := ats.getStorageId(translationStorage)
when(tpk.REDO){
Expand Down
202 changes: 202 additions & 0 deletions src/main/scala/vexiiriscv/fetch/FetchL1Bus.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package vexiiriscv.fetch

import spinal.lib.misc.plugin.FiberPlugin



import spinal.core._
import spinal.lib._
import spinal.lib.pipeline.Stageable
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4ReadOnly}
import spinal.lib.bus.tilelink
import spinal.lib.bus.amba4.axilite.{AxiLite4Config, AxiLite4ReadOnly}
import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbParameter, BmbSourceParameter}
import spinal.lib.bus.tilelink.{M2sSupport, SizeRange}
import spinal.lib.misc.Plru

import scala.collection.mutable.ArrayBuffer



case class FetchL1Cmd(physicalWidth : Int) extends Bundle{
val address = UInt(physicalWidth bits)
val io = Bool()
}

case class FetchL1Rsp(dataWidth : Int) extends Bundle{
val data = Bits(dataWidth bits)
val error = Bool()
}


case class FetchL1BusParam(physicalWidth : Int,
dataWidth : Int,
lineSize : Int,
withBackPresure : Boolean){
def toTileLinkM2sParameters(name : Nameable) = tilelink.M2sParameters(
sourceCount = 1,
support = M2sSupport(
addressWidth = physicalWidth,
dataWidth = dataWidth,
transfers = tilelink.M2sTransfers(get = SizeRange(lineSize))
)
)
}

case class FetchL1Bus(p : FetchL1BusParam) extends Bundle with IMasterSlave {
import p._

val cmd = Stream(FetchL1Cmd(physicalWidth))
val rsp = Stream(FetchL1Rsp(dataWidth))

def beatCount = lineSize*8/dataWidth
override def asMaster() = {
master(cmd)
slave(rsp)
}

def split(selGen : FetchL1Cmd => Bool) : (FetchL1Bus, FetchL1Bus) = new Composite(this, "split"){
val bus0, bus1 = cloneOf(self)
val selCmd = selGen(cmd)
val selRsp = RegNextWhen(selCmd, cmd.valid)

bus1.cmd.valid := cmd.valid && selCmd
bus0.cmd.valid := cmd.valid && !selCmd

bus1.cmd.payload := cmd.payload
bus0.cmd.payload := cmd.payload

cmd.ready := selCmd ? bus1.cmd.ready | bus0.cmd.ready

rsp.valid := bus1.rsp.valid || bus0.rsp.valid
rsp.payload := selRsp ? bus1.rsp.payload | bus0.rsp.payload
bus1.rsp.ready := rsp.ready
bus0.rsp.ready := rsp.ready

val ret = (bus0, bus1)
}.ret

def ioSplit() : (FetchL1Bus, FetchL1Bus) = split(!_.io)



def resizer(newDataWidth : Int) : FetchL1Bus = new Composite(this, "resizer"){
val ret = FetchL1Bus(
p.copy(
withBackPresure = withBackPresure || newDataWidth > dataWidth
)
)

ret.cmd << self.cmd

val rspOutputStream = Stream(Bits(dataWidth bits))
StreamWidthAdapter(ret.rsp.translateWith(ret.rsp.data), rspOutputStream)

rsp.valid := rspOutputStream.valid
rsp.data := rspOutputStream.payload
rsp.error := ret.rsp.error
rspOutputStream.ready := (if(withBackPresure) rsp.ready else True)
}.ret

def toAxi4(): Axi4ReadOnly = new Composite(this, "toAxi4"){
val axiConfig = Axi4Config(
addressWidth = physicalWidth,
dataWidth = dataWidth,
idWidth = 0,
useId = true,
useRegion = false,
useBurst = true,
useLock = false,
useCache = false,
useSize = true,
useQos = false,
useLen = true,
useLast = true,
useResp = true,
useProt = true,
useStrb = false
)

val axi = Axi4ReadOnly(axiConfig)
axi.ar.valid := cmd.valid
axi.ar.addr := cmd.address
axi.ar.id := 0
axi.ar.prot := B"110"
axi.ar.len := lineSize*8/dataWidth-1
axi.ar.size := log2Up(dataWidth/8)
axi.ar.setBurstINCR()
cmd.ready := axi.ar.ready

rsp.valid := axi.r.valid
rsp.data := axi.r.data
rsp.error := !axi.r.isOKAY()
axi.r.ready := (if(withBackPresure) rsp.ready else True)
}.axi


def toBmb(): Bmb = new Composite(this, "toBmb"){
val bmbConfig = BmbAccessParameter(
addressWidth = physicalWidth,
dataWidth = dataWidth
).addSources(1, BmbSourceParameter(
contextWidth = 0,
lengthWidth = log2Up(lineSize),
alignment = BmbParameter.BurstAlignement.LENGTH,
canWrite = false,
withCachedRead = true
))

val bmb = Bmb(bmbConfig)
bmb.cmd.arbitrationFrom(cmd)
bmb.cmd.setRead()
bmb.cmd.address := cmd.address
bmb.cmd.length := lineSize-1
bmb.cmd.last := True


rsp.arbitrationFrom(bmb.rsp)
rsp.data := bmb.rsp.data
rsp.error := bmb.rsp.isError
}.bmb

def toTilelink(): tilelink.Bus = new Composite(this, "toTilelink"){
val bus = tilelink.Bus(p.toTileLinkM2sParameters(null))
bus.a.valid := cmd.valid
bus.a.opcode := tilelink.Opcode.A.GET
bus.a.param := 0
bus.a.source := 0
bus.a.address := cmd.address
bus.a.size := log2Up(lineSize)
cmd.ready := bus.a.ready

rsp.valid := bus.d.valid
rsp.data := bus.d.data
rsp.error := bus.d.denied || bus.d.corrupt
bus.d.ready := (if(withBackPresure) rsp.ready else True)
}.bus

def toAxiLite4(): AxiLite4ReadOnly = new Composite(this, "toAxi4"){
val axiConfig = AxiLite4Config(
addressWidth = physicalWidth,
dataWidth = dataWidth
)

val counter = Reg(UInt(log2Up(lineSize*8/dataWidth) bits)) init(0)
val last = counter.andR

val axi = AxiLite4ReadOnly(axiConfig)
axi.ar.valid := cmd.valid
axi.ar.addr := cmd.address | (counter << log2Up(dataWidth/8)).resized
axi.ar.setUnprivileged
cmd.ready := axi.ar.ready && last
when(axi.ar.fire){
counter := counter + 1
}

rsp.valid := axi.r.valid
rsp.data := axi.r.data
rsp.error := !axi.r.isOKAY()
axi.r.ready := True
}.axi

}
Loading

0 comments on commit de25137

Please sign in to comment.