Skip to content

corrected regime bit generation and offset handling during subtraction #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions src/main/scala/PositGenerator.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package hardposit

import chisel3._
import chisel3.util.{Cat, MuxCase}
import chisel3.util.{Cat, Fill, MuxCase}

class PositGenerator(val nbits: Int, val es: Int) extends Module with HasHardPositParams {
override val desiredName = s"posit_${nbits}_generator"

val io = IO(new Bundle {
val in = Input(new unpackedPosit(nbits, es))
val trailingBits = Input(UInt(trailingBitCount.W))
Expand All @@ -15,42 +16,46 @@ class PositGenerator(val nbits: Int, val es: Int) extends Module with HasHardPos
val fraction = io.in.fraction(maxFractionBits - 1, 0)
val negExp = io.in.exponent < 0.S

val regime =
Mux(negExp, -io.in.exponent(maxExponentBits - 1, es), io.in.exponent(maxExponentBits - 1, es)).asUInt
val exponent = io.in.exponent(if (es > 0) es - 1 else 0, 0)
val offset =
regime - (negExp & regime =/= (nbits - 1).U)
// Regime calculation (robust)
val k = (io.in.exponent >> es).asSInt
val regimeBits = Wire(UInt((nbits - 1).W))
val regimeLength = Wire(UInt(log2Ceil(nbits).W))

when(k >= 0.S) {
regimeBits := Cat(Fill(k.asUInt + 1.U, 1.U(1.W)), 0.U((nbits - 1).W)) >> (nbits.U - (k.asUInt + 2.U))
regimeLength := k.asUInt + 2.U
} .otherwise {
regimeBits := Cat(1.U(1.W), Fill((-k).asUInt, 0.U(1.W))) >> (nbits.U - ((-k).asUInt + 2.U))
regimeLength := (-k).asUInt + 2.U
}

val exponent = if (es > 0) io.in.exponent(es - 1, 0).asUInt else 0.U
val offset = regimeLength

val expFrac =
if (es > 0)
Cat(Mux(negExp, 1.U(2.W), 2.U(2.W)), exponent, fraction, io.trailingBits).asSInt
Cat(regimeBits, exponent, fraction, io.trailingBits).asSInt
else
Cat(Mux(negExp, 1.U(2.W), 2.U(2.W)), fraction, io.trailingBits).asSInt
Cat(regimeBits, fraction, io.trailingBits).asSInt

//u => un ; T => Trimmed ; R => Rounded ; S => Signed
// u => un ; T => Trimmed ; R => Rounded ; S => Signed
val uT_uS_posit = (expFrac >> offset)(nbits - 2 + trailingBitCount, 0).asUInt
val uR_uS_posit = uT_uS_posit(nbits - 2 + trailingBitCount, trailingBitCount)

val stickyBitMask = lowerBitMask(offset)(nbits - 3, 0)
val gr =
uT_uS_posit(trailingBitCount - 1, trailingBitCount - 2)
val gr = uT_uS_posit(trailingBitCount - 1, trailingBitCount - 2)
val stickyBit =
io.stickyBit | (expFrac.asUInt & stickyBitMask).orR | {
if (trailingBitCount > 2) uT_uS_posit(trailingBitCount - 3, 0).orR
else false.B
}
val roundingBit =
Mux(uR_uS_posit.andR, false.B,
gr(1) & ~(~uR_uS_posit(0) & gr(1) & ~gr(0) & ~stickyBit))
val R_uS_posit = uR_uS_posit + roundingBit
io.stickyBit | (expFrac.asUInt & stickyBitMask).orR |
(if (trailingBitCount > 2) uT_uS_posit(trailingBitCount - 3, 0).orR else false.B)

//Underflow Correction
val uFC_R_uS_posit =
Cat(0.U(1.W), R_uS_posit | isZero(R_uS_posit))
val roundingBit = Mux(uR_uS_posit.andR, false.B,
gr(1) & ~(~uR_uS_posit(0) & gr(1) & ~gr(0) & ~stickyBit))
val R_uS_posit = uR_uS_posit + roundingBit

val R_S_posit =
Mux(io.in.sign, ~uFC_R_uS_posit + 1.U, uFC_R_uS_posit)
// Underflow Correction
val uFC_R_uS_posit = Cat(0.U(1.W), R_uS_posit | isZero(R_uS_posit))
val R_S_posit = Mux(io.in.sign, ~uFC_R_uS_posit + 1.U, uFC_R_uS_posit)

io.out := Mux(io.in.isNaR, NaR,
Mux((io.in.fraction === 0.U) | io.in.isZero, zero, R_S_posit))
Mux((io.in.fraction === 0.U) || io.in.isZero, zero, R_S_posit))
}
3 changes: 3 additions & 0 deletions src/test/scala/PositAddSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,7 @@ class PositAddSpec extends AnyFlatSpec with ChiselScalatestTester with Matchers
posit_add_test(8, 1, 0x42, 0x54, 0xBA, sub = true)
posit_add_test(8, 1, 0xAC, 0xBE, 0xBA, sub = true)
}
it should "return posit" in {
posit_add_test(32, 2, 1442843648, 1442840576, 2101346304, sub=true)
}
}