Skip to content

Commit

Permalink
Add support for setting HwachaFLen
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryz123 committed Mar 14, 2021
1 parent 62c01f5 commit dc71b0f
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 159 deletions.
4 changes: 4 additions & 0 deletions src/main/scala/TopLevelConfigs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class WithSmallPredRF extends Config((site, here, up) => {
case HwachaNPredRFEntries => 128
})

class WithHwachaFLen(flen: Int) extends Config((site, here, up) => {
case HwachaFLen => flen
})

class ISCA2016Config extends Config(
new Process28nmConfig ++
new WithNBanks(4) ++
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ class DefaultHwachaConfig extends Config((site, here, up) => {
case HwachaStagesHFMA => 3
case HwachaStagesFConv => 2
case HwachaStagesFCmp => 1
case HwachaFLen => 64
case HwachaSupportsFPD => site(HwachaFLen) >= 64
case HwachaSupportsFPS => site(HwachaFLen) >= 32
case HwachaSupportsFPH => site(HwachaFLen) >= 16

case HwachaNSeqEntries => 8

Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/lane.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ case object HwachaStagesSFMA extends Field[Int]
case object HwachaStagesHFMA extends Field[Int]
case object HwachaStagesFConv extends Field[Int]
case object HwachaStagesFCmp extends Field[Int]
case object HwachaFLen extends Field[Int]
case object HwachaSupportsFPD extends Field[Boolean]
case object HwachaSupportsFPS extends Field[Boolean]
case object HwachaSupportsFPH extends Field[Boolean]

abstract trait LaneParameters extends UsesHwachaParameters {
val nSRAM = p(HwachaNSRAMRFEntries)
Expand Down
139 changes: 79 additions & 60 deletions src/main/scala/scalar-decode.scala

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/main/scala/scalar-unit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ class ScalarUnit(resetSignal: Bool = null)(implicit p: Parameters) extends Hwach
// DECODE
val id_pc = io.imem.resp.bits.pc
val id_inst = io.imem.resp.bits.data; require(io.imem.resp.bits.data.getWidth == HwachaElementInstBytes*8)
val decode_table = ScalarDecode.table ++ VectorMemoryDecode.table ++ VectorArithmeticDecode.table
val decode_table = (ScalarDecode.table ++ VectorMemoryDecode.table ++ VectorArithmeticDecode.table
++ (if (p(HwachaSupportsFPD)) VectorArithmeticDecode.fpd_table else Array[(BitPat, List[BitPat])]())
++ (if (p(HwachaSupportsFPS)) VectorArithmeticDecode.fps_table else Array[(BitPat, List[BitPat])]())
++ (if (p(HwachaSupportsFPH)) VectorArithmeticDecode.fph_table else Array[(BitPat, List[BitPat])]()))
val id_ctrl = Wire(new IntCtrlSigs()).decode(id_inst, decode_table)
when (!killd && id_ctrl.decode_stop) {
vf_active := Bool(false)
Expand Down
46 changes: 26 additions & 20 deletions src/main/scala/vfu-fcmp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,35 @@ class FCmpSlice(implicit p: Parameters) extends VXUModule()(p) with Packing with
}
}

val supported = List(p(HwachaSupportsFPD), p(HwachaSupportsFPD), p(HwachaSupportsFPH))

val results =
List((unpack_d _, expand_float_d _, FType.D),
(unpack_w _, expand_float_s _, FType.S),
(unpack_h _, expand_float_h _, FType(whp._1, whp._2))) zip cmps zip ins zip classifys map {
case ((((unpack, expand, fType), cmp), (input0, input1)), classify) => {
val less = cmp.lt || (input0.asSInt < 0.S && input1.asSInt >= 0.S)
val in0_nan = fType.isNaN(input0)
val in1_nan = fType.isNaN(input1)
val isInvalid = fType.isSNaN(input0) || fType.isSNaN(input1)
val isNaNOut = (in0_nan && in1_nan)
val want_min = in1_nan || (fn.op_is(FC_MIN) === less) && !in0_nan
val in0_minmax = expand(unpack(in0, 0))
val in1_minmax = expand(unpack(in1, 0))
val qnan = fType.qNaN
val ieeeNaN = if(fType == FType.S || fType == FType.D) ieee(qnan, fType) else qnan
val minmax =
Mux(isNaNOut, ieeeNaN, Mux(want_min, in0_minmax, in1_minmax))
val sel = List(FC_MIN,FC_MAX,FC_CLASS).map(fn.op_is(_))
val in = List(
minmax, // FC_MIN
minmax, // FC_MAX
classify._1) // FC_CLASS
Mux1H(sel, in)
(unpack_h _, expand_float_h _, FType(whp._1, whp._2))) zip cmps zip ins zip classifys zip supported map {
case (((((unpack, expand, fType), cmp), (input0, input1)), classify), build) => {
if (build) {
val less = cmp.lt || (input0.asSInt < 0.S && input1.asSInt >= 0.S)
val in0_nan = fType.isNaN(input0)
val in1_nan = fType.isNaN(input1)
val isInvalid = fType.isSNaN(input0) || fType.isSNaN(input1)
val isNaNOut = (in0_nan && in1_nan)
val want_min = in1_nan || (fn.op_is(FC_MIN) === less) && !in0_nan
val in0_minmax = expand(unpack(in0, 0))
val in1_minmax = expand(unpack(in1, 0))
val qnan = fType.qNaN
val ieeeNaN = if(fType == FType.S || fType == FType.D) ieee(qnan, fType) else qnan
val minmax =
Mux(isNaNOut, ieeeNaN, Mux(want_min, in0_minmax, in1_minmax))
val sel = List(FC_MIN,FC_MAX,FC_CLASS).map(fn.op_is(_))
val in = List(
minmax, // FC_MIN
minmax, // FC_MAX
classify._1) // FC_CLASS
Mux1H(sel, in)
} else {
0.U
}
}
}

Expand Down
133 changes: 74 additions & 59 deletions src/main/scala/vfu-fconv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,83 +57,98 @@ class FConvSlice(implicit p: Parameters) extends VXUModule()(p) with Packing {
private def pipe(valid: Bool, out: Bits, exc: Bits, fn: Bits=>Bits = identity) =
(fn(Pipe(valid, out, stagesFConv).bits), Pipe(valid, exc, stagesFConv).bits)

val supported = List(p(HwachaSupportsFPD), p(HwachaSupportsFPS), p(HwachaSupportsFPH))
val results_int2float =
List((FPD, ieee_dp _, expand_float_d _, wdp),
(FPS, ieee_sp _, expand_float_s _, wsp),
(FPH, ieee_hp _, expand_float_h _, whp)) map {
case (fp, ieee, expand, (exp, sig)) => {
(FPH, ieee_hp _, expand_float_h _, whp)) zip supported map {
case ((fp, ieee, expand, (exp, sig)), build) => {
val valid = fn.fp_is(fp) && val_int2float && pred(0)
val input = dgate(valid, in)
val rm = dgate(valid, fn.rm)
val op = dgate(valid, op_int2float)
val l2fp = Module(new hardfloat.INToRecFN(SZ_D, exp, sig))
l2fp.suggestName("l2fpInst")
val w2fp = Module(new hardfloat.INToRecFN(SZ_W, exp, sig))
w2fp.suggestName("w2fpInst")
l2fp.io.signedIn := op(0)
l2fp.io.in := input
l2fp.io.roundingMode := rm
w2fp.io.signedIn := op(0)
w2fp.io.in := input
w2fp.io.roundingMode := rm
val output = Mux(op(1), l2fp.io.out, w2fp.io.out)
val exc = Mux(op(1), l2fp.io.exceptionFlags, w2fp.io.exceptionFlags)
val (output, exc) = if (build) {
val input = dgate(valid, in)
val rm = dgate(valid, fn.rm)
val op = dgate(valid, op_int2float)
val l2fp = Module(new hardfloat.INToRecFN(SZ_D, exp, sig))
l2fp.suggestName("l2fpInst")
val w2fp = Module(new hardfloat.INToRecFN(SZ_W, exp, sig))
w2fp.suggestName("w2fpInst")
l2fp.io.signedIn := op(0)
l2fp.io.in := input
l2fp.io.roundingMode := rm
w2fp.io.signedIn := op(0)
w2fp.io.in := input
w2fp.io.roundingMode := rm
val output = Mux(op(1), l2fp.io.out, w2fp.io.out)
val exc = Mux(op(1), l2fp.io.exceptionFlags, w2fp.io.exceptionFlags)
(output, exc)
} else {
(0.U, 0.U)
}
pipe(valid, ieee(output), exc, expand)
}
}

val results_float2int =
List((FPD, recode_dp _, unpack_d _, wdp),
(FPS, recode_sp _, unpack_w _, wsp),
(FPH, recode_hp _, unpack_h _, whp)) map {
case (fp, recode, unpack, (exp, sig)) => {
(FPH, recode_hp _, unpack_h _, whp)) zip supported map {
case ((fp, recode, unpack, (exp, sig)), build) => {
val valid = fn.fp_is(fp) && val_float2int && pred(0)
val input = recode(dgate(valid, unpack(in, 0)))
val rm = dgate(valid, fn.rm)
val op = dgate(valid, op_float2int)
val fp2l = Module(new hardfloat.RecFNToIN(exp, sig, SZ_D))
fp2l.suggestName("fp2lInst")
val fp2w = Module(new hardfloat.RecFNToIN(exp, sig, SZ_W))
fp2w.suggestName("fp2wInst")
fp2l.io.signedOut := op(0)
fp2l.io.in := input
fp2l.io.roundingMode := rm
fp2w.io.signedOut := op(0)
fp2w.io.in := input
fp2w.io.roundingMode := rm
val output = Mux(op(1), fp2l.io.out, expand_w(fp2w.io.out))
val iexc = Mux(op(1), fp2l.io.intExceptionFlags, fp2w.io.intExceptionFlags)
val (output, iexc) = if (build) {
val input = recode(dgate(valid, unpack(in, 0)))
val rm = dgate(valid, fn.rm)
val op = dgate(valid, op_float2int)
val fp2l = Module(new hardfloat.RecFNToIN(exp, sig, SZ_D))
fp2l.suggestName("fp2lInst")
val fp2w = Module(new hardfloat.RecFNToIN(exp, sig, SZ_W))
fp2w.suggestName("fp2wInst")
fp2l.io.signedOut := op(0)
fp2l.io.in := input
fp2l.io.roundingMode := rm
fp2w.io.signedOut := op(0)
fp2w.io.in := input
fp2w.io.roundingMode := rm
val output = Mux(op(1), fp2l.io.out, expand_w(fp2w.io.out))
val iexc = Mux(op(1), fp2l.io.intExceptionFlags, fp2w.io.intExceptionFlags)
(output, iexc)
} else {
(0.U, 0.U(3.W))
}
pipe(valid, output, Cat(iexc(2, 1).orR, UInt(0, 3), iexc(0)))
}
}

val results_float2float =
List((FV_CSTD, recode_sp _, unpack_w _, ieee_dp _, expand_float_d _, wsp, wdp),
(FV_CHTD, recode_hp _, unpack_h _, ieee_dp _, expand_float_d _, whp, wdp),
(FV_CDTS, recode_dp _, unpack_d _, ieee_sp _, expand_float_s _, wdp, wsp),
(FV_CHTS, recode_hp _, unpack_h _, ieee_sp _, expand_float_s _, whp, wsp),
(FV_CDTH, recode_dp _, unpack_d _, ieee_hp _, expand_float_h _, wdp, whp),
(FV_CSTH, recode_sp _, unpack_w _, ieee_hp _, expand_float_h _, wsp, whp)) map {
case (op, recode, unpack, ieee, expand, (exps, sigs), (expd, sigd)) => {
val (szs, szd) = (exps + sigs, expd + sigd)
val sz = math.max(szs, szd)
val (m, n) = (math.max(szd / szs, 1), regLen / sz)
val val_op = fn.op_is(op)
val results = for (i <- (0 until n) if (confprec || i == 0)) yield {
val fp2fp = Module(new hardfloat.RecFNToRecFN(exps, sigs, expd, sigd))
fp2fp.suggestName("fp2fpInst")
val valid = pred(i) && val_op
fp2fp.io.in := recode(dgate(valid, unpack(in, i * m)))
fp2fp.io.roundingMode := dgate(valid, fn.rm)
pipe(valid, ieee(fp2fp.io.out), fp2fp.io.exceptionFlags, expand)
List((FV_CSTD, recode_sp _, unpack_w _, ieee_dp _, expand_float_d _, wsp, wdp, p(HwachaSupportsFPD)),
(FV_CHTD, recode_hp _, unpack_h _, ieee_dp _, expand_float_d _, whp, wdp, p(HwachaSupportsFPD)),
(FV_CDTS, recode_dp _, unpack_d _, ieee_sp _, expand_float_s _, wdp, wsp, p(HwachaSupportsFPS)),
(FV_CHTS, recode_hp _, unpack_h _, ieee_sp _, expand_float_s _, whp, wsp, p(HwachaSupportsFPS)),
(FV_CDTH, recode_dp _, unpack_d _, ieee_hp _, expand_float_h _, wdp, whp, p(HwachaSupportsFPH)),
(FV_CSTH, recode_sp _, unpack_w _, ieee_hp _, expand_float_h _, wsp, whp, p(HwachaSupportsFPH))) map {
case (op, recode, unpack, ieee, expand, (exps, sigs), (expd, sigd), build) => {
if (build) {
val (szs, szd) = (exps + sigs, expd + sigd)
val sz = math.max(szs, szd)
val (m, n) = (math.max(szd / szs, 1), regLen / sz)
val val_op = fn.op_is(op)
val results = for (i <- (0 until n) if (confprec || i == 0)) yield {
val fp2fp = Module(new hardfloat.RecFNToRecFN(exps, sigs, expd, sigd))
fp2fp.suggestName("fp2fpInst")
val valid = pred(i) && val_op
fp2fp.io.in := recode(dgate(valid, unpack(in, i * m)))
fp2fp.io.roundingMode := dgate(valid, fn.rm)
pipe(valid, ieee(fp2fp.io.out), fp2fp.io.exceptionFlags, expand)
}
val valid = active && val_op
val output = if (results.size > 1) {
val rmatch = (io.req.bits.rate === UInt(log2Ceil(n)))
Mux(Pipe(valid, rmatch, stagesFConv).bits,
Vec(results.map(_._1(sz-1, 0))).asUInt, results.head._1)
} else results.head._1
(output, results.map(_._2).reduce(_.asUInt | _.asUInt ))
} else {
(0.U, 0.U)
}
val valid = active && val_op
val output = if (results.size > 1) {
val rmatch = (io.req.bits.rate === UInt(log2Ceil(n)))
Mux(Pipe(valid, rmatch, stagesFConv).bits,
Vec(results.map(_._1(sz-1, 0))).asUInt, results.head._1)
} else results.head._1
(output, results.map(_._2).reduce(_.asUInt | _.asUInt ))
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/vfu-fdiv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ class FDivSlice(implicit p: Parameters) extends VXUModule()(p) with Packing {
sp.io.roundingMode := io.req.bits.fn.rm
hp.io.in := recode_hp(in)
hp.io.roundingMode := io.req.bits.fn.rm
val out = Mux(io.req.bits.fn.fp_is(FPD), dp,
Mux(io.req.bits.fn.fp_is(FPS), sp.io.out, hp.io.out))
val exc = Mux(io.req.bits.fn.fp_is(FPD), Bits(0),
Mux(io.req.bits.fn.fp_is(FPS), sp.io.exceptionFlags, hp.io.exceptionFlags))
val out = Mux(io.req.bits.fn.fp_is(FPD) && p(HwachaSupportsFPD).B, dp,
Mux(io.req.bits.fn.fp_is(FPS) && p(HwachaSupportsFPS).B, sp.io.out, hp.io.out))
val exc = Mux(io.req.bits.fn.fp_is(FPD) && p(HwachaSupportsFPD).B, Bits(0),
Mux(io.req.bits.fn.fp_is(FPS) && p(HwachaSupportsFPS).B, sp.io.exceptionFlags, hp.io.exceptionFlags))
(out, exc)
}

Expand Down
38 changes: 23 additions & 15 deletions src/main/scala/vfu-fma.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,33 @@ class FMASlice(implicit p: Parameters) extends VXUModule()(p) with Packing {
fn.op_is(FM_MUL) -> Bits(0, SZ_D)
))

val buildDFMA = p(HwachaSupportsFPD)
val buildSFMA = p(HwachaSupportsFPS)
val buildHFMA = p(HwachaSupportsFPH)
val results =
List((stagesDFMA, SZ_D, FPD, recode_dp _, unpack_d _, ieee_dp _, repack_d _, expand_float_d _, (11, 53)),
(stagesSFMA, SZ_W, FPS, recode_sp _, unpack_w _, ieee_sp _, repack_w _, expand_float_s _, (8, 24)),
(stagesHFMA, SZ_H, FPH, recode_hp _, unpack_h _, ieee_hp _, repack_h _, expand_float_h _, (5, 11))) map {
case (stages, sz, fp, recode, unpack, ieee, repack, expand, (exp, sig)) => {
List((buildDFMA, stagesDFMA, SZ_D, FPD, recode_dp _, unpack_d _, ieee_dp _, repack_d _, expand_float_d _, (11, 53)),
(buildSFMA, stagesSFMA, SZ_W, FPS, recode_sp _, unpack_w _, ieee_sp _, repack_w _, expand_float_s _, (8, 24)),
(buildHFMA, stagesHFMA, SZ_H, FPH, recode_hp _, unpack_h _, ieee_hp _, repack_h _, expand_float_h _, (5, 11))) map {
case (build, stages, sz, fp, recode, unpack, ieee, repack, expand, (exp, sig)) => {
val n = SZ_D / sz
val val_fp = fn.fp_is(fp)
val results = for (i <- (0 until n) if (confprec || i == 0)) yield {
val fma = Module(new freechips.rocketchip.tile.MulAddRecFNPipe(stages min 2, exp, sig))
fma.suggestName("fmaInst")
val valid = pred(i) && val_fp
fma.io.validin := valid
fma.io.op := dgate(valid, fma_op)
fma.io.a := recode(dgate(valid, unpack(fma_multiplicand, i)))
fma.io.b := recode(dgate(valid, unpack(fma_multiplier, i)))
fma.io.c := recode(dgate(valid, unpack(fma_addend, i)))
fma.io.roundingMode := dgate(valid, fn.rm)
val out = Pipe(fma.io.validout, ieee(fma.io.out), (stages - 2) max 0).bits
val exc = Pipe(fma.io.validout, fma.io.exceptionFlags, (stages - 2) max 0).bits
val (out, exc) = if (build) {
val fma = Module(new freechips.rocketchip.tile.MulAddRecFNPipe(stages min 2, exp, sig))
fma.suggestName("fmaInst")
val valid = pred(i) && val_fp
fma.io.validin := valid
fma.io.op := dgate(valid, fma_op)
fma.io.a := recode(dgate(valid, unpack(fma_multiplicand, i)))
fma.io.b := recode(dgate(valid, unpack(fma_multiplier, i)))
fma.io.c := recode(dgate(valid, unpack(fma_addend, i)))
fma.io.roundingMode := dgate(valid, fn.rm)
val out = Pipe(fma.io.validout, ieee(fma.io.out), (stages - 2) max 0).bits
val exc = Pipe(fma.io.validout, fma.io.exceptionFlags, (stages - 2) max 0).bits
(out, exc)
} else {
(0.U, 0.U)
}
(out, exc)
}
val valid = active && val_fp
Expand Down

0 comments on commit dc71b0f

Please sign in to comment.