Skip to content

Commit

Permalink
asid: add asid, mainly work when hit check, not in sfence.vma (OpenXi…
Browse files Browse the repository at this point in the history
…angShan#1090)

add mmu's asid support.
1. put asid inside sram (if the entry is sram), or it will take too many sources.
2. when sfence, just flush it all, don't care asid.
3. when hit check, check asid.
4. when asid changed, flush all the inflight ptw req for safety
5. simple asid unit test:
asid 1 write, asid 2 read and check, asid 2 write, asid 1 read and check. same va, different pa

* ASID: make satp's asid bits configurable to RW
* use AsidLength to control it

* ASID: implement asid refilling and hit checking
* TODO: sfence flush with asid

* ASID: implement sfence with asid
* TODO: extract asid from SRAMTemplate

* ASID: extract asid from SRAMTemplate
* all is down
* TODO: test

* fix write to asid

* Sfence: support rs2 of sfence and fix Fence Unit
* rs2 of Sfence should be Reg and pass it to Fence Unit
* judge the value of reg instead of the index in Fence Unit

* mmu: re-write asid

now, asid is stored inside sram, so sfence just flush it
it's a complex job to handle the problem that asid is changed but
no sfence.vma is executed. when asid is changed, all the inflight
mmu reqs are flushed but entries in storage is not influenced.
so the inflight reqs do not need to record asid, just use satp.asid

* tlb: fix bug of refill mask

* ci: add asid unit test

Co-authored-by: ZhangZifei <[email protected]>
  • Loading branch information
happy-lx and Lemover authored Oct 21, 2021
1 parent 103fe42 commit 45f497a
Show file tree
Hide file tree
Showing 24 changed files with 343 additions and 390 deletions.
5 changes: 3 additions & 2 deletions scripts/xiangshan.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def __init__(self, args):
self.numa = args.numa
self.fork = not args.disable_fork
# wave dump path
if args.wave_dump is not None:
if args.wave_dump is not None:
self.set_wave_home(args.wave_dump)
else:
self.set_wave_home(self.default_wave_home)
Expand Down Expand Up @@ -147,7 +147,7 @@ def set_rvtest_home(self, path):

def set_wave_home(self, path):
print(f"set wave home to {path}")
self.wave_home = path
self.wave_home = path

# XiangShan environment
class XiangShan(object):
Expand Down Expand Up @@ -236,6 +236,7 @@ def __get_ci_misc(self, name=None):
"ext_intr/amtest-riscv64-xs.bin",
"cache-alias/aliastest-riscv64-xs.bin",
"pmp/pmp.riscv.bin",
"asid/asid.bin",
"cache-management/softprefetch-riscv64-noop.bin"
]
misc_tests = map(lambda x: os.path.join(base_dir, x), workloads)
Expand Down
9 changes: 9 additions & 0 deletions src/main/scala/utils/Hold.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,13 @@ object DataHoldBypass {
def apply(data: UInt, valid: Bool): UInt = {
Mux(valid, data, RegEnable(data, valid))
}
}

/*
* Data change or not
*/
object DataChanged {
def apply(data: UInt): UInt = {
data =/= RegNext(data)
}
}
17 changes: 17 additions & 0 deletions src/main/scala/xiangshan/Bundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -373,11 +373,27 @@ class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle {
val toFtq = Flipped(new CtrlToFtqIO)
}

class SatpStruct extends Bundle {
val mode = UInt(4.W)
val asid = UInt(16.W)
val ppn = UInt(44.W)
}

class TlbCsrBundle(implicit p: Parameters) extends XSBundle {
val satp = new Bundle {
val changed = Bool()
val mode = UInt(4.W) // TODO: may change number to parameter
val asid = UInt(16.W)
val ppn = UInt(44.W) // just use PAddrBits - 3 - vpnnLen

def apply(satp_value: UInt): Unit = {
require(satp_value.getWidth == XLEN)
val sa = satp_value.asTypeOf(new SatpStruct)
mode := sa.mode
asid := sa.asid
ppn := sa.ppn
changed := DataChanged(sa.asid) // when ppn is changed, software need do the flush
}
}
val priv = new Bundle {
val mxr = Bool()
Expand All @@ -398,6 +414,7 @@ class SfenceBundle(implicit p: Parameters) extends XSBundle {
val rs1 = Bool()
val rs2 = Bool()
val addr = UInt(VAddrBits.W)
val asid = UInt(AsidLength.W)
}

override def toPrintable: Printable = {
Expand Down
6 changes: 4 additions & 2 deletions src/main/scala/xiangshan/Parameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ case class XSCoreParameters
HasFPU: Boolean = true,
HasCustomCSRCacheOp: Boolean = true,
FetchWidth: Int = 8,
AsidLength: Int = 16,
EnableBPU: Boolean = true,
EnableBPD: Boolean = true,
EnableRAS: Boolean = true,
Expand Down Expand Up @@ -137,6 +138,7 @@ case class XSCoreParameters
StoreBufferThreshold: Int = 7,
EnableFastForward: Boolean = true,
RefillSize: Int = 512,
MMUAsidLen: Int = 16, // max is 16, 0 is not supported now
itlbParameters: TLBParameters = TLBParameters(
name = "itlb",
fetchi = true,
Expand Down Expand Up @@ -175,7 +177,6 @@ case class XSCoreParameters
normalNWays = 64,
superNWays = 4,
),
useBTlb: Boolean = false,
l2tlbParameters: L2TLBParameters = L2TLBParameters(),
NumPMP: Int = 16, // 0 or 16 or 64
NumPerfCounters: Int = 16,
Expand Down Expand Up @@ -248,6 +249,7 @@ trait HasXSParameter {
val AddrBits = coreParams.AddrBits // AddrBits is used in some cases
val VAddrBits = coreParams.VAddrBits // VAddrBits is Virtual Memory addr bits
val PAddrBits = coreParams.PAddrBits // PAddrBits is Phyical Memory addr bits
val AsidLength = coreParams.AsidLength
val AddrBytes = AddrBits / 8 // unused
val DataBits = XLEN
val DataBytes = DataBits / 8
Expand Down Expand Up @@ -309,9 +311,9 @@ trait HasXSParameter {
val StoreBufferThreshold = coreParams.StoreBufferThreshold
val EnableFastForward = coreParams.EnableFastForward
val RefillSize = coreParams.RefillSize
val asidLen = coreParams.MMUAsidLen
val BTLBWidth = coreParams.LoadPipelineWidth + coreParams.StorePipelineWidth
val refillBothTlb = coreParams.refillBothTlb
val useBTlb = coreParams.useBTlb
val itlbParams = coreParams.itlbParameters
val ldtlbParams = coreParams.ldtlbParameters
val sttlbParams = coreParams.sttlbParameters
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/xiangshan/XSCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
dtlbRepeater.io.tlb <> memBlock.io.ptw
itlbRepeater.io.sfence <> fenceio.sfence
dtlbRepeater.io.sfence <> fenceio.sfence
itlbRepeater.io.csr <> csrioIn.tlb
dtlbRepeater.io.csr <> csrioIn.tlb
ptw.io.tlb(0) <> itlbRepeater.io.ptw
ptw.io.tlb(1) <> dtlbRepeater.io.ptw
ptw.io.sfence <> fenceio.sfence
Expand Down
40 changes: 11 additions & 29 deletions src/main/scala/xiangshan/backend/MemBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import freechips.rocketchip.tile.HasFPUParameters
import xiangshan._
import xiangshan.backend.rob.RobLsqIO
import xiangshan.cache._
import xiangshan.cache.mmu.{BTlbPtwIO, BridgeTLB, PtwResp, TLB, TlbReplace}
import xiangshan.cache.mmu.{BTlbPtwIO, PtwResp, TLB, TlbReplace}
import xiangshan.mem._
import xiangshan.backend.fu.{FenceToSbuffer, FunctionUnit, HasExceptionNO, PMP, PMPChecker, PMPModule}
import utils._
Expand Down Expand Up @@ -160,35 +160,17 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
}
val dtlb = dtlb_ld ++ dtlb_st

if (!useBTlb) {
(dtlb_ld.map(_.ptw.req) ++ dtlb_st.map(_.ptw.req)).zipWithIndex.map{ case (tlb, i) =>
tlb(0) <> io.ptw.req(i)
}
dtlb_ld.map(_.ptw.resp.bits := io.ptw.resp.bits.data)
dtlb_st.map(_.ptw.resp.bits := io.ptw.resp.bits.data)
if (refillBothTlb) {
dtlb_ld.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector).orR)
dtlb_st.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector).orR)
} else {
dtlb_ld.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector.take(exuParameters.LduCnt)).orR)
dtlb_st.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector.drop(exuParameters.LduCnt)).orR)
}
(dtlb_ld.map(_.ptw.req) ++ dtlb_st.map(_.ptw.req)).zipWithIndex.map{ case (tlb, i) =>
tlb(0) <> io.ptw.req(i)
}
dtlb_ld.map(_.ptw.resp.bits := io.ptw.resp.bits.data)
dtlb_st.map(_.ptw.resp.bits := io.ptw.resp.bits.data)
if (refillBothTlb) {
dtlb_ld.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector).orR)
dtlb_st.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector).orR)
} else {
val btlb = Module(new BridgeTLB(BTLBWidth, btlbParams))
btlb.suggestName("btlb")

io.ptw <> btlb.io.ptw
btlb.io.sfence <> sfence
btlb.io.csr <> tlbcsr
btlb.io.requestor.take(exuParameters.LduCnt).map(_.req(0)).zip(dtlb_ld.map(_.ptw.req)).map{case (a,b) => a <> b}
btlb.io.requestor.drop(exuParameters.LduCnt).map(_.req(0)).zip(dtlb_st.map(_.ptw.req)).map{case (a,b) => a <> b}

val arb_ld = Module(new Arbiter(new PtwResp, exuParameters.LduCnt))
val arb_st = Module(new Arbiter(new PtwResp, exuParameters.StuCnt))
arb_ld.io.in <> btlb.io.requestor.take(exuParameters.LduCnt).map(_.resp)
arb_st.io.in <> btlb.io.requestor.drop(exuParameters.LduCnt).map(_.resp)
VecInit(dtlb_ld.map(_.ptw.resp)) <> arb_ld.io.out
VecInit(dtlb_st.map(_.ptw.resp)) <> arb_st.io.out
dtlb_ld.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector.take(exuParameters.LduCnt)).orR)
dtlb_st.map(_.ptw.resp.valid := io.ptw.resp.valid && Cat(io.ptw.resp.bits.vector.drop(exuParameters.LduCnt)).orR)
}
io.ptw.resp.ready := true.B

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ object XDecode extends DecodeConstants {
CSRRSI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
CSRRCI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),

SFENCE_VMA->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, Y, Y, Y, N, SelImm.IMM_X),
SFENCE_VMA->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, Y, Y, Y, N, SelImm.IMM_X),
EBREAK -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
ECALL -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
SRET -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
Expand Down
13 changes: 5 additions & 8 deletions src/main/scala/xiangshan/backend/fu/CSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,6 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
assert(this.getWidth == XLEN)
}

class SatpStruct extends Bundle {
val mode = UInt(4.W)
val asid = UInt(16.W)
val ppn = UInt(44.W)
}

class Interrupt extends Bundle {
// val d = Output(Bool()) // Debug
val e = new Priv
Expand Down Expand Up @@ -440,7 +434,10 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
// val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
// val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
// TODO: use config to control the length of asid
// val satpMask = "h8fffffffffffffff".U(XLEN.W) // enable asid, mode can only be 8 / 0
val satpMask = Cat("h8".U(4.W),Asid_true_mask(AsidLength),"hfffffffffff".U((XLEN - 4 - 16).W))
val sepc = RegInit(UInt(XLEN.W), 0.U)
val scause = RegInit(UInt(XLEN.W), 0.U)
val stval = Reg(UInt(XLEN.W))
Expand Down Expand Up @@ -485,7 +482,7 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
csrio.customCtrl.move_elim_enable := srnctl(0)

val tlbBundle = Wire(new TlbCsrBundle)
tlbBundle.satp := satp.asTypeOf(new SatpStruct)
tlbBundle.satp.apply(satp)

csrio.tlb := tlbBundle

Expand Down
1 change: 1 addition & 0 deletions src/main/scala/xiangshan/backend/fu/Fence.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Fence(implicit p: Parameters) extends FunctionUnit with HasExceptionNO {
XSError(sfence.valid && uop.ctrl.lsrc(0) =/= uop.ctrl.imm(4, 0), "lsrc0 is passed by imm\n")
XSError(sfence.valid && uop.ctrl.lsrc(1) =/= uop.ctrl.imm(9, 5), "lsrc1 is passed by imm\n")
sfence.bits.addr := RegEnable(io.in.bits.src(0), io.in.fire())
sfence.bits.asid := RegEnable(io.in.bits.src(1), io.in.fire())

when (state === s_idle && io.in.valid) { state := s_wait }
when (state === s_wait && func === FenceOpType.fencei && sbEmpty) { state := s_icache }
Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/xiangshan/backend/fu/util/CSRConst.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,22 @@ trait HasCSRConst {

def IRQ_DEBUG = 12

val Asid_true_len = 16

def Asid_true_mask(AsidLength : Int) : UInt = {
val res = Wire(Vec(Asid_true_len,Bool()))
(0 until Asid_true_len).map(i => {
res(i) := (i <= AsidLength).B
})
Cat(res.reverse)
// val zero = "h0".U(1.W)
// val one = "h1".U(1.W)
// val mask_high = Fill(Asid_true_len - AsidLength, zero)
// val mask_low = Fill(AsidLength, one)

// Cat(mask_high, mask_low)
}

val IntPriority = Seq(
IRQ_DEBUG,
IRQ_MEIP, IRQ_MSIP, IRQ_MTIP,
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/xiangshan/backend/issue/DataArray.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
when (SrcType.isPc(io.uop.ctrl.srcType(0))) {
io.data_out(0) := SignExt(jump_pc, XLEN)
}
io.data_out(1) := jalr_target
// when src1 is reg (like sfence's asid) do not let data_out(1) be the jarl_target
when (!SrcType.isReg(io.uop.ctrl.srcType(1))) {
io.data_out(1) := jalr_target
}
}

class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) {
Expand Down
127 changes: 0 additions & 127 deletions src/main/scala/xiangshan/cache/mmu/BTLB.scala

This file was deleted.

Loading

0 comments on commit 45f497a

Please sign in to comment.