Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/src/CoreCpuTop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class CoreCpuTop extends Module {
case (dst, src) =>
dst <> src
}
commitStage.io.hasInterrupt := csr.io.hasInterrupt

// Register file (GPR file)
regFile.io.writePorts <> cu.io.gprWritePassThroughPorts.out
Expand Down
23 changes: 12 additions & 11 deletions src/src/control/Cu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -220,19 +220,25 @@ class Cu(

io.csrMessage.ertnFlush := isExceptionReturn // TODO: Make ERTN jump gracefully like branch instruction
io.frontendFlush :=
isException || io.branchExe.en || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn
RegNext(
isException || io.branchExe.en || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn,
false.B
)
io.backendFlush := RegNext(
isException || io.branchCommit || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn,
false.B
)
io.idleFlush := idleFlush
io.idleFlush := RegNext(idleFlush)

// Select new pc
io.newPc := PcSetNdPort.default
io.newPc.en :=
val newPc = RegInit(PcSetNdPort.default)
io.newPc := newPc

newPc := PcSetNdPort.default
newPc.en :=
isTlbMaintenance || io.csrFlushRequest || isException || io.branchExe.en || cacopFlush || idleFlush || isExceptionReturn
io.newPc.isTlb := isTlbMaintenance
io.newPc.pcAddr := Mux(
newPc.isTlb := isTlbMaintenance
newPc.pcAddr := Mux(
isException,
Mux(
majorInstInfo.exceptionRecord === Csr.ExceptionIndex.tlbr,
Expand All @@ -250,11 +256,6 @@ class Cu(
)
)

val is_softwareInt = io.instInfoPorts(0).isValid &&
io.instInfoPorts(0).csrWritePort.en &&
(io.instInfoPorts(0).csrWritePort.addr === Csr.Index.estat) &&
io.instInfoPorts(0).csrWritePort.data(1, 0).orR

io.difftest match {
case Some(dt) =>
dt.cmt_ertn := RegNext(isExceptionReturn)
Expand Down
8 changes: 5 additions & 3 deletions src/src/pipeline/commit/CommitStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ class CommitStage(
// `CommitStage` -> `Cu` NO delay
val isExceptionValid = Output(Bool())

val hasInterrupt = Input(Bool())

val difftest =
if (isDiffTest)
Some(Output(new Bundle {
val valid = Bool()
val pc = UInt(Width.Reg.data)
val instr = UInt(Width.Reg.data)
val is_TLBFILL = Bool() // TODO
val TLBFILL_index = UInt(Width.Reg.addr) // TODO
val is_TLBFILL = Bool()
val TLBFILL_index = UInt(Width.Reg.addr)
val wen = Bool()
val wdest = UInt(Width.Reg.addr)
val wdata = UInt(Width.Reg.data)
Expand All @@ -73,7 +75,7 @@ class CommitStage(
else None
})

io.ins.foreach(_.ready := true.B)
io.ins.foreach(_.ready := !io.hasInterrupt)

val inBits = WireDefault(VecInit(io.ins.map(_.bits)))

Expand Down
20 changes: 3 additions & 17 deletions src/src/pipeline/common/DistributedQueue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ class DistributedQueue[ElemT <: Data](
val isFlush = Input(Bool())
val enqueuePorts = Vec(enqMaxNum, Flipped(Decoupled(elemNdFactory)))
val dequeuePorts = Vec(deqMaxNum, Decoupled(elemNdFactory))

// deq_ptr -> enq_ptr
val enqIncResults = Output(Vec(enqMaxNum + 1, UInt(log2Ceil(channelNum).W)))
val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelNum).W)))
val enq_ptr = Output(UInt(log2Ceil(channelNum).W))
val deq_ptr = Output(UInt(log2Ceil(channelNum).W))
})

// Fallback
Expand Down Expand Up @@ -53,22 +47,14 @@ class DistributedQueue[ElemT <: Data](

storeOuts.foreach(_.ready := false.B)
if (channelNum == 1) {
storeOuts(0) <> storeIns(0)
// storeOuts(0) <> storeIns(0)
io.enqueuePorts(0) <> storeIns(0)
io.dequeuePorts(0) <> storeOuts(0)
} else {
val enq_ptr = Module(new MultiCounter(channelNum, enqMaxNum))
val deq_ptr = Module(new MultiCounter(channelNum, deqMaxNum))
enq_ptr.io.flush := io.isFlush
deq_ptr.io.flush := io.isFlush
io.enq_ptr := enq_ptr.io.value
io.deq_ptr := deq_ptr.io.value
io.enqIncResults.zip(enq_ptr.io.incResults).foreach {
case (dst, src) =>
dst := src
}
io.deqIncResults.zip(deq_ptr.io.incResults).foreach {
case (dst, src) =>
dst := src
}

enq_ptr.io.inc := io.enqueuePorts.zipWithIndex.map {
case (enqPort, idx) =>
Expand Down
121 changes: 121 additions & 0 deletions src/src/pipeline/common/DistributedQueuePlus.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package pipeline.common

import chisel3._
import chisel3.util._
import utils.MultiCounter
import spec.Param

class DistributedQueuePlus[ElemT <: Data](
enqMaxNum: Int,
deqMaxNum: Int,
channelNum: Int,
channelLength: Int,
elemNdFactory: => ElemT,
blankElem: => ElemT,
useSyncReadMem: Boolean = true)
extends Module {

require(channelNum >= enqMaxNum)
require(channelNum >= deqMaxNum)
require(log2Ceil(channelNum) == log2Floor(channelNum))
val channelNumWidth = log2Ceil(channelNum)

val io = IO(new Bundle {
val isFlush = Input(Bool())
val enqueuePorts = Vec(enqMaxNum, Flipped(Decoupled(elemNdFactory)))
val dequeuePorts = Vec(deqMaxNum, Decoupled(elemNdFactory))

// deq_ptr -> enq_ptr
val enqIncResults = Output(Vec(enqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
// val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
// val enq_ptr = Output(UInt(log2Ceil(channelLength * channelNum).W))
// val deq_ptr = Output(UInt(log2Ceil(channelLength * channelNum).W))

val elems = Output(Vec(channelLength * channelNum, elemNdFactory))
val setPorts = Input(Vec(channelLength * channelNum, Valid(elemNdFactory)))
})

// Fallback
io.dequeuePorts.foreach(_ <> DontCare)
io.enqueuePorts.foreach(_.ready := false.B)
io.dequeuePorts.foreach(_.valid := false.B)

// val storeIns = Wire(Vec(channelNum, (DecoupledIO(elemNdFactory))))

val queues = Seq.fill(channelNum)(
Module(
new MultiQueue(
channelLength,
1,
1,
elemNdFactory,
blankElem,
writeFirst = false
)
)
)
queues.foreach(_.io.isFlush := io.isFlush)

val storeIns = VecInit(queues.map(_.io.enqueuePorts(0)))
val storeOuts = VecInit(queues.map(_.io.dequeuePorts(0)))

for (i <- 0 until channelLength) {
for (j <- 0 until channelNum) {
val idx = i * channelLength + j
io.elems(idx) := queues(j).io.elems(i)
queues(j).io.setPorts(i) := io.setPorts(idx)
}
}

storeIns.foreach { in =>
in.valid := false.B
in.bits := DontCare
}

storeOuts.foreach(_.ready := false.B)
if (channelNum == 1) {
io.enqueuePorts(0) <> storeIns(0)
io.dequeuePorts(0) <> storeOuts(0)
} else {
val enq_ptr = Module(new MultiCounter(channelLength * channelNum, enqMaxNum))
val deq_ptr = Module(new MultiCounter(channelLength * channelNum, deqMaxNum))

enq_ptr.io.flush := io.isFlush
deq_ptr.io.flush := io.isFlush
// io.enq_ptr := enq_ptr.io.value
// io.deq_ptr := deq_ptr.io.value
// io.enqIncResults.zip(enq_ptr.io.incResults).foreach {
// case (dst, src) =>
// dst := src
// }
// io.deqIncResults.zip(deq_ptr.io.incResults).foreach {
// case (dst, src) =>
// dst := src
// }
io.enqIncResults.zipWithIndex.foreach {
case (dst, idx) =>
dst := enq_ptr.io.incResults(idx)
}
io.deqIncResults.zipWithIndex.foreach {
case (dst, idx) =>
dst := deq_ptr.io.incResults(idx)
}

enq_ptr.io.inc := io.enqueuePorts.zipWithIndex.map {
case (enqPort, idx) =>
// connect
enqPort <> storeIns(enq_ptr.io.incResults(idx)(channelNumWidth - 1, 0))
// return
enqPort.valid && storeIns(enq_ptr.io.incResults(idx)(channelNumWidth - 1, 0)).ready
}.map(_.asUInt).reduce(_ +& _)

deq_ptr.io.inc := io.dequeuePorts.zipWithIndex.map {
case (deqPort, idx) =>
// connect
deqPort <> storeOuts(deq_ptr.io.incResults(idx)(channelNumWidth - 1, 0))
// return
deqPort.valid && storeOuts(deq_ptr.io.incResults(idx)(channelNumWidth - 1, 0)).ready
}.map(_.asUInt).reduce(_ +& _)
}
}
4 changes: 2 additions & 2 deletions src/src/pipeline/dispatch/RenameStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,13 @@ class RenameStage(
}

when(peer.branchFlush) {
peer.requests.foreach(_.en := false.B)
// peer.requests.foreach(_.en := false.B)
io.ins.foreach(_.ready := false.B)
fetchEnableFlag := false.B
}

when(io.isFlush) {
peer.requests.foreach(_.en := false.B)
// peer.requests.foreach(_.en := false.B)
io.ins.foreach(_.ready := false.B)
fetchEnableFlag := true.B
}
Expand Down
49 changes: 32 additions & 17 deletions src/src/pipeline/rob/Rob.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import pipeline.common.MultiQueue
import pipeline.rob.bundles._
import pipeline.rob.enums.{RegDataLocateSel, RobDistributeSel, RobInstState => State}
import spec._
import pipeline.common.DistributedQueuePlus

// assert: commits cannot ready 1 but not 0
class Rob(
Expand Down Expand Up @@ -57,15 +58,28 @@ class Rob(

val matchTable = RegInit(VecInit(Seq.fill(spec.Count.reg)(RobMatchBundle.default)))

// val queue = Module(
// new MultiQueue(
// robLength,
// issueNum,
// commitNum,
// new RobInstStoreBundle,
// RobInstStoreBundle.default
// )
// )

val queue = Module(
new MultiQueue(
robLength,
new DistributedQueuePlus(
issueNum,
commitNum,
Param.Width.Rob._channelNum,
Param.Width.Rob._channelLength,
new RobInstStoreBundle,
RobInstStoreBundle.default
RobInstStoreBundle.default,
useSyncReadMem = false
)
)

queue.io.enqueuePorts.foreach { port =>
port.valid := false.B
port.bits := DontCare
Expand All @@ -77,7 +91,7 @@ class Rob(
}
queue.io.dequeuePorts.foreach(_.ready := false.B)
queue.io.isFlush := io.isFlush
io.emptyNum := queue.io.emptyNum
io.emptyNum := VecInit(queue.io.enqueuePorts.map(_.ready.asUInt)).reduceTree(_ +& _)
io.instWbBroadCasts.zip(io.finishInsts).foreach {
case (dst, src) =>
dst.en := src.valid // && io.robInstValids(src.bits.instInfo.robId)
Expand All @@ -91,9 +105,9 @@ class Rob(
io.finishInsts.foreach { finishInst =>
finishInst.ready := true.B
when(finishInst.valid && finishInst.bits.instInfo.isValid) {
queue.io.elemValids.lazyZip(queue.io.elems).lazyZip(queue.io.setPorts).zipWithIndex.foreach {
case ((elemValid, elem, set), idx) =>
when(elemValid && elem.state === State.busy && idx.U === finishInst.bits.instInfo.robId) {
queue.io.elems.lazyZip(queue.io.setPorts).zipWithIndex.foreach {
case ((elem, set), idx) =>
when(elem.state === State.busy && idx.U === finishInst.bits.instInfo.robId) {
set.valid := true.B
set.bits.isValid := elem.isValid
set.bits.state := State.ready
Expand Down Expand Up @@ -138,8 +152,9 @@ class Rob(
!deqPort.bits.wbPort.instInfo.forbidParallelCommit &&
queue.io.dequeuePorts(idx - 1).valid &&
queue.io.dequeuePorts(idx - 1).ready && // promise commit in order
!hasInterruptReg &&
!io.hasInterrupt
!hasInterruptReg
// &&
// !io.hasInterrupt
}

commit.valid := deqPort.ready
Expand All @@ -159,12 +174,12 @@ class Rob(
}

when(io.hasInterrupt) {
when(io.commits(0).valid && io.commits(0).ready) {
io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
io.commits(0).bits.instInfo.exceptionPos := ExceptionPos.backend
}.otherwise {
hasInterruptReg := true.B
}
// when(io.commits(0).valid && io.commits(0).ready) {
// io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
// io.commits(0).bits.instInfo.exceptionPos := ExceptionPos.backend
// }.otherwise {
hasInterruptReg := true.B
// }
}.elsewhen(hasInterruptReg && io.commits(0).valid && io.commits(0).ready) {
hasInterruptReg := false.B
io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
Expand Down Expand Up @@ -241,8 +256,8 @@ class Rob(
*/

when(io.isFlush) {
queue.io.enqueuePorts.foreach(_.valid := false.B)
io.commits.foreach(_.valid := false.B)
// queue.io.enqueuePorts.foreach(_.valid := false.B)
// io.commits.foreach(_.valid := false.B)
matchTable.foreach(_.locate := RegDataLocateSel.regfile)
}
}
6 changes: 4 additions & 2 deletions src/src/spec/Param.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ object Param {
val exeOp = log2Ceil(ExeInst.Op.count + 1).W

object Rob {
val _length = 16
val id = log2Ceil(_length).W
val _length = 16
val _channelNum = 4
val _channelLength = _length / _channelNum
val id = log2Ceil(_length).W
}

object Axi {
Expand Down
Loading