Skip to content

Commit

Permalink
Clean up ugly unconditional 'if(1)' conditionals in field logic. #50
Browse files Browse the repository at this point in the history
  • Loading branch information
amykyta3 committed Jul 20, 2023
1 parent da8ff4a commit 2112241
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 18 deletions.
6 changes: 6 additions & 0 deletions src/peakrdl_regblock/field_logic/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ class NextStateConditional:
end
"""

# Assign to True if predicate can never evaluate to false.
# This will be generated as an 'else' clause, or a direct assignment
is_unconditional = False

# Optional comment to emit next to the conditional
comment = ""

def __init__(self, exp:'RegblockExporter'):
self.exp = exp

Expand Down
10 changes: 10 additions & 0 deletions src/peakrdl_regblock/field_logic/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,19 @@ def exit_Reg(self, node: 'RegNode') -> None:
def generate_field_storage(self, node: 'FieldNode') -> None:
conditionals = self.field_logic.get_conditionals(node)
extra_combo_signals = OrderedDict()
unconditional = None
new_conditionals = []
for conditional in conditionals:
for signal in conditional.get_extra_combo_signals(node):
extra_combo_signals[signal.name] = signal

if conditional.is_unconditional:
assert unconditional is None # Can only have one unconditional assignment per field
unconditional = conditional
else:
new_conditionals.append(conditional)
conditionals = new_conditionals

resetsignal = node.get_property('resetsignal')

reset_value = node.get_property('reset')
Expand All @@ -232,6 +241,7 @@ def generate_field_storage(self, node: 'FieldNode') -> None:
'field_logic': self.field_logic,
'extra_combo_signals': extra_combo_signals,
'conditionals': conditionals,
'unconditional': unconditional,
'resetsignal': resetsignal,
'get_always_ff_event': self.exp.dereferencer.get_always_ff_event,
'get_value': self.exp.dereferencer.get_value,
Expand Down
12 changes: 3 additions & 9 deletions src/peakrdl_regblock/field_logic/hw_interrupts.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class PosedgeNonsticky(NextStateConditional):
"""
Positive edge non-stickybit
"""
is_unconditional = True
comment = "posedge nonsticky"
def is_match(self, field: 'FieldNode') -> bool:
return (
Expand All @@ -145,9 +146,6 @@ def is_match(self, field: 'FieldNode') -> bool:
and field.get_property('intr type') == InterruptType.posedge
)

def get_predicate(self, field: 'FieldNode') -> str:
return "1"

def get_assignments(self, field: 'FieldNode') -> List[str]:
I = self.exp.hwif.get_input_identifier(field)
Iq = self.exp.field_logic.get_next_q_identifier(field)
Expand All @@ -160,6 +158,7 @@ class NegedgeNonsticky(NextStateConditional):
"""
Negative edge non-stickybit
"""
is_unconditional = True
comment = "negedge nonsticky"
def is_match(self, field: 'FieldNode') -> bool:
return (
Expand All @@ -168,9 +167,6 @@ def is_match(self, field: 'FieldNode') -> bool:
and field.get_property('intr type') == InterruptType.negedge
)

def get_predicate(self, field: 'FieldNode') -> str:
return "1"

def get_assignments(self, field: 'FieldNode') -> List[str]:
I = self.exp.hwif.get_input_identifier(field)
Iq = self.exp.field_logic.get_next_q_identifier(field)
Expand All @@ -183,6 +179,7 @@ class BothedgeNonsticky(NextStateConditional):
"""
edge-sensitive non-stickybit
"""
is_unconditional = True
comment = "bothedge nonsticky"
def is_match(self, field: 'FieldNode') -> bool:
return (
Expand All @@ -191,9 +188,6 @@ def is_match(self, field: 'FieldNode') -> bool:
and field.get_property('intr type') == InterruptType.bothedge
)

def get_predicate(self, field: 'FieldNode') -> str:
return "1"

def get_assignments(self, field: 'FieldNode') -> List[str]:
I = self.exp.hwif.get_input_identifier(field)
Iq = self.exp.field_logic.get_next_q_identifier(field)
Expand Down
9 changes: 5 additions & 4 deletions src/peakrdl_regblock/field_logic/hw_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ class AlwaysWrite(NextStateConditional):
"""
hw writable, without any qualifying we/wel
"""

is_unconditional = True
comment = "HW Write"

def is_match(self, field: 'FieldNode') -> bool:
return (
field.is_hw_writable
and not field.get_property('we')
and not field.get_property('wel')
)

def get_predicate(self, field: 'FieldNode') -> str:
# TODO: make exporter promote this to an "else"?
return "1"

def get_assignments(self, field: 'FieldNode') -> List[str]:
hwmask = field.get_property('hwmask')
hwenable = field.get_property('hwenable')
Expand All @@ -42,6 +41,7 @@ def get_assignments(self, field: 'FieldNode') -> List[str]:
]

class WEWrite(AlwaysWrite):
is_unconditional = False
comment = "HW Write - we"
def is_match(self, field: 'FieldNode') -> bool:
return (
Expand All @@ -59,6 +59,7 @@ def get_predicate(self, field: 'FieldNode') -> str:
return identifier

class WELWrite(AlwaysWrite):
is_unconditional = False
comment = "HW Write - wel"
def is_match(self, field: 'FieldNode') -> bool:
return (
Expand Down
6 changes: 1 addition & 5 deletions src/peakrdl_regblock/field_logic/sw_singlepulse.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@
from systemrdl.node import FieldNode

class Singlepulse(NextStateConditional):
is_unconditional = True
comment = "singlepulse clears back to 0"
def is_match(self, field: 'FieldNode') -> bool:
return field.get_property('singlepulse')

def get_predicate(self, field: 'FieldNode') -> str:
# TODO: make exporter promote this to an "else"?
# Be mindful of sw/hw precedence. this would have to come last regardless
return "1"

def get_assignments(self, field: 'FieldNode') -> List[str]:
return [
"next_c = '0;",
Expand Down
13 changes: 13 additions & 0 deletions src/peakrdl_regblock/field_logic/templates/field_storage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ always_comb begin
{%- endfor %}
end
{%- endfor %}
{%- if unconditional %}
{%- if conditionals %} else begin // {{unconditional.comment}}
{%- for assignment in unconditional.get_assignments(node) %}
{{assignment|indent}}
{%- endfor %}
end
{%- else %}
// {{unconditional.comment}}
{%- for assignment in unconditional.get_assignments(node) %}
{{assignment|indent}}
{%- endfor %}
{%- endif %}
{%- endif %}

{%- if node.is_up_counter %}
{{counter_macros.up_counter(node)}}
Expand Down

0 comments on commit 2112241

Please sign in to comment.