Skip to content
41 changes: 21 additions & 20 deletions src/src/CoreCpuTop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import common.{Pc, RegFile}
import control.{Csr, Cu, StableCounter}
import frontend.{Frontend, InstFetchStage, NaiiveFetchStage, SimpleFetchStage}
import memory.{DCache, Tlb, UncachedAgent}
import pipeline.dispatch.{RegReadNdPort, RegReadStage, Scoreboard}
import pipeline.dispatch.{RegReadNdPort, RegReadStage}
import pipeline.dispatch.Scoreboard
import pipeline.dispatch.CsrScoreboard

import pipeline.dispatch.BiIssueStage

import pipeline.execution.ExeStage
Expand All @@ -21,6 +24,7 @@ import pipeline.rob.bundles.RobIdDistributePort
import memory.ICache
import frontend.Frontend
import pipeline.dispatch.bundles.ScoreboardChangeNdPort
import spec.Param.csrIssuePipelineIndex

class CoreCpuTop extends Module {
val io = IO(new Bundle {
Expand Down Expand Up @@ -122,7 +126,7 @@ class CoreCpuTop extends Module {
val crossbar = Module(new Axi3x1Crossbar)

val scoreboard = Module(new Scoreboard)
val csrScoreBoard = Module(new Scoreboard(regNum = Count.csrReg))
val csrScoreBoard = Module(new CsrScoreboard)

// val dataforward = Module(new DataForwardStage)

Expand Down Expand Up @@ -184,31 +188,28 @@ class CoreCpuTop extends Module {
instQueue.io.dequeuePorts(1).ready := false.B // TODO: Connect Second Pipeline
issueStage.io.peer.get.regScores := scoreboard.io.regScores

issueStage.io.isFlush := cu.io.flushes(PipelineStageIndex.issueStage)
issueStage.io.peer.get.csrRegScores := csrScoreBoard.io.regScores
issueStage.io.isFlush := cu.io.flushes(PipelineStageIndex.issueStage)
issueStage.io.peer.get.csrRegScore := csrScoreBoard.io.regScore

issueStage.io.peer.get.robEmptyNum := 2.U // TODO: Connect Second Pipeline
issueStage.io.peer.get.idGetPorts.foreach { port =>
port.id := 0.U
} // TODO: Connect Second Pipeline

// Scoreboards
scoreboard.io.freePorts(0) := wbStage.io.freePort
csrScoreBoard.io.freePorts(0) := wbStage.io.csrFreePort
scoreboard.io.freePorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
csrScoreBoard.io.freePorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
scoreboard.io.toMemPorts(0) := exeStage.io.peer.get.scoreboardChangePort
scoreboard.io.toMemPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
csrScoreBoard.io.toMemPorts(0) := exeStage.io.peer.get.csrScoreboardChangePort
csrScoreBoard.io.toMemPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
scoreboard.io.occupyPorts(0) := issueStage.io.peer.get.occupyPortss(0)(0)
csrScoreBoard.io.occupyPorts(0) := issueStage.io.peer.get.csrOccupyPortss(0)(0)
scoreboard.io.occupyPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
csrScoreBoard.io.occupyPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
scoreboard.io.isFlush := cu.io.flushes(PipelineStageIndex.scoreboard)
csrScoreBoard.io.isFlush := cu.io.flushes(PipelineStageIndex.scoreboard)
scoreboard.io.branchFlush := cu.io.branchScoreboardFlush
csrScoreBoard.io.branchFlush := cu.io.branchScoreboardFlush
scoreboard.io.freePorts(0) := wbStage.io.freePort
csrScoreBoard.io.freePort := wbStage.io.csrFreePort
scoreboard.io.freePorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
scoreboard.io.toMemPorts(0) := exeStage.io.peer.get.scoreboardChangePort
scoreboard.io.toMemPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
csrScoreBoard.io.toMemPort := exeStage.io.peer.get.csrScoreboardChangePort
scoreboard.io.occupyPorts(0) := issueStage.io.peer.get.occupyPortss(0)(0)
csrScoreBoard.io.occupyPort := issueStage.io.peer.get.csrOccupyPort
scoreboard.io.occupyPorts(1) := ScoreboardChangeNdPort.default // TODO: Connect Second Pipeline
scoreboard.io.isFlush := cu.io.flushes(PipelineStageIndex.scoreboard)
csrScoreBoard.io.isFlush := cu.io.flushes(PipelineStageIndex.scoreboard)
scoreboard.io.branchFlush := cu.io.branchScoreboardFlush
csrScoreBoard.io.branchFlush := cu.io.branchScoreboardFlush

// Reg-read stage
regReadStage.io.in <> issueStage.io.outs(0)
Expand Down
6 changes: 1 addition & 5 deletions src/src/control/Csr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ class Csr(
// 保留域断断续续的样子真是可爱捏
io.writePorts.foreach { writePort =>
when(writePort.en) {
csrRegs(writePort.addr) := writePort.data
// 保留域
switch(writePort.addr) {
is(spec.Csr.Index.crmd) {
Expand Down Expand Up @@ -292,10 +291,7 @@ class Csr(
).asTypeOf(tval.in)
}
is(spec.Csr.Index.ticlr) {
ticlr.in := Cat(
0.U(31.W),
false.B
).asTypeOf(ticlr.in)
ticlr.in := 0.U(32.W).asTypeOf(ticlr.in)
when(writePort.data(0) === true.B) {
timeInterrupt := false.B
}
Expand Down
100 changes: 52 additions & 48 deletions src/src/control/Cu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,34 +81,16 @@ class Cu(
io.gprWritePassThroughPorts.out(0).data := io.stableCounterReadPort.output
}

// Handle after memory request exception valid
io.isAfterMemReqFlush := io.isExceptionValidVec.asUInt.orR
/** CSR
*/

// 软件写csr
// csr write by inst
io.csrWritePorts.zip(io.instInfoPorts).foreach {
case (dst, src) =>
dst := src.csrWritePort
}

/** flush
*/
val flushes = WireDefault(VecInit(Seq.fill(ctrlControlNum)(false.B)))
io.flushes := RegNext(flushes)
val branchScoreboardFlush = WireDefault(false.B)
io.branchScoreboardFlush := RegNext(branchScoreboardFlush)

when(io.jumpPc.en) {
Seq(
PipelineStageIndex.issueStage,
PipelineStageIndex.regReadStage,
PipelineStageIndex.frontend
).map(flushes(_))
.foreach(_ := true.B)

branchScoreboardFlush := true.B
}

/** 硬件写csr
/** csr write by exception
*/

io.csrMessage.exceptionFlush := hasException
Expand Down Expand Up @@ -175,32 +157,6 @@ class Cu(
}
}
}
// ertn flush (完成异常?)
val exceptionFlush = WireDefault(hasException)

val ertnFlush = WireDefault(
io.instInfoPorts.map { instInfo => instInfo.exeOp === ExeInst.Op.ertn && instInfo.isValid }.reduce(_ || _)
) // 指令控制

when(exceptionFlush || ertnFlush) {
flushes.foreach(_ := true.B)
}
io.csrMessage.ertnFlush := ertnFlush

// select new pc
when(ertnFlush) {
io.newPc.en := true.B
io.newPc.pcAddr := io.csrValues.era.asUInt
}.elsewhen(hasException) {
io.newPc.en := true.B
when(isTlbRefillException) {
io.newPc.pcAddr := io.csrValues.tlbrentry.asUInt
}.otherwise {
io.newPc.pcAddr := io.csrValues.eentry.asUInt
}
}.elsewhen(io.jumpPc.en) {
io.newPc := io.jumpPc
}

// tlb
io.csrMessage.tlbRefillException := isTlbRefillException
Expand All @@ -227,6 +183,54 @@ class Cu(
// ll -> 1, sc -> 0
io.csrMessage.llbitSet.setValue := line0Is_ll

/** Flush & jump
*/
val flushes = WireDefault(VecInit(Seq.fill(ctrlControlNum)(false.B)))
io.flushes := RegNext(flushes)

val branchScoreboardFlush = WireDefault(false.B)
io.branchScoreboardFlush := RegNext(branchScoreboardFlush)

val exceptionFlush = WireDefault(hasException)

val ertnFlush = WireDefault(
io.instInfoPorts.map { instInfo => instInfo.exeOp === ExeInst.Op.ertn && instInfo.isValid }.reduce(_ || _)
)

// Handle after memory request exception valid
io.isAfterMemReqFlush := io.isExceptionValidVec.asUInt.orR

when(exceptionFlush || ertnFlush) {
flushes.foreach(_ := true.B)
}
io.csrMessage.ertnFlush := ertnFlush

when(io.jumpPc.en) {
Seq(
PipelineStageIndex.issueStage,
PipelineStageIndex.regReadStage,
PipelineStageIndex.frontend
).map(flushes(_))
.foreach(_ := true.B)

branchScoreboardFlush := true.B
}

// select new pc
when(ertnFlush) {
io.newPc.en := true.B
io.newPc.pcAddr := io.csrValues.era.asUInt
}.elsewhen(exceptionFlush) {
io.newPc.en := true.B
when(isTlbRefillException) {
io.newPc.pcAddr := io.csrValues.tlbrentry.asUInt
}.otherwise {
io.newPc.pcAddr := io.csrValues.eentry.asUInt
}
}.elsewhen(io.jumpPc.en) {
io.newPc := io.jumpPc
}

io.difftest match {
case Some(dt) => {
dt.cmt_ertn := RegNext(ertnFlush)
Expand Down
44 changes: 29 additions & 15 deletions src/src/memory/Tlb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Tlb extends Module {
io.csr.out.tlbidx.valid := false.B
io.csr.out.tlbehi.valid := false.B
io.csr.out.tlbeloVec.foreach(_.valid := false.B)
io.csr.out.asId.valid := false.B
io.tlbTransPorts.foreach { port =>
port.exception.valid := false.B
port.exception.bits := DontCare
Expand Down Expand Up @@ -70,6 +71,7 @@ class Tlb extends Module {
)
val isFound = isFoundVec.asUInt.orR
io.csr.out.tlbidx.valid := io.maintenanceInfo.isSearch
io.csr.out.tlbidx.bits := io.csr.in.tlbidx
when(isFound) {
io.csr.out.tlbidx.bits.index := selectedIndex
io.csr.out.tlbidx.bits.ne := false.B
Expand Down Expand Up @@ -122,25 +124,36 @@ class Tlb extends Module {
// Maintenance: Read
val readEntry = tlbEntryVec(io.csr.in.tlbidx.index)
when(io.maintenanceInfo.isRead) {
io.csr.out.tlbehi.bits.vppn := readEntry.compare.virtPageNum
io.csr.out.tlbeloVec.map(_.bits).zip(readEntry.trans).foreach {
case (tlbelo, trans) =>
tlbelo.v := trans.isValid
tlbelo.d := trans.isDirty
tlbelo.plv := trans.plv
tlbelo.mat := trans.mat
tlbelo.g := readEntry.compare.isGlobal
tlbelo.ppn := trans.physPageNum
io.csr.out.tlbidx.valid := true.B
io.csr.out.tlbehi.valid := true.B
io.csr.out.tlbeloVec.foreach(_.valid := true.B)
io.csr.out.tlbidx.bits := io.csr.in.tlbidx
io.csr.out.tlbehi.bits := io.csr.in.tlbehi
io.csr.out.tlbeloVec.map(_.bits).zip(io.csr.in.tlbloVec).foreach {
case (out, in) =>
out := in
}
io.csr.out.tlbidx.bits.ps := readEntry.compare.pageSize
io.csr.out.tlbidx.valid := true.B
io.csr.out.asId.bits := io.csr.in.asId
when(readEntry.compare.isExisted) {
io.csr.out.tlbidx.bits.ne := false.B
io.csr.out.tlbehi.valid := true.B
io.csr.out.tlbeloVec.foreach(_.valid := true.B)
io.csr.out.tlbidx.bits.ne := false.B
io.csr.out.tlbidx.bits.ps := readEntry.compare.pageSize
io.csr.out.tlbehi.bits.vppn := readEntry.compare.virtPageNum
io.csr.out.tlbeloVec.map(_.bits).zip(readEntry.trans).foreach {
case (tlbelo, trans) =>
tlbelo.v := trans.isValid
tlbelo.d := trans.isDirty
tlbelo.plv := trans.plv
tlbelo.mat := trans.mat
tlbelo.g := readEntry.compare.isGlobal
tlbelo.ppn := trans.physPageNum
}
}.otherwise {
io.csr.out.asId.valid := true.B
io.csr.out.tlbidx.bits.ne := true.B
io.csr.out.tlbidx.bits.ps := 0.U
io.csr.out.asId.bits := 0.U.asTypeOf(new AsidBundle)
io.csr.out.tlbehi.bits := 0.U.asTypeOf(new TlbehiBundle)
io.csr.out.tlbeloVec.foreach(_.bits := 0.U.asTypeOf(new TlbeloBundle))
}
}

Expand All @@ -159,6 +172,7 @@ class Tlb extends Module {
writeEntry.compare.pageSize := io.csr.in.tlbidx.ps
writeEntry.compare.virtPageNum := io.csr.in.tlbehi.vppn
writeEntry.compare.isGlobal := io.csr.in.tlbloVec(0).g
writeEntry.compare.asId := io.csr.in.asId.asid
// Question: Should write ASID or not

writeEntry.trans.zip(io.csr.in.tlbloVec).foreach {
Expand All @@ -176,7 +190,7 @@ class Tlb extends Module {
entry.compare.isExisted := false.B
entry.trans.foreach(_.isValid := false.B)
}
def isAsIdMatched(entry: TlbEntryBundle) = entry.compare.asId === io.csr.in.asId.asid
def isAsIdMatched(entry: TlbEntryBundle) = entry.compare.asId === io.maintenanceInfo.registerAsid

when(io.maintenanceInfo.isInvalidate) {
switch(io.maintenanceInfo.invalidateInst) {
Expand Down
3 changes: 2 additions & 1 deletion src/src/memory/bundles/TlbCsrWriteNdPort.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package memory.bundles

import chisel3._
import chisel3.util._
import control.csrRegsBundles.{TlbehiBundle, TlbeloBundle, TlbidxBundle}
import control.csrRegsBundles.{AsidBundle, TlbehiBundle, TlbeloBundle, TlbidxBundle}
import spec._

class TlbCsrWriteNdPort extends Bundle {
val tlbidx = Valid(new TlbidxBundle)
val tlbehi = Valid(new TlbehiBundle)
val tlbeloVec = Vec(2, Valid(new TlbeloBundle))
val asId = Valid(new AsidBundle)
}
16 changes: 16 additions & 0 deletions src/src/memory/bundles/TlbMaintenanceNdPort.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package memory.bundles

import chisel3._
import chisel3.util._
import control.csrRegsBundles.AsidBundle
import spec._
import chisel3.experimental.BundleLiterals._

class TlbMaintenanceNdPort extends Bundle {
val isInvalidate = Bool()
Expand All @@ -12,4 +14,18 @@ class TlbMaintenanceNdPort extends Bundle {
val isFill = Bool()
val virtAddr = UInt(Width.Mem.addr)
val invalidateInst = UInt(Width.Tlb.op)
val registerAsid = UInt(Width.Csr.asid)
}

object TlbMaintenanceNdPort {
val default = (new TlbMaintenanceNdPort).Lit(
_.isInvalidate -> false.B,
_.isSearch -> false.B,
_.isRead -> false.B,
_.isWrite -> false.B,
_.isFill -> false.B,
_.registerAsid -> 0.U(Width.Csr.asid),
_.virtAddr -> 0.U(Width.Mem.addr),
_.invalidateInst -> 0.U(Width.Tlb.op)
)
}
Loading