hdl.ast: prohibit shifts by signed value.

These are not desirable in a HDL, and currently elaborate to broken
RTLIL (after YosysHQ/yosys#1551); prohibit them completely, like
we already do for division and modulo.

Fixes #302.
This commit is contained in:
whitequark 2020-02-01 23:04:25 +00:00
parent cce6b8687b
commit 49758a3a0c
4 changed files with 32 additions and 10 deletions

View file

@ -362,15 +362,27 @@ class OperatorTestCase(FHDLTestCase):
v1 = Const(1, 4) << Const(4)
self.assertEqual(repr(v1), "(<< (const 4'd1) (const 3'd4))")
self.assertEqual(v1.shape(), unsigned(11))
v2 = Const(1, 4) << Const(-3)
self.assertEqual(v2.shape(), unsigned(7))
def test_shl_wrong(self):
with self.assertRaises(NotImplementedError,
msg="Shift by a signed value is not supported"):
1 << Const(0, signed(6))
with self.assertRaises(NotImplementedError,
msg="Shift by a signed value is not supported"):
Const(1, unsigned(4)) << -1
def test_shr(self):
v1 = Const(1, 4) >> Const(4)
self.assertEqual(repr(v1), "(>> (const 4'd1) (const 3'd4))")
self.assertEqual(v1.shape(), unsigned(4))
v2 = Const(1, 4) >> Const(-3)
self.assertEqual(v2.shape(), unsigned(8))
def test_shr_wrong(self):
with self.assertRaises(NotImplementedError,
msg="Shift by a signed value is not supported"):
1 << Const(0, signed(6))
with self.assertRaises(NotImplementedError,
msg="Shift by a signed value is not supported"):
Const(1, unsigned(4)) << -1
def test_lt(self):
v = Const(0, 4) < Const(0, 6)

View file

@ -116,13 +116,11 @@ class SimulatorUnitTestCase(FHDLTestCase):
stmt = lambda y, a, b: y.eq(a << b)
self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 5))
self.assertStatement(stmt, [C(0b1001, 4), C(3)], C(0b1001000, 7))
self.assertStatement(stmt, [C(0b1001, 4), C(-2)], C(0b10, 7))
def test_shr(self):
stmt = lambda y, a, b: y.eq(a >> b)
self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 4))
self.assertStatement(stmt, [C(0b1001, 4), C(2)], C(0b10, 4))
self.assertStatement(stmt, [C(0b1001, 4), C(-2)], C(0b100100, 5))
def test_eq(self):
stmt = lambda y, a, b: y.eq(a == b)