You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is easy to make confusing mistakes with signed values in PyRTL. A broken example:
import pyrtl
a = -128
b = 127
# Compute a - b, which should be -255.
a_const = pyrtl.Const(name='a', val=a, signed=True, bitwidth=8)
b_const = pyrtl.Const(name='b', val=b, signed=True, bitwidth=8)
diff = a_const - b_const
diff.name = 'diff'
sim = pyrtl.Simulation()
sim.step()
print('expected diff is', a - b)
print('actual diff is',
pyrtl.val_to_signed_integer(sim.inspect('diff'), bitwidth=diff.bitwidth),
'bitwidth', diff.bitwidth)
When this example is run, it produces:
expected diff is -255
actual diff is 1 bitwidth 9
Note that the actual output has bitwidth 9, which is sufficient to represent -255.
This example is especially confusing because PyRTL has all the information to do the right thing, because we've marked the Consts as signed=True. To fix this example, the user currently has to call signed_sub instead of using the overloaded - operator.
The current approach is error prone because the user has to keep track of signed-ness as values propagate through their circuit, and make sure they call functions like signed_add and val_to_signed_integer at the right times.
It seems better to track signed-ness within WireVector, or within a WireVector subclass, but this raises questions about type promotion - what happens when we add a signed value and an unsigned value? My current intuition is to match Verilog's promotion behavior, but we should think about this more.
It is easy to make confusing mistakes with signed values in PyRTL. A broken example:
When this example is run, it produces:
Note that the actual output has bitwidth 9, which is sufficient to represent -255.
This example is especially confusing because PyRTL has all the information to do the right thing, because we've marked the
Const
s assigned=True
. To fix this example, the user currently has to callsigned_sub
instead of using the overloaded-
operator.The current approach is error prone because the user has to keep track of signed-ness as values propagate through their circuit, and make sure they call functions like
signed_add
andval_to_signed_integer
at the right times.It seems better to track signed-ness within WireVector, or within a WireVector subclass, but this raises questions about type promotion - what happens when we add a signed value and an unsigned value? My current intuition is to match Verilog's promotion behavior, but we should think about this more.
See also #417
The text was updated successfully, but these errors were encountered: