diff --git a/src/peakrdl_regblock/addr_decode.py b/src/peakrdl_regblock/addr_decode.py index 684d1b6..9c14f17 100644 --- a/src/peakrdl_regblock/addr_decode.py +++ b/src/peakrdl_regblock/addr_decode.py @@ -78,16 +78,12 @@ class DecodeStructGenerator(RDLStructGenerator): ) def enter_Addrmap(self, node: 'AddrmapNode') -> Optional[WalkerAction]: - if node.external: - self._enter_external_block(node) - return WalkerAction.SkipDescendants - super().enter_Addrmap(node) - return WalkerAction.Continue + assert node.external + self._enter_external_block(node) + return WalkerAction.SkipDescendants def exit_Addrmap(self, node: 'AddrmapNode') -> None: - if node.external: - return - super().exit_Addrmap(node) + assert node.external def enter_Regfile(self, node: 'RegfileNode') -> Optional[WalkerAction]: if node.external: @@ -102,16 +98,12 @@ class DecodeStructGenerator(RDLStructGenerator): super().exit_Regfile(node) def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: - if node.external: - self._enter_external_block(node) - return WalkerAction.SkipDescendants - super().enter_Mem(node) - return WalkerAction.Continue + assert node.external + self._enter_external_block(node) + return WalkerAction.SkipDescendants def exit_Mem(self, node: 'MemNode') -> None: - if node.external: - return - super().exit_Mem(node) + assert node.external def enter_Reg(self, node: 'RegNode') -> None: # if register is "wide", expand the strobe to be able to access the sub-words diff --git a/src/peakrdl_regblock/hwif/generators.py b/src/peakrdl_regblock/hwif/generators.py index f67dac7..7127d34 100644 --- a/src/peakrdl_regblock/hwif/generators.py +++ b/src/peakrdl_regblock/hwif/generators.py @@ -74,10 +74,9 @@ class InputStructGenerator_Hier(HWIFStructGenerator): def enter_Addrmap(self, node: 'AddrmapNode') -> None: super().enter_Addrmap(node) - if node.external: - self._add_external_block_members(node) - return WalkerAction.SkipDescendants - return WalkerAction.Continue + assert node.external + self._add_external_block_members(node) + return WalkerAction.SkipDescendants def enter_Regfile(self, node: 'RegfileNode') -> None: super().enter_Regfile(node) @@ -88,10 +87,9 @@ class InputStructGenerator_Hier(HWIFStructGenerator): def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: super().enter_Mem(node) - if node.external: - self._add_external_block_members(node) - return WalkerAction.SkipDescendants - return WalkerAction.Continue + assert node.external + self._add_external_block_members(node) + return WalkerAction.SkipDescendants def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: super().enter_Reg(node) @@ -170,10 +168,9 @@ class OutputStructGenerator_Hier(HWIFStructGenerator): def enter_Addrmap(self, node: 'AddrmapNode') -> None: super().enter_Addrmap(node) - if node.external: - self._add_external_block_members(node) - return WalkerAction.SkipDescendants - return WalkerAction.Continue + assert node.external + self._add_external_block_members(node) + return WalkerAction.SkipDescendants def enter_Regfile(self, node: 'RegfileNode') -> None: super().enter_Regfile(node) @@ -184,10 +181,9 @@ class OutputStructGenerator_Hier(HWIFStructGenerator): def enter_Mem(self, node: 'MemNode') -> Optional[WalkerAction]: super().enter_Mem(node) - if node.external: - self._add_external_block_members(node) - return WalkerAction.SkipDescendants - return WalkerAction.Continue + assert node.external + self._add_external_block_members(node) + return WalkerAction.SkipDescendants def enter_Reg(self, node: 'RegNode') -> Optional[WalkerAction]: super().enter_Reg(node) diff --git a/tests/test_buffered_swacc_swmod/__init__.py b/tests/test_buffered_swacc_swmod/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_buffered_swacc_swmod/regblock.rdl b/tests/test_buffered_swacc_swmod/regblock.rdl new file mode 100644 index 0000000..4b0d82f --- /dev/null +++ b/tests/test_buffered_swacc_swmod/regblock.rdl @@ -0,0 +1,31 @@ +addrmap top { + default regwidth = 16; + default accesswidth = 8; + + reg { + buffer_reads; + field { + sw=r; hw=w; + swacc; + } f[16]; + } r1; + + reg { + buffer_reads; + buffer_writes; + field { + sw=rw; hw=r; + swmod; + } f[16] = 0x4020; + } r2; + + reg { + buffer_reads; + buffer_writes; + field { + sw=rw; hw=r; + swmod; + rclr; + } f[16] = 0x1030; + } r3; +}; diff --git a/tests/test_buffered_swacc_swmod/tb_template.sv b/tests/test_buffered_swacc_swmod/tb_template.sv new file mode 100644 index 0000000..897b788 --- /dev/null +++ b/tests/test_buffered_swacc_swmod/tb_template.sv @@ -0,0 +1,96 @@ +{% extends "lib/tb_base.sv" %} + +{% block seq %} + {% sv_line_anchor %} + logic [15:0] counter; + logic [7:0] rd_data_l; + logic [7:0] rd_data_h; + logic [15:0] latched_data; + int event_count; + latched_data = 'x; + + ##1; + cb.rst <= '0; + ##1; + + // Verify that hwif gets sampled at the same cycle as swacc strobe + counter = 'h10; + cb.hwif_in.r1.f.next <= counter; + @cb; + event_count = 0; + fork + begin + ##0; + forever begin + counter++; + cb.hwif_in.r1.f.next <= counter; + @cb; + if(cb.hwif_out.r1.f.swacc) begin + latched_data = counter; + event_count++; + end + end + end + + begin + cpuif.read('h0, rd_data_l); + cpuif.read('h1, rd_data_h); + @cb; + end + join_any + disable fork; + assert({rd_data_h, rd_data_l} == latched_data) else $error("Read returned 0x%0x but swacc strobed during 0x%0x", {rd_data_h, rd_data_l}, latched_data); + assert(event_count == 1) else $error("Observed excess swacc events: %0d", event_count); + + + // Verify that hwif changes 1 cycle after swmod + fork + begin + ##0; + forever begin + assert(cb.hwif_out.r2.f.value == 'h4020); + if(cb.hwif_out.r2.f.swmod) break; + @cb; + end + @cb; + forever begin + assert(cb.hwif_out.r2.f.value == 'h4221); + assert(cb.hwif_out.r2.f.swmod == 0); + @cb; + end + end + + begin + cpuif.write('h2, 'h21); + cpuif.write('h3, 'h42); + @cb; + end + join_any + disable fork; + + // Verify that hwif changes 1 cycle after swmod + fork + begin + ##0; + forever begin + assert(cb.hwif_out.r3.f.value == 'h1030); + if(cb.hwif_out.r3.f.swmod) break; + @cb; + end + @cb; + forever begin + assert(cb.hwif_out.r3.f.value == 0); + assert(cb.hwif_out.r3.f.swmod == 0); + @cb; + end + end + + begin + cpuif.assert_read('h4, 'h30); + cpuif.assert_read('h5, 'h10); + @cb; + end + join_any + disable fork; + +{% endblock %} diff --git a/tests/test_buffered_swacc_swmod/testcase.py b/tests/test_buffered_swacc_swmod/testcase.py new file mode 100644 index 0000000..835b5ef --- /dev/null +++ b/tests/test_buffered_swacc_swmod/testcase.py @@ -0,0 +1,5 @@ +from ..lib.sim_testcase import SimTestCase + +class Test(SimTestCase): + def test_dut(self): + self.run_test()