-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests for blocking & deferring fields + fixes
- Loading branch information
1 parent
b8cf2f9
commit 2b228d5
Showing
10 changed files
with
456 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
test: | ||
- prot + hardening | ||
- register boilerplate logic: | ||
- blocking | ||
- deferral | ||
- errors | ||
- the above in the presence of multiple fields | ||
- field logic for every behavior class |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
"""Test blocking fields.""" | ||
|
||
from unittest import TestCase | ||
from ..testbench import RegisterFileTestbench | ||
|
||
class TestBlocking(TestCase): | ||
"""Test blocking fields.""" | ||
|
||
def test_block_normal(self): | ||
"""test blocking + normal field""" | ||
rft = RegisterFileTestbench({ | ||
'metadata': {'name': 'test'}, | ||
'fields': [ | ||
{ | ||
'address': 0, | ||
'bitrange': '15..0', | ||
'name': 'a', | ||
'behavior': 'custom', | ||
'interfaces': [{'state': 'count:4'}], | ||
'read-can-block': True, | ||
'read': ( | ||
'if $s.count$ = "1111" then\n' | ||
' $ack$ := true;\n' | ||
' $data$ := X"5678";\n' | ||
'else\n' | ||
' $block$ := true;\n' | ||
'end if;\n' | ||
'$s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n' | ||
) | ||
}, | ||
{ | ||
'address': 0, | ||
'bitrange': '31..16', | ||
'name': 'b', | ||
'behavior': 'constant', | ||
'value': 0x1234, | ||
} | ||
]}) | ||
self.assertEqual(rft.ports, ('bus',)) | ||
with rft as objs: | ||
start = rft.testbench.cycle | ||
self.assertEqual(objs.bus.read(0), 0x12345678) | ||
self.assertEqual(rft.testbench.cycle - start, 17) | ||
|
||
def test_block_error(self): | ||
"""test blocking + error field""" | ||
rft = RegisterFileTestbench({ | ||
'metadata': {'name': 'test'}, | ||
'fields': [ | ||
{ | ||
'address': 0, | ||
'bitrange': '15..0', | ||
'name': 'a', | ||
'behavior': 'custom', | ||
'interfaces': [{'state': 'count:4'}], | ||
'read-can-block': True, | ||
'read': ( | ||
'if $s.count$ = "1111" then\n' | ||
' $ack$ := true;\n' | ||
' $data$ := X"5678";\n' | ||
'else\n' | ||
' $block$ := true;\n' | ||
'end if;\n' | ||
'$s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n' | ||
) | ||
}, | ||
{ | ||
'address': 0, | ||
'bitrange': '31..16', | ||
'name': 'b', | ||
'behavior': 'primitive', | ||
'bus-read': 'error', | ||
} | ||
]}) | ||
self.assertEqual(rft.ports, ('bus',)) | ||
with rft as objs: | ||
start = rft.testbench.cycle | ||
with self.assertRaisesRegex(ValueError, 'slave'): | ||
objs.bus.read(0) | ||
self.assertEqual(rft.testbench.cycle - start, 17) | ||
|
||
def test_block_block(self): | ||
"""test blocking + blocking field""" | ||
msg = (r'cannot have more than one blocking field in a ' | ||
r'single register \(`A0` and `A1`\)') | ||
with self.assertRaisesRegex(Exception, msg): | ||
RegisterFileTestbench({ | ||
'metadata': {'name': 'test'}, | ||
'fields': [ | ||
{ | ||
'address': 0, | ||
'bitrange': '15..0', | ||
'repeat': 2, | ||
'name': 'a', | ||
'behavior': 'custom', | ||
'interfaces': [{'state': 'count:4'}], | ||
'read-can-block': True, | ||
'read': ( | ||
'if $s.count$ = "1111" then\n' | ||
' $ack$ := true;\n' | ||
' $data$ := X"5678";\n' | ||
'else\n' | ||
' $block$ := true;\n' | ||
'end if;\n' | ||
'$s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n' | ||
) | ||
}, | ||
]}) | ||
|
||
def test_block_volatile(self): | ||
"""test blocking + volatile field""" | ||
msg = (r'cannot have both volatile fields \(`B`\) and blocking ' | ||
r'fields \(`A`\) in a single register') | ||
with self.assertRaisesRegex(Exception, msg): | ||
RegisterFileTestbench({ | ||
'metadata': {'name': 'test'}, | ||
'fields': [ | ||
{ | ||
'address': 0, | ||
'bitrange': '15..0', | ||
'name': 'a', | ||
'behavior': 'custom', | ||
'interfaces': [{'state': 'count:4'}], | ||
'read-can-block': True, | ||
'read': ( | ||
'if $s.count$ = "1111" then\n' | ||
' $ack$ := true;\n' | ||
' $data$ := X"5678";\n' | ||
'else\n' | ||
' $block$ := true;\n' | ||
'end if;\n' | ||
'$s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n' | ||
) | ||
}, | ||
{ | ||
'address': 0, | ||
'bitrange': '31..16', | ||
'name': 'b', | ||
'behavior': 'primitive', | ||
'bus-read': 'enabled', | ||
'after-bus-read': 'increment', | ||
} | ||
]}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
"""Test deferring fields.""" | ||
|
||
from unittest import TestCase | ||
from ..testbench import RegisterFileTestbench | ||
|
||
class TestDefer(TestCase): | ||
"""Test deferring fields.""" | ||
|
||
def test_read_defer(self): | ||
"""test read-deferring fields""" | ||
rft = RegisterFileTestbench({ | ||
'metadata': {'name': 'test'}, | ||
'fields': [ | ||
{ | ||
'address': 0, | ||
'repeat': 4, | ||
'field-repeat': 1, | ||
'name': 'a', | ||
'behavior': 'custom', | ||
'interfaces': [{'state': 'count:3'}, {'state': 'data:32'}, {'state': 'busy'}], | ||
'read-can-block': True, | ||
'read-request': ( | ||
'if $s.busy$ = \'1\' then\n' | ||
' if $resp_ready$ then\n' | ||
' $block$ := true;\n' | ||
' end if;\n' | ||
'else\n' | ||
' $s.busy$ := \'1\';\n' | ||
' $defer$ := true;\n' | ||
'end if;\n' | ||
), | ||
'read-response': ( | ||
'if $s.count$ = "111" then\n' | ||
' $ack$ := true;\n' | ||
' $data$ := $s.data$;\n' | ||
' $s.data$ := std_logic_vector(unsigned($s.data$) + 1);\n' | ||
' $s.busy$ := \'0\';\n' | ||
'else\n' | ||
' $block$ := true;\n' | ||
'end if;\n' | ||
), | ||
'post-access': ( | ||
'if $s.busy$ = \'1\' then\n' | ||
' if $s.count$ /= "111" then\n' | ||
' $s.count$ := std_logic_vector(unsigned($s.count$) + 1);\n' | ||
' end if;\n' | ||
'else\n' | ||
' $s.count$ := "000";\n' | ||
'end if;\n' | ||
), | ||
}, | ||
]}) | ||
self.assertEqual(rft.ports, ('bus',)) | ||
with rft as objs: | ||
start = rft.testbench.cycle | ||
self.assertEqual(objs.bus.read(0), 0) | ||
self.assertEqual(rft.testbench.cycle - start, 9) | ||
|
||
start = rft.testbench.cycle | ||
responses = [] | ||
def callback(data, _): | ||
responses.append(int(data)) | ||
objs.bus.async_read(callback, 4) | ||
objs.bus.async_read(callback, 8) | ||
objs.bus.async_read(callback, 12) | ||
responses.append(objs.bus.read(0)) | ||
self.assertEqual(responses, [0, 0, 0, 1]) | ||
self.assertEqual(rft.testbench.cycle - start, 12) | ||
|
||
start = rft.testbench.cycle | ||
responses.clear() | ||
objs.bus.async_read(callback, 4) | ||
objs.bus.async_read(callback, 8) | ||
objs.bus.async_read(callback, 0) | ||
objs.bus.async_read(callback, 12) | ||
objs.bus.async_read(callback, 8) | ||
objs.bus.async_read(callback, 4) | ||
objs.bus.async_read(callback, 0) | ||
responses.append(objs.bus.read(0)) | ||
self.assertEqual(responses, [1, 1, 2, 1, 2, 2, 3, 4]) | ||
self.assertEqual(rft.testbench.cycle - start, 28) | ||
|
||
start = rft.testbench.cycle | ||
responses.clear() | ||
expected = [] | ||
for i in range(10): | ||
objs.bus.async_read(callback, 0) | ||
objs.bus.async_read(callback, 4) | ||
objs.bus.async_read(callback, 8) | ||
objs.bus.async_read(callback, 12) | ||
expected.extend([5+i, 3+i, 3+i, 2+i]) | ||
responses.append(objs.bus.read(0)) | ||
expected.append(15) | ||
self.assertEqual(responses, expected) | ||
self.assertEqual(rft.testbench.cycle - start, 89) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.