Skip to content

Commit 964e9ae

Browse files
committed
adding tests for bitpattern_to_val
1 parent cade7f7 commit 964e9ae

File tree

3 files changed

+94
-4
lines changed

3 files changed

+94
-4
lines changed

pyrtl/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .helperfuncs import log2
2929
from .helperfuncs import truncate
3030
from .helperfuncs import match_bitpattern
31+
from .helperfuncs import bitpattern_to_val
3132
from .helperfuncs import chop
3233
from .helperfuncs import val_to_signed_integer
3334
from .helperfuncs import val_to_formatted_str

pyrtl/helperfuncs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,21 +316,21 @@ def letters_in_field_order():
316316
raise PyrtlError('number of fields and number of unique patterns do not match')
317317
try:
318318
intfields = [int(named_fields[n]) for n in lifo]
319-
except KeyError:
320-
raise PyrtlError('named field does not appear in bitpattern format string')
319+
except KeyError as e:
320+
raise PyrtlError('bitpattern field %s was not provided in named_field list' % e.args[0])
321321

322322
fmap = dict(zip(lifo, intfields))
323323
for c in bitpattern[::-1]:
324324
if c == '0' or c == '1':
325325
bitlist.append(c)
326326
elif c == '?':
327-
raise PyrtlError('all fields in must have names')
327+
raise PyrtlError('all fields in the bitpattern must have names')
328328
else:
329329
bitlist.append(str(fmap[c] & 0x1)) # append lsb of the field
330330
fmap[c] = fmap[c] >> 1 # and bit shift by one position
331331
for f in fmap:
332332
if fmap[f] not in [0, -1]:
333-
raise PyrtlError('too many bits given to value to fit in field')
333+
raise PyrtlError('too many bits given to value to fit in field %s' % f)
334334
if len(bitpattern) != len(bitlist):
335335
raise PyrtlInternalError('resulting values have different bitwidths')
336336
final_str = ''.join(bitlist[::-1])

tests/test_helperfuncs.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,95 @@ def test_match_bitwidth_with_pattern_matched_fields_with_bad_field_map(self):
350350
out |= x.field2
351351

352352

353+
class TestBitpatternToVal(unittest.TestCase):
354+
def setUp(self):
355+
pyrtl.reset_working_block()
356+
357+
@staticmethod
358+
def r5_br_immed(x):
359+
# i is the 12th bit, k is the 11th bit, and j is the bottom 10 bits of the immediate field
360+
return {'i': (x >> 11) & 0x1, 'k': (x >> 10) & 0x1, 'j': x & ((1 << 10) - 1)}
361+
362+
def test_ordered_fields(self):
363+
self.assertEqual(
364+
pyrtl.bitpattern_to_val('0000000rrrrrsssss000ddddd0110011', 1, 2, 3), # RISC-V ADD
365+
0b00000000000100010000000110110011
366+
)
367+
368+
self.assertEqual(
369+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', 1, 3, 4), # RISC-V SW
370+
0b00000000001100100010000010100011
371+
)
372+
373+
m = TestBitpatternToVal.r5_br_immed(-5)
374+
self.assertEqual(
375+
pyrtl.bitpattern_to_val(
376+
'ijjjjjjrrrrrsssss100jjjjk1100011', m['i'], m['j'], 2, 3, m['k']
377+
), # RISC-V BLT
378+
0b11111110001000011100101111100011
379+
)
380+
381+
def test_named_fields(self):
382+
self.assertEqual(
383+
pyrtl.bitpattern_to_val(
384+
'0000000rrrrrsssss000ddddd0110011', r=1, s=2, d=3
385+
), # RISC-V ADD
386+
0b00000000000100010000000110110011
387+
)
388+
389+
self.assertEqual(
390+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', i=1, r=3, s=4), # RISC-V SW
391+
0b00000000001100100010000010100011
392+
)
393+
394+
self.assertEqual(
395+
pyrtl.bitpattern_to_val(
396+
'ijjjjjjrrrrrsssss100jjjjk1100011',
397+
r=2, s=3, **TestBitpatternToVal.r5_br_immed(-5)
398+
), # RISC-V BLT
399+
0b11111110001000011100101111100011
400+
)
401+
402+
def test_fields_all_different(self):
403+
self.assertEqual(
404+
pyrtl.bitpattern_to_val('abcdefg', a=1, b=0, c=1, d=0, e=0, f=1, g=0),
405+
0b1010010
406+
)
407+
408+
def test_no_fields(self):
409+
self.assertEqual(
410+
pyrtl.bitpattern_to_val('1010010'),
411+
0b1010010
412+
)
413+
414+
def test_error_both_ordered_and_named_fields(self):
415+
with self.assertRaises(pyrtl.PyrtlError):
416+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', 1, r=3, s=4)
417+
418+
def test_error_invalid_num_unique_patterns(self):
419+
with self.assertRaises(pyrtl.PyrtlError):
420+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', 1, 3)
421+
with self.assertRaises(pyrtl.PyrtlError):
422+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', i=1, r=3)
423+
424+
def test_error_bitpattern_field_not_provided(self):
425+
with self.assertRaises(pyrtl.PyrtlError):
426+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', i=1, r=3, t=4)
427+
428+
def test_error_unnamed_fields_in_bitpattern(self):
429+
with self.assertRaises(pyrtl.PyrtlError):
430+
pyrtl.bitpattern_to_val('iiiiiii?????sssss010iiiii0100011', 1, 3, 4)
431+
432+
def test_error_value_doesnt_fit_in_field(self):
433+
with self.assertRaises(pyrtl.PyrtlError):
434+
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', 1, 65, 4)
435+
436+
@unittest.skip("This error might not be possible")
437+
def test_error_bitlist_and_value_different_sizes(self):
438+
with self.assertRaises(pyrtl.PyrtlError):
439+
pass
440+
441+
353442
class TestChop(unittest.TestCase):
354443
def setUp(self):
355444
random.seed(8492049)

0 commit comments

Comments
 (0)