Omit unecessary hwif signals if an external register is read-only or write-only. #58
This commit is contained in:
@@ -184,7 +184,16 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
|
||||
s = f"{self.addr_decode.get_access_strobe(node)} = {rhs};"
|
||||
self.add_content(s)
|
||||
if node.external:
|
||||
self.add_content(f"is_external |= {rhs};")
|
||||
readable = node.has_sw_readable
|
||||
writable = node.has_sw_writable
|
||||
if readable and writable:
|
||||
self.add_content(f"is_external |= {rhs};")
|
||||
elif readable and not writable:
|
||||
self.add_content(f"is_external |= {rhs} & !cpuif_req_is_wr;")
|
||||
elif not readable and writable:
|
||||
self.add_content(f"is_external |= {rhs} & cpuif_req_is_wr;")
|
||||
else:
|
||||
raise RuntimeError
|
||||
else:
|
||||
# Register is wide. Create a substrobe for each subword
|
||||
n_subwords = regwidth // accesswidth
|
||||
@@ -194,7 +203,16 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
|
||||
s = f"{self.addr_decode.get_access_strobe(node)}[{i}] = {rhs};"
|
||||
self.add_content(s)
|
||||
if node.external:
|
||||
self.add_content(f"is_external |= {rhs};")
|
||||
readable = node.has_sw_readable
|
||||
writable = node.has_sw_writable
|
||||
if readable and writable:
|
||||
self.add_content(f"is_external |= {rhs};")
|
||||
elif readable and not writable:
|
||||
self.add_content(f"is_external |= {rhs} & !cpuif_req_is_wr;")
|
||||
elif not readable and writable:
|
||||
self.add_content(f"is_external |= {rhs} & cpuif_req_is_wr;")
|
||||
else:
|
||||
raise RuntimeError
|
||||
|
||||
def exit_AddressableComponent(self, node: 'AddressableNode') -> None:
|
||||
super().exit_AddressableComponent(node)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from systemrdl.walker import WalkerAction
|
||||
from systemrdl.node import RegNode
|
||||
|
||||
from .forloop_generator import RDLForLoopGenerator
|
||||
|
||||
@@ -24,7 +25,8 @@ class ExternalWriteAckGenerator(RDLForLoopGenerator):
|
||||
super().enter_AddressableComponent(node)
|
||||
|
||||
if node.external:
|
||||
self.add_content(f"wr_ack |= {self.exp.hwif.get_external_wr_ack(node)};")
|
||||
if not isinstance(node, RegNode) or node.has_sw_writable:
|
||||
self.add_content(f"wr_ack |= {self.exp.hwif.get_external_wr_ack(node)};")
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
@@ -45,7 +47,8 @@ class ExternalReadAckGenerator(RDLForLoopGenerator):
|
||||
super().enter_AddressableComponent(node)
|
||||
|
||||
if node.external:
|
||||
self.add_content(f"rd_ack |= {self.exp.hwif.get_external_rd_ack(node)};")
|
||||
if not isinstance(node, RegNode) or node.has_sw_readable:
|
||||
self.add_content(f"rd_ack |= {self.exp.hwif.get_external_rd_ack(node)};")
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
|
||||
@@ -347,6 +347,8 @@ class FieldLogicGenerator(RDLForLoopGenerator):
|
||||
bslice = ""
|
||||
|
||||
context = {
|
||||
"has_sw_writable": node.has_sw_writable,
|
||||
"has_sw_readable": node.has_sw_readable,
|
||||
"prefix": prefix,
|
||||
"strb": strb,
|
||||
"bslice": bslice,
|
||||
|
||||
@@ -5,13 +5,23 @@ always_ff {{get_always_ff_event(resetsignal)}} begin
|
||||
if({{get_resetsignal(resetsignal)}}) begin
|
||||
{{prefix}}.req <= '0;
|
||||
{{prefix}}.req_is_wr <= '0;
|
||||
{%- if has_sw_writable %}
|
||||
{{prefix}}.wr_data <= '0;
|
||||
{{prefix}}.wr_biten <= '0;
|
||||
{%- endif %}
|
||||
end else begin
|
||||
{%- if has_sw_readable and has_sw_writable %}
|
||||
{{prefix}}.req <= {{strb}};
|
||||
{%- elif has_sw_readable and not has_sw_writable %}
|
||||
{{prefix}}.req <= !decoded_req_is_wr ? {{strb}} : '0;
|
||||
{%- elif not has_sw_readable and has_sw_writable %}
|
||||
{{prefix}}.req <= decoded_req_is_wr ? {{strb}} : '0;
|
||||
{%- endif %}
|
||||
{{prefix}}.req_is_wr <= decoded_req_is_wr;
|
||||
{%- if has_sw_writable %}
|
||||
{{prefix}}.wr_data <= decoded_wr_data{{bslice}};
|
||||
{{prefix}}.wr_biten <= decoded_wr_biten{{bslice}};
|
||||
{%- endif %}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,10 +29,18 @@ end
|
||||
{%- else -%}
|
||||
|
||||
|
||||
{%- if has_sw_readable and has_sw_writable %}
|
||||
assign {{prefix}}.req = {{strb}};
|
||||
{%- elif has_sw_readable and not has_sw_writable %}
|
||||
assign {{prefix}}.req = !decoded_req_is_wr ? {{strb}} : '0;
|
||||
{%- elif not has_sw_readable and has_sw_writable %}
|
||||
assign {{prefix}}.req = decoded_req_is_wr ? {{strb}} : '0;
|
||||
{%- endif %}
|
||||
assign {{prefix}}.req_is_wr = decoded_req_is_wr;
|
||||
{%- if has_sw_writable %}
|
||||
assign {{prefix}}.wr_data = decoded_wr_data{{bslice}};
|
||||
assign {{prefix}}.wr_biten = decoded_wr_biten{{bslice}};
|
||||
{%- endif %}
|
||||
|
||||
|
||||
{%- endif %}
|
||||
|
||||
@@ -97,9 +97,11 @@ class InputStructGenerator_Hier(HWIFStructGenerator):
|
||||
super().enter_Reg(node)
|
||||
if node.external:
|
||||
width = min(self.hwif.ds.cpuif_data_width, node.get_property('regwidth'))
|
||||
self.add_member("rd_ack")
|
||||
self.add_member("rd_data", width)
|
||||
self.add_member("wr_ack")
|
||||
if node.has_sw_readable:
|
||||
self.add_member("rd_ack")
|
||||
self.add_member("rd_data", width)
|
||||
if node.has_sw_writable:
|
||||
self.add_member("wr_ack")
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
@@ -194,8 +196,9 @@ class OutputStructGenerator_Hier(HWIFStructGenerator):
|
||||
n_subwords = node.get_property("regwidth") // node.get_property("accesswidth")
|
||||
self.add_member("req", n_subwords)
|
||||
self.add_member("req_is_wr")
|
||||
self.add_member("wr_data", width)
|
||||
self.add_member("wr_biten", width)
|
||||
if node.has_sw_writable:
|
||||
self.add_member("wr_data", width)
|
||||
self.add_member("wr_biten", width)
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
return WalkerAction.Continue
|
||||
|
||||
@@ -92,11 +92,11 @@ class ReadbackAssignmentGenerator(RDLForLoopGenerator):
|
||||
return WalkerAction.Continue
|
||||
|
||||
def enter_Reg(self, node: RegNode) -> WalkerAction:
|
||||
if node.external:
|
||||
self.process_external_reg(node)
|
||||
if not node.has_sw_readable:
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
if not node.has_sw_readable:
|
||||
if node.external:
|
||||
self.process_external_reg(node)
|
||||
return WalkerAction.SkipDescendants
|
||||
|
||||
accesswidth = node.get_property('accesswidth')
|
||||
|
||||
Reference in New Issue
Block a user