fix lint
This commit is contained in:
@@ -12,15 +12,15 @@ class APB3Cpuif(BaseCpuif):
|
|||||||
|
|
||||||
def _port_declaration(self, child: AddressableNode) -> str:
|
def _port_declaration(self, child: AddressableNode) -> str:
|
||||||
base = f"apb3_intf.master m_apb_{child.inst_name}"
|
base = f"apb3_intf.master m_apb_{child.inst_name}"
|
||||||
|
|
||||||
# When unrolled, current_idx is set - append it to the name
|
# When unrolled, current_idx is set - append it to the name
|
||||||
if child.current_idx is not None:
|
if child.current_idx is not None:
|
||||||
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
||||||
|
|
||||||
# Only add array dimensions if this should be treated as an array
|
# Only add array dimensions if this should be treated as an array
|
||||||
if self.check_is_array(child):
|
if self.check_is_array(child):
|
||||||
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ class APB4Cpuif(BaseCpuif):
|
|||||||
|
|
||||||
def _port_declaration(self, child: AddressableNode) -> str:
|
def _port_declaration(self, child: AddressableNode) -> str:
|
||||||
base = f"apb4_intf.master m_apb_{child.inst_name}"
|
base = f"apb4_intf.master m_apb_{child.inst_name}"
|
||||||
|
|
||||||
# When unrolled, current_idx is set - append it to the name
|
# When unrolled, current_idx is set - append it to the name
|
||||||
if child.current_idx is not None:
|
if child.current_idx is not None:
|
||||||
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
||||||
|
|
||||||
# Only add array dimensions if this should be treated as an array
|
# Only add array dimensions if this should be treated as an array
|
||||||
if self.check_is_array(child):
|
if self.check_is_array(child):
|
||||||
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ class AXI4LiteCpuif(BaseCpuif):
|
|||||||
|
|
||||||
def _port_declaration(self, child: AddressableNode) -> str:
|
def _port_declaration(self, child: AddressableNode) -> str:
|
||||||
base = f"axi4lite_intf.master m_axil_{child.inst_name}"
|
base = f"axi4lite_intf.master m_axil_{child.inst_name}"
|
||||||
|
|
||||||
# When unrolled, current_idx is set - append it to the name
|
# When unrolled, current_idx is set - append it to the name
|
||||||
if child.current_idx is not None:
|
if child.current_idx is not None:
|
||||||
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
base = f"{base}_{'_'.join(map(str, child.current_idx))}"
|
||||||
|
|
||||||
# Only add array dimensions if this should be treated as an array
|
# Only add array dimensions if this should be treated as an array
|
||||||
if self.check_is_array(child):
|
if self.check_is_array(child):
|
||||||
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
return f"{base} {''.join(f'[{dim}]' for dim in child.array_dimensions)}"
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class BaseCpuif:
|
|||||||
def check_is_array(self, node: AddressableNode) -> bool:
|
def check_is_array(self, node: AddressableNode) -> bool:
|
||||||
# When unrolling is enabled, children(unroll=True) returns individual
|
# When unrolling is enabled, children(unroll=True) returns individual
|
||||||
# array elements with current_idx set. These should NOT be treated as arrays.
|
# array elements with current_idx set. These should NOT be treated as arrays.
|
||||||
if self.unroll and hasattr(node, 'current_idx') and node.current_idx is not None:
|
if self.unroll and hasattr(node, "current_idx") and node.current_idx is not None:
|
||||||
return False
|
return False
|
||||||
return node.is_array
|
return node.is_array
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class FanoutGenerator(BusDecoderListener):
|
|||||||
|
|
||||||
if action == WalkerAction.Continue:
|
if action == WalkerAction.Continue:
|
||||||
self._stack[-1] += self._cpuif.fanout(node)
|
self._stack[-1] += self._cpuif.fanout(node)
|
||||||
|
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
def exit_AddressableComponent(self, node: AddressableNode) -> None:
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ class BusDecoderExporter:
|
|||||||
loader=c_loader,
|
loader=c_loader,
|
||||||
undefined=jj.StrictUndefined,
|
undefined=jj.StrictUndefined,
|
||||||
)
|
)
|
||||||
self.jj_env.filters["kwf"] = kwf # type: ignore
|
self.jj_env.filters["kwf"] = kwf # type: ignore
|
||||||
self.jj_env.filters["walk"] = self.walk # type: ignore
|
self.jj_env.filters["walk"] = self.walk # type: ignore
|
||||||
|
|
||||||
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
|
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Unpack[ExporterKwargs]) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -129,7 +129,7 @@ class BusDecoderExporter:
|
|||||||
stream = template.stream(context)
|
stream = template.stream(context)
|
||||||
stream.dump(module_file_path)
|
stream.dump(module_file_path)
|
||||||
|
|
||||||
def walk(self, listener_cls: type[BusDecoderListener], **kwargs: Any) -> str:
|
def walk(self, listener_cls: type[BusDecoderListener], **kwargs: dict[str, Any]) -> str:
|
||||||
walker = RDLSteerableWalker()
|
walker = RDLSteerableWalker()
|
||||||
listener = listener_cls(self.ds, **kwargs)
|
listener = listener_cls(self.ds, **kwargs)
|
||||||
walker.walk(self.ds.top_node, listener, skip_top=True)
|
walker.walk(self.ds.top_node, listener, skip_top=True)
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
from systemrdl.udp import UDPDefinition
|
from systemrdl.udp import UDPDefinition
|
||||||
from .rw_buffering import BufferWrites, WBufferTrigger
|
|
||||||
from .rw_buffering import BufferReads, RBufferTrigger
|
|
||||||
from .extended_swacc import ReadSwacc, WriteSwacc
|
|
||||||
from .fixedpoint import IntWidth, FracWidth
|
|
||||||
from .signed import IsSigned
|
|
||||||
|
|
||||||
ALL_UDPS: list[type[UDPDefinition]] = [
|
ALL_UDPS: list[type[UDPDefinition]] = []
|
||||||
BufferWrites,
|
|
||||||
WBufferTrigger,
|
__all__ = ["ALL_UDPS"]
|
||||||
BufferReads,
|
|
||||||
RBufferTrigger,
|
|
||||||
ReadSwacc,
|
|
||||||
WriteSwacc,
|
|
||||||
IntWidth,
|
|
||||||
FracWidth,
|
|
||||||
IsSigned,
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
from typing import TYPE_CHECKING, Any
|
|
||||||
|
|
||||||
from systemrdl.udp import UDPDefinition
|
|
||||||
from systemrdl.component import Field
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from systemrdl.node import Node
|
|
||||||
|
|
||||||
|
|
||||||
class ReadSwacc(UDPDefinition):
|
|
||||||
name = "rd_swacc"
|
|
||||||
valid_components = {Field}
|
|
||||||
valid_type = bool
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class WriteSwacc(UDPDefinition):
|
|
||||||
name = "wr_swacc"
|
|
||||||
valid_components = {Field}
|
|
||||||
valid_type = bool
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
return False
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
|
|
||||||
from systemrdl.component import Field
|
|
||||||
from systemrdl.node import Node, FieldNode
|
|
||||||
from systemrdl.udp import UDPDefinition
|
|
||||||
|
|
||||||
|
|
||||||
class _FixedpointWidth(UDPDefinition):
|
|
||||||
valid_components = {Field}
|
|
||||||
valid_type = int
|
|
||||||
|
|
||||||
def validate(self, node: "Node", value: Any) -> None:
|
|
||||||
assert isinstance(node, FieldNode)
|
|
||||||
|
|
||||||
intwidth = node.get_property("intwidth")
|
|
||||||
fracwidth = node.get_property("fracwidth")
|
|
||||||
assert intwidth is not None
|
|
||||||
assert fracwidth is not None
|
|
||||||
prop_ref = node.inst.property_src_ref.get(self.name)
|
|
||||||
|
|
||||||
# incompatible with "counter" fields
|
|
||||||
if node.get_property("counter"):
|
|
||||||
self.msg.error("Fixed-point representations are not supported for counter fields.", prop_ref)
|
|
||||||
|
|
||||||
# incompatible with "encode" fields
|
|
||||||
if node.get_property("encode") is not None:
|
|
||||||
self.msg.error(
|
|
||||||
"Fixed-point representations are not supported for fields encoded as an enum.", prop_ref
|
|
||||||
)
|
|
||||||
|
|
||||||
# ensure node width = fracwidth + intwidth
|
|
||||||
if intwidth + fracwidth != node.width:
|
|
||||||
self.msg.error(
|
|
||||||
f"Number of integer bits ({intwidth}) plus number of fractional bits ({fracwidth})"
|
|
||||||
f" must be equal to the width of the component ({node.width}).",
|
|
||||||
prop_ref,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class IntWidth(_FixedpointWidth):
|
|
||||||
name = "intwidth"
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
"""
|
|
||||||
If 'fracwidth' is defined, 'intwidth' is inferred from the node width.
|
|
||||||
"""
|
|
||||||
assert isinstance(node, FieldNode)
|
|
||||||
fracwidth = node.get_property("fracwidth", default=None)
|
|
||||||
if fracwidth is not None:
|
|
||||||
return node.width - fracwidth
|
|
||||||
else:
|
|
||||||
# not a fixed-point number
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class FracWidth(_FixedpointWidth):
|
|
||||||
name = "fracwidth"
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
"""
|
|
||||||
If 'intwidth' is defined, 'fracwidth' is inferred from the node width.
|
|
||||||
"""
|
|
||||||
assert isinstance(node, FieldNode)
|
|
||||||
intwidth = node.get_property("intwidth", default=None)
|
|
||||||
if intwidth is not None:
|
|
||||||
return node.width - intwidth
|
|
||||||
else:
|
|
||||||
# not a fixed-point number
|
|
||||||
return None
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
|
|
||||||
from systemrdl.udp import UDPDefinition
|
|
||||||
from systemrdl.component import Reg
|
|
||||||
from systemrdl.rdltypes.references import RefType, PropertyReference
|
|
||||||
from systemrdl.rdltypes import NoValue
|
|
||||||
from systemrdl.node import Node, RegNode, VectorNode, SignalNode, FieldNode
|
|
||||||
|
|
||||||
|
|
||||||
class xBufferTrigger(UDPDefinition):
|
|
||||||
valid_components = {Reg}
|
|
||||||
valid_type = RefType
|
|
||||||
|
|
||||||
def validate(self, node: Node, value: Any) -> None:
|
|
||||||
# TODO: Reference shall not cross an internal/external boundary
|
|
||||||
|
|
||||||
if value is NoValue:
|
|
||||||
self.msg.error(
|
|
||||||
"Double-buffer trigger property is missing a value assignment", self.get_src_ref(node)
|
|
||||||
)
|
|
||||||
elif isinstance(value, VectorNode):
|
|
||||||
# Trigger can reference a vector, but only if it is a single-bit
|
|
||||||
if value.width != 1:
|
|
||||||
self.msg.error(
|
|
||||||
"%s '%s' references %s '%s' but its width is not 1"
|
|
||||||
% (
|
|
||||||
type(node.inst).__name__.lower(),
|
|
||||||
node.inst_name,
|
|
||||||
type(value.inst).__name__.lower(),
|
|
||||||
value.inst_name,
|
|
||||||
),
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
|
|
||||||
if isinstance(value, SignalNode):
|
|
||||||
if not value.get_property("activehigh") and not value.get_property("activelow"):
|
|
||||||
self.msg.error(
|
|
||||||
"Trigger was asigned a signal, but it does not specify whether it is activehigh/activelow",
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
|
|
||||||
elif isinstance(value, PropertyReference) and value.width is not None:
|
|
||||||
# Trigger can reference a property, but only if it is a single-bit
|
|
||||||
if value.width != 1:
|
|
||||||
self.msg.error(
|
|
||||||
"%s '%s' references property '%s->%s' but its width is not 1"
|
|
||||||
% (
|
|
||||||
type(node.inst).__name__.lower(),
|
|
||||||
node.inst_name,
|
|
||||||
value.node.inst_name,
|
|
||||||
value.name,
|
|
||||||
),
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
elif isinstance(value, RegNode):
|
|
||||||
# Trigger can reference a register, which implies access of the
|
|
||||||
# 'correct half' of the register is the trigger.
|
|
||||||
# For buffered writes, it is the upper-half.
|
|
||||||
# For buffered reads, it is the lower-half.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# All other reference types are invalid
|
|
||||||
self.msg.error(
|
|
||||||
"Reference to a %s component is incompatible with the '%s' property."
|
|
||||||
% (type(node.inst).__name__.lower(), self.name),
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------
|
|
||||||
class BufferWrites(UDPDefinition):
|
|
||||||
name = "buffer_writes"
|
|
||||||
valid_components = {Reg}
|
|
||||||
valid_type = bool
|
|
||||||
|
|
||||||
def validate(self, node: "Node", value: Any) -> None:
|
|
||||||
assert isinstance(node, RegNode)
|
|
||||||
if value:
|
|
||||||
if not node.has_sw_writable:
|
|
||||||
self.msg.error(
|
|
||||||
"'buffer_writes' is set to true, but this register does not contain any writable fields.",
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class WBufferTrigger(xBufferTrigger):
|
|
||||||
name = "wbuffer_trigger"
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
# If buffering is enabled, trigger is the register itself
|
|
||||||
if node.get_property("buffer_writes"):
|
|
||||||
return node
|
|
||||||
return None
|
|
||||||
|
|
||||||
def validate(self, node: Node, value: Any) -> None:
|
|
||||||
super().validate(node, value)
|
|
||||||
|
|
||||||
if isinstance(value, FieldNode):
|
|
||||||
if value.parent == node:
|
|
||||||
self.msg.error(
|
|
||||||
"Trigger for a write-buffered register cannot be a field "
|
|
||||||
"within the same register since the buffering makes it impossible to trigger."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class BufferReads(UDPDefinition):
|
|
||||||
name = "buffer_reads"
|
|
||||||
valid_components = {Reg}
|
|
||||||
valid_type = bool
|
|
||||||
|
|
||||||
def validate(self, node: "Node", value: Any) -> None:
|
|
||||||
assert isinstance(node, RegNode)
|
|
||||||
if value:
|
|
||||||
if not node.has_sw_readable:
|
|
||||||
self.msg.error(
|
|
||||||
"'buffer_reads' is set to true, but this register does not contain any readable fields.",
|
|
||||||
self.get_src_ref(node),
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class RBufferTrigger(xBufferTrigger):
|
|
||||||
name = "rbuffer_trigger"
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
# If buffering is enabled, trigger is the register itself
|
|
||||||
if node.get_property("buffer_reads"):
|
|
||||||
return node
|
|
||||||
return None
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
|
|
||||||
from systemrdl.component import Field
|
|
||||||
from systemrdl.node import Node
|
|
||||||
from systemrdl.udp import UDPDefinition
|
|
||||||
|
|
||||||
|
|
||||||
class IsSigned(UDPDefinition):
|
|
||||||
name = "is_signed"
|
|
||||||
valid_components = {Field}
|
|
||||||
valid_type = bool
|
|
||||||
default_assignment = True
|
|
||||||
|
|
||||||
def validate(self, node: "Node", value: Any) -> None:
|
|
||||||
# "counter" fields can not be signed
|
|
||||||
if value and node.get_property("counter"):
|
|
||||||
self.msg.error(
|
|
||||||
"The property is_signed=true is not supported for counter fields.",
|
|
||||||
node.inst.property_src_ref["is_signed"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# incompatible with "encode" fields
|
|
||||||
if value and node.get_property("encode") is not None:
|
|
||||||
self.msg.error(
|
|
||||||
"The property is_signed=true is not supported for fields encoded as an enum.",
|
|
||||||
node.inst.property_src_ref["is_signed"],
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_unassigned_default(self, node: "Node") -> Any:
|
|
||||||
"""
|
|
||||||
Unsigned by default if not specified.
|
|
||||||
"""
|
|
||||||
return False
|
|
||||||
Reference in New Issue
Block a user