prop reference infrastructure, and other things

This commit is contained in:
Alex Mykyta
2021-07-16 12:43:58 -07:00
parent 0d5b663f98
commit 5f2319860f
14 changed files with 338 additions and 68 deletions

View File

@@ -6,21 +6,24 @@ if TYPE_CHECKING:
from .exporter import RegblockExporter
from .hwif.base import HwifBase
from .field_logic import FieldLogic
from .addr_decode import AddressDecode
class Dereferencer:
"""
This class provides an interface to convert conceptual SystemRDL references
into Verilog identifiers
"""
def __init__(self, exporter:'RegblockExporter', hwif:'HwifBase', field_logic: "FieldLogic", top_node:Node):
def __init__(self, exporter:'RegblockExporter', top_node:Node, hwif:'HwifBase', address_decode: 'AddressDecode', field_logic: 'FieldLogic'):
self.exporter = exporter
self.hwif = hwif
self.address_decode = address_decode
self.field_logic = field_logic
self.top_node = top_node
def get_value(self, obj: Union[int, FieldNode, SignalNode, PropertyReference]) -> str:
"""
Returns the Verilog string that represents the value associated with the object.
Returns the Verilog string that represents the readable value associated
with the object.
If given a simple scalar value, then the corresponding Verilog literal is returned.
@@ -31,7 +34,7 @@ class Dereferencer:
# Is a simple scalar value
return f"'h{obj:x}"
elif isinstance(obj, FieldNode):
if isinstance(obj, FieldNode):
if obj.implements_storage:
return self.field_logic.get_storage_identifier(obj)
@@ -48,14 +51,14 @@ class Dereferencer:
# Fall back to a value of 0
return "'h0"
elif isinstance(obj, SignalNode):
if isinstance(obj, SignalNode):
# Signals are always inputs from the hwif
return self.hwif.get_input_identifier(obj)
elif isinstance(obj, PropertyReference):
# TODO: Table G1 describes other possible ref targets
if isinstance(obj, PropertyReference):
# Value reduction properties
# Value reduction properties.
# Wrap with the appropriate Verilog reduction operator
val = self.get_value(obj.node)
if obj.name == "anded":
return f"&({val})"
@@ -63,15 +66,98 @@ class Dereferencer:
return f"|({val})"
elif obj.name == "xored":
return f"^({val})"
else:
raise RuntimeError
else:
raise RuntimeError
# references that directly access a property value
if obj.name in {
'decrvalue',
'enable',
'haltenable',
'haltmask',
'hwenable',
'hwmask',
'incrvalue',
'mask',
'reset',
'resetsignal',
}:
return self.get_value(obj.node.get_property(obj.name))
elif obj.name in {'incr', 'decr'}:
prop_value = obj.node.get_property(obj.name)
if prop_value is None:
# unset by the user, points to the implied internal signal
raise NotImplementedError # TODO: Implement this
else:
return self.get_value(prop_value)
elif obj.name == "next":
prop_value = obj.node.get_property(obj.name)
if prop_value is None:
# unset by the user, points to the implied internal signal
raise NotImplementedError # TODO: Implement this
else:
return self.get_value(prop_value)
def get_access_strobe(self, reg: RegNode) -> str:
# References to another component value, or an implied input
if obj.name in {'hwclr', 'hwset'}:
prop_value = obj.node.get_property(obj.name)
if prop_value is True:
# Points to inferred hwif input
return self.hwif.get_input_identifier(obj)
elif prop_value is False:
# This should never happen, as this is checked by the compiler's validator
raise RuntimeError
else:
return self.get_value(prop_value)
# References to another component value, or an implied input
# May have a complementary partner property
complementary_pairs = {
"we": "wel",
"wel": "we",
"swwe": "swwel",
"swwel": "swwe",
}
if obj.name in complementary_pairs:
prop_value = obj.node.get_property(obj.name)
if prop_value is True:
# Points to inferred hwif input
return self.hwif.get_input_identifier(obj)
elif prop_value is False:
# Try complementary property
prop_value = obj.node.get_property(complementary_pairs[obj.name])
if prop_value is True:
# Points to inferred hwif input
return f"!({self.hwif.get_input_identifier(obj)})"
raise NotImplementedError # TODO: Implement this
elif prop_value is False:
# This should never happen, as this is checked by the compiler's validator
raise RuntimeError
else:
return f"!({self.get_value(prop_value)})"
else:
return self.get_value(prop_value)
"""
TODO:
Resolves to an internal signal used in the field's logic
decrsaturate
decrthreshold
halt
incrsaturate
incrthreshold
intr
overflow
saturate
swacc
swmod
threshold
"""
raise RuntimeError("Unhandled reference to: %s", obj)
def get_access_strobe(self, obj: Union[RegNode, FieldNode]) -> str:
"""
Returns the Verilog string that represents the register's access strobe
"""
# TODO: Implement me
raise NotImplementedError
return self.address_decode.get_access_strobe(obj)