Skip to content

Commit

Permalink
Andr, Orr, and Xorr were broken because mask applied to their input
Browse files Browse the repository at this point in the history
was based on output width of operation instead of input width. This
fixes that problem and adds a test for this error
Fixes Issue #78
  • Loading branch information
chick committed Jan 17, 2019
1 parent a10de08 commit 6b17390
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 10 deletions.
20 changes: 11 additions & 9 deletions src/main/scala/treadle/executable/ExpressionCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ class ExpressionCompiler(
case ClockType => 1
}

val sourceWidth = getWidth(expressions.head)

arg1 match {
case e1: IntExpressionResult =>
op match {
Expand All @@ -475,9 +477,9 @@ class ExpressionCompiler(
case Neg => NegInts(e1.apply)
case Not => NotInts(e1.apply, width)

case Andr => AndrInts(e1.apply, width)
case Orr => OrrInts(e1.apply, width)
case Xorr => XorrInts(e1.apply, width)
case Andr => AndrInts(e1.apply, sourceWidth)
case Orr => OrrInts(e1.apply, sourceWidth)
case Xorr => XorrInts(e1.apply, sourceWidth)
}
case e1: LongExpressionResult =>
op match {
Expand All @@ -490,9 +492,9 @@ class ExpressionCompiler(
case Neg => NegLongs(e1.apply)
case Not => NotLongs(e1.apply, width)

case Andr => AndrLongs(e1.apply, width)
case Orr => OrrLongs(e1.apply, width)
case Xorr => XorrLongs(e1.apply, width)
case Andr => AndrLongs(e1.apply, sourceWidth)
case Orr => OrrLongs(e1.apply, sourceWidth)
case Xorr => XorrLongs(e1.apply, sourceWidth)
}
case e1: BigExpressionResult =>
op match {
Expand All @@ -505,9 +507,9 @@ class ExpressionCompiler(
case Neg => NegBigs(e1.apply)
case Not => NotBigs(e1.apply, width)

case Andr => AndrBigs(e1.apply, width)
case Orr => OrrBigs(e1.apply, width)
case Xorr => XorrBigs(e1.apply, width)
case Andr => AndrBigs(e1.apply, sourceWidth)
case Orr => OrrBigs(e1.apply, sourceWidth)
case Xorr => XorrBigs(e1.apply, sourceWidth)
}
}
}
Expand Down
70 changes: 69 additions & 1 deletion src/test/scala/treadle/primops/AndrOrrXorr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package treadle.primops

import treadle.executable._
import treadle.{BigIntTestValuesGenerator, BitTwiddlingUtils, extremaOfUIntOfWidth, extremaOfSIntOfWidth}
import treadle._
import org.scalatest.{FreeSpec, Matchers}


Expand Down Expand Up @@ -114,6 +114,74 @@ class AndrOrrXorr extends FreeSpec with Matchers {
}
}

"Andr, Orr, Xorr reduction should work with vec converted to uint" in {
val input =
"""
|circuit XorReduce :
| module XorReduce :
| input clock : Clock
| input reset : UInt<1>
| input io_in1_0 : UInt<1>
| input io_in1_1 : UInt<1>
| input io_in1_2 : UInt<1>
| input io_in1_3 : UInt<1>
| output io_out_andr : UInt<1>
| output io_out_orr : UInt<1>
| output io_out_xorr : UInt<1>
|
| node _T = cat(io_in1_1, io_in1_0) @[XorReducer.scala 15:21]
| node _T_1 = cat(io_in1_3, io_in1_2) @[XorReducer.scala 15:21]
| node _T_2 = cat(_T_1, _T) @[XorReducer.scala 15:21]
| node _T_3 = andr(_T_2) @[XorReducer.scala 15:28]
| node _T_4 = orr(_T_2) @[XorReducer.scala 15:28]
| node _T_5 = xorr(_T_2) @[XorReducer.scala 15:28]
| io_out_andr <= _T_3 @[XorReducer.scala 15:11]
| io_out_orr <= _T_4 @[XorReducer.scala 15:11]
| io_out_xorr <= _T_5 @[XorReducer.scala 15:11]
""".stripMargin

val manager = new TreadleOptionsManager {
treadleOptions = treadleOptions.copy(
showFirrtlAtLoad = false,
setVerbose = false,
rollbackBuffers = 0
)
}

def scalaXorReduce(x: BigInt, width: Int): Int = {
if(x.bitCount % 2 == 0) 0 else 1
}

def scalaAndReduce(x: BigInt, width: Int): Int = {
if((0 until width).forall(i => x.testBit(i))) 1 else 0
}

def scalaOrReduce(x: BigInt, width: Int): Int = {
if((0 until width).exists(i => x.testBit(i))) 1 else 0
}

val t = new TreadleTester(input, manager)
for {
i0 <- 0 to 1
i1 <- 0 to 1
i2 <- 0 to 1
i3 <- 0 to 1
} {
t.poke(s"io_in1_0", i0)
t.poke(s"io_in1_1", i1)
t.poke(s"io_in1_2", i2)
t.poke(s"io_in1_3", i3)

t.expect("io_out_andr", scalaAndReduce(i0 + (i1 << 1) + (i2 << 2) + (i3 << 3), 4))
t.expect("io_out_orr", scalaOrReduce(i0 + (i1 << 1) + (i2 << 2) + (i3 << 3), 4))
t.expect("io_out_xorr", scalaXorReduce(i0 + (i1 << 1) + (i2 << 2) + (i3 << 3), 4))

// println(s"got $i0$i1$i2$i3 " + t.peek("io_out_andr") + " " +
// t.peek("io_out_orr") + " " + t.peek("io_out_xorr"))
}
t.report()
}

"Reductions should pass for different bit widths when using SInt" in {
for (size <- BigIntTestValuesGenerator((1, DataSize.LongThreshold * Big(2)))) {
val bitWidth = size.toInt
Expand Down

0 comments on commit 6b17390

Please sign in to comment.