提交 52c3f215 编写于 作者: L LinJiawei

[WIP] exu: spilt exuConfig and it's module

上级 ccce3504
......@@ -13,7 +13,7 @@ import xiangshan.backend.regfile.{Regfile, RfWritePort}
import xiangshan.backend.roq.Roq
import xiangshan.mem._
import utils.ParallelOR
import xiangshan.backend.fu.FunctionUnit.{lduCfg, mouCfg, stuCfg}
import xiangshan.backend.exu.Exu.{ldExeUnitCfg, stExeUnitCfg}
/** Backend Pipeline:
* Decode -> Rename -> Dispatch-1 -> Dispatch-2 -> Issue -> Exe
......@@ -45,8 +45,6 @@ class Backend extends XSModule
// wb int exu + wb fp exu + ldu / stu + brq
val wbSize = wbIntExus.length + wbFpExus.length + exuParameters.LduCnt + exuParameters.StuCnt + 1
val ldExeUnitCfg = ExuConfig("LoadExu", Seq(lduCfg), wbIntPriority = 0, wbFpPriority = 0)
val stExeUnitCfg = ExuConfig("StoreExu", Seq(stuCfg, mouCfg), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue)
val ldIntOut = io.mem.ldout.map(x => {
val raw = WireInit(x)
......
......@@ -38,7 +38,8 @@ class IntegerBlock extends XSModule {
val regfile = Module(new Regfile(
numReadPorts = NRIntReadPorts,
numWirtePorts = NRIntWritePorts,
hasZero = true
hasZero = true,
XLEN
))
val jmpExeUnit = Module(new JumpExeUnit)
......
......@@ -2,20 +2,10 @@ package xiangshan.backend.exu
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.FuType._
import utils._
import xiangshan.backend._
import xiangshan.backend.fu.{Alu, FunctionUnit}
import xiangshan.backend.fu.FunctionUnit._
import xiangshan.backend.exu.Exu.aluExeUnitCfg
import xiangshan.backend.fu.Alu
class AluExeUnit extends Exu(
exuName = "AluExeUnit",
fuGen = Seq((FunctionUnit.alu _, (_: FunctionUnit) => true.B)),
wbIntPriority = 0,
wbFpPriority = Int.MaxValue
)
class AluExeUnit extends Exu(aluExeUnitCfg)
{
val alu = supportedFunctionUnits.collectFirst{
case a: Alu => a
......
......@@ -3,10 +3,8 @@ package xiangshan.backend.exu
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.FuType._
import xiangshan.backend.fu.{CertainLatency, FuConfig, FuOutput, FunctionUnit, HasFuLatency, UncertainLatency}
import utils.ParallelOR
import xiangshan.backend.fu.FunctionUnit._
import xiangshan.backend.fu.{FuConfig, FuOutput, FunctionUnit, HasFuLatency, UncertainLatency}
case class ExuParameters
(
......@@ -38,22 +36,22 @@ case class ExuParameters
case class ExuConfig
(
name: String,
supportedFuncUnits: Seq[FuConfig],
fuConfigs: Seq[FuConfig],
wbIntPriority: Int,
wbFpPriority: Int
) {
def max(in: Seq[Int]): Int = in.reduce((x, y) => if (x > y) x else y)
val intSrcCnt = max(supportedFuncUnits.map(_.numIntSrc))
val fpSrcCnt = max(supportedFuncUnits.map(_.numFpSrc))
val intSrcCnt = max(fuConfigs.map(_.numIntSrc))
val fpSrcCnt = max(fuConfigs.map(_.numFpSrc))
val readIntRf = intSrcCnt > 0
val readFpRf = fpSrcCnt > 0
val writeIntRf = supportedFuncUnits.map(_.writeIntRf).reduce(_ || _)
val writeFpRf = supportedFuncUnits.map(_.writeFpRf).reduce(_ || _)
val hasRedirect = supportedFuncUnits.map(_.hasRedirect).reduce(_ || _)
val writeIntRf = fuConfigs.map(_.writeIntRf).reduce(_ || _)
val writeFpRf = fuConfigs.map(_.writeFpRf).reduce(_ || _)
val hasRedirect = fuConfigs.map(_.hasRedirect).reduce(_ || _)
val latency: HasFuLatency = {
val lats = supportedFuncUnits.map(_.latency)
val lats = fuConfigs.map(_.latency)
if (lats.exists(x => x.latencyVal.isEmpty)) {
UncertainLatency()
} else {
......@@ -68,35 +66,18 @@ case class ExuConfig
val hasUncertainlatency = latency.latencyVal.isEmpty
def canAccept(fuType: UInt): Bool = {
Cat(supportedFuncUnits.map(_.fuType === fuType)).orR()
Cat(fuConfigs.map(_.fuType === fuType)).orR()
}
}
abstract class Exu[T <: FunctionUnit]
(
val exuName: String,
val fuGen: Seq[(() => T, T => Bool)],
val wbIntPriority: Int,
val wbFpPriority: Int
) extends XSModule {
val supportedFunctionUnits = fuGen.map(_._1).map(gen => Module(gen()))
val fuSel = supportedFunctionUnits.zip(fuGen.map(_._2)).map(x => x._2(x._1))
abstract class Exu[T <: FunctionUnit](val config: ExuConfig) extends XSModule {
def fuConfigs = supportedFunctionUnits.map(_.cfg)
val supportedFunctionUnits = config.fuConfigs.map(_.fuGen).map(gen => Module(gen()))
def config: ExuConfig = {
ExuConfig(exuName, fuConfigs, wbIntPriority, wbFpPriority)
val fuSel = supportedFunctionUnits.zip(config.fuConfigs.map(_.fuSel)).map{
case (fu, sel) => sel(fu)
}
require(fuGen.nonEmpty)
require(!fuConfigs.exists(c => {
(c.numIntSrc > 0) && (c.numFpSrc > 0)
}))
// val io = IO(new ExuIO)
val io = IO(new Bundle() {
val fromInt = if (config.readIntRf) Flipped(DecoupledIO(new ExuInput)) else null
val fromFp = if (config.readFpRf) Flipped(DecoupledIO(new ExuInput)) else null
......@@ -105,13 +86,13 @@ abstract class Exu[T <: FunctionUnit]
val toFp = if (config.writeFpRf) DecoupledIO(new ExuOutput) else null
})
for ((fu, sel) <- supportedFunctionUnits.zip(fuSel)) {
for ((fuCfg, (fu, sel)) <- config.fuConfigs.zip(supportedFunctionUnits.zip(fuSel))) {
val in = if (fu.cfg.numIntSrc > 0) {
assert(fu.cfg.numFpSrc == 0)
val in = if (fuCfg.numIntSrc > 0) {
assert(fuCfg.numFpSrc == 0)
io.fromInt
} else {
assert(fu.cfg.numFpSrc > 0)
assert(fuCfg.numFpSrc > 0)
io.fromFp
}
......@@ -121,13 +102,14 @@ abstract class Exu[T <: FunctionUnit]
fu.io.in.valid := in.valid && sel
fu.io.in.bits.uop := in.bits.uop
if (fu.cfg.srcCnt > 0) {
fu.io.in.bits.src.foreach(_ <> DontCare)
if (fuCfg.srcCnt > 0) {
fu.io.in.bits.src(0) := src1
}
if (fu.cfg.srcCnt > 1) {
if (fuCfg.srcCnt > 1) {
fu.io.in.bits.src(1) := src2
}
if (fu.cfg.srcCnt > 2) {
if (fuCfg.srcCnt > 2) {
fu.io.in.bits.src(2) := src3
}
fu.io.redirectIn := io.redirect
......@@ -156,19 +138,26 @@ abstract class Exu[T <: FunctionUnit]
}
val intArb = if (config.writeIntRf) writebackArb(
supportedFunctionUnits.filter(_.cfg.writeIntRf).map(_.io.out),
supportedFunctionUnits.zip(config.fuConfigs).filter(x => x._2.writeIntRf).map(_._1.io.out),
io.toInt
) else null
val fpArb = if (config.writeFpRf) writebackArb(
supportedFunctionUnits.filter(_.cfg.writeFpRf).map(_.io.out),
supportedFunctionUnits.zip(config.fuConfigs).filter(x => x._2.writeFpRf).map(_._1.io.out),
io.toFp
) else null
val readIntFu = supportedFunctionUnits.zip(fuSel).filter(p => p._1.cfg.numIntSrc > 0)
val readFpFu = supportedFunctionUnits.zip(fuSel).filter(p => p._1.cfg.numFpSrc > 0)
val readIntFu = config.fuConfigs
.zip(supportedFunctionUnits.zip(fuSel))
.filter(_._1.numIntSrc > 0)
.map(_._2)
def inReady(s: Seq[(T, Bool)]): Bool = {
val readFpFu = config.fuConfigs
.zip(supportedFunctionUnits.zip(fuSel))
.filter(_._1.numFpSrc > 0)
.map(_._2)
def inReady(s: Seq[(FunctionUnit, Bool)]): Bool = {
if (s.size == 1) {
s.head._1.io.in.ready
} else {
......@@ -182,15 +171,11 @@ abstract class Exu[T <: FunctionUnit]
if (config.readIntRf) {
io.fromInt.ready := inReady(
supportedFunctionUnits.zip(fuSel).filter(p => p._1.cfg.numIntSrc > 0)
)
io.fromInt.ready := inReady(readIntFu)
}
if (config.readFpRf) {
io.fromFp.ready := inReady(
supportedFunctionUnits.zip(fuSel).filter(p => p._1.cfg.numFpSrc > 0)
)
io.fromFp.ready := inReady(readFpFu)
}
def assignDontCares(out: ExuOutput) = {
......@@ -209,3 +194,20 @@ abstract class Exu[T <: FunctionUnit]
assignDontCares(io.toInt.bits)
}
}
object Exu {
val aluExeUnitCfg = ExuConfig("AluExeUnit", Seq(aluCfg), 0, Int.MaxValue)
val jumpExeUnitCfg = ExuConfig("JmpExeUnit", Seq(jmpCfg, csrCfg, fenceCfg, i2fCfg), 2, Int.MaxValue)
val mulDivExeUnitCfg = ExuConfig("MulDivExeUnit", Seq(mulCfg, divCfg), 1, Int.MaxValue)
val fmacExeUnitCfg = ExuConfig("FmacExeUnit", Seq(fmacCfg), Int.MaxValue, 0)
val fmiscExeUnitCfg = ExuConfig(
"FmiscExeUnit",
Seq(fcmpCfg, fmvCfg, f2iCfg, s2dCfg, d2sCfg, fdivSqrtCfg),
Int.MaxValue, 1
)
val ldExeUnitCfg = ExuConfig("LoadExu", Seq(lduCfg), wbIntPriority = 0, wbFpPriority = 0)
val stExeUnitCfg = ExuConfig("StoreExu", Seq(stuCfg, mouCfg), wbIntPriority = Int.MaxValue, wbFpPriority = Int.MaxValue)
}
\ No newline at end of file
......@@ -2,17 +2,10 @@ package xiangshan.backend.exu
import chisel3._
import chisel3.util._
import xiangshan.backend.fu.FunctionUnit
import xiangshan.backend.exu.Exu.fmacExeUnitCfg
import xiangshan.backend.fu.fpu._
class FmacExeUnit extends Exu(
exuName = "FmacExeUnit",
fuGen = Seq(
(FunctionUnit.fmac _, (_:FunctionUnit) => true.B)
),
wbIntPriority = Int.MaxValue,
wbFpPriority = 0
)
class FmacExeUnit extends Exu(fmacExeUnitCfg)
{
val frm = IO(Input(UInt(3.W)))
......
......@@ -3,26 +3,13 @@ package xiangshan.backend.exu
import chisel3._
import chisel3.util._
import utils._
import xiangshan.backend.exu.Exu.fmiscExeUnitCfg
import xiangshan.backend.fu.FunctionUnit
import xiangshan.backend.fu.FunctionUnit.fmiscSel
import xiangshan.backend.fu.fpu.FPUOpType._
import xiangshan.backend.fu.fpu._
class FmiscExeUnit extends Exu(
exuName = "FmiscExeUnit",
fuGen = {
Seq[(() => FPUSubModule, FPUSubModule => Bool)](
(FunctionUnit.fcmp _, fmiscSel(FU_FCMP)),
(FunctionUnit.fmv _, fmiscSel(FU_FMV)),
(FunctionUnit.f2i _, fmiscSel(FU_F2I)),
(FunctionUnit.f32toF64 _, fmiscSel(FU_S2D)),
(FunctionUnit.f64toF32 _, fmiscSel(FU_D2S)),
(FunctionUnit.fdivSqrt _, fmiscSel(FU_DIVSQRT))
)
},
wbIntPriority = Int.MaxValue,
wbFpPriority = 1
) {
class FmiscExeUnit extends Exu(fmiscExeUnitCfg) {
val frm = IO(Input(UInt(3.W)))
......@@ -45,14 +32,12 @@ class FmiscExeUnit extends Exu(
unboxF64ToF32(src1),
src1
)
if (module.cfg.srcCnt > 1) {
module.io.in.bits.src(1) := Mux(isRVF, unboxF64ToF32(src2), src2)
}
module.rm := Mux(instr_rm =/= 7.U, instr_rm, frm)
module.io.in.bits.src(1) := Mux(isRVF, unboxF64ToF32(src2), src2)
module.asInstanceOf[FPUSubModule].rm := Mux(instr_rm =/= 7.U, instr_rm, frm)
}
io.toFp.bits.fflags := Mux1H(fpArb.io.in.zip(toFpUnits).map(
x => x._1.fire() -> x._2.fflags
x => x._1.fire() -> x._2.asInstanceOf[FPUSubModule].fflags
))
val fpOutCtrl = io.toFp.bits.uop.ctrl
io.toFp.bits.data := Mux(fpOutCtrl.isRVF,
......@@ -68,6 +53,6 @@ class FmiscExeUnit extends Exu(
intArb.io.out.bits.data
)
io.toInt.bits.fflags := Mux1H(intArb.io.in.zip(toIntUnits).map(
x => x._1.fire() -> x._2.fflags
x => x._1.fire() -> x._2.asInstanceOf[FPUSubModule].fflags
))
}
......@@ -3,22 +3,13 @@ package xiangshan.backend.exu
import chisel3._
import chisel3.util._
import xiangshan.backend.exu.Exu.jumpExeUnitCfg
import xiangshan.backend.fu.fpu.FPUOpType.FU_I2F
import xiangshan.backend.fu.{CSR, Fence, FenceToSbuffer, FunctionUnit, Jump}
import xiangshan.{CSRSpecialIO, FuType, SfenceBundle, TlbCsrBundle}
import xiangshan.backend.fu.fpu.{Fflags, IntToFloatSingleCycle, boxF32ToF64}
class JumpExeUnit extends Exu(
exuName = "JmpExeUnit",
fuGen = Seq(
(FunctionUnit.jmp _, (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp),
(FunctionUnit.csr _, (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr),
(FunctionUnit.fence _, (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence),
(FunctionUnit.i2f _, (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.i2f)
),
wbIntPriority = 2,
wbFpPriority = Int.MaxValue
)
class JumpExeUnit extends Exu(jumpExeUnitCfg)
{
val fflags = IO(Input(new Fflags))
val dirty_fs = IO(Input(Bool()))
......
......@@ -5,32 +5,15 @@ import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend.MDUOpType
import xiangshan.backend.exu.Exu.mulDivExeUnitCfg
import xiangshan.backend.fu.{AbstractDivider, ArrayMultiplier, FunctionUnit, Radix2Divider}
class MulDivExeUnit(hasDiv: Boolean = true) extends Exu(
exuName = if(hasDiv) "MulDivExeUnit" else "MulExeUnit",
fuGen = {
Seq(
(
FunctionUnit.multiplier _,
(x: FunctionUnit) =>
if(hasDiv) MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType) else true.B
)
) ++ {
if(hasDiv) Seq(
(FunctionUnit.divider _, (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType))
) else Nil
}
},
wbIntPriority = 1,
wbFpPriority = Int.MaxValue
)
{
class MulDivExeUnit extends Exu(mulDivExeUnitCfg) {
val func = io.fromInt.bits.uop.ctrl.fuOpType
val (src1, src2) = (
io.fromInt.bits.src1(XLEN-1, 0),
io.fromInt.bits.src2(XLEN-1, 0)
io.fromInt.bits.src1(XLEN - 1, 0),
io.fromInt.bits.src2(XLEN - 1, 0)
)
val mul = supportedFunctionUnits.collectFirst {
......@@ -42,23 +25,23 @@ class MulDivExeUnit(hasDiv: Boolean = true) extends Exu(
}.orNull
// override inputs
val op = MDUOpType.getMulOp(func)
val signext = SignExt(_: UInt, XLEN+1)
val zeroext = ZeroExt(_: UInt, XLEN+1)
val op = MDUOpType.getMulOp(func)
val signext = SignExt(_: UInt, XLEN + 1)
val zeroext = ZeroExt(_: UInt, XLEN + 1)
val mulInputFuncTable = List(
MDUOpType.mul -> (zeroext, zeroext),
MDUOpType.mulh -> (signext, signext),
MDUOpType.mul -> (zeroext, zeroext),
MDUOpType.mulh -> (signext, signext),
MDUOpType.mulhsu -> (signext, zeroext),
MDUOpType.mulhu -> (zeroext, zeroext)
MDUOpType.mulhu -> (zeroext, zeroext)
)
mul.io.in.bits.src(0) := LookupTree(
op,
mulInputFuncTable.map(p => (p._1(1,0), p._2._1(src1)))
mulInputFuncTable.map(p => (p._1(1, 0), p._2._1(src1)))
)
mul.io.in.bits.src(1) := LookupTree(
op,
mulInputFuncTable.map(p => (p._1(1,0), p._2._2(src2)))
mulInputFuncTable.map(p => (p._1(1, 0), p._2._2(src2)))
)
val isW = MDUOpType.isW(func)
......@@ -71,18 +54,16 @@ class MulDivExeUnit(hasDiv: Boolean = true) extends Exu(
val divInputFunc = (x: UInt) => Mux(
isW,
Mux(isDivSign,
SignExt(x(31,0), XLEN),
ZeroExt(x(31,0), XLEN)
SignExt(x(31, 0), XLEN),
ZeroExt(x(31, 0), XLEN)
),
x
)
if(hasDiv){
div.io.in.bits.src(0) := divInputFunc(src1)
div.io.in.bits.src(1) := divInputFunc(src2)
div.ctrl.isHi := isH
div.ctrl.isW := isW
div.ctrl.sign := isDivSign
}
div.io.in.bits.src(0) := divInputFunc(src1)
div.io.in.bits.src(1) := divInputFunc(src2)
div.ctrl.isHi := isH
div.ctrl.isW := isW
div.ctrl.sign := isDivSign
XSDebug(io.fromInt.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
io.fromInt.valid, io.fromInt.ready,
......@@ -98,4 +79,3 @@ class MulDivExeUnit(hasDiv: Boolean = true) extends Exu(
)
}
class MulExeUnit extends MulDivExeUnit(hasDiv = false)
......@@ -6,14 +6,7 @@ import utils.{LookupTree, LookupTreeDefault, SignExt, XSDebug, ZeroExt}
import xiangshan._
import xiangshan.backend.ALUOpType
class Alu extends FunctionUnit(FuConfig(
fuType = FuType.alu,
numIntSrc = 2,
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = true
)) with HasRedirectOut {
class Alu extends FunctionUnit with HasRedirectOut {
val (src1, src2, offset, func, pc, uop) = (
io.in.bits.src(0),
......
......@@ -168,14 +168,7 @@ class PerfCounterIO extends XSBundle {
val value = Input(UInt(XLEN.W))
}
class CSR extends FunctionUnit(FuConfig(
fuType = FuType.csr,
numIntSrc = 1,
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = false
)) with HasCSRConst
class CSR extends FunctionUnit with HasCSRConst
{
val redirectOut = IO(Output(new Redirect))
......
......@@ -11,9 +11,7 @@ class FenceToSbuffer extends XSBundle {
val sbIsEmpty = Input(Bool())
}
class Fence extends FunctionUnit(FuConfig(
FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false
)){
class Fence extends FunctionUnit{
val sfence = IO(Output(new SfenceBundle))
val fencei = IO(Output(Bool()))
......
......@@ -3,6 +3,8 @@ package xiangshan.backend.fu
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.backend.MDUOpType
import xiangshan.backend.fu.fpu.FPUOpType.{FU_D2S, FU_DIVSQRT, FU_F2I, FU_FCMP, FU_FMV, FU_S2D}
import xiangshan.backend.fu.fpu.divsqrt.DivSqrt
import xiangshan.backend.fu.fpu._
import xiangshan.backend.fu.fpu.fma.FMA
......@@ -16,7 +18,7 @@ trait HasFuLatency {
val latencyVal: Option[Int]
}
case class CertainLatency(value: Int) extends HasFuLatency{
case class CertainLatency(value: Int) extends HasFuLatency {
override val latencyVal: Option[Int] = Some(value)
}
......@@ -25,9 +27,10 @@ case class UncertainLatency() extends HasFuLatency {
}
case class FuConfig
(
fuGen: () => FunctionUnit,
fuSel: FunctionUnit => Bool,
fuType: UInt,
numIntSrc: Int,
numFpSrc: Int,
......@@ -40,28 +43,16 @@ case class FuConfig
}
class FuOutput extends XSBundle {
val data = UInt(XLEN.W)
val uop = new MicroOp
}
class FunctionUnitIO[TI <: Data, TO <: Data]
(
cfg: FuConfig,
len: Int
) extends XSBundle
{
class FunctionUnitIO(len: Int) extends XSBundle {
val in = Flipped(DecoupledIO(new Bundle() {
val src = Vec(cfg.srcCnt, UInt(len.W))
val src = Vec(3, UInt(len.W))
val uop = new MicroOp
def connectToExuInput(exuIn: ExuInput): Unit = {
val exuSrcIn = Seq(exuIn.src1, exuIn.src2, exuIn.src3)
src.zip(exuSrcIn).foreach{case (x, y) => x := y}
uop := exuIn.uop
}
}))
val out = DecoupledIO(new FuOutput)
......@@ -69,23 +60,21 @@ class FunctionUnitIO[TI <: Data, TO <: Data]
val redirectIn = Flipped(ValidIO(new Redirect))
override def cloneType: FunctionUnitIO.this.type =
new FunctionUnitIO(cfg, len).asInstanceOf[this.type]
new FunctionUnitIO(len).asInstanceOf[this.type]
}
abstract class FunctionUnit
(
val cfg: FuConfig,
val len: Int = 64
) extends XSModule {
abstract class FunctionUnit(len: Int = 64) extends XSModule {
val io = IO(new FunctionUnitIO(cfg, len))
val io = IO(new FunctionUnitIO(len))
}
trait HasPipelineReg { this: FunctionUnit =>
trait HasPipelineReg {
this: FunctionUnit =>
require(cfg.latency.latencyVal.nonEmpty && cfg.latency.latencyVal.get > 0)
val latency = cfg.latency.latencyVal.get
val latency: Int
require(latency > 0)
val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
......@@ -130,39 +119,172 @@ trait HasPipelineReg { this: FunctionUnit =>
object FunctionUnit extends HasXSParameter {
def divider = new SRT4Divider(XLEN)
def multiplier = new ArrayMultiplier(XLEN+1, Seq(0, 2))
def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2))
def alu = new Alu
def jmp = new Jump
def fence = new Fence
def csr = new CSR
def i2f = new IntToFloatSingleCycle
def fmac = new FMA
def fcmp = new FCMP
def fmv = new FMV(XLEN)
def f2i = new FloatToInt
def f32toF64 = new F32toF64
def f64toF32 = new F64toF32
def fdivSqrt = new DivSqrt
def fmiscSel(fu: String)(x: FPUSubModule): Bool = {
def fmiscSel(fu: String)(x: FunctionUnit): Bool = {
x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U
}
val lduCfg =
FuConfig(FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
UncertainLatency()
)
val aluCfg = FuConfig(
fuGen = alu _,
fuSel = _ => true.B,
fuType = FuType.alu,
numIntSrc = 2,
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = true
)
val jmpCfg = FuConfig(
fuGen = jmp _,
fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp,
fuType = FuType.jmp,
numIntSrc = 1,
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = true
)
val fenceCfg = FuConfig(
fuGen = fence _,
fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence,
FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false
)
val csrCfg = FuConfig(
fuGen = csr _,
fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr,
fuType = FuType.csr,
numIntSrc = 1,
numFpSrc = 0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = false
)
val stuCfg =
FuConfig(FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
UncertainLatency()
)
val i2fCfg = FuConfig(
fuGen = i2f _,
fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.i2f,
FuType.i2f,
numIntSrc = 1,
numFpSrc = 0,
writeIntRf = false,
writeFpRf = true,
hasRedirect = false,
CertainLatency(0)
)
val divCfg = FuConfig(
fuGen = divider _,
fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType),
FuType.div,
2,
0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = false,
UncertainLatency()
)
val mulCfg = FuConfig(
fuGen = multiplier _,
fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType),
FuType.mul,
2,
0,
writeIntRf = true,
writeFpRf = false,
hasRedirect = false,
CertainLatency(3)
)
val fmacCfg = FuConfig(
fuGen = fmac _,
fuSel = _ => true.B,
FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5)
)
val fcmpCfg = FuConfig(
fuGen = fcmp _,
fuSel = fmiscSel(FU_FCMP),
FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
)
val fmvCfg = FuConfig(
fuGen = fmv _,
fuSel = fmiscSel(FU_FMV),
FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = true, hasRedirect = false, CertainLatency(1)
)
val f2iCfg = FuConfig(
fuGen = f2i _,
fuSel = fmiscSel(FU_F2I),
FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2)
)
val s2dCfg = FuConfig(
fuGen = f32toF64 _,
fuSel = fmiscSel(FU_S2D),
FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
)
val d2sCfg = FuConfig(
fuGen = f64toF32 _,
fuSel = fmiscSel(FU_D2S),
FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2)
)
val fdivSqrtCfg = FuConfig(
fuGen = fdivSqrt _,
fuSel = fmiscSel(FU_DIVSQRT),
FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency()
)
val lduCfg = FuConfig(
null, // DontCare
null,
FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false,
UncertainLatency()
)
val stuCfg = FuConfig(
null,
null,
FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false,
UncertainLatency()
)
val mouCfg =
FuConfig(FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
UncertainLatency()
val mouCfg = FuConfig(
null,
null,
FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
UncertainLatency()
)
}
......@@ -14,9 +14,7 @@ trait HasRedirectOut { this: RawModule =>
val brUpdate = IO(Output(new BranchUpdateInfo))
}
class Jump extends FunctionUnit(
FuConfig(FuType.jmp, 1, 0, writeIntRf = true, writeFpRf = false, hasRedirect = true)
) with HasRedirectOut {
class Jump extends FunctionUnit with HasRedirectOut {
val (src1, offset, func, pc, uop) = (
io.in.bits.src(0),
......
......@@ -12,15 +12,14 @@ class MulDivCtrl extends Bundle{
val isHi = Bool() // return hi bits of result ?
}
class AbstractMultiplier(len: Int, latency: Int = 2) extends FunctionUnit(
FuConfig(FuType.mul, 2, 0, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(latency)),
class AbstractMultiplier(len: Int) extends FunctionUnit(
len
){
val ctrl = IO(Input(new MulDivCtrl))
}
class NaiveMultiplier(len: Int, latency: Int = 3)
extends AbstractMultiplier(len, latency)
class NaiveMultiplier(len: Int, val latency: Int)
extends AbstractMultiplier(len)
with HasPipelineReg
{
......@@ -43,7 +42,9 @@ class NaiveMultiplier(len: Int, latency: Int = 3)
XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")
}
class ArrayMultiplier(len: Int, doReg: Seq[Int]) extends AbstractMultiplier(len, doReg.size) with HasPipelineReg {
class ArrayMultiplier(len: Int, doReg: Seq[Int]) extends AbstractMultiplier(len) with HasPipelineReg {
override val latency = doReg.size
val doRegSorted = doReg.sortWith(_ < _)
println(doRegSorted)
......
......@@ -5,10 +5,7 @@ import chisel3.util._
import xiangshan._
import utils._
abstract class AbstractDivider(len: Int) extends FunctionUnit(
FuConfig(FuType.div, 2, 0, writeIntRf = true, writeFpRf = false, hasRedirect = false, UncertainLatency()),
len
){
abstract class AbstractDivider(len: Int) extends FunctionUnit(len){
val ctrl = IO(Input(new MulDivCtrl))
val sign = ctrl.sign
}
......
......@@ -3,12 +3,12 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.FunctionUnit._
class F32toF64 extends FPUPipelineModule(
FuConfig(FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2))
) {
class F32toF64 extends FPUPipelineModule {
override val latency: Int = FunctionUnit.s2dCfg.latency.latencyVal.get
val a = io.in.bits.src(0)
val f32 = Float32(a)
......
......@@ -3,12 +3,13 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.fpu.util.ShiftRightJam
class F64toF32 extends FPUPipelineModule(
FuConfig(FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2))
){
class F64toF32 extends FPUPipelineModule {
override val latency = FunctionUnit.d2sCfg.latency.latencyVal.get
def SEXP_WIDTH = Float64.expWidth + 2
val a = io.in.bits.src(0)
......
......@@ -3,12 +3,12 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.FunctionUnit._
class FCMP extends FPUPipelineModule(
FuConfig(FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2))
){
class FCMP extends FPUPipelineModule {
override val latency = FunctionUnit.fcmpCfg.latency.latencyVal.get
val src = io.in.bits.src.map(x => Mux(isDouble, x, extF32ToF64(x)))
val sign = src.map(_(63))
......
......@@ -3,11 +3,11 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
class FMV(XLEN: Int) extends FPUPipelineModule(
FuConfig(FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = true, hasRedirect = false, CertainLatency(1))
) {
class FMV(XLEN: Int) extends FPUPipelineModule {
override val latency = FunctionUnit.fmvCfg.latency.latencyVal.get
val src = io.in.bits.src.map(x =>
Mux(isDouble || op(2,1)==="b00".U, x, extF32ToF64(x))
......
......@@ -35,7 +35,7 @@ trait HasFPUSigs { this: FPUSubModule =>
val isDouble = !io.in.bits.uop.ctrl.isRVF
}
abstract class FPUSubModule(cfg: FuConfig) extends FunctionUnit(cfg)
abstract class FPUSubModule extends FunctionUnit
with HasUIntToSIntHelper
with HasFPUSigs
{
......@@ -43,6 +43,6 @@ abstract class FPUSubModule(cfg: FuConfig) extends FunctionUnit(cfg)
val fflags = IO(Output(new Fflags))
}
abstract class FPUPipelineModule(cfg: FuConfig)
extends FPUSubModule(cfg)
abstract class FPUPipelineModule
extends FPUSubModule
with HasPipelineReg
\ No newline at end of file
......@@ -3,7 +3,7 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.fpu.util.{ORTree, ShiftRightJam}
//def f2w:UInt = FpuOp("011", "000")
......@@ -11,9 +11,9 @@ import xiangshan.backend.fu.fpu.util.{ORTree, ShiftRightJam}
//def f2l:UInt = FpuOp("011", "010")
//def f2lu:UInt = FpuOp("011", "011")
class FloatToInt extends FPUPipelineModule(
FuConfig(FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2))
){
class FloatToInt extends FPUPipelineModule {
override val latency = FunctionUnit.f2iCfg.latency.latencyVal.get
def SEXP_WIDTH = Float64.expWidth + 2
......
......@@ -3,12 +3,10 @@ package xiangshan.backend.fu.fpu
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.fpu.util.ORTree
class IntToFloatSingleCycle extends FPUSubModule(
FuConfig(FuType.i2f, 1, 0, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(0))
) {
class IntToFloatSingleCycle extends FPUSubModule {
val a = io.in.bits.src(0)
val aNeg = (~a).asUInt()
......
......@@ -4,12 +4,10 @@ import xiangshan.backend.fu.fpu._
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{FuConfig, UncertainLatency}
import xiangshan.backend.fu.{FuConfig, FunctionUnit, UncertainLatency}
import xiangshan.backend.fu.fpu.util.{FPUDebug, ORTree, ShiftRightJam}
class DivSqrt extends FPUSubModule(
FuConfig(FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency())
) {
class DivSqrt extends FPUSubModule {
def SEXP_WIDTH: Int = Float64.expWidth + 2
def D_MANT_WIDTH: Int = Float64.mantWidth + 1
......
......@@ -3,14 +3,14 @@ package xiangshan.backend.fu.fpu.fma
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.fu.{CertainLatency, FuConfig}
import xiangshan.backend.fu.{CertainLatency, FuConfig, FunctionUnit}
import xiangshan.backend.fu.fpu._
import xiangshan.backend.fu.fpu.util.{CSA3_2, FPUDebug, ORTree, ShiftLeftJam, ShiftRightJam}
class FMA extends FPUPipelineModule(
FuConfig(FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5))
) {
class FMA extends FPUPipelineModule {
override val latency = FunctionUnit.fmaCfg.latency.latencyVal.get
def UseRealArraryMult = false
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册