Collapse hwif into one file

This commit is contained in:
Alex Mykyta
2021-07-16 13:02:05 -07:00
parent 5f2319860f
commit e3a49a65fb
6 changed files with 101 additions and 122 deletions

View File

@@ -7,26 +7,30 @@ Any field that implements storage is defined here.
Bigass struct that only contains storage elements Bigass struct that only contains storage elements
Each field consists of: Each field consists of:
- an always_ff block - an always_comb block:
- generates the "next value" combinational signal
- May generate other intermediate strobes?
incr/decr?
- series of if/else statements that assign the next value in the storage element - series of if/else statements that assign the next value in the storage element
Think of this as a flat list of "next state" conditons, ranked by their precedence as follows: Think of this as a flat list of "next state" conditons, ranked by their precedence as follows:
- reset - reset
Actually, handle this in the always_ff
- sw access (if sw precedence) - sw access (if sw precedence)
- onread/onwrite - onread/onwrite
- hw access - hw access
- Counter - Counter
beware of clear events and incr/decr events happening simultaneously
- next - next
- etc - etc
- sw access (if hw precedence) - sw access (if hw precedence)
- onread/onwrite - onread/onwrite
- always_comb block to also generate write-enable strobes for the actual
TODO: storage element
What about stuff like read-clear counters that cant lose a count? This is better for low-power design
In a traditional if/else chain, i need to be aware of the fact that its a counter - an always_ff block
when handling the swaccess case Implements the actual storage element
Is it possible to code this in a way where I can isolate the need to know every nuanced case here? Also a tidy place to abstract the specifics of activehigh/activelow field reset
this may actually only apply to counters... selection.
This is trivial in a 2-process implementation, but i'd rather avoid the overheads
TODO: TODO:
Scour the RDL spec. Scour the RDL spec.

View File

@@ -4,7 +4,7 @@ from systemrdl.rdltypes import PropertyReference
if TYPE_CHECKING: if TYPE_CHECKING:
from .exporter import RegblockExporter from .exporter import RegblockExporter
from .hwif.base import HwifBase from .hwif import Hwif
from .field_logic import FieldLogic from .field_logic import FieldLogic
from .addr_decode import AddressDecode from .addr_decode import AddressDecode
@@ -13,7 +13,7 @@ class Dereferencer:
This class provides an interface to convert conceptual SystemRDL references This class provides an interface to convert conceptual SystemRDL references
into Verilog identifiers into Verilog identifiers
""" """
def __init__(self, exporter:'RegblockExporter', top_node:Node, hwif:'HwifBase', address_decode: 'AddressDecode', field_logic: 'FieldLogic'): def __init__(self, exporter:'RegblockExporter', top_node:Node, hwif:'Hwif', address_decode: 'AddressDecode', field_logic: 'FieldLogic'):
self.exporter = exporter self.exporter = exporter
self.hwif = hwif self.hwif = hwif
self.address_decode = address_decode self.address_decode = address_decode

View File

@@ -11,7 +11,7 @@ from .readback_mux import ReadbackMux
from .signals import InferredSignal from .signals import InferredSignal
from .cpuif.apb4 import APB4_Cpuif from .cpuif.apb4 import APB4_Cpuif
from .hwif.struct import StructHwif from .hwif import Hwif
class RegblockExporter: class RegblockExporter:
def __init__(self, **kwargs): def __init__(self, **kwargs):
@@ -50,7 +50,7 @@ class RegblockExporter:
node = node.top node = node.top
cpuif_cls = kwargs.pop("cpuif_cls", APB4_Cpuif) cpuif_cls = kwargs.pop("cpuif_cls", APB4_Cpuif)
hwif_cls = kwargs.pop("hwif_cls", StructHwif) hwif_cls = kwargs.pop("hwif_cls", Hwif)
module_name = kwargs.pop("module_name", node.inst_name) module_name = kwargs.pop("module_name", node.inst_name)
package_name = kwargs.pop("package_name", module_name + "_pkg") package_name = kwargs.pop("package_name", module_name + "_pkg")

View File

@@ -1,16 +1,22 @@
from typing import Union, List, TYPE_CHECKING from typing import TYPE_CHECKING, Union, List
from systemrdl.node import Node, SignalNode, FieldNode, AddressableNode
from systemrdl.node import Node, AddressableNode, FieldNode, SignalNode from systemrdl.rdltypes import PropertyReference
from .base import HwifBase
if TYPE_CHECKING: if TYPE_CHECKING:
from ..exporter import RegblockExporter from .exporter import RegblockExporter
class StructHwif(HwifBase): class Hwif:
"""
Defines how the hardware input/output signals are generated:
- Field outputs
- Field inputs
- Signal inputs (except those that are promoted to the top)
"""
def __init__(self, exporter:'RegblockExporter', top_node:Node, package_name:str): def __init__(self, exporter: 'RegblockExporter', top_node: Node, package_name: str):
super().__init__(exporter, top_node, package_name) self.exporter = exporter
self.top_node = top_node
self.package_name = package_name
self.has_input_struct = None self.has_input_struct = None
self.has_output_struct = None self.has_output_struct = None
@@ -18,6 +24,9 @@ class StructHwif(HwifBase):
def get_package_declaration(self) -> str: def get_package_declaration(self) -> str:
"""
If this hwif requires a package, generate the string
"""
lines = [] lines = []
lines.append(f"package {self.package_name};") lines.append(f"package {self.package_name};")
@@ -49,6 +58,7 @@ class StructHwif(HwifBase):
return ",\n".join(lines) return ",\n".join(lines)
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Struct generation functions # Struct generation functions
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
@@ -180,3 +190,58 @@ class StructHwif(HwifBase):
""" """
return contents return contents
#---------------------------------------------------------------------------
# hwif utility functions
#---------------------------------------------------------------------------
def has_value_input(self, obj: Union[FieldNode, SignalNode]) -> bool:
"""
Returns True if the object infers an input wire in the hwif
"""
if isinstance(obj, FieldNode):
return obj.is_hw_writable
elif isinstance(obj, SignalNode):
# Signals are implicitly always inputs
return True
else:
raise RuntimeError
def has_value_output(self, obj: FieldNode) -> bool:
"""
Returns True if the object infers an output wire in the hwif
"""
# TODO: Extend this for signals and prop references?
return obj.is_hw_readable
def get_input_identifier(self, obj: Union[FieldNode, SignalNode, PropertyReference]) -> str:
"""
Returns the identifier string that best represents the input object.
if obj is:
Field: the fields input value port
Signal: signal input value
Prop reference:
could be an implied hwclr/hwset/swwe/swwel/we/wel input
Raise a runtime error if an illegal prop ref is requested, or if
the prop ref is not actually implied, but explicitly ref a component
TODO: finish this
raises an exception if obj is invalid
"""
raise NotImplementedError()
def get_output_identifier(self, obj: FieldNode) -> str:
"""
Returns the identifier string that best represents the output object.
if obj is:
Field: the fields output value port
Property ref: this is also part of the struct
TODO: finish this
raises an exception if obj is invalid
"""
raise NotImplementedError()

View File

@@ -1 +0,0 @@
from .base import HwifBase

View File

@@ -1,89 +0,0 @@
from typing import TYPE_CHECKING, Union
from systemrdl.node import Node, SignalNode, FieldNode
from systemrdl.rdltypes import AccessType, PropertyReference
if TYPE_CHECKING:
from ..exporter import RegblockExporter
class HwifBase:
"""
Defines how the hardware input/output signals are generated:
- Field outputs
- Field inputs
- Signal inputs (except those that are promoted to the top)
"""
def __init__(self, exporter: 'RegblockExporter', top_node: Node, package_name: str):
self.exporter = exporter
self.top_node = top_node
self.package_name = package_name
def get_package_declaration(self) -> str:
"""
If this hwif requires a package, generate the string
"""
return ""
@property
def port_declaration(self) -> str:
"""
Returns the declaration string for all I/O ports in the hwif group
"""
raise NotImplementedError()
#---------------------------------------------------------------------------
# hwif utility functions
#---------------------------------------------------------------------------
def has_value_input(self, obj: Union[FieldNode, SignalNode]) -> bool:
"""
Returns True if the object infers an input wire in the hwif
"""
if isinstance(obj, FieldNode):
return obj.is_hw_writable
elif isinstance(obj, SignalNode):
# Signals are implicitly always inputs
return True
else:
raise RuntimeError
def has_value_output(self, obj: FieldNode) -> bool:
"""
Returns True if the object infers an output wire in the hwif
"""
# TODO: Extend this for signals and prop references?
return obj.is_hw_readable
def get_input_identifier(self, obj: Union[FieldNode, SignalNode, PropertyReference]) -> str:
"""
Returns the identifier string that best represents the input object.
if obj is:
Field: the fields input value port
Signal: signal input value
Prop reference:
could be an implied hwclr/hwset/swwe/swwel/we/wel input
Raise a runtime error if an illegal prop ref is requested, or if
the prop ref is not actually implied, but explicitly ref a component
TODO: finish this
raises an exception if obj is invalid
"""
raise NotImplementedError()
def get_output_identifier(self, obj: FieldNode) -> str:
"""
Returns the identifier string that best represents the output object.
if obj is:
Field: the fields output value port
Property ref: this is also part of the struct
TODO: finish this
raises an exception if obj is invalid
"""
raise NotImplementedError()