Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ ipynb-examples/.ipynb_checkpoints

# VS Code
.vscode

# Python venv
pyvenv.cfg
16 changes: 10 additions & 6 deletions pyrtl/helperfuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,11 +795,20 @@ def _convert_verilog_str(val: str, bitwidth: int = None,
if val.startswith('-'):
neg = True
val = val[1:]

split_string = val.lower().split("'")
if len(split_string) != 2:
raise PyrtlError('error, string not in verilog style format')
try:
bitwidth = int(split_string[0])
if passed_bitwidth is not None:
if bitwidth > passed_bitwidth:
raise PyrtlError(
"bitwidth parameter passed (%d) cannot fit Verilog-style constant with bitwidth %d"
% (passed_bitwidth, bitwidth)
)
bitwidth = passed_bitwidth

sval = split_string[1]
if sval[0] == 's':
raise PyrtlError('error, signed integers are not supported in verilog-style constants')
Expand All @@ -811,17 +820,12 @@ def _convert_verilog_str(val: str, bitwidth: int = None,
num = int(sval, base)
except (IndexError, ValueError):
raise PyrtlError('error, string not in verilog style format')

if neg and num:
if (num >> bitwidth - 1):
raise PyrtlError('error, insufficient bits for negative number')
num = (1 << bitwidth) - num

if passed_bitwidth and passed_bitwidth != bitwidth:
raise PyrtlError('error, bitwidth parameter of constant does not match'
' the bitwidth infered from the verilog style specification'
' (if bitwidth=None is used, pyrtl will determine the bitwidth from the'
' verilog-style constant specification)')

if num >> bitwidth != 0:
raise PyrtlError('specified bitwidth %d for verilog constant insufficient to store value %d'
% (bitwidth, num))
Expand Down
8 changes: 6 additions & 2 deletions pyrtl/wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,11 +852,15 @@ def __init__(self, bitwidth: int, name: str = '', reset_value: int = None,
super(Register, self).__init__(bitwidth=bitwidth, name=name, block=block)
self.reg_in = None # wire vector setting self.next
if reset_value is not None:
reset_value, rst_bitwidth = infer_val_and_bitwidth(reset_value)
reset_value, rst_bitwidth = infer_val_and_bitwidth(
reset_value,
bitwidth=bitwidth,
)
if rst_bitwidth > bitwidth:
raise PyrtlError(
'reset_value "%s" cannot fit in the specified %d bits for this register'
% (str(reset_value), bitwidth))
% (str(reset_value), bitwidth)
)
self.reset_value = reset_value

@property
Expand Down
30 changes: 27 additions & 3 deletions tests/test_wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,38 @@ def test_reset_value_as_string(self):
self.assertEqual(r.reset_value, 1)

def test_invalid_reset_value_too_large(self):
with self.assertRaisesRegex(pyrtl.PyrtlError, "cannot fit in the specified"):
with self.assertRaises(pyrtl.PyrtlError):
r = pyrtl.Register(4, reset_value=16)

def test_invalid_reset_value_too_large_as_string(self):
with self.assertRaisesRegex(pyrtl.PyrtlError, "cannot fit in the specified"):
with self.assertRaises(pyrtl.PyrtlError):
r = pyrtl.Register(4, reset_value="5'd16")

def test_negative_reset_value(self):
r = pyrtl.Register(4, reset_value=-4)
self.assertEqual(
pyrtl.helperfuncs.val_to_signed_integer(r.reset_value, r.bitwidth),
-4
)

def test_negative_reset_value_as_string(self):
r = pyrtl.Register(4, reset_value="-4'd1")
self.assertEqual(
pyrtl.helperfuncs.val_to_signed_integer(r.reset_value, r.bitwidth),
-1
)

def test_invalid_negative_reset_value_as_string(self):
with self.assertRaises(pyrtl.PyrtlError):
r = pyrtl.Register(2, reset_value="-4'd1")

def test_extending_negative_reset_value_as_string(self):
r = pyrtl.Register(4, reset_value="-3'd3")
self.assertEqual(
pyrtl.helperfuncs.val_to_signed_integer(r.reset_value, r.bitwidth),
-3
)

def test_invalid_reset_value_not_an_integer(self):
with self.assertRaises(pyrtl.PyrtlError):
r = pyrtl.Register(4, reset_value='hello')
Expand Down Expand Up @@ -345,7 +370,6 @@ def test_bad_string(self):
self.assert_bad_const("5'b111111'")
self.assert_bad_const("'")
self.assert_bad_const("'1")
self.assert_bad_const("2'b01", bitwidth=3)
self.assert_bad_const("1'")

def test_bool(self):
Expand Down
Loading