diff --git a/src/src/CoreCpuTop.scala b/src/src/CoreCpuTop.scala index fd57d43c..74e208e7 100644 --- a/src/src/CoreCpuTop.scala +++ b/src/src/CoreCpuTop.scala @@ -16,6 +16,7 @@ import spec.Param.isDiffTest import control.Cu import pmu.Pmu import pmu.bundles.PmuNdPort +import spec.ExeInst class CoreCpuTop extends Module { val io = IO(new Bundle { @@ -220,6 +221,7 @@ class CoreCpuTop extends Module { exePassWbStage_1.io.peer.get.csrReadPort.get <> csr.io.readPorts(0) exePassWbStage_1.io.peer.get.stableCounterReadPort.get <> stableCounter.io + exePassWbStage_1.io.peer.get.robQueryPcPort.get <> rob.io.queryPcPort assert(Param.loadStoreIssuePipelineIndex == 0) exePassWbStages.zipWithIndex.foreach { case (exe, idx) => @@ -300,8 +302,10 @@ class CoreCpuTop extends Module { cu.io.branchExe := exePassWbStages(Param.jumpBranchPipelineIndex - 1).io.peer.get.branchSetPort.get cu.io.redirectFromDecode := instQueue.io.redirectRequest - cu.io.csrFlushRequest := csr.io.csrFlushRequest - cu.io.csrWriteInfo := csrScoreBoard.io.csrWritePort + cu.io.csrFlushRequest := csr.io.csrFlushRequest + cu.io.csrWriteInfo := csrScoreBoard.io.csrWritePort + cu.io.majorPc := commitStage.io.majorPc + cu.io.exceptionVirtAddr := addrTransStage.io.peer.get.exceptionVirtAddr // CSR csr.io.writePorts.zip(cu.io.csrWritePorts).foreach { @@ -322,8 +326,8 @@ class CoreCpuTop extends Module { csr.io.hardwareInterrupt := io.intrpt // Debug ports - io.debug0_wb.pc := commitStage.io.ins(0).bits.instInfo.pc - io.debug0_wb.inst := commitStage.io.ins(0).bits.instInfo.inst + io.debug0_wb.pc := commitStage.io.ins(0).bits.fetchInfo.pcAddr + io.debug0_wb.inst := commitStage.io.ins(0).bits.fetchInfo.inst io.debug0_wb.rf.wen := VecInit( Seq.fill(4)( commitStage.io.gprWritePorts(0).en && commitStage.io.ins(0).bits.instInfo.isValid && commitStage.io diff --git a/src/src/control/Cu.scala b/src/src/control/Cu.scala index 657e9669..52baee6d 100644 --- a/src/src/control/Cu.scala +++ b/src/src/control/Cu.scala @@ -10,6 +10,7 @@ import spec.Param.isDiffTest import spec.{Csr, ExeInst, Param} import frontend.bundles.CuCommitFtqNdPort import frontend.bundles.QueryPcBundle +import spec.Width // Note. Exception只从第0个提交 class Cu( @@ -21,6 +22,7 @@ class Cu( // `WbStage` -> `Cu` -> `Regfile` val gprWritePassThroughPorts = new PassThroughPort(Vec(commitNum, new RfWriteNdPort)) val instInfoPorts = Input(Vec(commitNum, new InstInfoNdPort)) + val majorPc = Input(UInt(Width.Reg.data)) // `Cu` -> `Csr`, 软件写 val csrWritePorts = Output(Vec(writeNum, new CsrWriteNdPort)) // `Cu` -> `Csr`, 硬件写 @@ -49,6 +51,8 @@ class Cu( val ftqPort = Output(new CuCommitFtqNdPort) val queryPcPort = Flipped(new QueryPcBundle) + val exceptionVirtAddr = Input(UInt(Width.Mem.addr)) + val isDbarFinish = Output(Bool()) val difftest = if (isDiffTest) { @@ -65,7 +69,7 @@ class Cu( // Values val majorInstInfo = io.instInfoPorts.head io.queryPcPort.ftqId := majorInstInfo.ftqInfo.ftqId - val majorPc: UInt = WireDefault(io.queryPcPort.pc + (majorInstInfo.ftqInfo.idxInBlock << 2)) + val majorPc = io.majorPc // : UInt = WireDefault(io.queryPcPort.pc + (majorInstInfo.ftqInfo.idxInBlock << 2)) val isException = (majorInstInfo.exceptionPos =/= ExceptionPos.none) && majorInstInfo.isValid // Write GPR @@ -159,7 +163,7 @@ class Cu( io.csrMessage.badVAddrSet.en := true.B io.csrMessage.badVAddrSet.addr := Mux( majorInstInfo.exceptionPos === ExceptionPos.backend, - majorInstInfo.vaddr, + io.exceptionVirtAddr, majorPc ) } diff --git a/src/src/frontend/fetch/InstResStage.scala b/src/src/frontend/fetch/InstResStage.scala index f306eb10..f210e082 100644 --- a/src/src/frontend/fetch/InstResStage.scala +++ b/src/src/frontend/fetch/InstResStage.scala @@ -41,8 +41,8 @@ class InstResStage out.enqInfos.zipWithIndex.foreach { case (infoBundle, index) => - infoBundle.bits.pcAddr := selectedIn.ftqBlock.startPc + index.asUInt(Width.Mem.addr) * 4.U - infoBundle.bits.ftqInfo.idxInBlock := index.U + infoBundle.bits.pcAddr := selectedIn.ftqBlock.startPc + index.asUInt(Width.Mem.addr) * 4.U + // infoBundle.bits.ftqInfo.idxInBlock := index.U if (Param.fetchInstMaxNum == 1) { infoBundle.bits.inst := peer.memRes.read.dataVec(0) infoBundle.valid := true.B diff --git a/src/src/memory/DCache.scala b/src/src/memory/DCache.scala index ed71a6a0..74c74788 100644 --- a/src/src/memory/DCache.scala +++ b/src/src/memory/DCache.scala @@ -231,7 +231,6 @@ class DCache( val writeData = UInt(Width.Mem.data) val writeMask = UInt(Width.Mem.data) val isWrite = Bool() - val writeDataLine = Vec(Param.Count.DCache.dataPerLine, UInt(Width.Mem.data)) })) lastReg := lastReg // Fallback: Keep data lastReg.isWrite := false.B @@ -326,7 +325,7 @@ class DCache( lastReg.memAddr(Width.Mem._addr - 1, Param.Width.DCache._byteOffset) val lastQueryIndex = queryIndexFromMemAddr(lastReg.memAddr) when(isLastMatched && lastReg.isWrite) { - selectedDataLine := lastReg.writeDataLine + selectedDataLine := lastReg.dataLine } when(lastQueryIndex === queryIndex) { statusTagLines.zipWithIndex.foreach { @@ -341,7 +340,6 @@ class DCache( lastReg.memAddr := reqMemAddr lastReg.statusTagLines := statusTagLines lastReg.setIndex := setIndex - lastReg.dataLine := selectedDataLine lastReg.writeData := reqWriteData lastReg.writeMask := reqWriteMask @@ -376,7 +374,7 @@ class DCache( case (data, index) => Mux(index.U === dataIndex, newData, data) })) - lastReg.writeDataLine := writeDataLine + lastReg.dataLine := writeDataLine // Set dirty bit writeStatusTag.isDirty := true.B @@ -442,7 +440,7 @@ class DCache( lastReg.setIndex := refillSetIndex lastReg.dataLine := toDataLine(dataLines(refillSetIndex)) when(lastReg.isWrite && refillSetIndex === lastReg.setIndex && queryIndex === lastQueryIndex) { - lastReg.dataLine := lastReg.writeDataLine + lastReg.dataLine := lastReg.dataLine } // Init refill state regs diff --git a/src/src/pipeline/commit/CommitStage.scala b/src/src/pipeline/commit/CommitStage.scala index 3694297a..494bce17 100644 --- a/src/src/pipeline/commit/CommitStage.scala +++ b/src/src/pipeline/commit/CommitStage.scala @@ -10,6 +10,8 @@ import pipeline.dispatch.bundles.ScoreboardChangeNdPort import spec.Param.isDiffTest import spec._ import pmu.bundles.PmuBranchPredictNdPort +import pipeline.dispatch.bundles.FetchInstInfoBundle +import pipeline.commit.bundles.PcInstBundle class WbNdPort extends Bundle { val gprWrite = new RfWriteNdPort @@ -20,17 +22,26 @@ object WbNdPort { def default = 0.U.asTypeOf(new WbNdPort) } +class CommitNdPort extends Bundle { + val gprWrite = new RfWriteNdPort + val instInfo = new InstInfoNdPort + val fetchInfo = new PcInstBundle +} + +object CommitNdPort { + def default = 0.U.asTypeOf(new CommitNdPort) +} + class CommitStage( commitNum: Int = Param.commitNum) extends Module { val io = IO(new Bundle { - val ins = Vec(commitNum, Flipped(Decoupled(new WbNdPort))) + val ins = Vec(commitNum, Flipped(Decoupled(new CommitNdPort))) // `CommitStage` -> `Cu` NO delay - val gprWritePorts = Output(Vec(commitNum, new RfWriteNdPort)) - - // `AddrTransStage` -> `CommitStage` -> `Cu` NO delay + val gprWritePorts = Output(Vec(commitNum, new RfWriteNdPort)) val cuInstInfoPorts = Output(Vec(commitNum, new InstInfoNdPort)) + val majorPc = Output(UInt(Width.Reg.data)) val pmu_branchInfo = if (Param.usePmu) Some(Output(new PmuBranchPredictNdPort)) else None @@ -79,6 +90,7 @@ class CommitStage( dstGprWrite := inBit.gprWrite dstGprWrite.en := in.valid && in.ready && inBit.gprWrite.en } + io.majorPc := inBits.head.fetchInfo.pcAddr io.pmu_branchInfo match { case None => @@ -97,14 +109,14 @@ class CommitStage( io.difftest match { case Some(dt) => dt.valid := RegNext(inBits(0).instInfo.isValid && io.ins(0).valid && io.ins(0).ready, false.B) // && nextCommit) - dt.pc := RegNext(inBits(0).instInfo.pc, 0.U) - dt.instr := RegNext(inBits(0).instInfo.inst, 0.U) + dt.pc := RegNext(inBits(0).fetchInfo.pcAddr, 0.U) + dt.instr := RegNext(inBits(0).fetchInfo.inst, 0.U) dt.wen := RegNext(inBits(0).gprWrite.en, false.B) dt.wdest := RegNext(inBits(0).gprWrite.addr, 0.U) dt.wdata := RegNext(inBits(0).gprWrite.data, 0.U) dt.csr_rstat := RegNext( - inBits(0).instInfo.inst(31, 24) === Inst._2RI14.csr_ && - inBits(0).instInfo.inst(23, 10) === "h5".U, + inBits(0).fetchInfo.inst(31, 24) === Inst._2RI14.csr_ && + inBits(0).fetchInfo.inst(23, 10) === "h5".U, false.B ) && io.ins(0).valid && io.ins(0).ready dt.ld_en := RegNext(inBits(0).instInfo.load.get.en, false.B) @@ -127,8 +139,8 @@ class CommitStage( if (commitNum == 2) { dt.valid_1 := RegNext(inBits(1).instInfo.isValid && io.ins(1).valid && io.ins(1).ready, false.B) - dt.instr_1 := RegNext(inBits(1).instInfo.inst, 0.U) - dt.pc_1 := RegNext(inBits(1).instInfo.pc, 0.U) + dt.instr_1 := RegNext(inBits(1).fetchInfo.inst, 0.U) + dt.pc_1 := RegNext(inBits(1).fetchInfo.pcAddr, 0.U) dt.wen_1 := RegNext(inBits(1).gprWrite.en, false.B) dt.wdest_1 := RegNext(inBits(1).gprWrite.addr, 0.U) dt.wdata_1 := RegNext(inBits(1).gprWrite.data, 0.U) diff --git a/src/src/pipeline/commit/bundles/InstInfoNdPort.scala b/src/src/pipeline/commit/bundles/InstInfoNdPort.scala index a70be93c..6dea5ed5 100644 --- a/src/src/pipeline/commit/bundles/InstInfoNdPort.scala +++ b/src/src/pipeline/commit/bundles/InstInfoNdPort.scala @@ -11,15 +11,11 @@ import pipeline.dispatch.bundles.FtqInfoBundle class InstInfoNdPort extends Bundle { val isValid = Bool() - val pc = UInt(Width.Reg.data) - val inst = UInt(Width.Reg.data) val exceptionPos = ExceptionPos() val exceptionRecord = UInt(Csr.ExceptionIndex.width) val isStore = Bool() - val vaddr = UInt(Width.Mem.addr) val needRefetch = Bool() val isCsrWrite = Bool() - val branchSuccess = Bool() val exeOp = UInt(Param.Width.exeOp) val robId = UInt(Param.Width.Rob.id) @@ -48,7 +44,6 @@ object InstInfoNdPort { instInfo.isTlb := false.B instInfo.isStore := false.B instInfo.forbidParallelCommit := false.B - instInfo.branchSuccess := false.B if (isDiffTest) { instInfo.load.get.en := false.B diff --git a/src/src/pipeline/commit/bundles/PcInstBundle.scala b/src/src/pipeline/commit/bundles/PcInstBundle.scala new file mode 100644 index 00000000..c950b109 --- /dev/null +++ b/src/src/pipeline/commit/bundles/PcInstBundle.scala @@ -0,0 +1,8 @@ +package pipeline.commit.bundles +import chisel3._ +import spec._ + +class PcInstBundle extends Bundle { + val pcAddr = UInt(Width.Reg.data) + val inst = UInt(Width.Reg.data) +} diff --git a/src/src/pipeline/dispatch/NewDispatchStage.scala b/src/src/pipeline/dispatch/NewDispatchStage.scala index 20a58959..0e172475 100644 --- a/src/src/pipeline/dispatch/NewDispatchStage.scala +++ b/src/src/pipeline/dispatch/NewDispatchStage.scala @@ -95,7 +95,7 @@ class NewDispatchStage( } } - // dontcare if input valid + // dontcare if input not valid val dispatchMap = WireDefault(VecInit(Seq.fill(issueNum)(VecInit(Seq.fill(pipelineNum)(false.B))))) val srcEns = WireDefault(VecInit(dispatchMap.map(_.reduceTree(_ || _)))) val dstEns = WireDefault(dispatchMap.reduce { (a, b) => diff --git a/src/src/pipeline/dispatch/NewRenameStage.scala b/src/src/pipeline/dispatch/NewRenameStage.scala index 47cf3394..f42488dc 100644 --- a/src/src/pipeline/dispatch/NewRenameStage.scala +++ b/src/src/pipeline/dispatch/NewRenameStage.scala @@ -123,6 +123,7 @@ class NewRenameStage( case (dst, src) => dst := src } + req.bits.fetchInfo := in.fetchInfo } // -> reservation station diff --git a/src/src/pipeline/dispatch/bundles/FtqInfoBundle.scala b/src/src/pipeline/dispatch/bundles/FtqInfoBundle.scala index 70765cb2..927e1fb8 100644 --- a/src/src/pipeline/dispatch/bundles/FtqInfoBundle.scala +++ b/src/src/pipeline/dispatch/bundles/FtqInfoBundle.scala @@ -8,7 +8,7 @@ import chisel3.util.log2Ceil class FtqInfoBundle extends Bundle { val isLastInBlock = Bool() val ftqId = UInt(Param.BPU.Width.id) - val idxInBlock = UInt(log2Ceil(Param.fetchInstMaxNum).W) + // val idxInBlock = UInt(log2Ceil(Param.fetchInstMaxNum).W) val predictBranch = Bool() } diff --git a/src/src/pipeline/execution/ExeForMemStage.scala b/src/src/pipeline/execution/ExeForMemStage.scala index f46ace47..9c20c963 100644 --- a/src/src/pipeline/execution/ExeForMemStage.scala +++ b/src/src/pipeline/execution/ExeForMemStage.scala @@ -100,7 +100,7 @@ class ExeForMemStage } } resultOutReg.bits.memRequest.isValid := isValidLoadStore - resultOutReg.bits.memRequest.addr := Cat(loadStoreAddr(wordLength - 1, 2), 0.U(2.W)) + resultOutReg.bits.memRequest.addr := loadStoreAddr resultOutReg.bits.memRequest.read.isUnsigned := VecInit(ExeInst.Op.ld_bu, ExeInst.Op.ld_hu).contains(selectedIn.exeOp) resultOutReg.bits.memRequest.rw := Mux(isWrite, ReadWriteSel.write, ReadWriteSel.read) resultOutReg.bits.isAtomicStore := selectedIn.exeOp === ExeInst.Op.sc @@ -138,7 +138,6 @@ class ExeForMemStage // Cache maintenance val cacopAddr = WireDefault(selectedIn.leftOperand + selectedIn.rightOperand) val isCacop = WireDefault(selectedIn.exeOp === ExeInst.Op.cacop) - resultOutReg.bits.instInfo.vaddr := Mux(isCacop, cacopAddr, loadStoreAddr) when(isCacop) { resultOutReg.bits.memRequest.addr := cacopAddr resultOutReg.bits.instInfo.forbidParallelCommit := true.B diff --git a/src/src/pipeline/execution/ExePassWbStage.scala b/src/src/pipeline/execution/ExePassWbStage.scala index 173d4973..deadfc22 100644 --- a/src/src/pipeline/execution/ExePassWbStage.scala +++ b/src/src/pipeline/execution/ExePassWbStage.scala @@ -17,6 +17,7 @@ import control.bundles.CsrWriteNdPort import control.bundles.StableCounterReadPort import control.bundles.CsrReadPort import pmu.bundles.PmuBranchMisPredictExeNdPort +import pipeline.rob.bundles.RobQueryPcPort class ExeNdPort extends Bundle { // Micro-instruction for execution stage @@ -59,6 +60,8 @@ class ExePeerPort(supportBranchCsr: Boolean) extends Bundle { }) val feedbackFtq = if (supportBranchCsr) Some(Flipped(new ExeFtqPort)) else None + + val robQueryPcPort = if (supportBranchCsr) Some(Flipped(new RobQueryPcPort)) else None } class ExePassWbStage(supportBranchCsr: Boolean = true) @@ -95,6 +98,10 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) resultOutReg.bits.gprWrite.en := selectedIn.gprWritePort.en resultOutReg.bits.gprWrite.addr := selectedIn.gprWritePort.addr + if (supportBranchCsr) { + io.peer.get.robQueryPcPort.get.robId := selectedIn.instInfo.robId + } + switch(selectedIn.exeSel) { is(Sel.logic) { resultOutReg.bits.gprWrite.data := alu.io.result.logic @@ -106,7 +113,9 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) resultOutReg.bits.gprWrite.data := alu.io.result.arithmetic } is(Sel.jumpBranch) { - resultOutReg.bits.gprWrite.data := selectedIn.instInfo.pc + 4.U + if (supportBranchCsr) { + resultOutReg.bits.gprWrite.data := io.peer.get.robQueryPcPort.get.pc + 4.U + } } } @@ -195,7 +204,7 @@ class ExePassWbStage(supportBranchCsr: Boolean = true) val feedbackFtq = io.peer.get.feedbackFtq.get val jumpBranchInfo = WireDefault(alu.io.result.jumpBranchInfo) val inFtqInfo = WireDefault(selectedIn.instInfo.ftqInfo) - val fallThroughPc = WireDefault(selectedIn.instInfo.pc + 4.U) + val fallThroughPc = WireDefault(io.peer.get.robQueryPcPort.get.pc + 4.U) feedbackFtq.queryPcBundle.ftqId := selectedIn.instInfo.ftqInfo.ftqId + 1.U val ftqQueryPc = feedbackFtq.queryPcBundle.pc diff --git a/src/src/pipeline/memory/AddrTransStage.scala b/src/src/pipeline/memory/AddrTransStage.scala index 62d80f59..e4eed7b7 100644 --- a/src/src/pipeline/memory/AddrTransStage.scala +++ b/src/src/pipeline/memory/AddrTransStage.scala @@ -12,7 +12,7 @@ import pipeline.memory.bundles.{CacheMaintenanceInstNdPort, MemCsrNdPort, MemReq import pipeline.memory.enums.AddrTransType import spec.Param.{isCacheOnPg, isDiffTest, isForcedCache, isForcedUncached, isNoPrivilege} import spec.Value.Csr -import spec.Width +import spec._ import scala.collection.immutable import pipeline.common.BaseStageWOSaveIn @@ -31,9 +31,10 @@ object AddrTransNdPort { } class AddrTransPeerPort extends Bundle { - val csr = Input(new MemCsrNdPort) - val tlbTrans = Flipped(new TlbTransPort) - val tlbMaintenance = Output(new TlbMaintenanceNdPort) + val csr = Input(new MemCsrNdPort) + val tlbTrans = Flipped(new TlbTransPort) + val tlbMaintenance = Output(new TlbMaintenanceNdPort) + val exceptionVirtAddr = Output(UInt(Width.Mem.addr)) } class AddrTransStage @@ -43,13 +44,23 @@ class AddrTransStage AddrTransNdPort.default, Some(new AddrTransPeerPort) ) { - val selectedIn = io.in.bits - val peer = io.peer.get - val out = resultOutReg.bits + val selectedIn = io.in.bits + val selectedInVirtAddr = Cat(selectedIn.memRequest.addr(wordLength - 1, 2), 0.U(2.W)) + val peer = io.peer.get + val resultOut = WireDefault(0.U.asTypeOf(Valid(new MemReqNdPort))) + val out = resultOut.bits + resultOutReg := resultOut val tlbBlockingReg = RegInit(false.B) tlbBlockingReg := tlbBlockingReg + val exceptionVirtAddr = RegInit(0.U.asTypeOf(Valid(UInt(Width.Mem.addr)))) + peer.exceptionVirtAddr := exceptionVirtAddr.bits + when(resultOut.valid && !exceptionVirtAddr.valid && resultOut.bits.instInfo.exceptionPos =/= ExceptionPos.none) { + exceptionVirtAddr.valid := true.B + exceptionVirtAddr.bits := selectedIn.memRequest.addr + } + // Fallback output out.instInfo := selectedIn.instInfo out.gprAddr := selectedIn.gprAddr @@ -73,11 +84,13 @@ class AddrTransStage case (target, window) => target.isHit := ((peer.csr.crmd.plv === Csr.Crmd.Plv.high && window.plv0) || (peer.csr.crmd.plv === Csr.Crmd.Plv.low && window.plv3)) && - window.vseg === selectedIn.memRequest - .addr(selectedIn.memRequest.addr.getWidth - 1, selectedIn.memRequest.addr.getWidth - 3) + window.vseg === selectedInVirtAddr( + selectedInVirtAddr.getWidth - 1, + selectedInVirtAddr.getWidth - 3 + ) target.mappedAddr := Cat( window.pseg, - selectedIn.memRequest.addr(selectedIn.memRequest.addr.getWidth - 4, 0) + selectedInVirtAddr(selectedInVirtAddr.getWidth - 4, 0) ) } @@ -100,7 +113,7 @@ class AddrTransStage selectedIn.cacheMaintenance.control.isCoherentByIndex || selectedIn.cacheMaintenance.control.isCoherentByHit val isCanTlbException = selectedIn.memRequest.isValid || selectedIn.cacheMaintenance.control.isCoherentByHit - val translatedAddr = WireDefault(selectedIn.memRequest.addr) + val translatedAddr = WireDefault(selectedInVirtAddr) if (isDiffTest) { out.instInfo.load.get.paddr := Cat(translatedAddr(Width.Mem._addr - 1, 2), selectedIn.instInfo.load.get.vaddr(1, 0)) out.instInfo.store.get.paddr := Cat( @@ -118,11 +131,11 @@ class AddrTransStage ReadWriteSel.write -> TlbMemType.store ) ) - peer.tlbTrans.virtAddr := selectedIn.memRequest.addr + peer.tlbTrans.virtAddr := selectedInVirtAddr peer.tlbTrans.isValid := !tlbBlockingReg switch(transMode) { is(AddrTransType.direct) { - translatedAddr := selectedIn.memRequest.addr + translatedAddr := selectedInVirtAddr } is(AddrTransType.directMapping) { translatedAddr := Mux(directMapVec(0).isHit, directMapVec(0).mappedAddr, directMapVec(1).mappedAddr) @@ -185,7 +198,8 @@ class AddrTransStage // Handle flush (actually is TLB maintenance done) when(io.isFlush) { - tlbBlockingReg := false.B + tlbBlockingReg := false.B + exceptionVirtAddr.valid := false.B } if (isNoPrivilege) { @@ -194,6 +208,6 @@ class AddrTransStage // Submit result when(selectedIn.instInfo.isValid && !tlbBlockingReg && io.in.ready && io.in.valid) { - resultOutReg.valid := true.B + resultOut.valid := true.B } } diff --git a/src/src/pipeline/queue/InstQueue.scala b/src/src/pipeline/queue/InstQueue.scala deleted file mode 100644 index 15b86463..00000000 --- a/src/src/pipeline/queue/InstQueue.scala +++ /dev/null @@ -1,96 +0,0 @@ -package pipeline.queue - -import chisel3._ -import chisel3.util._ -import control.bundles.PipelineControlNdPort -import pipeline.commit.bundles.InstInfoNdPort -import pipeline.dispatch.bundles.FetchInstInfoBundle -import pipeline.queue.bundles.DecodeOutNdPort -import pipeline.queue.decode._ -import spec._ - -class InstQueue(val queueLength: Int = Param.instQueueLength) extends Module { - val io = IO(new Bundle { - // val isFlush = Input(Bool()) - val pipelineControlPort = Input(new PipelineControlNdPort) - val enqueuePort = Flipped(Decoupled(new FetchInstInfoBundle)) - - // `InstQueue` -> `IssueStage` - // val dequeuePort = Decoupled(new InstInfoBundle) - val dequeuePort = Decoupled(new Bundle { - val decode = new DecodeOutNdPort - val instInfo = new InstInfoNdPort - }) - }) - - // val queue = - // Queue(io.enqueuePort, entries = queueLength, pipe = false, flow = true, flush = Some(io.pipelineControlPort.flush)) - - val ram = RegInit(VecInit(Seq.fill(queueLength)(FetchInstInfoBundle.default))) - val enq_ptr = Counter(queueLength) - val deq_ptr = Counter(queueLength) - val maybeFull = RegInit(false.B) - val ptrMatch = enq_ptr.value === deq_ptr.value - val isEmpty = ptrMatch && !maybeFull - val isFull = ptrMatch && maybeFull - - val enqueueRequest = WireDefault(io.enqueuePort.valid) - val enqueueBits = WireDefault(io.enqueuePort.bits) - val dequeueRequest = WireDefault(io.dequeuePort.ready) - - when(enqueueRequest && !isFull) { - ram(enq_ptr.value) := enqueueBits - enq_ptr.inc() - } - when(dequeueRequest && !isEmpty) { - deq_ptr.inc() - } - when(enqueueRequest =/= dequeueRequest) { - // 入队就可能满,否则不可能满 - maybeFull := enqueueRequest - } - - io.enqueuePort.ready := !isFull - io.dequeuePort.valid := !isEmpty - - // Decode - - // Select a decoder - val decodeInstInfo = WireDefault(ram(deq_ptr.value)) - - val decoders = Seq( - Module(new Decoder_2RI12), - Module(new Decoder_2RI14), - Module(new Decoder_2RI16), - // Module(new Decoder_2R), - Module(new Decoder_3R), - // Module(new Decoder_4R), - Module(new Decoder_special) - ) - decoders.foreach(_.io.instInfoPort := decodeInstInfo) - - val decoderWires = Wire(Vec(decoders.length, new DecodeOutNdPort)) - decoderWires.zip(decoders).foreach { - case (port, decoder) => - port := decoder.io.out - } - - val isMatched = WireDefault(decoderWires.map(_.isMatched).reduce(_ || _)) - val decoderIndex = WireDefault(OHToUInt(Cat(decoderWires.map(_.isMatched).reverse))) - val selectedDecoder = WireDefault(decoderWires(decoderIndex)) - - io.dequeuePort.bits.decode := selectedDecoder - // InstInfoNdPort.setDefault(io.dequeuePort.bits.instInfo) - io.dequeuePort.bits.instInfo := InstInfoNdPort.default - // io.dequeuePort.bits.instInfo.exceptionRecords(Csr.ExceptionIndex.ine) := !isMatched - io.dequeuePort.bits.instInfo.pc := decodeInstInfo.pcAddr - io.dequeuePort.bits.instInfo.inst := decodeInstInfo.inst - - // io.dequeuePort <> queue - - when(io.pipelineControlPort.flush) { - enq_ptr.reset() - deq_ptr.reset() - maybeFull := false.B - } -} diff --git a/src/src/pipeline/queue/MultiInstQueue.scala b/src/src/pipeline/queue/MultiInstQueue.scala index 8848baeb..8549f5fb 100644 --- a/src/src/pipeline/queue/MultiInstQueue.scala +++ b/src/src/pipeline/queue/MultiInstQueue.scala @@ -10,6 +10,7 @@ import pipeline.queue.bundles.DecodeOutNdPort import pipeline.queue.decode._ import spec._ import common.bundles.BackendRedirectPcNdPort +import pipeline.commit.bundles.PcInstBundle class InstQueueEnqNdPort extends Bundle { val enqInfos = Vec(Param.fetchInstMaxNum, Valid(new FetchInstInfoBundle)) @@ -19,8 +20,9 @@ object InstQueueEnqNdPort { } class FetchInstDecodeNdPort extends Bundle { - val decode = new DecodeOutNdPort - val instInfo = new InstInfoNdPort + val decode = new DecodeOutNdPort + val instInfo = new InstInfoNdPort + val fetchInfo = new PcInstBundle } object FetchInstDecodeNdPort { @@ -173,9 +175,10 @@ class MultiInstQueue( .zipWithIndex .foreach { case ((dequeuePort, selectedDecoder, decodeInstInfo, redirectRequest), index) => - dequeuePort.bits.instInfo := InstInfoNdPort.default - dequeuePort.bits.instInfo.pc := decodeInstInfo.pcAddr - dequeuePort.bits.instInfo.inst := decodeInstInfo.inst + dequeuePort.bits.instInfo := InstInfoNdPort.default + dequeuePort.bits.fetchInfo.pcAddr := decodeInstInfo.pcAddr + dequeuePort.bits.fetchInfo.inst := decodeInstInfo.inst + val isMatched = WireDefault(decoderWires(index).map(_.isMatched).reduce(_ || _)) dequeuePort.bits.instInfo.isValid := true.B dequeuePort.bits.instInfo.isCsrWrite := selectedDecoder.info.csrWriteEn diff --git a/src/src/pipeline/rob/Rob.scala b/src/src/pipeline/rob/Rob.scala index 9e6a9107..b78ad6a0 100644 --- a/src/src/pipeline/rob/Rob.scala +++ b/src/src/pipeline/rob/Rob.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util._ import common.bundles.RfReadPort import control.enums.ExceptionPos -import pipeline.commit.WbNdPort +import pipeline.commit._ import pipeline.commit.bundles._ import pipeline.common.DistributedQueuePlus import pipeline.rob.bundles._ @@ -35,7 +35,7 @@ class Rob( val finishInsts = Vec(pipelineNum, Flipped(Decoupled(new WbNdPort))) // `Rob` -> `WbStage` - val commits = Vec(commitNum, Decoupled(new WbNdPort)) + val commits = Vec(commitNum, Decoupled(new CommitNdPort)) // `MemReqStage` <-> `Rob` val commitStore = Decoupled() @@ -43,6 +43,9 @@ class Rob( // `Rob` -> `Tlb` val tlbMaintenanceTrigger = Output(Bool()) + // `ExePassWb_1` <-> `Rob` + val queryPcPort = new RobQueryPcPort + // `Cu` <-> `Rob` val isFlush = Input(Bool()) @@ -89,6 +92,8 @@ class Rob( dst.data := src.bits.gprWrite.data } + io.queryPcPort.pc := queue.io.elems(io.queryPcPort.robId).fetchInfo.pcAddr + // deal with finished insts if (Param.isOptimizedByMultiMux) { io.finishInsts.foreach(_.ready := true.B) @@ -173,6 +178,10 @@ class Rob( io.commitStore.valid := false.B io.commits.zip(queue.io.dequeuePorts).zipWithIndex.foreach { case ((commit, deqPort), idx) => + commit.bits.fetchInfo := deqPort.bits.fetchInfo + commit.bits.instInfo := deqPort.bits.wbPort.instInfo + commit.bits.gprWrite := deqPort.bits.wbPort.gprWrite + when( deqPort.valid && deqPort.bits.state === State.ready && io.commits .take(idx) @@ -180,7 +189,6 @@ class Rob( .foldLeft(true.B)(_ && _) ) { commit.valid := deqPort.ready - commit.bits := deqPort.bits.wbPort // commit if (idx == 0) { @@ -222,11 +230,10 @@ class Rob( .foreach { case ((enq, req, res), instIdx) => // enqueue - enq.valid := req.valid - enq.bits := RobInstStoreBundle.default - enq.bits.state := State.busy - enq.bits.wbPort.gprWrite.en := req.bits.writeRequest.en - enq.bits.wbPort.gprWrite.addr := req.bits.writeRequest.addr + enq.valid := req.valid + enq.bits := RobInstStoreBundle.default + enq.bits.state := State.busy + enq.bits.fetchInfo := req.bits.fetchInfo // distribute rob id res := RobReadResultNdPort.default diff --git a/src/src/pipeline/rob/bundles/RobInstStoreBundle.scala b/src/src/pipeline/rob/bundles/RobInstStoreBundle.scala index 11ab3d2a..0afd5302 100644 --- a/src/src/pipeline/rob/bundles/RobInstStoreBundle.scala +++ b/src/src/pipeline/rob/bundles/RobInstStoreBundle.scala @@ -1,13 +1,16 @@ package pipeline.rob.bundles import chisel3._ +import spec.Width import pipeline.commit.WbNdPort import pipeline.rob.enums.RobInstState +import pipeline.dispatch.bundles.FetchInstInfoBundle +import pipeline.commit.bundles.PcInstBundle class RobInstStoreBundle extends Bundle { - val state = RobInstState() - // val isValid = Bool() - val wbPort = new WbNdPort + val state = RobInstState() + val wbPort = new WbNdPort + val fetchInfo = new PcInstBundle } object RobInstStoreBundle { diff --git a/src/src/pipeline/rob/bundles/RobQueryPcPort.scala b/src/src/pipeline/rob/bundles/RobQueryPcPort.scala new file mode 100644 index 00000000..95b5d69c --- /dev/null +++ b/src/src/pipeline/rob/bundles/RobQueryPcPort.scala @@ -0,0 +1,9 @@ +package pipeline.rob.bundles + +import chisel3._ +import spec._ + +class RobQueryPcPort extends Bundle { + val robId = Input(UInt(Param.Width.Rob.id)) + val pc = Output(UInt(Width.Reg.data)) +} diff --git a/src/src/pipeline/rob/bundles/RobReadRequestNdPort.scala b/src/src/pipeline/rob/bundles/RobReadRequestNdPort.scala index 1497862a..4e8a298f 100644 --- a/src/src/pipeline/rob/bundles/RobReadRequestNdPort.scala +++ b/src/src/pipeline/rob/bundles/RobReadRequestNdPort.scala @@ -5,17 +5,15 @@ import chisel3.experimental.BundleLiterals._ import chisel3.experimental.VecLiterals._ import common.bundles.RfAccessInfoNdPort import spec._ +import pipeline.dispatch.bundles.FetchInstInfoBundle +import pipeline.commit.bundles.PcInstBundle class RobReadRequestNdPort extends Bundle { - // val en = Bool() val writeRequest = new RfAccessInfoNdPort val readRequests = Vec(Param.regFileReadNum, new RfAccessInfoNdPort) + val fetchInfo = new PcInstBundle } object RobReadRequestNdPort { - def default = (new RobReadRequestNdPort).Lit( - // _.en -> false.B, - _.writeRequest -> RfAccessInfoNdPort.default, - _.readRequests -> Vec.Lit(Seq.fill(Param.regFileReadNum)(RfAccessInfoNdPort.default): _*) - ) + def default = 0.U.asTypeOf(new RobReadRequestNdPort) } diff --git a/src/src/utils/MultiMux.scala b/src/src/utils/MultiMux.scala index d2a31dbe..0116ce80 100644 --- a/src/src/utils/MultiMux.scala +++ b/src/src/utils/MultiMux.scala @@ -13,7 +13,6 @@ class MultiMux1[T <: Data](length: Int, tFactory: => T, blankT: => T) extends Mo val flatten = Wire(Vec(length, tFactory)) for (i <- 0 until length) { flatten(i) := Mux(io.inputs(i).valid, io.inputs(i).bits, blankT) - } io.output.bits := VecInit(flatten.map(_.asUInt)).reduceTree(_ | _).asTypeOf(tFactory) }