Why Bool(true) != Bool(true) in chisel3?

766 views Asked by At

If I run a scala console in my sbt project and import chisel3 package like it:

$ sbt 
sbt:CIC> console
scala> import chisel3._
import chisel3._
scala> 

Then if I declare two Bool variables, there are not equal :

scala> val value1 = true.B
value1: chisel3.Bool = Bool(true)

scala> val value2 = true.B
value2: chisel3.Bool = Bool(true)

scala> value1 == value2
res0: Boolean = false

scala> value1.==(value2)
res3: Boolean = false

scala> value1.`==`(value2)
res4: Boolean = false

scala> value1
res5: chisel3.Bool = Bool(true)

scala> value2
res6: chisel3.Bool = Bool(true)

Is it normal ?

Note: I tried to use the hardware equality === without success :

scala> value1 === value2
chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
  at chisel3.internal.throwException$.apply(Error.scala:155)
  at chisel3.internal.Builder$.forcedUserModule(Builder.scala:494)
  at chisel3.internal.Builder$.pushOp(Builder.scala:558)
  at chisel3.Bits.compop(Bits.scala:206)
  at chisel3.UInt.do_$eq$eq$eq(Bits.scala:617)
  at .$anonfun$res1$2(<console>:17)
  at chisel3.internal.prefix$.apply(prefix.scala:49)
  at .$anonfun$res1$1(<console>:17)
  at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:52)
  ... 31 elided

scala> 

Is it a bug or a normal behavior ?

I need to compare some Bool() values in my tester2 testbench.

2

There are 2 answers

0
Jack Koenig On BEST ANSWER

The short answer is that while we probably should make equality work as one might expect for literals, it is not as clear cut a decision as one might think.

Thinking about Chisel's primary purpose as a hardware generator language, writing Chisel is fundamentally metaprogramming where we have to reason about two different phases: Chisel elaboration time (aka Scala run-time), and the actual hardware you're generating that is used in simulation and synthesis.

== returns a Scala Boolean so it only makes sense at elaboration time and means nothing to the resulting Verilog. Chisel provides === which returns a chisel3.Bool which is a hardware value that will show up in the Verilog.

Thinking in terms of Wires and Regs, == doesn't really make sense because these hardware components don't have statically knowable values during elaboration time. Thus in Chisel3, == is implemented a referential equality, ie. it is true only if the two objects are the exact same object.

Now as I said at the beginning, there is an argument that we should make == work for literals at least, even if it won't work for hardware components like Wires. It's not 100% clear if this is the right move because it could confuse people that sometimes they use == (only with literals) and sometimes they use === (with everything else). Because of testing libraries like chiseltest, I tend to agree that we should make == work for literals, but I just want to note that there is disagreement on this point.

0
FabienM On

The solution I found to use equality is to use .litValue:

scala> value1.litValue == value2.litValue
res2: Boolean = true

But it remain a strange behavior.