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.
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 ScalaBoolean
so it only makes sense at elaboration time and means nothing to the resulting Verilog. Chisel provides===
which returns achisel3.Bool
which is a hardware value that will show up in the Verilog.Thinking in terms of
Wires
andRegs
,==
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 likeWires
. 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 likechiseltest
, I tend to agree that we should make==
work for literals, but I just want to note that there is disagreement on this point.