diff options
| author | Chick Markley | 2017-02-15 09:45:16 -0800 |
|---|---|---|
| committer | GitHub | 2017-02-15 09:45:16 -0800 |
| commit | 41bee3f347e743e328ee520a48109cb542f3b245 (patch) | |
| tree | 3dba38b3f8f04d87466f7bb258ae338347235fbe | |
| parent | abb05d0569dd6b6c3e736a4db2ea739d767b3c3f (diff) | |
Fixed point factory stuff (#505)
* Don't allow analog to analog monoconnect
adjust tests accordingly
* demonstrate bit loss in shift right for fixed point
* cleaned up some stuff.
this does not test clean due to bug in firrtl
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 47 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/package.scala | 10 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/FixedPointSpec.scala | 52 |
3 files changed, 91 insertions, 18 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index bf134771..baf4b8b0 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -918,24 +918,33 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit def do_=== (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, EqualOp, that) def do_abs(implicit sourceInfo: SourceInfo): FixedPoint = { - Mux(this < 0.F(0), 0.F(0) - this, this) + Mux(this < 0.F(0.BP), 0.F(0.BP) - this, this) } override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, that) override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo): FixedPoint = - this << that.toInt + (this << that.toInt).asFixedPoint(this.binaryPoint) override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo): FixedPoint = binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that) override def do_>> (that: Int)(implicit sourceInfo: SourceInfo): FixedPoint = binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, that) override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo): FixedPoint = - this >> that.toInt + (this >> that.toInt).asFixedPoint(this.binaryPoint) override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo): FixedPoint = binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that) override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref)) + override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo): FixedPoint = { + binaryPoint match { + case KnownBinaryPoint(value) => + val iLit = ILit(value) + pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit)) + case _ => + throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") + } + } def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = { val res = Wire(this, null).asInstanceOf[this.type] res := (that match { @@ -961,14 +970,31 @@ object FixedPoint { def apply(): FixedPoint = apply(Width(), BinaryPoint()) /** Create an FixedPoint type or port with fixed width. */ + @deprecated("Use FixedPoint(width: Width, binaryPoint: BinaryPoint) example FixedPoint(16.W, 8.BP)", "chisel3") def apply(width: Int, binaryPoint: Int): FixedPoint = apply(Width(width), BinaryPoint(binaryPoint)) + + /** Create an FixedPoint type or port with fixed width. */ + def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint) + /** Create an FixedPoint port with inferred width. */ def apply(dir: Direction): FixedPoint = apply(dir, Width(), BinaryPoint()) /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ - def fromBigInt(value: BigInt, width: Int = -1, binaryPoint: Int = 0): FixedPoint = + def fromBigInt(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = { + apply(value, Width(), binaryPoint) + } + /** Create an FixedPoint literal with inferred width from BigInt. + * Use PrivateObject to force users to specify width and binaryPoint by name + */ + def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = { + apply(value, Width(), binaryPoint) + } + /** Create an FixedPoint literal with inferred width from BigInt. + * Use PrivateObject to force users to specify width and binaryPoint by name + */ + def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint = if(width == -1) { apply(value, Width(), BinaryPoint(binaryPoint)) } @@ -978,15 +1004,22 @@ object FixedPoint { /** Create an FixedPoint literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated("use fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint)", "chisel3") def fromDouble(value: Double, dummy: PrivateType = PrivateObject, width: Int = -1, binaryPoint: Int = 0): FixedPoint = { fromBigInt( toBigInt(value, binaryPoint), width = width, binaryPoint = binaryPoint ) } + /** Create an FixedPoint literal with inferred width from Double. + * Use PrivateObject to force users to specify width and binaryPoint by name + */ + def fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint): FixedPoint = { + fromBigInt( + toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint + ) + } - /** Create an FixedPoint type with specified width and binary position. */ - def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint) /** Create an FixedPoint port with specified width and binary position. */ def apply(dir: Direction, width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint) def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = { @@ -1015,7 +1048,7 @@ object FixedPoint { * @return */ def toDouble(i: BigInt, binaryPoint : Int): Double = { - val multiplier = math.pow(2,binaryPoint ) + val multiplier = math.pow(2,binaryPoint) val result = i.toDouble / multiplier result } diff --git a/chiselFrontend/src/main/scala/chisel3/core/package.scala b/chiselFrontend/src/main/scala/chisel3/core/package.scala index 9fa20f49..aec5398d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/package.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/package.scala @@ -1,3 +1,5 @@ +// See LICENSE for license details. + package chisel3 { import internal.Builder @@ -93,8 +95,16 @@ package chisel3 { def asBool(): Bool = Bool.Lit(boolean) } + //scalastyle:off method.name implicit class fromDoubleToLiteral(val double: Double) { + @deprecated("Use notation <double>.F(<binary_point>.BP) instead", "chisel3") def F(binaryPoint: Int): FixedPoint = FixedPoint.fromDouble(double, binaryPoint = binaryPoint) + def F(binaryPoint: BinaryPoint): FixedPoint = { + FixedPoint.fromDouble(double, Width(), binaryPoint) + } + def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = { + FixedPoint.fromDouble(double, width, binaryPoint) + } } implicit class fromIntToWidth(val int: Int) { diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala index d0557e66..0f5b3e9e 100644 --- a/src/test/scala/chiselTests/FixedPointSpec.scala +++ b/src/test/scala/chiselTests/FixedPointSpec.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import chisel3.experimental.FixedPoint +import chisel3.internal.firrtl.{BinaryPoint, Width} import chisel3.testers.BasicTester import org.scalatest._ @@ -20,46 +21,75 @@ class FixedPointLiteralSpec extends FlatSpec with Matchers { } } +//noinspection TypeAnnotation,EmptyParenMethodAccessedAsParameterless class FixedPointFromBitsTester extends BasicTester { val uint = 3.U(4.W) - val sint = -3.S + val sint = (-3).S - val fp = FixedPoint.fromDouble(3.0, width = 4, binaryPoint = 0) + val fp = FixedPoint.fromDouble(3.0, 4.W, 0.BP) val fp_tpe = FixedPoint(4.W, 1.BP) - val uint_result = FixedPoint.fromDouble(1.5, width = 4, binaryPoint = 1) - val sint_result = FixedPoint.fromDouble(-1.5, width = 4, binaryPoint = 1) - val fp_result = FixedPoint.fromDouble(1.5, width = 4, binaryPoint = 1) + val uint_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP) + val sint_result = FixedPoint.fromDouble(-1.5, 4.W, 1.BP) + val fp_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP) val uint2fp = fp_tpe.fromBits(uint) val sint2fp = fp_tpe.fromBits(sint) val fp2fp = fp_tpe.fromBits(fp) - val negativefp = -3.5.F(binaryPoint = 4) - val positivefp = 3.5.F(binaryPoint = 4) + val uintToFp = uint.asFixedPoint(1.BP) + val sintToFp = sint.asFixedPoint(1.BP) + val fpToFp = fp.asFixedPoint(1.BP) + + val negativefp = (-3.5).F(4.BP) + val positivefp = 3.5.F(4.BP) assert(uint2fp === uint_result) assert(sint2fp === sint_result) assert(fp2fp === fp_result) + assert(uintToFp === uint_result) + assert(sintToFp === sint_result) + assert(fpToFp === fp_result) + assert(positivefp.abs() === positivefp) assert(negativefp.abs() === positivefp) assert(negativefp.abs() =/= negativefp) + val f1bp5 = 1.5.F(1.BP) + val f6bp0 = 6.0.F(0.BP) + val f6bp2 = 6.0.F(2.BP) + + val f1bp5shiftleft2 = Wire(FixedPoint(Width(), BinaryPoint())) + val f6bp0shiftright2 = Wire(FixedPoint(Width(), BinaryPoint())) + val f6bp2shiftright2 = Wire(FixedPoint(Width(), BinaryPoint())) + + f1bp5shiftleft2 := f1bp5 << 2 + f6bp0shiftright2 := f6bp0 >> 2 + f6bp2shiftright2 := f6bp2 >> 2 + + assert(f1bp5shiftleft2 === f6bp0) + assert(f1bp5shiftleft2 === 6.0.F(8.BP)) + + // shifting does not move binary point, so in first case below one bit is lost in shift + assert(f6bp0shiftright2 === 1.0.F(0.BP)) + assert(f6bp2shiftright2 === 1.5.F(2.BP)) + + stop() } class SBP extends Module { val io = IO(new Bundle { - val in = Input(FixedPoint(6, 2)) - val out = Output(FixedPoint(4, 0)) + val in = Input(FixedPoint(6.W, 2.BP)) + val out = Output(FixedPoint(4.W, 0.BP)) }) io.out := io.in.setBinaryPoint(0) } class SBPTester extends BasicTester { val dut = Module(new SBP) - dut.io.in := FixedPoint.fromDouble(3.75, binaryPoint = 2) + dut.io.in := 3.75.F(2.BP) - assert(dut.io.out === FixedPoint.fromDouble(3.0, binaryPoint = 0)) + assert(dut.io.out === 3.0.F(0.BP)) stop() } |
