提交 b0ae3ac4 编写于 作者: L LinJiawei

Opt imm: save imm in 20-bit space

上级 c43ef4ed
......@@ -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
......
......@@ -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
......
......@@ -49,8 +49,6 @@ case class ExuConfig
val writeIntRf = fuConfigs.map(_.writeIntRf).reduce(_ || _)
val writeFpRf = fuConfigs.map(_.writeFpRf).reduce(_ || _)
val hasRedirect = fuConfigs.map(_.hasRedirect).reduce(_ || _)
val usePc = fuConfigs.map(_.usePc).reduce(_||_)
val useImm = fuConfigs.map(_.useImm).reduce(_||_)
val latency: HasFuLatency = {
val lats = fuConfigs.map(_.latency)
......
......@@ -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)
......
......@@ -518,13 +518,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())
))
......
......@@ -30,8 +30,6 @@ case class FuConfig
writeFpRf: Boolean,
hasRedirect: Boolean,
latency: HasFuLatency = CertainLatency(0),
usePc: Boolean = false,
useImm: Boolean = false
) {
def srcCnt: Int = math.max(numIntSrc, numFpSrc)
}
......@@ -162,8 +160,6 @@ object FunctionUnit extends HasXSParameter {
writeIntRf = true,
writeFpRf = false,
hasRedirect = true,
usePc = true,
useImm = true
)
val jmpCfg = FuConfig(
......@@ -175,8 +171,6 @@ object FunctionUnit extends HasXSParameter {
writeIntRf = true,
writeFpRf = false,
hasRedirect = true,
usePc = true,
useImm = 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
......
......@@ -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 {
......@@ -420,26 +422,29 @@ class ReservationStationData
}
when (enqEnReg) {
(0 until srcNum).foreach(i => {
val writeData = if(i == 0){
if(exuCfg.usePc)
Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(enqUopReg.cf.pc, XLEN),
io.srcRegValue(i)
exuCfg match {
case Exu.jumpExeUnitCfg =>
val src1Data = Mux(enqUopReg.ctrl.src1Type === SrcType.pc,
SignExt(enqUopReg.cf.pc, XLEN),
io.srcRegValue(0)
)
else io.srcRegValue(i)
} else if(i == 1){
if(exuCfg.useImm)
Mux(enqUopReg.ctrl.src2Type === SrcType.imm,
enqUopReg.ctrl.imm,
io.srcRegValue(i)
)
else io.srcRegValue(i)
} else {
io.srcRegValue(i)
}
dataWrite(enqPtrReg, i, writeData)
})
dataWrite(enqPtrReg, 0, src1Data)
case Exu.aluExeUnitCfg =>
dataWrite(enqPtrReg, 0, io.srcRegValue(0))
// 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")
}
......
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册