Skip to content

Commit fc93887

Browse files
committed
adding a way to supply field_map to bitpattern_to_val
1 parent 4f6ff02 commit fc93887

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

pyrtl/helperfuncs.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,6 @@ def field_name(name):
266266
return MatchedFields(match, fields)
267267

268268

269-
# TODO: not currently tested or exported at package level
270269
def bitpattern_to_val(bitpattern, *ordered_fields, **named_fields):
271270
""" Return an unsigned integer representation of field format filled with the provided values.
272271
@@ -275,6 +274,9 @@ def bitpattern_to_val(bitpattern, *ordered_fields, **named_fields):
275274
the order provided. If ordered_fields are provided then no named_fields can be used.
276275
:param named_fields: A list of parameters to be matched to the provided bit pattern in
277276
by the names provided. If named_fields are provided then no ordered_fields can be used.
277+
A special keyword argument, 'field_map', can be provided, which will allow you specify
278+
a correspondence between the 1-letter field names in the bitpattern string and longer,
279+
human readable field names (see example below).
278280
:return: An unsigned integer carrying the result of the field substitution.
279281
280282
This function will compare take a specified pattern of bits, where some
@@ -285,14 +287,24 @@ def bitpattern_to_val(bitpattern, *ordered_fields, **named_fields):
285287
creating values for testing when the resulting values will be "chopped" up by the hardware
286288
later (e.g. instruction decode or other bitfield heavy functions).
287289
290+
If a special keyword argument, 'field_map', is provided, then the named fields provided
291+
can be longer, human-readable field names, which will correspond to the field in the
292+
bitpattern according to the field_map. See the third example below.
293+
288294
Examples::
289295
290-
bitpattern_to_val('0000000rrrrrsssss000ddddd0110011', r=1, s=2, d=3) # RISCV ADD instr
296+
bitpattern_to_val('0000000sssssrrrrr000ddddd0110011', s=2, r=1, d=3) # RISCV ADD instr
291297
# evaluates to 0b00000000000100010000000110110011
292298
293-
bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', i=1, r=3, s=4) # RISCV SW instr
299+
bitpattern_to_val('iiiiiiisssssrrrrr010iiiii0100011', i=1, s=4, r=3) # RISCV SW instr
294300
# evaluates to 0b00000000001100100010000010100011
295301
302+
bitpattern_to_val(
303+
'iiiiiiisssssrrrrr010iiiii0100011',
304+
imm=1, rs2=4, rs1=3,
305+
field_map={'i': 'imm', 's': 'rs2', 'r': 'rs1}
306+
) # RISCV SW instr
307+
# evaluates to 0b00000000001100100010000010100011
296308
"""
297309

298310
if len(ordered_fields) > 0 and len(named_fields) > 0:
@@ -305,6 +317,11 @@ def letters_in_field_order():
305317
seen.append(c)
306318
return seen
307319

320+
field_map = None
321+
if 'field_map' in named_fields:
322+
field_map = named_fields['field_map']
323+
named_fields.pop('field_map')
324+
308325
bitlist = []
309326
lifo = letters_in_field_order()
310327
if ordered_fields:
@@ -315,7 +332,9 @@ def letters_in_field_order():
315332
if len(lifo) != len(named_fields):
316333
raise PyrtlError('number of fields and number of unique patterns do not match')
317334
try:
318-
intfields = [int(named_fields[n]) for n in lifo]
335+
def fn(n):
336+
return field_map[n] if field_map else n
337+
intfields = [int(named_fields[fn(n)]) for n in lifo]
319338
except KeyError as e:
320339
raise PyrtlError('bitpattern field %s was not provided in named_field list' % e.args[0])
321340

tests/test_helperfuncs.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,44 +361,65 @@ def r5_br_immed(x):
361361

362362
def test_ordered_fields(self):
363363
self.assertEqual(
364-
pyrtl.bitpattern_to_val('0000000rrrrrsssss000ddddd0110011', 1, 2, 3), # RISC-V ADD
364+
pyrtl.bitpattern_to_val('0000000sssssrrrrr000ddddd0110011', 1, 2, 3), # RISC-V ADD
365365
0b00000000000100010000000110110011
366366
)
367367

368368
self.assertEqual(
369-
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', 1, 3, 4), # RISC-V SW
369+
pyrtl.bitpattern_to_val('iiiiiiisssssrrrrr010iiiii0100011', 1, 3, 4), # RISC-V SW
370370
0b00000000001100100010000010100011
371371
)
372372

373373
m = TestBitpatternToVal.r5_br_immed(-5)
374374
self.assertEqual(
375375
pyrtl.bitpattern_to_val(
376-
'ijjjjjjrrrrrsssss100jjjjk1100011', m['i'], m['j'], 2, 3, m['k']
376+
'ijjjjjjsssssrrrrr100jjjjk1100011', m['i'], m['j'], 2, 3, m['k']
377377
), # RISC-V BLT
378378
0b11111110001000011100101111100011
379379
)
380380

381381
def test_named_fields(self):
382382
self.assertEqual(
383383
pyrtl.bitpattern_to_val(
384-
'0000000rrrrrsssss000ddddd0110011', r=1, s=2, d=3
384+
'0000000sssssrrrrr000ddddd0110011', s=1, r=2, d=3
385385
), # RISC-V ADD
386386
0b00000000000100010000000110110011
387387
)
388388

389389
self.assertEqual(
390-
pyrtl.bitpattern_to_val('iiiiiiirrrrrsssss010iiiii0100011', i=1, r=3, s=4), # RISC-V SW
390+
pyrtl.bitpattern_to_val('iiiiiiisssssrrrrr010iiiii0100011', i=1, s=3, r=4), # RISC-V SW
391391
0b00000000001100100010000010100011
392392
)
393393

394394
self.assertEqual(
395395
pyrtl.bitpattern_to_val(
396-
'ijjjjjjrrrrrsssss100jjjjk1100011',
397-
r=2, s=3, **TestBitpatternToVal.r5_br_immed(-5)
396+
'ijjjjjjsssssrrrrr100jjjjk1100011',
397+
s=2, r=3, **TestBitpatternToVal.r5_br_immed(-5)
398398
), # RISC-V BLT
399399
0b11111110001000011100101111100011
400400
)
401401

402+
def test_named_fields_with_field_map(self):
403+
field_map = {
404+
's': 'rs2',
405+
'r': 'rs1',
406+
'd': 'rd',
407+
'i': 'imm',
408+
}
409+
self.assertEqual(
410+
pyrtl.bitpattern_to_val(
411+
'0000000sssssrrrrr000ddddd0110011', rs2=1, rs1=2, rd=3, field_map=field_map
412+
), # RISC-V ADD
413+
0b00000000000100010000000110110011
414+
)
415+
416+
self.assertEqual(
417+
pyrtl.bitpattern_to_val(
418+
'iiiiiiisssssrrrrr010iiiii0100011', imm=1, rs2=3, rs1=4, field_map=field_map
419+
), # RISC-V SW
420+
0b00000000001100100010000010100011
421+
)
422+
402423
def test_fields_all_different(self):
403424
self.assertEqual(
404425
pyrtl.bitpattern_to_val('abcdefg', a=1, b=0, c=1, d=0, e=0, f=1, g=0),

0 commit comments

Comments
 (0)