Does m.when support chaining comparison operators?
Closed this issue · 2 comments
rkshthrmsh commented
Can comparison operators be chained in m.when
?
class Test(m.Circuit):
io = m.IO(
CLK=m.In(m.Clock),
load=m.In(m.Bit),
value=m.In(m.UInt[16]),
A=m.In(m.UInt[32]),
C=m.Out(m.Bit)
)
value = m.Register(m.UInt[16], has_enable=True)()(I=io.value, CE=io.load)
a = m.Register(m.UInt[32], has_enable=True)()(I=io.A, CE=io.load)
with m.when(1 < a < m.zext(value, 16)): # <-- Like this
io.C @= 1
with m.otherwise():
io.C @= 0
Traceback (most recent call last):
File "/home/giambla2/ws/magma_examples/magma_examples/test.py", line 253, in <module>
class Test(m.Circuit):
File "/home/giambla2/ws/magma_examples/magma_examples/test.py", line 266, in Test
with m.when(1 < a.O < m.zext(value, 16)):
File "/home/giambla2/.local/lib/python3.9/site-packages/magma/digital.py", line 233, in __bool__
raise ValueError(
ValueError: Converting non-constant magma bit to bool not supported
leonardt commented
This doesn't work because of how Python implements it under the hood.
It will turn an expression into the form 1 < a and a < value
, the problem is that in Python we can't override the and
operator (it invokes bool on the arguments and then does a logical and). Instead we'd want __and__
to be called (which is what happens when you call &
) which "stages" the computation and constructs the hardware graph.
So for this pattern you'll need to explicitly &
the two expressions rather than use the Python convenience syntax.
rkshthrmsh commented
Thanks for the explanation, @leonardt.