Skip to content

Commit

Permalink
Merge pull request #113 from ucb-bar/tester-util-patch
Browse files Browse the repository at this point in the history
Fix toBigIntUnsigned
  • Loading branch information
stevobailey authored Oct 17, 2017
2 parents 374e30a + 82c1633 commit a9dff60
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/main/scala/dsptools/tester/DspTesterUtilities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import chisel3.iotesters.TestersCompatibility

object DspTesterUtilities {

// Converts negative Double's to their 2's complement BigInt equivalents
// Converts signed Double's to their 2's complement BigInt equivalents (unsigned)
// (totalWidth, fractionalWidth of some FixedPoint)
def toBigIntUnsigned(x: Double, totalWidth: Int, fractionalWidth: Int): BigInt = {
def signedToBigIntUnsigned(x: Double, totalWidth: Int, fractionalWidth: Int): BigInt = {
val bi = FixedPoint.toBigInt(x, fractionalWidth)
val neg = bi < 0
val neededWidth = if (neg) bi.bitLength + 1 else bi.bitLength
val neededWidth = bi.bitLength + 1
require(neededWidth <= totalWidth, "Double -> BigInt width larger than total width allocated!")
if (neg) (BigInt(1) << neededWidth) + bi
if (neg) (BigInt(1) << totalWidth) + bi
else bi
}

Expand Down Expand Up @@ -119,4 +119,4 @@ object DspTesterUtilities {
}
}

}
}
62 changes: 62 additions & 0 deletions src/test/scala/dsptools/DspTesterSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,68 @@

package dsptools

import DspTesterUtilities._
import org.scalatest.{FlatSpec, Matchers}
import scala.math.{pow, abs}

class DspTesterSpec {

}

class DspTesterUtilitiesSpec extends FlatSpec with Matchers {

behavior of "Tester Converters"

it should "convert positive and negative doubles to their BigInt, fixed point equivalents" in {

def check_conversion(value: Double, totalWidth: Int, fractionalWidth: Int, verbose: Boolean = false): Unit = {
if (verbose) { println(s"value = $value\ntotal width = $totalWidth\nfractional width = $fractionalWidth") }
var bi = signedToBigIntUnsigned(value, totalWidth, fractionalWidth)
if (verbose) { println(s"result = $bi") }
// check sign, flip if necessary
if (totalWidth > 0 && bi.testBit(totalWidth-1)) {
bi = -1 * ((bi ^ ((BigInt(1) << totalWidth) - 1)) + 1)
}
val bid = bi.toDouble / (BigInt(1) << fractionalWidth).toDouble
if (verbose) { println(s"back to double = $bid") }
val comp = scala.math.abs(bid-value)
if (verbose) { println(s"comp = $comp") }
val ref = scala.math.pow(2, -fractionalWidth)
if (verbose) { println(s"ref = $ref") }
require(abs(bid-value) < pow(2, -fractionalWidth))
}

// integers
var width = 14
for (i <- -pow(2,width-1).toInt until pow(2,width-1).toInt) {
check_conversion(i, width, 0)
}

// big integers
width = 40
for (i <- -pow(2,width-1).toInt to pow(2,width-1).toInt by pow(2, 20).toInt) {
check_conversion(i, width, 0)
}

// total > fractional
width = 19
var fract = 8
for (i <- -pow(2,width-fract-1) to pow(2,width-fract-1)-1 by 1.0/fract*0.9) {
check_conversion(i, width, fract)
}

// total < fractional
width = 11
fract = 17
for (i <- -pow(2,width-fract-1) to pow(2,width-fract-1)-1 by 1.0/fract*0.9) {
check_conversion(i, width, fract)
}

}

it should "fail to convert doubles to BigInts when not enough space is supplied" in {
intercept[IllegalArgumentException] { signedToBigIntUnsigned(2.0, 4, 2) }
intercept[IllegalArgumentException] { signedToBigIntUnsigned(-2.25, 4, 2) }
}

}

0 comments on commit a9dff60

Please sign in to comment.