Clean up ugly unconditional 'if(1)' conditionals in field logic. #50
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -212,10 +212,19 @@ class FieldLogicGenerator(RDLForLoopGenerator):
|
||||
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')
|
||||
@@ -232,6 +241,7 @@ class FieldLogicGenerator(RDLForLoopGenerator):
|
||||
'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,
|
||||
|
||||
@@ -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 (
|
||||
@@ -145,9 +146,6 @@ class PosedgeNonsticky(NextStateConditional):
|
||||
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)
|
||||
@@ -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 (
|
||||
@@ -168,9 +167,6 @@ class NegedgeNonsticky(NextStateConditional):
|
||||
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)
|
||||
@@ -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 (
|
||||
@@ -191,9 +188,6 @@ class BothedgeNonsticky(NextStateConditional):
|
||||
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)
|
||||
|
||||
@@ -10,7 +10,10 @@ 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
|
||||
@@ -18,10 +21,6 @@ class AlwaysWrite(NextStateConditional):
|
||||
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')
|
||||
@@ -42,6 +41,7 @@ class AlwaysWrite(NextStateConditional):
|
||||
]
|
||||
|
||||
class WEWrite(AlwaysWrite):
|
||||
is_unconditional = False
|
||||
comment = "HW Write - we"
|
||||
def is_match(self, field: 'FieldNode') -> bool:
|
||||
return (
|
||||
@@ -59,6 +59,7 @@ class WEWrite(AlwaysWrite):
|
||||
return identifier
|
||||
|
||||
class WELWrite(AlwaysWrite):
|
||||
is_unconditional = False
|
||||
comment = "HW Write - wel"
|
||||
def is_match(self, field: 'FieldNode') -> bool:
|
||||
return (
|
||||
|
||||
@@ -6,15 +6,11 @@ if TYPE_CHECKING:
|
||||
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;",
|
||||
|
||||
@@ -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)}}
|
||||
|
||||
Reference in New Issue
Block a user