Skip to content

Commit 300a776

Browse files
committed
negative constants allowed in signed_mult and signed_add
1 parent e5ad017 commit 300a776

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

pyrtl/corecircuits.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ def signed_add(a, b):
167167
168168
Given a length n and length m wirevector the result of the
169169
signed addition is length max(n,m)+1. The inputs are twos
170-
complement sign extended to the same length before adding."""
170+
complement sign extended to the same length before adding.
171+
If an integer is passed to either a or b, it will be converted
172+
automatically to a two's complemented constant"""
173+
if isinstance(a, int):
174+
a = Const(a, signed=True)
175+
if isinstance(b, int):
176+
b = Const(b, signed=True)
171177
a, b = match_bitwidth(as_wires(a), as_wires(b), signed=True)
172178
result_len = len(a) + 1
173179
ext_a = a.sign_extended(result_len)
@@ -182,7 +188,19 @@ def mult_signed(a, b):
182188

183189

184190
def signed_mult(a, b):
185-
""" Return a*b where a and b are treated as signed values. """
191+
""" Return a*b where a and b are treated as signed values.
192+
193+
:param a: a wirevector to serve as first input to multiplication
194+
:param b: a wirevector to serve as second input to multiplication
195+
196+
If an integer is passed to either a or b, it will be converted
197+
automatically to a two's complemented constant"""
198+
# if an integer, convert to a two's complement constant
199+
if isinstance(a, int):
200+
a = Const(a, signed=True)
201+
if isinstance(b, int):
202+
b = Const(b, signed=True)
203+
# if not a wirevector yet, use standard conversion method
186204
a, b = as_wires(a), as_wires(b)
187205
final_len = len(a) + len(b)
188206
# sign extend both inputs to the final target length

tests/test_signed.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_basic_signed_gte(self):
127127
self.check_trace('o 0 0 0 0 0 1 1 1 \n')
128128

129129

130-
class TestSignedAddBasicOperations(unittest.TestCase):
130+
class TestSignedArithBasicOperations(unittest.TestCase):
131131
def setUp(self):
132132
pyrtl.reset_working_block()
133133
# test with '101' in binary, which should be
@@ -152,3 +152,38 @@ def test_basic_signed_add(self):
152152
self.o <<= pyrtl.signed_add(self.r, self.c)
153153
# 0 1 2 3 -4 -3 -2 -1
154154
self.check_trace('-3 -2 -1 0 -7 -6 -5 -4')
155+
156+
def test_basic_signed_add(self):
157+
self.o <<= pyrtl.signed_add(self.r, Const(-3, signed=True))
158+
self.check_trace('-3 -2 -1 0 -7 -6 -5 -4')
159+
160+
def test_basic_signed_add(self):
161+
self.o <<= pyrtl.signed_add(self.r, -3)
162+
self.check_trace('-3 -2 -1 0 -7 -6 -5 -4')
163+
164+
def test_basic_signed_mult(self):
165+
self.o <<= pyrtl.signed_mult(self.r, self.c)
166+
# 0 1 2 3 -4 -3 -2 -1
167+
self.check_trace('0 -3 -6 7 -4 -7 6 3')
168+
# the above numbers don't look like multiplication but when you sign
169+
# extend the inputs, truncate to the last 4 digits and then sign extend,
170+
# the output I assure that they are indeed correct. :)
171+
172+
def test_basic_signed_mult(self):
173+
self.o <<= pyrtl.signed_mult(self.r, pyrtl.Const(-2, bitwidth=3))
174+
# 0 1 2 3 -4 -3 -2 -1
175+
self.check_trace('0 -2 -4 -6 -8 6 4 2')
176+
# this one is multiplies by -2 and the trend is easier to see (-4 x -3 does
177+
# overflow the 4 bits though).
178+
179+
def test_basic_signed_mult(self):
180+
self.o <<= pyrtl.signed_mult(self.r, pyrtl.Const(-2, signed=True))
181+
self.check_trace('0 -2 -4 -6 -8 6 4 2')
182+
183+
def test_basic_signed_mult(self):
184+
self.o <<= pyrtl.signed_mult(self.r, -2)
185+
self.check_trace('0 -2 -4 -6 -8 6 4 2')
186+
187+
def test_basic_signed_mult(self):
188+
self.o <<= pyrtl.signed_mult(-2, self.r)
189+
self.check_trace('0 -2 -4 -6 -8 6 4 2')

0 commit comments

Comments
 (0)