提交 e0d9a9f0 编写于 作者: L Lingrui98

core: move ftq to frontend

上级 259a82eb
...@@ -30,12 +30,13 @@ import xiangshan.frontend.HasIFUConst ...@@ -30,12 +30,13 @@ import xiangshan.frontend.HasIFUConst
import xiangshan.frontend.GlobalHistory import xiangshan.frontend.GlobalHistory
import xiangshan.frontend.RASEntry import xiangshan.frontend.RASEntry
import xiangshan.frontend.BPUCtrl import xiangshan.frontend.BPUCtrl
import xiangshan.frontend.FtqPtr
import xiangshan.frontend.FtqRead
import utils._ import utils._
import scala.math.max import scala.math.max
import Chisel.experimental.chiselName import Chisel.experimental.chiselName
import chipsalliance.rocketchip.config.Parameters import chipsalliance.rocketchip.config.Parameters
import xiangshan.backend.ftq.FtqPtr
// Fetch FetchWidth x 32-bit insts from Icache // Fetch FetchWidth x 32-bit insts from Icache
class FetchPacket(implicit p: Parameters) extends XSBundle { class FetchPacket(implicit p: Parameters) extends XSBundle {
...@@ -456,12 +457,27 @@ class RSFeedback(implicit p: Parameters) extends XSBundle { ...@@ -456,12 +457,27 @@ class RSFeedback(implicit p: Parameters) extends XSBundle {
class FrontendToBackendIO(implicit p: Parameters) extends XSBundle { class FrontendToBackendIO(implicit p: Parameters) extends XSBundle {
// to backend end // to backend end
val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
val fetchInfo = DecoupledIO(new FtqEntry)
val fromFtq = new Bundle {
val ftqRead = Vec(1 + 6 + 1 + 1, Flipped(new FtqRead))
val cfiRead = Flipped(new FtqRead)
}
// from backend // from backend
val redirect_cfiUpdate = Flipped(ValidIO(new Redirect)) val redirect_cfiUpdate = Flipped(ValidIO(new Redirect))
val commit_cfiUpdate = Flipped(ValidIO(new FtqEntry))
val ftqEnqPtr = Input(new FtqPtr) val toFtq = new Bundle {
val ftqLeftOne = Input(Bool()) // roq commit, read out fectch packet and deq
val roq_commits = Vec(CommitWidth, Flipped(ValidIO(new RoqCommitInfo)))
val redirect = Flipped(ValidIO(new Redirect))
val flush = Input(Bool())
val flushIdx = Input(new FtqPtr)
val flushOffset = Input(UInt(log2Up(PredictWidth).W))
val exuWriteback = Vec(exuParameters.JmpCnt + exuParameters.AluCnt, Flipped(ValidIO(new ExuOutput)))
val frontendRedirect = Flipped(ValidIO(new Redirect))
}
} }
class TlbCsrBundle(implicit p: Parameters) extends XSBundle { class TlbCsrBundle(implicit p: Parameters) extends XSBundle {
......
...@@ -194,7 +194,6 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) ...@@ -194,7 +194,6 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
integerBlock.io.csrio.hartId <> io.hartId integerBlock.io.csrio.hartId <> io.hartId
integerBlock.io.csrio.perf <> DontCare integerBlock.io.csrio.perf <> DontCare
integerBlock.io.csrio.perf.retiredInstr <> ctrlBlock.io.roqio.toCSR.perfinfo.retiredInstr integerBlock.io.csrio.perf.retiredInstr <> ctrlBlock.io.roqio.toCSR.perfinfo.retiredInstr
integerBlock.io.csrio.perf.bpuInfo <> ctrlBlock.io.perfInfo.bpuInfo
integerBlock.io.csrio.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo integerBlock.io.csrio.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo
integerBlock.io.csrio.perf.memInfo <> memBlock.io.memInfo integerBlock.io.csrio.perf.memInfo <> memBlock.io.memInfo
integerBlock.io.csrio.perf.frontendInfo <> frontend.io.frontendInfo integerBlock.io.csrio.perf.frontendInfo <> frontend.io.frontendInfo
......
...@@ -24,7 +24,7 @@ import xiangshan.backend.decode.{DecodeStage, ImmUnion} ...@@ -24,7 +24,7 @@ import xiangshan.backend.decode.{DecodeStage, ImmUnion}
import xiangshan.backend.rename.{BusyTable, Rename} import xiangshan.backend.rename.{BusyTable, Rename}
import xiangshan.backend.dispatch.Dispatch import xiangshan.backend.dispatch.Dispatch
import xiangshan.backend.exu._ import xiangshan.backend.exu._
import xiangshan.backend.ftq.{Ftq, FtqRead, HasFtqHelper} import xiangshan.frontend.{FtqRead, HasFtqHelper}
import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqLsqIO, RoqPtr} import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqLsqIO, RoqPtr}
import xiangshan.mem.LsqEnqIO import xiangshan.mem.LsqEnqIO
...@@ -234,15 +234,9 @@ class CtrlBlock(implicit p: Parameters) extends XSModule ...@@ -234,15 +234,9 @@ class CtrlBlock(implicit p: Parameters) extends XSModule
val fpdqFull = Input(Bool()) val fpdqFull = Input(Bool())
val lsdqFull = Input(Bool()) val lsdqFull = Input(Bool())
} }
val bpuInfo = new Bundle {
val bpRight = Output(UInt(XLEN.W))
val bpWrong = Output(UInt(XLEN.W))
}
}) })
}) })
val ftq = Module(new Ftq)
val decode = Module(new DecodeStage) val decode = Module(new DecodeStage)
val rename = Module(new Rename) val rename = Module(new Rename)
val dispatch = Module(new Dispatch) val dispatch = Module(new Dispatch)
...@@ -272,31 +266,30 @@ class CtrlBlock(implicit p: Parameters) extends XSModule ...@@ -272,31 +266,30 @@ class CtrlBlock(implicit p: Parameters) extends XSModule
init = false.B init = false.B
) )
loadReplay.bits := RegEnable(io.fromLsBlock.replay.bits, io.fromLsBlock.replay.valid) loadReplay.bits := RegEnable(io.fromLsBlock.replay.bits, io.fromLsBlock.replay.valid)
VecInit(ftq.io.ftqRead.tail.dropRight(2)) <> redirectGen.io.stage1FtqRead VecInit(io.frontend.fromFtq.ftqRead.tail.dropRight(2)) <> redirectGen.io.stage1FtqRead
ftq.io.ftqRead.dropRight(1).last <> redirectGen.io.memPredFtqRead io.frontend.fromFtq.ftqRead.dropRight(1).last <> redirectGen.io.memPredFtqRead
ftq.io.cfiRead <> redirectGen.io.stage2FtqRead io.frontend.fromFtq.cfiRead <> redirectGen.io.stage2FtqRead
redirectGen.io.exuMispredict <> exuRedirect redirectGen.io.exuMispredict <> exuRedirect
redirectGen.io.loadReplay <> loadReplay redirectGen.io.loadReplay <> loadReplay
redirectGen.io.flush := flushReg redirectGen.io.flush := flushReg
ftq.io.enq <> io.frontend.fetchInfo
for(i <- 0 until CommitWidth){ for(i <- 0 until CommitWidth){
ftq.io.roq_commits(i).valid := roq.io.commits.valid(i) && !roq.io.commits.isWalk io.frontend.toFtq.roq_commits(i).valid := roq.io.commits.valid(i) && !roq.io.commits.isWalk
ftq.io.roq_commits(i).bits := roq.io.commits.info(i) io.frontend.toFtq.roq_commits(i).bits := roq.io.commits.info(i)
} }
ftq.io.redirect <> backendRedirect io.frontend.toFtq.redirect <> backendRedirect
ftq.io.flush := flushReg io.frontend.toFtq.flush := flushReg
ftq.io.flushIdx := RegNext(roq.io.flushOut.bits.ftqIdx) io.frontend.toFtq.flushIdx := RegNext(roq.io.flushOut.bits.ftqIdx)
ftq.io.flushOffset := RegNext(roq.io.flushOut.bits.ftqOffset) io.frontend.toFtq.flushOffset := RegNext(roq.io.flushOut.bits.ftqOffset)
ftq.io.frontendRedirect <> frontendRedirect io.frontend.toFtq.frontendRedirect <> frontendRedirect
ftq.io.exuWriteback <> exuRedirect io.frontend.toFtq.exuWriteback <> exuRedirect
ftq.io.ftqRead.last.ptr := roq.io.flushOut.bits.ftqIdx io.frontend.fromFtq.ftqRead.last.ptr := roq.io.flushOut.bits.ftqIdx
val flushPC = GetPcByFtq( val flushPC = GetPcByFtq(
ftq.io.ftqRead.last.entry.ftqPC, io.frontend.fromFtq.ftqRead.last.entry.ftqPC,
RegEnable(roq.io.flushOut.bits.ftqOffset, roq.io.flushOut.valid), RegEnable(roq.io.flushOut.bits.ftqOffset, roq.io.flushOut.valid),
ftq.io.ftqRead.last.entry.lastPacketPC.valid, io.frontend.fromFtq.ftqRead.last.entry.lastPacketPC.valid,
ftq.io.ftqRead.last.entry.lastPacketPC.bits io.frontend.fromFtq.ftqRead.last.entry.lastPacketPC.bits
) )
val flushRedirect = Wire(Valid(new Redirect)) val flushRedirect = Wire(Valid(new Redirect))
...@@ -313,9 +306,6 @@ class CtrlBlock(implicit p: Parameters) extends XSModule ...@@ -313,9 +306,6 @@ class CtrlBlock(implicit p: Parameters) extends XSModule
flushRedirectReg.bits := RegEnable(flushRedirect.bits, enable = flushRedirect.valid) flushRedirectReg.bits := RegEnable(flushRedirect.bits, enable = flushRedirect.valid)
io.frontend.redirect_cfiUpdate := Mux(flushRedirectReg.valid, flushRedirectReg, frontendRedirect) io.frontend.redirect_cfiUpdate := Mux(flushRedirectReg.valid, flushRedirectReg, frontendRedirect)
io.frontend.commit_cfiUpdate := ftq.io.commit_ftqEntry
io.frontend.ftqEnqPtr := ftq.io.enqPtr
io.frontend.ftqLeftOne := ftq.io.leftOne
decode.io.in <> io.frontend.cfVec decode.io.in <> io.frontend.cfVec
// currently, we only update wait table when isReplay // currently, we only update wait table when isReplay
...@@ -329,13 +319,13 @@ class CtrlBlock(implicit p: Parameters) extends XSModule ...@@ -329,13 +319,13 @@ class CtrlBlock(implicit p: Parameters) extends XSModule
val jumpInst = dispatch.io.enqIQCtrl(0).bits val jumpInst = dispatch.io.enqIQCtrl(0).bits
val ftqOffsetReg = Reg(UInt(log2Up(PredictWidth).W)) val ftqOffsetReg = Reg(UInt(log2Up(PredictWidth).W))
ftqOffsetReg := jumpInst.cf.ftqOffset ftqOffsetReg := jumpInst.cf.ftqOffset
ftq.io.ftqRead(0).ptr := jumpInst.cf.ftqPtr // jump io.frontend.fromFtq.ftqRead(0).ptr := jumpInst.cf.ftqPtr // jump
io.toIntBlock.jumpPc := GetPcByFtq( io.toIntBlock.jumpPc := GetPcByFtq(
ftq.io.ftqRead(0).entry.ftqPC, ftqOffsetReg, io.frontend.fromFtq.ftqRead(0).entry.ftqPC, ftqOffsetReg,
ftq.io.ftqRead(0).entry.lastPacketPC.valid, io.frontend.fromFtq.ftqRead(0).entry.lastPacketPC.valid,
ftq.io.ftqRead(0).entry.lastPacketPC.bits io.frontend.fromFtq.ftqRead(0).entry.lastPacketPC.bits
) )
io.toIntBlock.jalr_target := ftq.io.ftqRead(0).entry.target io.toIntBlock.jalr_target := io.frontend.fromFtq.ftqRead(0).entry.target
// pipeline between decode and dispatch // pipeline between decode and dispatch
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
...@@ -415,5 +405,4 @@ class CtrlBlock(implicit p: Parameters) extends XSModule ...@@ -415,5 +405,4 @@ class CtrlBlock(implicit p: Parameters) extends XSModule
io.perfInfo.ctrlInfo.intdqFull := RegNext(dispatch.io.ctrlInfo.intdqFull) io.perfInfo.ctrlInfo.intdqFull := RegNext(dispatch.io.ctrlInfo.intdqFull)
io.perfInfo.ctrlInfo.fpdqFull := RegNext(dispatch.io.ctrlInfo.fpdqFull) io.perfInfo.ctrlInfo.fpdqFull := RegNext(dispatch.io.ctrlInfo.fpdqFull)
io.perfInfo.ctrlInfo.lsdqFull := RegNext(dispatch.io.ctrlInfo.lsdqFull) io.perfInfo.ctrlInfo.lsdqFull := RegNext(dispatch.io.ctrlInfo.lsdqFull)
io.perfInfo.bpuInfo <> RegNext(ftq.io.bpuInfo)
} }
...@@ -130,6 +130,10 @@ class PerfCounterIO(implicit p: Parameters) extends XSBundle { ...@@ -130,6 +130,10 @@ class PerfCounterIO(implicit p: Parameters) extends XSBundle {
val retiredInstr = UInt(3.W) val retiredInstr = UInt(3.W)
val frontendInfo = new Bundle { val frontendInfo = new Bundle {
val ibufFull = Bool() val ibufFull = Bool()
val bpuInfo = new Bundle {
val bpRight = UInt(XLEN.W)
val bpWrong = UInt(XLEN.W)
}
} }
val ctrlInfo = new Bundle { val ctrlInfo = new Bundle {
val roqFull = Bool() val roqFull = Bool()
...@@ -142,10 +146,7 @@ class PerfCounterIO(implicit p: Parameters) extends XSBundle { ...@@ -142,10 +146,7 @@ class PerfCounterIO(implicit p: Parameters) extends XSBundle {
val lqFull = Bool() val lqFull = Bool()
val dcacheMSHRFull = Bool() val dcacheMSHRFull = Bool()
} }
val bpuInfo = new Bundle {
val bpRight = UInt(XLEN.W)
val bpWrong = UInt(XLEN.W)
}
val cacheInfo = new Bundle { val cacheInfo = new Bundle {
val l2MSHRFull = Bool() val l2MSHRFull = Bool()
val l3MSHRFull = Bool() val l3MSHRFull = Bool()
...@@ -486,9 +487,9 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst ...@@ -486,9 +487,9 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst
val dcacheMSHRFull = RegInit(0.U(XLEN.W)) val dcacheMSHRFull = RegInit(0.U(XLEN.W))
dcacheMSHRFull := dcacheMSHRFull + RegNext(csrio.perf.memInfo.dcacheMSHRFull) dcacheMSHRFull := dcacheMSHRFull + RegNext(csrio.perf.memInfo.dcacheMSHRFull)
val bpRight = RegInit(0.U(XLEN.W)) val bpRight = RegInit(0.U(XLEN.W))
bpRight := bpRight + RegNext(csrio.perf.bpuInfo.bpRight) bpRight := bpRight + RegNext(csrio.perf.frontendInfo.bpuInfo.bpRight)
val bpWrong = RegInit(0.U(XLEN.W)) val bpWrong = RegInit(0.U(XLEN.W))
bpWrong := bpWrong + RegNext(csrio.perf.bpuInfo.bpWrong) bpWrong := bpWrong + RegNext(csrio.perf.frontendInfo.bpuInfo.bpWrong)
// CSR reg map // CSR reg map
val basicPrivMapping = Map( val basicPrivMapping = Map(
......
...@@ -21,7 +21,7 @@ import chisel3._ ...@@ -21,7 +21,7 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import xiangshan._ import xiangshan._
import utils._ import utils._
import xiangshan.backend.ftq.FtqPtr import xiangshan.frontend.FtqPtr
import difftest._ import difftest._
class RoqPtr(implicit p: Parameters) extends CircularQueuePtr[RoqPtr]( class RoqPtr(implicit p: Parameters) extends CircularQueuePtr[RoqPtr](
......
...@@ -52,6 +52,10 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer) ...@@ -52,6 +52,10 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer)
val error = new L1CacheErrorInfo val error = new L1CacheErrorInfo
val frontendInfo = new Bundle { val frontendInfo = new Bundle {
val ibufFull = Output(Bool()) val ibufFull = Output(Bool())
val bpuInfo = new Bundle {
val bpRight = Output(UInt(XLEN.W))
val bpWrong = Output(UInt(XLEN.W))
}
} }
}) })
...@@ -59,15 +63,16 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer) ...@@ -59,15 +63,16 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer)
val ibuffer = Module(new Ibuffer) val ibuffer = Module(new Ibuffer)
val l1plusPrefetcher = Module(new L1plusPrefetcher) val l1plusPrefetcher = Module(new L1plusPrefetcher)
val instrUncache = outer.instrUncache.module val instrUncache = outer.instrUncache.module
val ftq = Module(new Ftq)
val needFlush = io.backend.redirect_cfiUpdate.valid val needFlush = io.backend.redirect_cfiUpdate.valid
// from backend // from backend
ifu.io.redirect <> io.backend.redirect_cfiUpdate ifu.io.redirect <> io.backend.redirect_cfiUpdate
ifu.io.bp_ctrl <> RegNext(io.csrCtrl.bp_ctrl) ifu.io.bp_ctrl <> RegNext(io.csrCtrl.bp_ctrl)
ifu.io.commitUpdate <> io.backend.commit_cfiUpdate ifu.io.commitUpdate <> ftq.io.commit_ftqEntry
ifu.io.ftqEnqPtr <> io.backend.ftqEnqPtr ifu.io.ftqEnqPtr <> ftq.io.enqPtr
ifu.io.ftqLeftOne <> io.backend.ftqLeftOne ifu.io.ftqLeftOne <> ftq.io.leftOne
// to icache // to icache
val grantClientId = clientId(io.icacheMemGrant.bits.id) val grantClientId = clientId(io.icacheMemGrant.bits.id)
val grantEntryId = entryId(io.icacheMemGrant.bits.id) val grantEntryId = entryId(io.icacheMemGrant.bits.id)
...@@ -83,6 +88,18 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer) ...@@ -83,6 +88,18 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer)
l1plusPrefetcher.io.mem_grant.ready) l1plusPrefetcher.io.mem_grant.ready)
ifu.io.fencei := RegNext(io.fencei) ifu.io.fencei := RegNext(io.fencei)
ftq.io.enq <> ifu.io.toFtq
ftq.io.roq_commits <> io.backend.toFtq.roq_commits
ftq.io.redirect <> io.backend.toFtq.redirect
ftq.io.flush := io.backend.toFtq.flush
ftq.io.flushIdx := io.backend.toFtq.flushIdx
ftq.io.flushOffset := io.backend.toFtq.flushOffset
ftq.io.frontendRedirect <> io.backend.toFtq.frontendRedirect
ftq.io.exuWriteback <> io.backend.toFtq.exuWriteback
io.backend.fromFtq.ftqRead <> ftq.io.ftqRead
io.backend.fromFtq.cfiRead <> ftq.io.cfiRead
io.frontendInfo.bpuInfo <> ftq.io.bpuInfo
instrUncache.io.req <> ifu.io.mmio_acquire instrUncache.io.req <> ifu.io.mmio_acquire
instrUncache.io.resp <> ifu.io.mmio_grant instrUncache.io.resp <> ifu.io.mmio_grant
...@@ -111,8 +128,6 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer) ...@@ -111,8 +128,6 @@ class FrontendImp (outer: Frontend) extends LazyModuleImp(outer)
ibuffer.io.flush := needFlush ibuffer.io.flush := needFlush
// ibuffer to backend // ibuffer to backend
io.backend.cfVec <> ibuffer.io.out io.backend.cfVec <> ibuffer.io.out
// ifu to backend
io.backend.fetchInfo <> ifu.io.toFtq
io.error <> RegNext(RegNext(ifu.io.error)) io.error <> RegNext(RegNext(ifu.io.error))
......
...@@ -13,15 +13,14 @@ ...@@ -13,15 +13,14 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
***************************************************************************************/ ***************************************************************************************/
package xiangshan.backend.ftq package xiangshan.frontend
import chipsalliance.rocketchip.config.Parameters import chipsalliance.rocketchip.config.Parameters
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import utils.{AsyncDataModuleTemplate, CircularQueuePtr, DataModuleTemplate, HasCircularQueuePtrHelper, SRAMTemplate, SyncDataModuleTemplate, XSDebug, XSPerfAccumulate, XSError} import utils.{AsyncDataModuleTemplate, CircularQueuePtr, DataModuleTemplate, HasCircularQueuePtrHelper, SRAMTemplate, SyncDataModuleTemplate, XSDebug, XSPerfAccumulate, XSError}
import xiangshan._ import xiangshan._
import xiangshan.frontend.{GlobalHistory, RASEntry} import scala.tools.nsc.doc.model.Val
import xiangshan.frontend.PreDecodeInfoForDebug
class FtqPtr(implicit p: Parameters) extends CircularQueuePtr[FtqPtr]( class FtqPtr(implicit p: Parameters) extends CircularQueuePtr[FtqPtr](
p => p(XSCoreParamsKey).FtqSize p => p(XSCoreParamsKey).FtqSize
......
...@@ -23,7 +23,6 @@ import utils._ ...@@ -23,7 +23,6 @@ import utils._
import xiangshan.cache._ import xiangshan.cache._
import chisel3.experimental.chiselName import chisel3.experimental.chiselName
import freechips.rocketchip.tile.HasLazyRoCC import freechips.rocketchip.tile.HasLazyRoCC
import xiangshan.backend.ftq.FtqPtr
import system.L1CacheErrorInfo import system.L1CacheErrorInfo
trait HasInstrMMIOConst extends HasXSParameter with HasIFUConst{ trait HasInstrMMIOConst extends HasXSParameter with HasIFUConst{
......
...@@ -20,7 +20,6 @@ import chisel3._ ...@@ -20,7 +20,6 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import xiangshan._ import xiangshan._
import utils._ import utils._
import xiangshan.backend.ftq.FtqPtr
class IbufPtr(implicit p: Parameters) extends CircularQueuePtr[IbufPtr]( class IbufPtr(implicit p: Parameters) extends CircularQueuePtr[IbufPtr](
p => p(XSCoreParamsKey).IBufSize p => p(XSCoreParamsKey).IBufSize
......
...@@ -26,7 +26,7 @@ import xiangshan.cache.{DCacheLineIO, DCacheWordIO, MemoryOpConstants, TlbReques ...@@ -26,7 +26,7 @@ import xiangshan.cache.{DCacheLineIO, DCacheWordIO, MemoryOpConstants, TlbReques
import xiangshan.mem._ import xiangshan.mem._
import xiangshan.backend.roq.RoqLsqIO import xiangshan.backend.roq.RoqLsqIO
import xiangshan.backend.fu.HasExceptionNO import xiangshan.backend.fu.HasExceptionNO
import xiangshan.backend.ftq.FtqPtr import xiangshan.frontend.FtqPtr
class LqPtr(implicit p: Parameters) extends CircularQueuePtr[LqPtr]( class LqPtr(implicit p: Parameters) extends CircularQueuePtr[LqPtr](
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册