未验证 提交 a4ef1e8d 编写于 作者: Y Yinan Xu 提交者: GitHub

Merge pull request #429 from RISCVERS/opt-imm-pc

Optimize imm and pc
......@@ -6,7 +6,7 @@ import xiangshan.backend.SelImm
import xiangshan.backend.brq.BrqPtr
import xiangshan.backend.rename.FreeListPtr
import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.decode.XDecode
import xiangshan.backend.decode.{ImmUnion, XDecode}
import xiangshan.mem.{LqPtr, SqPtr}
import xiangshan.frontend.PreDecodeInfo
import xiangshan.frontend.HasBPUParameter
......@@ -14,6 +14,7 @@ import xiangshan.frontend.HasTageParameter
import xiangshan.frontend.HasIFUConst
import xiangshan.frontend.GlobalHistory
import utils._
import scala.math.max
import Chisel.experimental.chiselName
......@@ -219,7 +220,7 @@ class CtrlSignals extends XSBundle {
val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit
val isRVF = Bool()
val selImm = SelImm()
val imm = UInt(XLEN.W)
val imm = UInt(ImmUnion.maxLen.W)
val commitType = CommitType()
val fpu = new FPUCtrlSignals
......
......@@ -5,18 +5,19 @@ import chisel3.util._
import utils._
import xiangshan._
import xiangshan.backend.decode.DecodeStage
import xiangshan.backend.rename.{Rename, BusyTable}
import xiangshan.backend.brq.Brq
import xiangshan.backend.rename.{BusyTable, Rename}
import xiangshan.backend.brq.{Brq, BrqPcRead}
import xiangshan.backend.dispatch.Dispatch
import xiangshan.backend.exu._
import xiangshan.backend.exu.Exu.exuConfigs
import xiangshan.backend.regfile.RfReadPort
import xiangshan.backend.roq.{Roq, RoqPtr, RoqCSRIO}
import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqPtr}
import xiangshan.mem.LsqEnqIO
class CtrlToIntBlockIO extends XSBundle {
val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
val readRf = Vec(NRIntReadPorts, Flipped(new RfReadPort(XLEN)))
val jumpPc = Output(UInt(VAddrBits.W))
// int block only uses port 0~7
val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) // TODO parameterize 8 here
val redirect = ValidIO(new Redirect)
......@@ -87,6 +88,8 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq.io.redirect.bits <> redirect
brq.io.bcommit <> roq.io.bcommit
brq.io.exuRedirectWb <> io.fromIntBlock.exuRedirect
brq.io.pcReadReq.brqIdx := dispatch.io.enqIQCtrl(0).bits.brTag // jump
io.toIntBlock.jumpPc := brq.io.pcReadReq.pc
// pipeline between decode and dispatch
val lastCycleRedirect = RegNext(redirectValid)
......
......@@ -156,8 +156,9 @@ class FloatBlock
(0 until exuParameters.StuCnt).foreach(i => io.toMemBlock.readFpRf(i).data := fpRf.io.readPorts(i + 12).data)
// write fp rf arbiter
val fpWbArbiter = Module(new Wb(
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn).map(_.wbFpPriority),
NRFpWritePorts
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn),
NRFpWritePorts,
isFp = true
))
fpWbArbiter.io.in <> exeUnits.map(_.io.toFp) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow
......
......@@ -151,6 +151,7 @@ class IntegerBlock
val src2Value = VecInit((0 until 4).map(i => intRf.io.readPorts(i * 2 + 1).data))
rsData.io.srcRegValue(0) := src1Value(readPortIndex(i))
if (cfg.intSrcCnt > 1) rsData.io.srcRegValue(1) := src2Value(readPortIndex(i))
if (cfg == Exu.jumpExeUnitCfg) rsData.io.jumpPc := io.fromCtrlBlock.jumpPc
rsData.io.redirect <> redirect
rsData.io.writeBackedData <> writeBackData
......@@ -221,8 +222,9 @@ class IntegerBlock
(0 until NRMemReadPorts).foreach(i => io.toMemBlock.readIntRf(i).data := intRf.io.readPorts(i + 8).data)
// write int rf arbiter
val intWbArbiter = Module(new Wb(
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn).map(_.wbIntPriority),
NRIntWritePorts
(exeUnits.map(_.config) ++ fastWakeUpIn ++ slowWakeUpIn),
NRIntWritePorts,
isFp = false
))
intWbArbiter.io.in <> exeUnits.map(_.io.toInt) ++ io.wakeUpIn.fast ++ io.wakeUpIn.slow
......
......@@ -5,6 +5,7 @@ import chisel3.util._
import xiangshan._
import utils._
import chisel3.ExcitingUtils._
import xiangshan.backend.decode.ImmUnion
class BrqPtr extends CircularQueuePtr(BrqPtr.BrqSize) with HasCircularQueuePtrHelper {
......@@ -44,6 +45,11 @@ class BrqEnqIO extends XSBundle {
val resp = Vec(RenameWidth, Output(new BrqPtr))
}
class BrqPcRead extends XSBundle {
val brqIdx = Input(new BrqPtr)
val pc = Output(UInt(VAddrBits.W))
}
class BrqIO extends XSBundle{
val redirect = Input(ValidIO(new Redirect))
// receive branch/jump calculated target
......@@ -57,6 +63,8 @@ class BrqIO extends XSBundle{
val cfiInfo = ValidIO(new CfiUpdateInfo)
// commit cnt of branch instr
val bcommit = Input(UInt(BrTagWidth.W))
// read pc for jump unit
val pcReadReq = new BrqPcRead
}
class Brq extends XSModule with HasCircularQueuePtrHelper {
......@@ -69,8 +77,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val s_idle :: s_wb :: Nil = Enum(2)
class DecodeEnqBrqData extends Bundle {
val cfiUpdateInfo = new CfiUpdateInfo
// we use this to calculate branch target
val imm12 = UInt(12.W)
}
// data and state
val decodeData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, DecodeWidth))
val decodeData = Module(new SyncDataModuleTemplate(new DecodeEnqBrqData, BrqSize, 3, DecodeWidth))
val writebackData = Module(new SyncDataModuleTemplate(new ExuOutput, BrqSize, 2, exuParameters.AluCnt + exuParameters.JmpCnt))
val ptrFlagVec = Reg(Vec(BrqSize, Bool()))
val stateQueue = RegInit(VecInit(Seq.fill(BrqSize)(s_idle)))
......@@ -109,9 +123,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
}
val brUpdateReadIdx = Mux(io.redirect.bits.flushItself(), io.redirect.bits.brTag - 1.U, io.redirect.bits.brTag)
val brUpdateReadEntry = Wire(new ExuOutput)
val brUpdateReadEntry = Wire(new CfiUpdateInfo)
io.cfiInfo.valid := RegNext(io.redirect.valid || wbValid)
io.cfiInfo.bits := brUpdateReadEntry.brUpdate
io.cfiInfo.bits := brUpdateReadEntry
io.cfiInfo.bits.target := RegNext(Mux(io.redirect.bits.flushItself(),
io.redirect.bits.target,
wbEntry.brUpdate.target
))
io.cfiInfo.bits.brTarget := io.cfiInfo.bits.target
io.cfiInfo.bits.brTag := RegNext(brUpdateReadIdx)
io.cfiInfo.bits.isReplay := RegNext(io.redirect.bits.flushItself())
io.cfiInfo.bits.isMisPred := RegNext(wbIsMisPred)
......@@ -183,31 +202,48 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
}
}
def mergeDecodeWbData(dec: ExuOutput, wb: ExuOutput) : ExuOutput = {
def mergeWbEntry(dec: DecodeEnqBrqData, wb: ExuOutput) : ExuOutput = {
val mergeData = Wire(new ExuOutput)
mergeData := dec
// only writeback necessary information
mergeData.uop := wb.uop
mergeData.data := wb.data
mergeData.fflags := wb.fflags
mergeData.redirectValid := wb.redirectValid
// calculate target pc
val pc = dec.cfiUpdateInfo.pc
val offset = SignExt(ImmUnion.B.toImm32(dec.imm12), VAddrBits)
val snpc = pc + Mux(dec.cfiUpdateInfo.pd.isRVC, 2.U, 4.U)
val bnpc = pc + offset
val branch_pc = Mux(wb.brUpdate.taken, bnpc, snpc)
val redirectTarget = Mux(dec.cfiUpdateInfo.pd.isBr, branch_pc, wb.redirect.target)
mergeData.redirect := wb.redirect
mergeData.redirect.target := redirectTarget
mergeData.debug := wb.debug
mergeData.brUpdate.target := wb.brUpdate.target
mergeData.brUpdate.brTarget := wb.brUpdate.brTarget
mergeData.brUpdate := dec.cfiUpdateInfo
mergeData.brUpdate.target := redirectTarget
mergeData.brUpdate.brTarget := redirectTarget
mergeData.brUpdate.taken := wb.brUpdate.taken
mergeData
}
def mergeBrUpdateEntry(dec: DecodeEnqBrqData, wb: ExuOutput): CfiUpdateInfo = {
val mergeData = WireInit(dec.cfiUpdateInfo)
mergeData.taken := wb.brUpdate.taken
mergeData
}
decodeData.io.raddr(0) := writebackPtr_next.value
decodeData.io.raddr(1) := brUpdateReadIdx.value
decodeData.io.raddr(2) := io.pcReadReq.brqIdx.value
decodeData.io.wen := VecInit(io.enq.req.map(_.fire()))
decodeData.io.waddr := VecInit(enqBrTag.map(_.value))
decodeData.io.wdata.zip(io.enq.req).map{ case (wdata, req) => {
wdata := DontCare
wdata.brUpdate := req.bits.brUpdate
wdata.brUpdate.pc := req.bits.pc
}}
decodeData.io.wdata.zip(io.enq.req).foreach{ case (wdata, req) =>
wdata.cfiUpdateInfo := req.bits.brUpdate
wdata.cfiUpdateInfo.pc := req.bits.pc
wdata.imm12 := ImmUnion.B.minBitsFromInstr(req.bits.instr)
}
writebackData.io.raddr(0) := writebackPtr_next.value
writebackData.io.raddr(1) := brUpdateReadIdx.value
......@@ -215,9 +251,10 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
writebackData.io.waddr := VecInit(io.exuRedirectWb.map(_.bits.redirect.brTag.value))
writebackData.io.wdata := VecInit(io.exuRedirectWb.map(_.bits))
wbEntry := mergeDecodeWbData(decodeData.io.rdata(0), writebackData.io.rdata(0))
brUpdateReadEntry := mergeDecodeWbData(decodeData.io.rdata(1), writebackData.io.rdata(1))
wbEntry := mergeWbEntry(decodeData.io.rdata(0), writebackData.io.rdata(0))
brUpdateReadEntry := mergeBrUpdateEntry(decodeData.io.rdata(1), writebackData.io.rdata(1))
io.pcReadReq.pc := decodeData.io.rdata(2).cfiUpdateInfo.pc
// Debug info
val debug_roq_redirect = io.redirect.valid && io.redirect.bits.isUnconditional()
......
......@@ -150,9 +150,9 @@ object XDecode extends DecodeConstants {
CSRRS -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.set, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRC -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clr, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRWI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrti, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRSI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRCI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, Y, N, N, Y, Y, N, N, SelImm.IMM_I),
CSRRWI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrti, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
CSRRSI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
CSRRCI -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, Y, N, N, Y, Y, N, N, SelImm.IMM_Z),
SFENCE_VMA->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, Y, Y, Y, N, SelImm.IMM_X),
ECALL -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, Y, N, N, Y, Y, N, N, SelImm.IMM_X),
......@@ -316,26 +316,98 @@ class RVCExpander extends XSModule {
}
}
object Imm32Gen {
def apply(sel: UInt, inst: UInt) = {
val sign = Mux(sel === SelImm.IMM_Z, 0.S, inst(31).asSInt)
val b30_20 = Mux(sel === SelImm.IMM_U, inst(30,20).asSInt, sign)
val b19_12 = Mux(sel =/= SelImm.IMM_U && sel =/= SelImm.IMM_UJ, sign, inst(19,12).asSInt)
val b11 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.S,
Mux(sel === SelImm.IMM_UJ, inst(20).asSInt,
Mux(sel === SelImm.IMM_SB, inst(7).asSInt, sign)))
val b10_5 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.U(1.W), inst(30,25))
val b4_1 = Mux(sel === SelImm.IMM_U, 0.U(1.W),
Mux(sel === SelImm.IMM_S || sel === SelImm.IMM_SB, inst(11,8),
Mux(sel === SelImm.IMM_Z, inst(19,16), inst(24,21))))
val b0 = Mux(sel === SelImm.IMM_S, inst(7),
Mux(sel === SelImm.IMM_I, inst(20),
Mux(sel === SelImm.IMM_Z, inst(15), 0.U(1.W))))
Cat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0)
//object Imm32Gen {
// def apply(sel: UInt, inst: UInt) = {
// val sign = Mux(sel === SelImm.IMM_Z, 0.S, inst(31).asSInt)
// val b30_20 = Mux(sel === SelImm.IMM_U, inst(30,20).asSInt, sign)
// val b19_12 = Mux(sel =/= SelImm.IMM_U && sel =/= SelImm.IMM_UJ, sign, inst(19,12).asSInt)
// val b11 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.S,
// Mux(sel === SelImm.IMM_UJ, inst(20).asSInt,
// Mux(sel === SelImm.IMM_SB, inst(7).asSInt, sign)))
// val b10_5 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.U(1.W), inst(30,25))
// val b4_1 = Mux(sel === SelImm.IMM_U, 0.U(1.W),
// Mux(sel === SelImm.IMM_S || sel === SelImm.IMM_SB, inst(11,8),
// Mux(sel === SelImm.IMM_Z, inst(19,16), inst(24,21))))
// val b0 = Mux(sel === SelImm.IMM_S, inst(7),
// Mux(sel === SelImm.IMM_I, inst(20),
// Mux(sel === SelImm.IMM_Z, inst(15), 0.U(1.W))))
//
// Cat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0)
// }
//}
abstract class Imm(val len: Int) extends Bundle {
def toImm32(minBits: UInt): UInt = do_toImm32(minBits(len - 1, 0))
def do_toImm32(minBits: UInt): UInt
def minBitsFromInstr(instr: UInt): UInt
}
case class Imm_I() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31, 20))
}
case class Imm_S() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31, 25), instr(11, 7))
}
case class Imm_B() extends Imm(12) {
override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
override def minBitsFromInstr(instr: UInt): UInt =
Cat(instr(31), instr(7), instr(30, 25), instr(11, 8))
}
case class Imm_U() extends Imm(20){
override def do_toImm32(minBits: UInt): UInt = Cat(minBits, 0.U(12.W))
override def minBitsFromInstr(instr: UInt): UInt = {
instr(31, 12)
}
}
case class Imm_J() extends Imm(20){
override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
override def minBitsFromInstr(instr: UInt): UInt = {
Cat(instr(31), instr(19, 12), instr(20), instr(30, 25), instr(24, 21))
}
}
case class Imm_Z() extends Imm(12 + 5){
override def do_toImm32(minBits: UInt): UInt = minBits
override def minBitsFromInstr(instr: UInt): UInt = {
Cat(instr(19, 15), instr(31, 20))
}
}
object ImmUnion {
val I = Imm_I()
val S = Imm_S()
val B = Imm_B()
val U = Imm_U()
val J = Imm_J()
val Z = Imm_Z()
val imms = Seq(I, S, B, U, J, Z)
val maxLen = imms.maxBy(_.len).len
val immSelMap = Seq(
SelImm.IMM_I,
SelImm.IMM_S,
SelImm.IMM_SB,
SelImm.IMM_U,
SelImm.IMM_UJ,
SelImm.IMM_Z
).zip(imms)
println(s"ImmUnion max len: $maxLen")
}
/**
* IO bundle for the Decode unit
*/
......@@ -403,19 +475,27 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs.lsrc1 := XSTrapDecode.lsrc1
}
cs.imm := SignExt(Imm32Gen(cs.selImm, ctrl_flow.instr), XLEN)
val instr = io.enq.ctrl_flow.instr
cs.imm := LookupTree(cs.selImm, ImmUnion.immSelMap.map(
x => {
val minBits = x._2.minBitsFromInstr(instr)
require(minBits.getWidth == x._2.len)
x._1 -> minBits
}
))
cf_ctrl.ctrl := cs
// TODO: do we still need this?
// fix ret and call
when (cs.fuType === FuType.jmp) {
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
when (isLink(cs.ldest) && cs.fuOpType === JumpOpType.jal) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
when (cs.fuOpType === JumpOpType.jalr) {
when (isLink(cs.lsrc1)) { cf_ctrl.ctrl.fuOpType := JumpOpType.ret }
when (isLink(cs.ldest)) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
}
}
// when (cs.fuType === FuType.jmp) {
// def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
// when (isLink(cs.ldest) && cs.fuOpType === JumpOpType.jal) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
// when (cs.fuOpType === JumpOpType.jalr) {
// when (isLink(cs.lsrc1)) { cf_ctrl.ctrl.fuOpType := JumpOpType.ret }
// when (isLink(cs.ldest)) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
// }
// }
io.deq.cf_ctrl := cf_ctrl
......
......@@ -6,9 +6,12 @@ import xiangshan._
import utils._
class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule {
val priorities = cfgs.map(c => if(isFp) c.wbFpPriority else c.wbIntPriority)
val io = IO(new Bundle() {
val in = Vec(priorities.size, Flipped(DecoupledIO(new ExuOutput)))
val in = Vec(cfgs.size, Flipped(DecoupledIO(new ExuOutput)))
val out = Vec(numOut, ValidIO(new ExuOutput))
})
......@@ -35,7 +38,7 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
}
def splitN[T](in: Seq[T], n: Int): Seq[Option[Seq[T]]] = {
require(n > 0)
if(n == 0) return Seq()
if(n == 1){
Seq(Some(in))
} else {
......@@ -48,24 +51,38 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
}
}
if(mulReq.nonEmpty){
val arbReq = splitN(
otherReq,
mulReq.size
)
for(i <- mulReq.indices){
val other = arbReq(i).getOrElse(Seq())
val arb = Module(new Arbiter(new ExuOutput, 1+other.size))
arb.io.in <> mulReq(i) +: other
val out = io.out(directConnect.size + i)
out.valid := arb.io.out.valid
out.bits := arb.io.out.bits
arb.io.out.ready := true.B
}
val arbReq = splitN(
otherReq,
mulReq.size
)
val arbiters = for(i <- mulReq.indices) yield {
val other = arbReq(i).getOrElse(Seq())
val arb = Module(new Arbiter(new ExuOutput, 1+other.size))
arb.io.in <> mulReq(i) +: other
val out = io.out(directConnect.size + i)
out.valid := arb.io.out.valid
out.bits := arb.io.out.bits
arb.io.out.ready := true.B
arb
}
if(portUsed < numOut){
println(s"Warning: ${numOut - portUsed} ports are not used!")
io.out.drop(portUsed).foreach(_ <> DontCare)
}
val sb = new StringBuffer(s"\n${if(isFp) "fp" else "int"} wb arbiter:\n")
for((conn, i) <- directConnect.zipWithIndex){
sb.append(s"[ ${cfgs(io.in.indexOf(conn)).name} ] -> out #$i\n")
}
for(i <- mulReq.indices){
sb.append(s"[ ${cfgs(io.in.indexOf(mulReq(i))).name} ")
for(req <- arbReq(i).getOrElse(Nil)){
sb.append(s"${cfgs(io.in.indexOf(req)).name} ")
}
sb.append(s"] -> arb -> out #${directConnect.size + i}\n")
}
println(sb)
}
\ No newline at end of file
......@@ -8,15 +8,16 @@ import xiangshan.backend.ALUOpType
class Alu extends FunctionUnit with HasRedirectOut {
val (src1, src2, offset, func, pc, uop) = (
val (src1, src2, func, pc, uop) = (
io.in.bits.src(0),
io.in.bits.src(1),
io.in.bits.uop.ctrl.imm,
io.in.bits.uop.ctrl.fuOpType,
SignExt(io.in.bits.uop.cf.pc, AddrBits),
io.in.bits.uop
)
val offset = src2
val valid = io.in.valid
val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
......@@ -63,21 +64,30 @@ class Alu extends FunctionUnit with HasRedirectOut {
val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
redirectOutValid := io.out.valid && isBranch
redirectOut.pc := uop.cf.pc
redirectOut.target := Mux(!taken && isBranch, snpc, target)
// Only brTag, level, roqIdx are needed
// other infos are stored in brq
redirectOut := DontCare
redirectOut.brTag := uop.brTag
redirectOut.level := RedirectLevel.flushAfter
redirectOut.interrupt := DontCare
redirectOut.roqIdx := uop.roqIdx
brUpdate := uop.cf.brUpdate
// override brUpdate
brUpdate.pc := uop.cf.pc
brUpdate.target := Mux(!taken && isBranch, snpc, target)
brUpdate.brTarget := target
// redirectOut.pc := DontCare//uop.cf.pc
// redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target)
// redirectOut.interrupt := DontCare//DontCare
// Only taken really needed, do we need brTag ?
brUpdate := DontCare
brUpdate.taken := isBranch && taken
brUpdate.brTag := uop.brTag
// brUpdate := uop.cf.brUpdate
// // override brUpdate
// brUpdate.pc := uop.cf.pc
// brUpdate.target := Mux(!taken && isBranch, snpc, target)
// brUpdate.brTarget := target
// brUpdate.taken := isBranch && taken
// brUpdate.brTag := uop.brTag
io.in.ready := io.out.ready
io.out.valid := valid
io.out.bits.uop <> io.in.bits.uop
......
......@@ -430,13 +430,13 @@ class CSR extends FunctionUnit with HasCSRConst
(if (HasFPU) fcsrMapping else Nil)
val addr = src2(11, 0)
val csri = src2(16, 12)
val rdata = Wire(UInt(XLEN.W))
val csri = ZeroExt(cfIn.instr(19,15), XLEN) //unsigned imm for csri. [TODO]
val wdata = LookupTree(func, List(
CSROpType.wrt -> src1,
CSROpType.set -> (rdata | src1),
CSROpType.clr -> (rdata & (~src1).asUInt()),
CSROpType.wrti -> csri, //TODO: csri --> src2
CSROpType.wrti -> csri,
CSROpType.seti -> (rdata | csri),
CSROpType.clri -> (rdata & (~csri).asUInt())
))
......
......@@ -29,7 +29,7 @@ case class FuConfig
writeIntRf: Boolean,
writeFpRf: Boolean,
hasRedirect: Boolean,
latency: HasFuLatency = CertainLatency(0)
latency: HasFuLatency = CertainLatency(0),
) {
def srcCnt: Int = math.max(numIntSrc, numFpSrc)
}
......@@ -159,7 +159,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = true
hasRedirect = true,
)
val jmpCfg = FuConfig(
......@@ -170,7 +170,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = true
hasRedirect = true,
)
val fenceCfg = FuConfig(
......
......@@ -5,6 +5,7 @@ import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend._
import xiangshan.backend.decode.ImmUnion
import xiangshan.backend.fu.FunctionUnit._
import xiangshan.backend.decode.isa._
......@@ -16,7 +17,7 @@ trait HasRedirectOut { this: RawModule =>
class Jump extends FunctionUnit with HasRedirectOut {
val (src1, offset, func, pc, uop) = (
val (src1, immMin, func, pc, uop) = (
io.in.bits.src(0),
io.in.bits.uop.ctrl.imm,
io.in.bits.uop.ctrl.fuOpType,
......@@ -24,6 +25,11 @@ class Jump extends FunctionUnit with HasRedirectOut {
io.in.bits.uop
)
val offset = SignExt(Mux(JumpOpType.jumpOpIsJal(func),
ImmUnion.J.toImm32(immMin),
ImmUnion.I.toImm32(immMin)
), XLEN)
val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
val valid = io.in.valid
......@@ -32,15 +38,16 @@ class Jump extends FunctionUnit with HasRedirectOut {
val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
redirectOutValid := valid
redirectOut.pc := uop.cf.pc
redirectOut := DontCare
// redirectOut.pc := uop.cf.pc
redirectOut.target := target
redirectOut.brTag := uop.brTag
redirectOut.level := RedirectLevel.flushAfter
redirectOut.interrupt := DontCare
// redirectOut.interrupt := DontCare
redirectOut.roqIdx := uop.roqIdx
brUpdate := uop.cf.brUpdate
brUpdate.pc := uop.cf.pc
brUpdate := DontCare //uop.cf.brUpdate
// brUpdate.pc := uop.cf.pc
brUpdate.target := target
brUpdate.brTarget := target
brUpdate.taken := true.B
......
......@@ -4,8 +4,10 @@ import chisel3._
import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend.decode.ImmUnion
import xiangshan.backend.exu.{Exu, ExuConfig}
import xiangshan.backend.regfile.RfReadPort
import scala.math.max
class BypassQueue(number: Int) extends XSModule {
......@@ -336,6 +338,7 @@ class ReservationStationData
// read src op value
val srcRegValue = Vec(srcNum, Input(UInt((XLEN + 1).W)))
val jumpPc = if(exuCfg == Exu.jumpExeUnitCfg) Input(UInt(VAddrBits.W)) else null
// broadcast selected uop to other issue queues
val selectedUop = ValidIO(new MicroOp)
......@@ -404,6 +407,7 @@ class ReservationStationData
val deq = RegEnable(sel.bits, sel.valid)
val enqCtrl = io.ctrl.enqCtrl
val enqUop = enqCtrl.bits
val enqUopReg = RegEnable(enqUop, enqCtrl.fire())
// enq
val enqPtr = enq(log2Up(IssQueSize)-1,0)
......@@ -418,7 +422,33 @@ class ReservationStationData
}
when (enqEnReg) {
(0 until srcNum).foreach(i => dataWrite(enqPtrReg, i, io.srcRegValue(i)))
exuCfg match {
case Exu.jumpExeUnitCfg =>
val src1Mux = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(io.jumpPc, XLEN),
io.srcRegValue(0)
)
dataWrite(enqPtrReg, 0, src1Mux)
case Exu.aluExeUnitCfg =>
val src1Mux = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(enqUopReg.cf.pc, XLEN),
io.srcRegValue(0)
)
dataWrite(enqPtrReg, 0, src1Mux)
// TODO: opt this, a full map is not necesscary here
val imm32 = LookupTree(
enqUopReg.ctrl.selImm,
ImmUnion.immSelMap.map(x => x._1 -> x._2.toImm32(enqUopReg.ctrl.imm))
)
val imm64 = SignExt(imm32, XLEN)
val src2Mux = Mux(enqUopReg.ctrl.src2Type === SrcType.imm,
imm64, io.srcRegValue(1)
)
dataWrite(enqPtrReg, 1, src2Mux)
case _ =>
(0 until srcNum).foreach(i => dataWrite(enqPtrReg, i, io.srcRegValue(i)))
}
XSDebug(p"${exuCfg.name}: enqPtrReg:${enqPtrReg} pc: ${Hexadecimal(uop(enqPtrReg).cf.pc)}\n")
XSDebug(p"[srcRegValue] " + List.tabulate(srcNum)(idx => p"src$idx: ${Hexadecimal(io.srcRegValue(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n")
}
......@@ -472,8 +502,8 @@ class ReservationStationData
exuInput.uop := uop(deq)
val regValues = List.tabulate(srcNum)(i => dataRead(Mux(sel.valid, sel.bits, deq), i))
XSDebug(io.deq.fire(), p"[regValues] " + List.tabulate(srcNum)(idx => p"reg$idx: ${Hexadecimal(regValues(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n")
exuInput.src1 := Mux(uop(deq).ctrl.src1Type === SrcType.pc, SignExt(uop(deq).cf.pc, XLEN + 1), regValues(0))
if (srcNum > 1) exuInput.src2 := Mux(uop(deq).ctrl.src2Type === SrcType.imm, uop(deq).ctrl.imm, regValues(1))
exuInput.src1 := regValues(0)
if (srcNum > 1) exuInput.src2 := regValues(1)
if (srcNum > 2) exuInput.src3 := regValues(2)
io.deq.valid := RegNext(sel.valid)
......@@ -496,7 +526,7 @@ class ReservationStationData
io.ctrl.feedback := DontCare
if (feedback) {
(0 until IssQueSize).map(i =>
(0 until IssQueSize).foreach(i =>
io.ctrl.feedback(i) := uop(i).roqIdx.asUInt === io.feedback.bits.roqIdx.asUInt && io.feedback.valid)
io.ctrl.feedback(IssQueSize) := io.feedback.bits.hit
}
......
......@@ -19,8 +19,10 @@ package object backend {
object JumpOpType {
def jal = "b11_000".U
def jalr = "b11_010".U
def call = "b11_011".U
def ret = "b11_100".U
// def call = "b11_011".U
// def ret = "b11_100".U
def jumpOpIsJal(op: UInt) = !op(1)
def jumpOpisJalr(op: UInt) = op(1)
}
object FenceOpType {
......
......@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._
import utils._
import xiangshan._
import xiangshan.backend.decode.ImmUnion
import xiangshan.cache._
// import xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants, TlbReq, DCacheLoadReq, DCacheWordResp}
import xiangshan.backend.LSUOpType
......@@ -25,7 +26,7 @@ class LoadUnit_S0 extends XSModule {
})
val s0_uop = io.in.bits.uop
val s0_vaddr = io.in.bits.src1 + s0_uop.ctrl.imm
val s0_vaddr = io.in.bits.src1 + SignExt(ImmUnion.I.toImm32(s0_uop.ctrl.imm), XLEN)
val s0_mask = genWmask(s0_vaddr, s0_uop.ctrl.fuOpType(1,0))
// query DTLB
......
......@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._
import utils._
import xiangshan._
import xiangshan.backend.decode.ImmUnion
import xiangshan.cache._
// Store Pipeline Stage 0
......@@ -16,7 +17,7 @@ class StoreUnit_S0 extends XSModule {
})
// send req to dtlb
val saddr = io.in.bits.src1 + io.in.bits.uop.ctrl.imm
val saddr = io.in.bits.src1 + SignExt(ImmUnion.S.toImm32(io.in.bits.uop.ctrl.imm), XLEN)
io.dtlbReq.bits.vaddr := saddr
io.dtlbReq.valid := io.in.valid
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册