[go: up one dir, main page]

Skip to content

Commit

Permalink
Add test for custom regs with internals + bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanstraten committed Sep 2, 2019
1 parent 12b0acc commit 89f1e07
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
80 changes: 80 additions & 0 deletions tests/integration/test_custom_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,86 @@ def test_state(self):
self.assertEqual(objs.bus.read(0), 0xCCCCCCCC)
self.assertEqual(objs.bus.read(4), 0xBDBDBDBD)

def test_internals(self):
"""test custom field internal connectivity"""
rft = RegisterFileTestbench({
'metadata': {'name': 'test'},
'fields': [
{
'address': 0,
'bitrange': '2..0',
'name': 'a',
'behavior': 'custom',
'interfaces': [
{'drive': 'a:3'},
{'strobe': 'b:3'},
{'state': 'data:3'},
],
'write': (
'$s.data$ := $data$;\n'
'$ack$ := true;\n'
'$s.b$ := "111";\n'
),
'post-access': (
'$s.a$ := $s.data$;\n'
'if reset = \'1\' then'
' $s.data$ := "000";\n'
'end if;\n'
),
},
{
'address': 4,
'bitrange': 0,
'repeat': 3,
'name': 'b',
'behavior': 'custom',
'interfaces': [
{'monitor': 'a'},
{'strobe': 'b'},
],
'read': (
'$data$ := $s.a$;\n'
'$ack$ := true;\n'
'$s.b$ := \'1\';\n'
),
},
{
'address': 8,
'name': 'c',
'behavior': 'custom',
'interfaces': [
{'monitor': 'b:3'},
{'state': 'count:32'},
],
'pre-access': (
'if $s.b$(0) = \'1\' then'
' $s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n'
'end if;\n'
),
'read': (
'$data$ := $s.count$;\n'
'$ack$ := true;\n'
),
'post-access': (
'if reset = \'1\' then'
' $s.count$ := (others => \'0\');\n'
'end if;\n'
),
},
]})
with rft as objs:
self.assertEqual(objs.bus.read(8), 0)
self.assertEqual(objs.bus.read(4), 0)
self.assertEqual(objs.bus.read(8), 1)
objs.bus.write(0, 3)
self.assertEqual(objs.bus.read(8), 2)
self.assertEqual(objs.bus.read(4), 3)
self.assertEqual(objs.bus.read(8), 3)
objs.bus.write(0, 4)
self.assertEqual(objs.bus.read(8), 4)
self.assertEqual(objs.bus.read(4), 4)
self.assertEqual(objs.bus.read(8), 5)

def test_errors(self):
"""test custom field errors"""
msg = ('must support either or both read and write mode')
Expand Down
22 changes: 16 additions & 6 deletions vhdmmio/core/behavior/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ def __init__(self, resources, field_descriptor,
'repeated fields cannot %s a vector internal signal'
% kind)

# Internal signals are shaped based on the field repetition.
internal_shape = shape
internal_suffix = ''
if field_descriptor.is_vector():
internal_shape = field_descriptor.width
internal_suffix = '($i$)'

# Determine the VHDL type.
vhdl_type = None
if interface.type == 'natural':
Expand All @@ -91,18 +98,21 @@ def __init__(self, resources, field_descriptor,
elif kind == 'drive':
assert vhdl_type is None
internal = resources.internals.drive(
field_descriptor, name, shape)
internal_interfaces.append(internal, internal.drive_name)
field_descriptor, name, internal_shape)
internal_interfaces.append((
internal, internal.drive_name + internal_suffix))
elif kind == 'strobe':
assert vhdl_type is None
internal = resources.internals.strobe(
field_descriptor, name, shape)
internal_interfaces.append(internal, internal.drive_name)
field_descriptor, name, internal_shape)
internal_interfaces.append((
internal, internal.drive_name + internal_suffix))
elif kind == 'monitor':
assert vhdl_type is None
internal = resources.internals.use(
field_descriptor, name, shape)
internal_interfaces.append(internal, internal.use_name)
field_descriptor, name, internal_shape)
internal_interfaces.append((
internal, internal.use_name + internal_suffix))
elif kind == 'state':
assert vhdl_type is None
state.append((name, shape))
Expand Down
2 changes: 2 additions & 0 deletions vhdmmio/vhdl/behavior/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def generate(self):
# identifiers using `<object>.<ident>`.
class Identifiers: #pylint: disable=R0903
"""Storage object for VHDL identifiers."""
def __getattr__(self, attr):
raise ValueError('template object $s.%s$ does not exist' % attr)
identifiers = Identifiers()

# Construct the external interfaces.
Expand Down

0 comments on commit 89f1e07

Please sign in to comment.