fix: resolve OoO simulation timeout
This commit is contained in:
@@ -4,23 +4,50 @@ import chisel3.util._
|
||||
class FreeList(p: CoreParams = CoreParams()) extends Module {
|
||||
private val physBits = log2Ceil(p.physRegs)
|
||||
val io = IO(new Bundle {
|
||||
val alloc = Input(Bool())
|
||||
val allocPhys = Output(UInt(physBits.W))
|
||||
val canAlloc = Output(Bool())
|
||||
val free = Input(Bool())
|
||||
val freePhys = Input(UInt(physBits.W))
|
||||
val allocReq = Input(Vec(p.issueWidth, Bool()))
|
||||
val allocPhys = Output(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val allocValid = Output(Vec(p.issueWidth, Bool()))
|
||||
val canAllocate = Output(Bool())
|
||||
val freeReq = Input(Vec(p.issueWidth, Bool()))
|
||||
val freePhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val recover = Input(Bool())
|
||||
val committedPhys = Input(Vec(p.archRegs, UInt(physBits.W)))
|
||||
})
|
||||
|
||||
val freeBits = RegInit(VecInit((0 until p.physRegs).map(i => (i >= p.archRegs).B)))
|
||||
val chosen = PriorityEncoder(freeBits)
|
||||
io.canAlloc := freeBits.asUInt.orR
|
||||
io.allocPhys := chosen
|
||||
val freeMask = freeBits.asUInt
|
||||
val firstOH = PriorityEncoderOH(freeMask)
|
||||
val secondMask = freeMask & ~firstOH
|
||||
val secondOH = PriorityEncoderOH(secondMask)
|
||||
val freeCount = PopCount(freeMask)
|
||||
dontTouch(freeMask)
|
||||
dontTouch(freeCount)
|
||||
|
||||
when(io.alloc && io.canAlloc) {
|
||||
freeBits(chosen) := false.B
|
||||
io.canAllocate := freeCount >= p.issueWidth.U
|
||||
io.allocPhys(0) := OHToUInt(firstOH)
|
||||
io.allocPhys(1) := OHToUInt(secondOH)
|
||||
io.allocValid(0) := io.allocReq(0) && freeMask.orR
|
||||
io.allocValid(1) := io.allocReq(1) && secondMask.orR
|
||||
|
||||
val nextFree = Wire(Vec(p.physRegs, Bool()))
|
||||
nextFree := freeBits
|
||||
when(io.allocReq(0) && io.allocValid(0)) {
|
||||
nextFree(io.allocPhys(0)) := false.B
|
||||
}
|
||||
when(io.free && io.freePhys >= p.archRegs.U) {
|
||||
freeBits(io.freePhys) := true.B
|
||||
when(io.allocReq(1) && io.allocValid(1)) {
|
||||
nextFree(io.allocPhys(1)) := false.B
|
||||
}
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
when(io.freeReq(i) && io.freePhys(i) =/= 0.U) {
|
||||
nextFree(io.freePhys(i)) := true.B
|
||||
}
|
||||
}
|
||||
when(io.recover) {
|
||||
for (i <- 0 until p.physRegs) {
|
||||
val isCommitted = io.committedPhys.map(_ === i.U).foldLeft(false.B)(_ || _)
|
||||
freeBits(i) := !isCommitted
|
||||
}
|
||||
}.otherwise {
|
||||
freeBits := nextFree
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,69 +3,184 @@ import chisel3.util._
|
||||
|
||||
class RobEntry(p: CoreParams = CoreParams()) extends Bundle {
|
||||
val valid = Bool()
|
||||
val robIdx = UInt(log2Ceil(p.robEntries).W)
|
||||
val pc = UInt(p.xlen.W)
|
||||
val archDest = UInt(5.W)
|
||||
val writesDest = Bool()
|
||||
val opClass = UInt(Consts.OpClassWidth.W)
|
||||
val dest = UInt(log2Ceil(p.physRegs).W)
|
||||
val oldDest = UInt(log2Ceil(p.physRegs).W)
|
||||
val completed = Bool()
|
||||
val exception = Bool()
|
||||
val exceptionCause = UInt(p.xlen.W)
|
||||
val badAddr = UInt(p.xlen.W)
|
||||
val branchMispredict = Bool()
|
||||
val redirectPc = UInt(p.xlen.W)
|
||||
val csrValid = Bool()
|
||||
val csrAddr = UInt(12.W)
|
||||
val csrCmd = UInt(3.W)
|
||||
val csrRs1 = UInt(p.xlen.W)
|
||||
val csrZimm = UInt(5.W)
|
||||
}
|
||||
|
||||
class ROB(p: CoreParams = CoreParams()) extends Module {
|
||||
private val idxBits = log2Ceil(p.robEntries)
|
||||
val io = IO(new Bundle {
|
||||
val allocate = Input(Bool())
|
||||
val allocatePc = Input(UInt(p.xlen.W))
|
||||
val allocateClass = Input(UInt(Consts.OpClassWidth.W))
|
||||
val allocateDest = Input(UInt(log2Ceil(p.physRegs).W))
|
||||
val allocateOldDest = Input(UInt(log2Ceil(p.physRegs).W))
|
||||
val allocateIdx = Output(UInt(idxBits.W))
|
||||
val allocateValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val allocateEntry = Input(Vec(p.issueWidth, new RobEntry(p)))
|
||||
val allocateIdx = Output(Vec(p.issueWidth, UInt(idxBits.W)))
|
||||
val canAllocate = Output(Bool())
|
||||
val complete = Input(Bool())
|
||||
val completeIdx = Input(UInt(idxBits.W))
|
||||
val commitValid = Output(Bool())
|
||||
val commit = Output(new RobEntry(p))
|
||||
val commitReady = Input(Bool())
|
||||
val completeValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeIdx = Input(Vec(p.issueWidth, UInt(idxBits.W)))
|
||||
val completeException = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeCause = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeBadAddr = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeMispredict = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeRedirectPc = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeCsrValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeCsrAddr = Input(Vec(p.issueWidth, UInt(12.W)))
|
||||
val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W)))
|
||||
val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val commitValid = Output(Vec(p.issueWidth, Bool()))
|
||||
val commit = Output(Vec(p.issueWidth, new RobEntry(p)))
|
||||
val commitReady = Input(Vec(p.issueWidth, Bool()))
|
||||
val flush = Input(Bool())
|
||||
val empty = Output(Bool())
|
||||
})
|
||||
|
||||
val entries = RegInit(VecInit(Seq.fill(p.robEntries)(0.U.asTypeOf(new RobEntry(p)))))
|
||||
val valid = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
|
||||
val completed = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
|
||||
val exception = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
|
||||
val exceptionCause = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W))))
|
||||
val badAddr = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W))))
|
||||
val branchMispredict = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
|
||||
val redirectPc = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W))))
|
||||
val csrValid = RegInit(VecInit(Seq.fill(p.robEntries)(false.B)))
|
||||
val csrAddr = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(12.W))))
|
||||
val csrCmd = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(3.W))))
|
||||
val csrRs1 = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(p.xlen.W))))
|
||||
val csrZimm = RegInit(VecInit(Seq.fill(p.robEntries)(0.U(5.W))))
|
||||
val head = RegInit(0.U(idxBits.W))
|
||||
val tail = RegInit(0.U(idxBits.W))
|
||||
val count = RegInit(0.U(log2Ceil(p.robEntries + 1).W))
|
||||
val allocCount = PopCount(io.allocateValid)
|
||||
|
||||
io.canAllocate := count =/= p.robEntries.U
|
||||
io.allocateIdx := tail
|
||||
io.commit := entries(head)
|
||||
io.commitValid := count =/= 0.U && entries(head).valid && entries(head).completed
|
||||
val head0 = head
|
||||
val head1 = head + 1.U
|
||||
val tail0 = tail
|
||||
val tail1 = tail + 1.U
|
||||
val headEntry0 = Wire(new RobEntry(p))
|
||||
val headEntry1 = Wire(new RobEntry(p))
|
||||
headEntry0 := entries(head0)
|
||||
headEntry0.valid := valid(head0)
|
||||
headEntry0.completed := completed(head0)
|
||||
headEntry0.exception := exception(head0)
|
||||
headEntry0.exceptionCause := exceptionCause(head0)
|
||||
headEntry0.badAddr := badAddr(head0)
|
||||
headEntry0.branchMispredict := branchMispredict(head0)
|
||||
headEntry0.redirectPc := redirectPc(head0)
|
||||
headEntry0.csrValid := csrValid(head0)
|
||||
headEntry0.csrAddr := csrAddr(head0)
|
||||
headEntry0.csrCmd := csrCmd(head0)
|
||||
headEntry0.csrRs1 := csrRs1(head0)
|
||||
headEntry0.csrZimm := csrZimm(head0)
|
||||
headEntry1 := entries(head1)
|
||||
headEntry1.valid := valid(head1)
|
||||
headEntry1.completed := completed(head1)
|
||||
headEntry1.exception := exception(head1)
|
||||
headEntry1.exceptionCause := exceptionCause(head1)
|
||||
headEntry1.badAddr := badAddr(head1)
|
||||
headEntry1.branchMispredict := branchMispredict(head1)
|
||||
headEntry1.redirectPc := redirectPc(head1)
|
||||
headEntry1.csrValid := csrValid(head1)
|
||||
headEntry1.csrAddr := csrAddr(head1)
|
||||
headEntry1.csrCmd := csrCmd(head1)
|
||||
headEntry1.csrRs1 := csrRs1(head1)
|
||||
headEntry1.csrZimm := csrZimm(head1)
|
||||
|
||||
io.empty := count === 0.U
|
||||
io.canAllocate := (p.robEntries.U - count) >= p.issueWidth.U
|
||||
io.allocateIdx(0) := tail0
|
||||
io.allocateIdx(1) := tail1
|
||||
io.commit(0) := headEntry0
|
||||
io.commit(1) := headEntry1
|
||||
io.commitValid(0) := count =/= 0.U && valid(head0) && completed(head0)
|
||||
io.commitValid(1) := count > 1.U && io.commitValid(0) && !headEntry0.exception &&
|
||||
!headEntry0.branchMispredict && valid(head1) && completed(head1)
|
||||
|
||||
when(io.flush) {
|
||||
entries.foreach(_.valid := false.B)
|
||||
valid := VecInit(Seq.fill(p.robEntries)(false.B))
|
||||
completed := VecInit(Seq.fill(p.robEntries)(false.B))
|
||||
exception := VecInit(Seq.fill(p.robEntries)(false.B))
|
||||
branchMispredict := VecInit(Seq.fill(p.robEntries)(false.B))
|
||||
csrValid := VecInit(Seq.fill(p.robEntries)(false.B))
|
||||
head := 0.U
|
||||
tail := 0.U
|
||||
count := 0.U
|
||||
}.otherwise {
|
||||
when(io.allocate && io.canAllocate) {
|
||||
entries(tail).valid := true.B
|
||||
entries(tail).pc := io.allocatePc
|
||||
entries(tail).opClass := io.allocateClass
|
||||
entries(tail).dest := io.allocateDest
|
||||
entries(tail).oldDest := io.allocateOldDest
|
||||
entries(tail).completed := false.B
|
||||
entries(tail).exception := false.B
|
||||
entries(tail).branchMispredict := false.B
|
||||
tail := tail + 1.U
|
||||
count := count + 1.U
|
||||
when(io.allocateValid(0) && io.canAllocate) {
|
||||
entries(tail0) := io.allocateEntry(0)
|
||||
entries(tail0).robIdx := tail0
|
||||
valid(tail0) := true.B
|
||||
completed(tail0) := false.B
|
||||
exception(tail0) := false.B
|
||||
exceptionCause(tail0) := 0.U
|
||||
badAddr(tail0) := 0.U
|
||||
branchMispredict(tail0) := false.B
|
||||
redirectPc(tail0) := 0.U
|
||||
csrValid(tail0) := false.B
|
||||
csrAddr(tail0) := 0.U
|
||||
csrCmd(tail0) := 0.U
|
||||
csrRs1(tail0) := 0.U
|
||||
csrZimm(tail0) := 0.U
|
||||
}
|
||||
when(io.complete) {
|
||||
entries(io.completeIdx).completed := true.B
|
||||
when(io.allocateValid(1) && io.canAllocate) {
|
||||
entries(tail1) := io.allocateEntry(1)
|
||||
entries(tail1).robIdx := tail1
|
||||
valid(tail1) := true.B
|
||||
completed(tail1) := false.B
|
||||
exception(tail1) := false.B
|
||||
exceptionCause(tail1) := 0.U
|
||||
badAddr(tail1) := 0.U
|
||||
branchMispredict(tail1) := false.B
|
||||
redirectPc(tail1) := 0.U
|
||||
csrValid(tail1) := false.B
|
||||
csrAddr(tail1) := 0.U
|
||||
csrCmd(tail1) := 0.U
|
||||
csrRs1(tail1) := 0.U
|
||||
csrZimm(tail1) := 0.U
|
||||
}
|
||||
when(io.commitValid && io.commitReady) {
|
||||
entries(head).valid := false.B
|
||||
head := head + 1.U
|
||||
count := count - 1.U
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
when(io.completeValid(i)) {
|
||||
completed(io.completeIdx(i)) := true.B
|
||||
exception(io.completeIdx(i)) := io.completeException(i)
|
||||
exceptionCause(io.completeIdx(i)) := io.completeCause(i)
|
||||
badAddr(io.completeIdx(i)) := io.completeBadAddr(i)
|
||||
branchMispredict(io.completeIdx(i)) := io.completeMispredict(i)
|
||||
redirectPc(io.completeIdx(i)) := io.completeRedirectPc(i)
|
||||
csrValid(io.completeIdx(i)) := io.completeCsrValid(i)
|
||||
csrAddr(io.completeIdx(i)) := io.completeCsrAddr(i)
|
||||
csrCmd(io.completeIdx(i)) := io.completeCsrCmd(i)
|
||||
csrRs1(io.completeIdx(i)) := io.completeCsrRs1(i)
|
||||
csrZimm(io.completeIdx(i)) := io.completeCsrZimm(i)
|
||||
}
|
||||
}
|
||||
val commit0 = io.commitValid(0) && io.commitReady(0)
|
||||
val commit1 = io.commitValid(1) && io.commitReady(1)
|
||||
when(commit0) { valid(head0) := false.B }
|
||||
when(commit1) { valid(head1) := false.B }
|
||||
|
||||
val committed = PopCount(VecInit(Seq(commit0, commit1)))
|
||||
val allocated = Mux(io.canAllocate, allocCount, 0.U)
|
||||
head := head + committed
|
||||
tail := tail + allocated
|
||||
count := count + allocated - committed
|
||||
when(!commit0 && !commit1 && allocated === 0.U) {
|
||||
head := head
|
||||
tail := tail
|
||||
count := count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,43 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class RenameStage(p: CoreParams = CoreParams()) extends Module {
|
||||
private val physBits = log2Ceil(p.physRegs)
|
||||
private val robBits = log2Ceil(p.robEntries)
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val inValid = Input(Bool())
|
||||
val in = Input(new DecodedInst(p))
|
||||
val outValid = Output(Bool())
|
||||
val out = Output(new RenamePacket(p))
|
||||
val commitFree = Input(Bool())
|
||||
val commitOldPhys = Input(UInt(log2Ceil(p.physRegs).W))
|
||||
val inValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val in = Input(Vec(p.issueWidth, new DecodedInst(p)))
|
||||
val outValid = Output(Vec(p.issueWidth, Bool()))
|
||||
val out = Output(Vec(p.issueWidth, new RenamePacket(p)))
|
||||
val canAccept = Output(Bool())
|
||||
|
||||
val wbValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val wbPhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
|
||||
val completeValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeIdx = Input(Vec(p.issueWidth, UInt(robBits.W)))
|
||||
val completeException = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeCause = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeBadAddr = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeMispredict = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeRedirectPc = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeCsrValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val completeCsrAddr = Input(Vec(p.issueWidth, UInt(12.W)))
|
||||
val completeCsrCmd = Input(Vec(p.issueWidth, UInt(3.W)))
|
||||
val completeCsrRs1 = Input(Vec(p.issueWidth, UInt(p.xlen.W)))
|
||||
val completeCsrZimm = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
|
||||
val commitReady = Input(Vec(p.issueWidth, Bool()))
|
||||
val commitValid = Output(Vec(p.issueWidth, Bool()))
|
||||
val commitEntry = Output(Vec(p.issueWidth, new RobEntry(p)))
|
||||
val robEmpty = Output(Bool())
|
||||
|
||||
val commitMapValid = Input(Vec(p.issueWidth, Bool()))
|
||||
val commitArch = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val commitPhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val commitFreeOld = Input(Vec(p.issueWidth, Bool()))
|
||||
val commitOldPhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
|
||||
val flush = Input(Bool())
|
||||
})
|
||||
|
||||
@@ -16,34 +46,97 @@ class RenameStage(p: CoreParams = CoreParams()) extends Module {
|
||||
val freeList = Module(new FreeList(p))
|
||||
val rob = Module(new ROB(p))
|
||||
|
||||
table.io.rs1 := io.in.rs1
|
||||
table.io.rs2 := io.in.rs2
|
||||
table.io.rd := io.in.rd
|
||||
val needsPhys = Wire(Vec(p.issueWidth, Bool()))
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
needsPhys(i) := io.inValid(i) && io.in(i).writesRd
|
||||
}
|
||||
|
||||
table.io.rs1 := VecInit(io.in.map(_.rs1))
|
||||
table.io.rs2 := VecInit(io.in.map(_.rs2))
|
||||
table.io.rd := VecInit(io.in.map(_.rd))
|
||||
table.io.newPhys := freeList.io.allocPhys
|
||||
table.io.wen := io.inValid && io.in.writesRd && freeList.io.canAlloc && rob.io.canAllocate
|
||||
table.io.wen := VecInit((0 until p.issueWidth).map(i => io.outValid(i) && io.in(i).writesRd))
|
||||
table.io.commitWen := io.commitMapValid
|
||||
table.io.commitRd := io.commitArch
|
||||
table.io.commitPhys := io.commitPhys
|
||||
table.io.recover := io.flush
|
||||
|
||||
freeList.io.alloc := table.io.wen
|
||||
freeList.io.free := io.commitFree
|
||||
freeList.io.allocReq := needsPhys
|
||||
freeList.io.freeReq := io.commitFreeOld
|
||||
freeList.io.freePhys := io.commitOldPhys
|
||||
freeList.io.recover := io.flush
|
||||
freeList.io.committedPhys := table.io.committedPhys
|
||||
|
||||
rob.io.allocate := io.inValid && rob.io.canAllocate && (!io.in.writesRd || freeList.io.canAlloc)
|
||||
rob.io.allocatePc := io.in.pc
|
||||
rob.io.allocateClass := io.in.opClass
|
||||
rob.io.allocateDest := Mux(io.in.writesRd, freeList.io.allocPhys, table.io.oldPrd)
|
||||
rob.io.allocateOldDest := table.io.oldPrd
|
||||
rob.io.complete := false.B
|
||||
rob.io.completeIdx := 0.U
|
||||
rob.io.commitReady := false.B
|
||||
val requested = PopCount(io.inValid)
|
||||
val canRename = freeList.io.canAllocate && rob.io.canAllocate
|
||||
io.canAccept := canRename
|
||||
|
||||
val readyReg = RegInit(VecInit(Seq.fill(p.physRegs)(true.B)))
|
||||
when(io.flush) {
|
||||
readyReg := VecInit(Seq.fill(p.physRegs)(true.B))
|
||||
}.otherwise {
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
when(io.wbValid(i)) {
|
||||
readyReg(io.wbPhys(i)) := true.B
|
||||
}
|
||||
when(io.outValid(i) && io.in(i).writesRd) {
|
||||
readyReg(freeList.io.allocPhys(i)) := false.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rob.io.allocateValid := VecInit((0 until p.issueWidth).map(i => io.inValid(i) && canRename))
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
val e = WireDefault(0.U.asTypeOf(new RobEntry(p)))
|
||||
e.valid := io.inValid(i) && canRename
|
||||
e.pc := io.in(i).pc
|
||||
e.archDest := io.in(i).rd
|
||||
e.writesDest := io.in(i).writesRd
|
||||
e.opClass := io.in(i).opClass
|
||||
e.dest := Mux(io.in(i).writesRd, freeList.io.allocPhys(i), table.io.oldPrd(i))
|
||||
e.oldDest := table.io.oldPrd(i)
|
||||
rob.io.allocateEntry(i) := e
|
||||
}
|
||||
rob.io.completeValid := io.completeValid
|
||||
rob.io.completeIdx := io.completeIdx
|
||||
rob.io.completeException := io.completeException
|
||||
rob.io.completeCause := io.completeCause
|
||||
rob.io.completeBadAddr := io.completeBadAddr
|
||||
rob.io.completeMispredict := io.completeMispredict
|
||||
rob.io.completeRedirectPc := io.completeRedirectPc
|
||||
rob.io.completeCsrValid := io.completeCsrValid
|
||||
rob.io.completeCsrAddr := io.completeCsrAddr
|
||||
rob.io.completeCsrCmd := io.completeCsrCmd
|
||||
rob.io.completeCsrRs1 := io.completeCsrRs1
|
||||
rob.io.completeCsrZimm := io.completeCsrZimm
|
||||
rob.io.commitReady := io.commitReady
|
||||
rob.io.flush := io.flush
|
||||
io.commitValid := rob.io.commitValid
|
||||
io.commitEntry := rob.io.commit
|
||||
io.robEmpty := rob.io.empty
|
||||
|
||||
io.outValid := rob.io.allocate
|
||||
io.out.valid := io.outValid
|
||||
io.out.decoded := io.in
|
||||
io.out.prs1 := table.io.prs1
|
||||
io.out.prs2 := table.io.prs2
|
||||
io.out.prd := Mux(io.in.writesRd, freeList.io.allocPhys, table.io.oldPrd)
|
||||
io.out.oldPrd := table.io.oldPrd
|
||||
io.out.robIdx := rob.io.allocateIdx
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
val src1FromOlder = (0 until i).map(j =>
|
||||
io.outValid(j) && io.in(j).writesRd && io.in(j).rd =/= 0.U && io.in(j).rd === io.in(i).rs1
|
||||
).foldLeft(false.B)(_ || _)
|
||||
val src2FromOlder = (0 until i).map(j =>
|
||||
io.outValid(j) && io.in(j).writesRd && io.in(j).rd =/= 0.U && io.in(j).rd === io.in(i).rs2
|
||||
).foldLeft(false.B)(_ || _)
|
||||
|
||||
io.outValid(i) := io.inValid(i) && canRename
|
||||
io.out(i).valid := io.outValid(i)
|
||||
io.out(i).decoded := io.in(i)
|
||||
io.out(i).prs1 := table.io.prs1(i)
|
||||
io.out(i).prs2 := table.io.prs2(i)
|
||||
io.out(i).src1Ready := io.in(i).rs1 === 0.U || (!src1FromOlder && readyReg(table.io.prs1(i)))
|
||||
io.out(i).src2Ready := io.in(i).rs2 === 0.U || (!src2FromOlder && readyReg(table.io.prs2(i)))
|
||||
io.out(i).prd := Mux(io.in(i).writesRd, freeList.io.allocPhys(i), table.io.oldPrd(i))
|
||||
io.out(i).oldPrd := table.io.oldPrd(i)
|
||||
io.out(i).robIdx := rob.io.allocateIdx(i)
|
||||
|
||||
}
|
||||
|
||||
when(requested === 0.U) {
|
||||
io.canAccept := true.B
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,29 +4,45 @@ import chisel3.util._
|
||||
class RenameTable(p: CoreParams = CoreParams()) extends Module {
|
||||
private val physBits = log2Ceil(p.physRegs)
|
||||
val io = IO(new Bundle {
|
||||
val rs1 = Input(UInt(5.W))
|
||||
val rs2 = Input(UInt(5.W))
|
||||
val rd = Input(UInt(5.W))
|
||||
val newPhys = Input(UInt(physBits.W))
|
||||
val wen = Input(Bool())
|
||||
val prs1 = Output(UInt(physBits.W))
|
||||
val prs2 = Output(UInt(physBits.W))
|
||||
val oldPrd = Output(UInt(physBits.W))
|
||||
val rs1 = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val rs2 = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val rd = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val newPhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val wen = Input(Vec(p.issueWidth, Bool()))
|
||||
val prs1 = Output(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val prs2 = Output(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val oldPrd = Output(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val commitWen = Input(Vec(p.issueWidth, Bool()))
|
||||
val commitRd = Input(Vec(p.issueWidth, UInt(5.W)))
|
||||
val commitPhys = Input(Vec(p.issueWidth, UInt(physBits.W)))
|
||||
val recover = Input(Bool())
|
||||
val committedPhys = Output(Vec(p.archRegs, UInt(physBits.W)))
|
||||
})
|
||||
|
||||
val init = VecInit((0 until p.archRegs).map(_.U(physBits.W)))
|
||||
val speculative = RegInit(init)
|
||||
val committed = RegInit(init)
|
||||
io.committedPhys := committed
|
||||
|
||||
io.prs1 := speculative(io.rs1)
|
||||
io.prs2 := speculative(io.rs2)
|
||||
io.oldPrd := speculative(io.rd)
|
||||
io.prs1(0) := speculative(io.rs1(0))
|
||||
io.prs2(0) := speculative(io.rs2(0))
|
||||
io.oldPrd(0) := speculative(io.rd(0))
|
||||
|
||||
val slot0Writes = io.wen(0) && io.rd(0) =/= 0.U
|
||||
io.prs1(1) := Mux(slot0Writes && io.rd(0) === io.rs1(1), io.newPhys(0), speculative(io.rs1(1)))
|
||||
io.prs2(1) := Mux(slot0Writes && io.rd(0) === io.rs2(1), io.newPhys(0), speculative(io.rs2(1)))
|
||||
io.oldPrd(1) := Mux(slot0Writes && io.rd(0) === io.rd(1), io.newPhys(0), speculative(io.rd(1)))
|
||||
|
||||
when(io.recover) {
|
||||
speculative := committed
|
||||
}.elsewhen(io.wen && io.rd =/= 0.U) {
|
||||
speculative(io.rd) := io.newPhys
|
||||
}.otherwise {
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
when(io.wen(i) && io.rd(i) =/= 0.U) {
|
||||
speculative(io.rd(i)) := io.newPhys(i)
|
||||
}
|
||||
when(io.commitWen(i) && io.commitRd(i) =/= 0.U) {
|
||||
committed(io.commitRd(i)) := io.commitPhys(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user