uvx format
This commit is contained in:
@@ -26,9 +26,7 @@ class AddressDecode:
|
||||
assert s is not None
|
||||
return s
|
||||
|
||||
def get_access_strobe(
|
||||
self, node: RegNode | FieldNode, reduce_substrobes: bool = True
|
||||
) -> str:
|
||||
def get_access_strobe(self, node: RegNode | FieldNode, reduce_substrobes: bool = True) -> str:
|
||||
"""
|
||||
Returns the Verilog string that represents the register/field's access strobe.
|
||||
"""
|
||||
@@ -72,9 +70,7 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
|
||||
# List of address strides for each dimension
|
||||
self._array_stride_stack: list[int] = []
|
||||
|
||||
def enter_AddressableComponent(
|
||||
self, node: "AddressableNode"
|
||||
) -> WalkerAction | None:
|
||||
def enter_AddressableComponent(self, node: "AddressableNode") -> WalkerAction | None:
|
||||
super().enter_AddressableComponent(node)
|
||||
|
||||
if node.array_dimensions:
|
||||
@@ -103,9 +99,7 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
|
||||
expr_width = self.addr_decode.exp.ds.addr_width
|
||||
a = str(
|
||||
SVInt(
|
||||
node.raw_absolute_address
|
||||
- self.addr_decode.top_node.raw_absolute_address
|
||||
+ subword_offset,
|
||||
node.raw_absolute_address - self.addr_decode.top_node.raw_absolute_address + subword_offset,
|
||||
expr_width,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .apb3_cpuif import APB3Cpuif
|
||||
from .apb3_cpuif_flat import APB3CpuifFlat
|
||||
|
||||
__all__ = ["APB3Cpuif", "APB3CpuifFlat"]
|
||||
__all__ = ["APB3Cpuif", "APB3CpuifFlat"]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from systemrdl.node import AddressableNode
|
||||
|
||||
from ..base_cpuif import BaseCpuif
|
||||
|
||||
|
||||
@@ -17,9 +18,7 @@ class APB3Cpuif(BaseCpuif):
|
||||
@property
|
||||
def port_declaration(self) -> str:
|
||||
slave_ports: list[str] = ["apb3_intf.slave s_apb"]
|
||||
master_ports: list[str] = list(
|
||||
map(self._port_declaration, self.addressable_children)
|
||||
)
|
||||
master_ports: list[str] = list(map(self._port_declaration, self.addressable_children))
|
||||
|
||||
return ",\n".join(slave_ports + master_ports)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from systemrdl.node import AddressableNode
|
||||
|
||||
from ..base_cpuif import BaseCpuif
|
||||
|
||||
|
||||
|
||||
@@ -30,86 +30,4 @@ assign {{self.signal("PWRITE", child)}} = {{self.signal("PWRITE")}};
|
||||
assign {{self.signal("PADDR", child)}} = {{self.signal("PADDR")}} [{{child.addr_width - 1}}:0]; // FIXME: Check slicing
|
||||
assign {{self.signal("PWDATA", child)}} = {{self.signal("PWDATA")}};
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
//======================================================
|
||||
// Address Decode Logic
|
||||
//======================================================
|
||||
always_comb begin
|
||||
// Default all PSELx signals to 0
|
||||
{%- for child in cpuif.addressable_children -%}
|
||||
{%- if child is array -%}
|
||||
for (int {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
|
||||
{{self.signal("PSELx", child, f"{child.inst_name.lower()}_idx")}} = 1'b0;
|
||||
end
|
||||
{%- else -%}
|
||||
{{self.signal("PSELx", child)}} = 1'b0;
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
if ({{self.signal("PSELx")}}) begin
|
||||
{%- for child in cpuif.addressable_children -%}
|
||||
{%- if loop.first -%}
|
||||
if ({{cpuif.get_address_decode_condition(child)}}) begin
|
||||
{%- else -%}
|
||||
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
|
||||
{%- endif -%}
|
||||
// Address matched for {{child.inst_name}}
|
||||
{%- if child is array -%}
|
||||
for (genvar {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
|
||||
{{self.signal("PSELx", child, f"{child.inst_name.lower()}_idx")}} = 1'b1;
|
||||
end
|
||||
{%- else -%}
|
||||
{{self.signal("PSELx", child)}} = 1'b1;
|
||||
{%- endif -%}
|
||||
{%- if loop.last -%}
|
||||
end else begin
|
||||
// No address matched
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
end
|
||||
end else begin
|
||||
// PSELx is low, nothing to do
|
||||
end
|
||||
end
|
||||
|
||||
//======================================================
|
||||
// Read Data Mux
|
||||
//======================================================
|
||||
always_comb begin
|
||||
// Default read data to 0
|
||||
{{self.signal("PRDATA")}} = '0;
|
||||
{{self.signal("PREADY")}} = 1'b1;
|
||||
{{self.signal("PSLVERR")}} = 1'b0;
|
||||
|
||||
if ({{self.signal("PSELx")}} && !{{self.signal("PWRITE")}} && {{self.signal("PENABLE")}}) begin
|
||||
{%- for child in cpuif.addressable_children -%}
|
||||
{%- if loop.first -%}
|
||||
if ({{cpuif.get_address_decode_condition(child)}}) begin
|
||||
{%- else -%}
|
||||
end else if ({{cpuif.get_address_decode_condition(child)}}) begin
|
||||
{%- endif -%}
|
||||
// Address matched for {{child.inst_name}}
|
||||
{%- if child is array -%}
|
||||
for (genvar {{child.inst_name|lower}}_idx = 0; {{child.inst_name|lower}}_idx < N_{{child.inst_name|upper}}S; {{child.inst_name|lower}}_idx++) begin
|
||||
{{self.signal("PRDATA")}} = {{self.signal("PRDATA", child, f"{child.inst_name.lower()}_idx")}};
|
||||
{{self.signal("PREADY")}} = {{self.signal("PREADY", child, f"{child.inst_name.lower()}_idx")}};
|
||||
{{self.signal("PSLVERR")}} = {{self.signal("PSLVERR", child, f"{child.inst_name.lower()}_idx")}};
|
||||
end
|
||||
{%- else -%}
|
||||
{{self.signal("PRDATA")}} = {{self.signal("PRDATA", child)}};
|
||||
{{self.signal("PREADY")}} = {{self.signal("PREADY", child)}};
|
||||
{{self.signal("PSLVERR")}} = {{self.signal("PSLVERR", child)}};
|
||||
{%- endif -%}
|
||||
{%- if loop.last -%}
|
||||
end else begin
|
||||
// No address matched
|
||||
{{self.signal("PRDATA")}} = {'hdeadbeef}[{{ds.data_width - 1}}:0]; // Indicate error on no match
|
||||
{{self.signal("PSLVERR")}} = 1'b1; // Indicate error on no match
|
||||
end
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
end else begin
|
||||
// Not a read transfer, nothing to do
|
||||
end
|
||||
end
|
||||
{%- endfor -%}
|
||||
@@ -1,4 +1,4 @@
|
||||
from .apb4_cpuif import APB4Cpuif
|
||||
from .apb4_cpuif_flat import APB4CpuifFlat
|
||||
|
||||
__all__ = ["APB4Cpuif", "APB4CpuifFlat"]
|
||||
__all__ = ["APB4Cpuif", "APB4CpuifFlat"]
|
||||
|
||||
@@ -18,9 +18,7 @@ class APB4Cpuif(BaseCpuif):
|
||||
def port_declaration(self) -> str:
|
||||
"""Returns the port declaration for the APB4 interface."""
|
||||
slave_ports: list[str] = ["apb4_intf.slave s_apb"]
|
||||
master_ports: list[str] = list(
|
||||
map(self._port_declaration, self.addressable_children)
|
||||
)
|
||||
master_ports: list[str] = list(map(self._port_declaration, self.addressable_children))
|
||||
|
||||
return ",\n".join(slave_ports + master_ports)
|
||||
|
||||
@@ -78,4 +76,4 @@ class APB4Cpuif(BaseCpuif):
|
||||
address on the bus matches the address range of the given node.
|
||||
"""
|
||||
addr_pred = self.get_address_predicate(node)
|
||||
return addr_pred
|
||||
return addr_pred
|
||||
|
||||
@@ -27,9 +27,7 @@ class Dereferencer:
|
||||
def top_node(self) -> AddrmapNode:
|
||||
return self.exp.ds.top_node
|
||||
|
||||
def get_access_strobe(
|
||||
self, obj: RegNode | FieldNode, reduce_substrobes: bool = True
|
||||
) -> str:
|
||||
def get_access_strobe(self, obj: RegNode | FieldNode, reduce_substrobes: bool = True) -> str:
|
||||
"""
|
||||
Returns the Verilog string that represents the register's access strobe
|
||||
"""
|
||||
|
||||
@@ -28,9 +28,7 @@ class BusDecoderExporter:
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
# Check for stray kwargs
|
||||
if kwargs:
|
||||
raise TypeError(
|
||||
f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'"
|
||||
)
|
||||
raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'")
|
||||
|
||||
loader = jj.ChoiceLoader(
|
||||
[
|
||||
@@ -49,9 +47,7 @@ class BusDecoderExporter:
|
||||
undefined=jj.StrictUndefined,
|
||||
)
|
||||
|
||||
def export(
|
||||
self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Any
|
||||
) -> None:
|
||||
def export(self, node: RootNode | AddrmapNode, output_dir: str, **kwargs: Any) -> None:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
@@ -88,9 +84,7 @@ class BusDecoderExporter:
|
||||
|
||||
# Check for stray kwargs
|
||||
if kwargs:
|
||||
raise TypeError(
|
||||
f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'"
|
||||
)
|
||||
raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'")
|
||||
|
||||
# Construct exporter components
|
||||
self.cpuif = cpuif_cls(self)
|
||||
@@ -139,12 +133,8 @@ class DesignState:
|
||||
# Extract compiler args
|
||||
# ------------------------
|
||||
self.reuse_hwif_typedefs: bool = kwargs.pop("reuse_hwif_typedefs", True)
|
||||
self.module_name: str = kwargs.pop("module_name", None) or kwf(
|
||||
self.top_node.inst_name
|
||||
)
|
||||
self.package_name: str = kwargs.pop("package_name", None) or (
|
||||
self.module_name + "_pkg"
|
||||
)
|
||||
self.module_name: str = kwargs.pop("module_name", None) or kwf(self.top_node.inst_name)
|
||||
self.package_name: str = kwargs.pop("package_name", None) or (self.module_name + "_pkg")
|
||||
user_addr_width: int | None = kwargs.pop("address_width", None)
|
||||
|
||||
self.cpuif_unroll: bool = kwargs.pop("cpuif_unroll", False)
|
||||
@@ -172,9 +162,7 @@ class DesignState:
|
||||
|
||||
# ------------------------
|
||||
# Min address width encloses the total size AND at least 1 useful address bit
|
||||
self.addr_width = max(
|
||||
clog2(self.top_node.size), clog2(self.cpuif_data_width // 8) + 1
|
||||
)
|
||||
self.addr_width = max(clog2(self.top_node.size), clog2(self.cpuif_data_width // 8) + 1)
|
||||
|
||||
if user_addr_width is not None:
|
||||
if user_addr_width < self.addr_width:
|
||||
|
||||
@@ -82,9 +82,7 @@ class RDLForLoopGenerator(ForLoopGenerator, RDLListener):
|
||||
walker.walk(node, self, skip_top=True)
|
||||
return self.finish()
|
||||
|
||||
def enter_AddressableComponent(
|
||||
self, node: "AddressableNode"
|
||||
) -> WalkerAction | None:
|
||||
def enter_AddressableComponent(self, node: "AddressableNode") -> WalkerAction | None:
|
||||
if not node.array_dimensions:
|
||||
return None
|
||||
|
||||
|
||||
@@ -1,42 +1,253 @@
|
||||
|
||||
# All SystemVerilog 2017 keywords
|
||||
SV_KEYWORDS = {
|
||||
'accept_on', 'alias', 'always', 'always_comb', 'always_ff', 'always_latch',
|
||||
'and', 'assert', 'assign', 'assume', 'automatic', 'before', 'begin', 'bind',
|
||||
'bins', 'binsof', 'bit', 'break', 'buf', 'bufif0', 'bufif1', 'byte', 'case',
|
||||
'casex', 'casez', 'cell', 'chandle', 'checker', 'class', 'clocking', 'cmos',
|
||||
'config', 'const', 'constraint', 'context', 'continue', 'cover', 'covergroup',
|
||||
'coverpoint', 'cross', 'deassign', 'default', 'defparam', 'design', 'disable',
|
||||
'dist', 'do', 'edge', 'else', 'end', 'endcase', 'endchecker', 'endclass',
|
||||
'endclocking', 'endconfig', 'endfunction', 'endgenerate', 'endgroup',
|
||||
'endinterface', 'endmodule', 'endpackage', 'endprimitive', 'endprogram',
|
||||
'endproperty', 'endspecify', 'endsequence', 'endtable', 'endtask', 'enum',
|
||||
'event', 'eventually', 'expect', 'export', 'extends', 'extern', 'final',
|
||||
'first_match', 'for', 'force', 'foreach', 'forever', 'fork', 'forkjoin',
|
||||
'function', 'generate', 'genvar', 'global', 'highz0', 'highz1', 'if', 'iff',
|
||||
'ifnone', 'ignore_bins', 'illegal_bins', 'implements', 'implies', 'import',
|
||||
'incdir', 'include', 'initial', 'inout', 'input', 'inside', 'instance',
|
||||
'int', 'integer', 'interconnect', 'interface', 'intersect', 'join',
|
||||
'join_any', 'join_none', 'large', 'let', 'liblist', 'library', 'local',
|
||||
'localparam', 'logic', 'longint', 'macromodule', 'matches', 'medium',
|
||||
'modport', 'module', 'nand', 'negedge', 'nettype', 'new', 'nexttime', 'nmos',
|
||||
'nor', 'noshowcancelled', 'not', 'notif0', 'notif1', 'null', 'or', 'output',
|
||||
'package', 'packed', 'parameter', 'pmos', 'posedge', 'primitive', 'priority',
|
||||
'program', 'property', 'protected', 'pull0', 'pull1', 'pulldown', 'pullup',
|
||||
'pulsestyle_ondetect', 'pulsestyle_onevent', 'pure', 'rand', 'randc',
|
||||
'randcase', 'randsequence', 'rcmos', 'real', 'realtime', 'ref', 'reg',
|
||||
'reject_on', 'release', 'repeat', 'restrict', 'return', 'rnmos', 'rpmos',
|
||||
'rtran', 'rtranif0', 'rtranif1', 's_always', 's_eventually', 's_nexttime',
|
||||
's_until', 's_until_with', 'scalared', 'sequence', 'shortint', 'shortreal',
|
||||
'showcancelled', 'signed', 'small', 'soft', 'solve', 'specify', 'specparam',
|
||||
'static', 'string', 'strong', 'strong0', 'strong1', 'struct', 'super',
|
||||
'supply0', 'supply1', 'sync_accept_on', 'sync_reject_on', 'table', 'tagged',
|
||||
'task', 'this', 'throughout', 'time', 'timeprecision', 'timeunit', 'tran',
|
||||
'tranif0', 'tranif1', 'tri', 'tri0', 'tri1', 'triand', 'trior', 'trireg',
|
||||
'type', 'typedef', 'union', 'unique', 'unique0', 'unsigned', 'until',
|
||||
'until_with', 'untyped', 'use', 'uwire', 'var', 'vectored', 'virtual', 'void',
|
||||
'wait', 'wait_order', 'wand', 'weak', 'weak0', 'weak1', 'while', 'wildcard',
|
||||
'wire', 'with', 'within', 'wor', 'xnor', 'xor'
|
||||
"accept_on",
|
||||
"alias",
|
||||
"always",
|
||||
"always_comb",
|
||||
"always_ff",
|
||||
"always_latch",
|
||||
"and",
|
||||
"assert",
|
||||
"assign",
|
||||
"assume",
|
||||
"automatic",
|
||||
"before",
|
||||
"begin",
|
||||
"bind",
|
||||
"bins",
|
||||
"binsof",
|
||||
"bit",
|
||||
"break",
|
||||
"buf",
|
||||
"bufif0",
|
||||
"bufif1",
|
||||
"byte",
|
||||
"case",
|
||||
"casex",
|
||||
"casez",
|
||||
"cell",
|
||||
"chandle",
|
||||
"checker",
|
||||
"class",
|
||||
"clocking",
|
||||
"cmos",
|
||||
"config",
|
||||
"const",
|
||||
"constraint",
|
||||
"context",
|
||||
"continue",
|
||||
"cover",
|
||||
"covergroup",
|
||||
"coverpoint",
|
||||
"cross",
|
||||
"deassign",
|
||||
"default",
|
||||
"defparam",
|
||||
"design",
|
||||
"disable",
|
||||
"dist",
|
||||
"do",
|
||||
"edge",
|
||||
"else",
|
||||
"end",
|
||||
"endcase",
|
||||
"endchecker",
|
||||
"endclass",
|
||||
"endclocking",
|
||||
"endconfig",
|
||||
"endfunction",
|
||||
"endgenerate",
|
||||
"endgroup",
|
||||
"endinterface",
|
||||
"endmodule",
|
||||
"endpackage",
|
||||
"endprimitive",
|
||||
"endprogram",
|
||||
"endproperty",
|
||||
"endspecify",
|
||||
"endsequence",
|
||||
"endtable",
|
||||
"endtask",
|
||||
"enum",
|
||||
"event",
|
||||
"eventually",
|
||||
"expect",
|
||||
"export",
|
||||
"extends",
|
||||
"extern",
|
||||
"final",
|
||||
"first_match",
|
||||
"for",
|
||||
"force",
|
||||
"foreach",
|
||||
"forever",
|
||||
"fork",
|
||||
"forkjoin",
|
||||
"function",
|
||||
"generate",
|
||||
"genvar",
|
||||
"global",
|
||||
"highz0",
|
||||
"highz1",
|
||||
"if",
|
||||
"iff",
|
||||
"ifnone",
|
||||
"ignore_bins",
|
||||
"illegal_bins",
|
||||
"implements",
|
||||
"implies",
|
||||
"import",
|
||||
"incdir",
|
||||
"include",
|
||||
"initial",
|
||||
"inout",
|
||||
"input",
|
||||
"inside",
|
||||
"instance",
|
||||
"int",
|
||||
"integer",
|
||||
"interconnect",
|
||||
"interface",
|
||||
"intersect",
|
||||
"join",
|
||||
"join_any",
|
||||
"join_none",
|
||||
"large",
|
||||
"let",
|
||||
"liblist",
|
||||
"library",
|
||||
"local",
|
||||
"localparam",
|
||||
"logic",
|
||||
"longint",
|
||||
"macromodule",
|
||||
"matches",
|
||||
"medium",
|
||||
"modport",
|
||||
"module",
|
||||
"nand",
|
||||
"negedge",
|
||||
"nettype",
|
||||
"new",
|
||||
"nexttime",
|
||||
"nmos",
|
||||
"nor",
|
||||
"noshowcancelled",
|
||||
"not",
|
||||
"notif0",
|
||||
"notif1",
|
||||
"null",
|
||||
"or",
|
||||
"output",
|
||||
"package",
|
||||
"packed",
|
||||
"parameter",
|
||||
"pmos",
|
||||
"posedge",
|
||||
"primitive",
|
||||
"priority",
|
||||
"program",
|
||||
"property",
|
||||
"protected",
|
||||
"pull0",
|
||||
"pull1",
|
||||
"pulldown",
|
||||
"pullup",
|
||||
"pulsestyle_ondetect",
|
||||
"pulsestyle_onevent",
|
||||
"pure",
|
||||
"rand",
|
||||
"randc",
|
||||
"randcase",
|
||||
"randsequence",
|
||||
"rcmos",
|
||||
"real",
|
||||
"realtime",
|
||||
"ref",
|
||||
"reg",
|
||||
"reject_on",
|
||||
"release",
|
||||
"repeat",
|
||||
"restrict",
|
||||
"return",
|
||||
"rnmos",
|
||||
"rpmos",
|
||||
"rtran",
|
||||
"rtranif0",
|
||||
"rtranif1",
|
||||
"s_always",
|
||||
"s_eventually",
|
||||
"s_nexttime",
|
||||
"s_until",
|
||||
"s_until_with",
|
||||
"scalared",
|
||||
"sequence",
|
||||
"shortint",
|
||||
"shortreal",
|
||||
"showcancelled",
|
||||
"signed",
|
||||
"small",
|
||||
"soft",
|
||||
"solve",
|
||||
"specify",
|
||||
"specparam",
|
||||
"static",
|
||||
"string",
|
||||
"strong",
|
||||
"strong0",
|
||||
"strong1",
|
||||
"struct",
|
||||
"super",
|
||||
"supply0",
|
||||
"supply1",
|
||||
"sync_accept_on",
|
||||
"sync_reject_on",
|
||||
"table",
|
||||
"tagged",
|
||||
"task",
|
||||
"this",
|
||||
"throughout",
|
||||
"time",
|
||||
"timeprecision",
|
||||
"timeunit",
|
||||
"tran",
|
||||
"tranif0",
|
||||
"tranif1",
|
||||
"tri",
|
||||
"tri0",
|
||||
"tri1",
|
||||
"triand",
|
||||
"trior",
|
||||
"trireg",
|
||||
"type",
|
||||
"typedef",
|
||||
"union",
|
||||
"unique",
|
||||
"unique0",
|
||||
"unsigned",
|
||||
"until",
|
||||
"until_with",
|
||||
"untyped",
|
||||
"use",
|
||||
"uwire",
|
||||
"var",
|
||||
"vectored",
|
||||
"virtual",
|
||||
"void",
|
||||
"wait",
|
||||
"wait_order",
|
||||
"wand",
|
||||
"weak",
|
||||
"weak0",
|
||||
"weak1",
|
||||
"while",
|
||||
"wildcard",
|
||||
"wire",
|
||||
"with",
|
||||
"within",
|
||||
"wor",
|
||||
"xnor",
|
||||
"xor",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@ module {{ds.module_name}}
|
||||
// Default all read select signals to 0
|
||||
cpuif_rd_sel = '0;
|
||||
|
||||
|
||||
if (cpuif_req && !cpuif_wr_en) begin
|
||||
// A read request is pending
|
||||
{%- for child in cpuif.addressable_children -%}
|
||||
|
||||
@@ -6,18 +6,20 @@ 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:
|
||||
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:
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
return False
|
||||
|
||||
@@ -20,16 +20,12 @@ class _FixedpointWidth(UDPDefinition):
|
||||
|
||||
# incompatible with "counter" fields
|
||||
if node.get_property("counter"):
|
||||
self.msg.error(
|
||||
"Fixed-point representations are not supported for counter fields.",
|
||||
prop_ref
|
||||
)
|
||||
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
|
||||
"Fixed-point representations are not supported for fields encoded as an enum.", prop_ref
|
||||
)
|
||||
|
||||
# ensure node width = fracwidth + intwidth
|
||||
@@ -37,7 +33,7 @@ class _FixedpointWidth(UDPDefinition):
|
||||
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
|
||||
prop_ref,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ class xBufferTrigger(UDPDefinition):
|
||||
|
||||
if value is NoValue:
|
||||
self.msg.error(
|
||||
"Double-buffer trigger property is missing a value assignment",
|
||||
self.get_src_ref(node)
|
||||
"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
|
||||
@@ -25,17 +24,19 @@ class xBufferTrigger(UDPDefinition):
|
||||
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
|
||||
type(node.inst).__name__.lower(),
|
||||
node.inst_name,
|
||||
type(value.inst).__name__.lower(),
|
||||
value.inst_name,
|
||||
),
|
||||
self.get_src_ref(node)
|
||||
self.get_src_ref(node),
|
||||
)
|
||||
|
||||
if isinstance(value, SignalNode):
|
||||
if not value.get_property('activehigh') and not value.get_property('activelow'):
|
||||
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)
|
||||
self.get_src_ref(node),
|
||||
)
|
||||
|
||||
elif isinstance(value, PropertyReference) and value.width is not None:
|
||||
@@ -44,10 +45,12 @@ class xBufferTrigger(UDPDefinition):
|
||||
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,
|
||||
type(node.inst).__name__.lower(),
|
||||
node.inst_name,
|
||||
value.node.inst_name,
|
||||
value.name,
|
||||
),
|
||||
self.get_src_ref(node)
|
||||
self.get_src_ref(node),
|
||||
)
|
||||
elif isinstance(value, RegNode):
|
||||
# Trigger can reference a register, which implies access of the
|
||||
@@ -60,34 +63,35 @@ class xBufferTrigger(UDPDefinition):
|
||||
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)
|
||||
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:
|
||||
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)
|
||||
self.get_src_ref(node),
|
||||
)
|
||||
|
||||
def get_unassigned_default(self, node: 'Node') -> Any:
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
return False
|
||||
|
||||
|
||||
class WBufferTrigger(xBufferTrigger):
|
||||
name = "wbuffer_trigger"
|
||||
|
||||
def get_unassigned_default(self, node: 'Node') -> Any:
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
# If buffering is enabled, trigger is the register itself
|
||||
if node.get_property('buffer_writes'):
|
||||
if node.get_property("buffer_writes"):
|
||||
return node
|
||||
return None
|
||||
|
||||
@@ -107,24 +111,24 @@ class BufferReads(UDPDefinition):
|
||||
valid_components = {Reg}
|
||||
valid_type = bool
|
||||
|
||||
def validate(self, node: 'Node', value: Any) -> None:
|
||||
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)
|
||||
self.get_src_ref(node),
|
||||
)
|
||||
|
||||
def get_unassigned_default(self, node: 'Node') -> Any:
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
return False
|
||||
|
||||
|
||||
class RBufferTrigger(xBufferTrigger):
|
||||
name = "rbuffer_trigger"
|
||||
|
||||
def get_unassigned_default(self, node: 'Node') -> Any:
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
# If buffering is enabled, trigger is the register itself
|
||||
if node.get_property('buffer_reads'):
|
||||
if node.get_property("buffer_reads"):
|
||||
return node
|
||||
return None
|
||||
|
||||
@@ -16,14 +16,14 @@ class IsSigned(UDPDefinition):
|
||||
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"]
|
||||
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"]
|
||||
node.inst.property_src_ref["is_signed"],
|
||||
)
|
||||
|
||||
def get_unassigned_default(self, node: "Node") -> Any:
|
||||
|
||||
@@ -49,9 +49,7 @@ class DesignValidator(RDLListener):
|
||||
if isinstance(value, PropertyReference):
|
||||
src_ref = value.src_ref
|
||||
else:
|
||||
src_ref = node.inst.property_src_ref.get(
|
||||
prop_name, node.inst.inst_src_ref
|
||||
)
|
||||
src_ref = node.inst.property_src_ref.get(prop_name, node.inst.inst_src_ref)
|
||||
self.msg.error(
|
||||
"Property is assigned a reference that points to a component not internal to the busdecoder being exported.",
|
||||
src_ref,
|
||||
@@ -125,9 +123,9 @@ class DesignValidator(RDLListener):
|
||||
def enter_Field(self, node: "FieldNode") -> None:
|
||||
parent_accesswidth = node.parent.get_property("accesswidth")
|
||||
parent_regwidth = node.parent.get_property("regwidth")
|
||||
if (parent_accesswidth < parent_regwidth) and (
|
||||
node.lsb // parent_accesswidth
|
||||
) != (node.msb // parent_accesswidth):
|
||||
if (parent_accesswidth < parent_regwidth) and (node.lsb // parent_accesswidth) != (
|
||||
node.msb // parent_accesswidth
|
||||
):
|
||||
# field spans multiple sub-words
|
||||
|
||||
if node.is_sw_writable and not node.parent.get_property("buffer_writes"):
|
||||
@@ -141,9 +139,7 @@ class DesignValidator(RDLListener):
|
||||
node.inst.inst_src_ref,
|
||||
)
|
||||
|
||||
if node.get_property("onread") is not None and not node.parent.get_property(
|
||||
"buffer_reads"
|
||||
):
|
||||
if node.get_property("onread") is not None and not node.parent.get_property("buffer_reads"):
|
||||
# ... is modified by an onread action without the atomicity of read buffering
|
||||
# Enforce 10.6.1-f
|
||||
self.msg.error(
|
||||
|
||||
Reference in New Issue
Block a user