summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Waterman2015-08-10 16:58:04 -0700
committerAndrew Waterman2015-08-10 16:58:04 -0700
commit4dadc8c2adb92cbae81590681acd91226b94b211 (patch)
treee16556260059d16fc2f733fe9992021a4613ceb0 /src
parent0d2f241a7ffbadaaa2765b504d98442613766c59 (diff)
Avoid floating point in log2 computation
The previous implementations were incorrect for large N.
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/Chisel/Utils.scala28
1 files changed, 12 insertions, 16 deletions
diff --git a/src/main/scala/Chisel/Utils.scala b/src/main/scala/Chisel/Utils.scala
index 5756fee0..a7c60677 100644
--- a/src/main/scala/Chisel/Utils.scala
+++ b/src/main/scala/Chisel/Utils.scala
@@ -6,30 +6,26 @@ import scala.language.experimental.macros
import scala.reflect.runtime.universe._
import scala.reflect.macros.blackbox._
-object log2Up
-{
- def apply(in: Int): Int = if(in == 1) 1 else ceil(log(in)/log(2)).toInt
+object log2Up {
+ def apply(in: Int): Int = 1 max BigInt(in-1).bitLength
}
-object log2Ceil
-{
- def apply(in: Int): Int = ceil(log(in)/log(2)).toInt
+object log2Ceil {
+ def apply(in: Int): Int = {
+ require(in > 0)
+ BigInt(in-1).bitLength
+ }
}
-
-object log2Down
-{
- def apply(x : Int): Int = if (x == 1) 1 else floor(log(x)/log(2.0)).toInt
+object log2Down {
+ def apply(in: Int): Int = log2Up(in) - (if (isPow2(in)) 0 else 1)
}
-object log2Floor
-{
- def apply(x : Int): Int = floor(log(x)/log(2.0)).toInt
+object log2Floor {
+ def apply(in: Int): Int = log2Ceil(in) - (if (isPow2(in)) 0 else 1)
}
-
-object isPow2
-{
+object isPow2 {
def apply(in: Int): Boolean = in > 0 && ((in & (in-1)) == 0)
}