Use sized integer literals in comparisons. #49

This commit is contained in:
Alex Mykyta
2023-06-14 21:58:41 -07:00
parent ac3f466fb2
commit b056a443f1
9 changed files with 43 additions and 35 deletions

View File

@@ -157,7 +157,7 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
# Is an external block
addr_str = self._get_address_str(node)
strb = self.addr_decode.get_external_block_access_strobe(node)
rhs = f"cpuif_req_masked & (cpuif_addr >= {addr_str}) & (cpuif_addr <= {addr_str} + {get_sv_int(node.size - 1)})"
rhs = f"cpuif_req_masked & (cpuif_addr >= {addr_str}) & (cpuif_addr <= {addr_str} + {get_sv_int(node.size - 1, self.addr_decode.exp.ds.addr_width)})"
self.add_content(f"{strb} = {rhs};")
self.add_content(f"is_external |= {rhs};")
return WalkerAction.SkipDescendants
@@ -166,9 +166,12 @@ class DecodeLogicGenerator(RDLForLoopGenerator):
def _get_address_str(self, node: 'AddressableNode', subword_offset: int=0) -> str:
a = get_sv_int(node.raw_absolute_address - self.addr_decode.top_node.raw_absolute_address + subword_offset)
a = get_sv_int(
node.raw_absolute_address - self.addr_decode.top_node.raw_absolute_address + subword_offset,
self.addr_decode.exp.ds.addr_width
)
for i, stride in enumerate(self._array_stride_stack):
a += f" + i{i}*{get_sv_int(stride)}"
a += f" + i{i}*{get_sv_int(stride, self.addr_decode.exp.ds.addr_width)}"
return a

View File

@@ -78,7 +78,7 @@ always_comb begin
axil_ar_accept = '0;
axil_aw_accept = '0;
if(axil_n_in_flight < 'd{{cpuif.max_outstanding}}) begin
if(axil_n_in_flight < {{clog2(cpuif.max_outstanding+1)}}'d{{cpuif.max_outstanding}}) begin
// Can safely issue more transactions without overwhelming response buffer
if(axil_arvalid && !axil_prev_was_rd) begin
cpuif_req = '1;

View File

@@ -38,7 +38,7 @@ class Dereferencer:
def top_node(self) -> AddrmapNode:
return self.exp.ds.top_node
def get_value(self, obj: Union[int, FieldNode, SignalNode, PropertyReference]) -> str:
def get_value(self, obj: Union[int, FieldNode, SignalNode, PropertyReference], width: Optional[int] = None) -> str:
"""
Returns the Verilog string that represents the readable value associated
with the object.
@@ -47,10 +47,12 @@ class Dereferencer:
If obj references a structural systemrdl object, then the corresponding Verilog
expression is returned that represents its value.
The optional width argument can be provided to hint at the expression's desired bitwidth.
"""
if isinstance(obj, int):
# Is a simple scalar value
return get_sv_int(obj)
return get_sv_int(obj, width)
if isinstance(obj, FieldNode):
if obj.implements_storage:

View File

@@ -10,7 +10,7 @@ from .field_logic import FieldLogic
from .dereferencer import Dereferencer
from .readback import Readback
from .identifier_filter import kw_filter as kwf
from .utils import clog2
from .scan_design import DesignScanner
from .validate_design import DesignValidator
from .cpuif import CpuifBase
@@ -134,9 +134,6 @@ class RegblockExporter:
if kwargs:
raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'")
# Scan the design for pre-export information
DesignScanner(self).do_scan()
if generate_hwif_report:
path = os.path.join(output_dir, f"{self.ds.module_name}_hwif.rpt")
hwif_report_file = open(path, "w", encoding='utf-8') # pylint: disable=consider-using-with
@@ -251,9 +248,13 @@ class DesignState:
# Track any referenced enums
self.user_enums = [] # type: List[Type[UserEnum]]
#------------------------
# Scan the design to fill in above variables
DesignScanner(self).do_scan()
#------------------------
# 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 = (self.top_node.size - 1).bit_length()
if user_addr_width is not None:
if user_addr_width < self.addr_width:
msg.fatal(f"User-specified address width shall be greater than or equal to {self.addr_width}.")

View File

@@ -110,7 +110,7 @@ class FieldLogic:
"""
incrvalue = field.get_property('incrvalue')
if incrvalue is not None:
return self.exp.dereferencer.get_value(incrvalue)
return self.exp.dereferencer.get_value(incrvalue, field.width)
if field.get_property('incrwidth'):
return self.exp.hwif.get_implied_prop_input_identifier(field, "incrvalue")
return "1'b1"
@@ -118,8 +118,8 @@ class FieldLogic:
def get_counter_incrsaturate_value(self, field: 'FieldNode') -> str:
prop_value = field.get_property('incrsaturate')
if prop_value is True:
return self.exp.dereferencer.get_value(2**field.width - 1)
return self.exp.dereferencer.get_value(prop_value)
return self.exp.dereferencer.get_value(2**field.width - 1, field.width)
return self.exp.dereferencer.get_value(prop_value, field.width)
def counter_incrsaturates(self, field: 'FieldNode') -> bool:
"""
@@ -131,8 +131,8 @@ class FieldLogic:
prop_value = field.get_property('incrthreshold')
if isinstance(prop_value, bool):
# No explicit value set. use max
return self.exp.dereferencer.get_value(2**field.width - 1)
return self.exp.dereferencer.get_value(prop_value)
return self.exp.dereferencer.get_value(2**field.width - 1, field.width)
return self.exp.dereferencer.get_value(prop_value, field.width)
def get_counter_decr_strobe(self, field: 'FieldNode') -> str:
"""
@@ -151,7 +151,7 @@ class FieldLogic:
"""
decrvalue = field.get_property('decrvalue')
if decrvalue is not None:
return self.exp.dereferencer.get_value(decrvalue)
return self.exp.dereferencer.get_value(decrvalue, field.width)
if field.get_property('decrwidth'):
return self.exp.hwif.get_implied_prop_input_identifier(field, "decrvalue")
return "1'b1"
@@ -159,8 +159,8 @@ class FieldLogic:
def get_counter_decrsaturate_value(self, field: 'FieldNode') -> str:
prop_value = field.get_property('decrsaturate')
if prop_value is True:
return "'d0"
return self.exp.dereferencer.get_value(prop_value)
return f"{field.width}'d0"
return self.exp.dereferencer.get_value(prop_value, field.width)
def counter_decrsaturates(self, field: 'FieldNode') -> bool:
"""
@@ -172,8 +172,8 @@ class FieldLogic:
prop_value = field.get_property('decrthreshold')
if isinstance(prop_value, bool):
# No explicit value set. use min
return "'d0"
return self.exp.dereferencer.get_value(prop_value)
return f"{field.width}'d0"
return self.exp.dereferencer.get_value(prop_value, field.width)
def get_swacc_identifier(self, field: 'FieldNode') -> str:
"""

View File

@@ -220,7 +220,7 @@ class FieldLogicGenerator(RDLForLoopGenerator):
reset_value = node.get_property('reset')
if reset_value is not None:
reset_value_str = self.exp.dereferencer.get_value(reset_value)
reset_value_str = self.exp.dereferencer.get_value(reset_value, node.width)
else:
# 5.9.1-g: If no reset value given, the field is not reset, even if it has a resetsignal.
reset_value_str = None

View File

@@ -7,7 +7,7 @@
next_c = next_c + {{field_logic.get_counter_incrvalue(node)}};
end
{%- else %}
{{field_logic.get_field_combo_identifier(node, "overflow")}} = ((({{node.width+1}})'(next_c) + {{field_logic.get_counter_incrvalue(node)}}) > {{get_value(2**node.width - 1)}});
{{field_logic.get_field_combo_identifier(node, "overflow")}} = ((({{node.width+1}})'(next_c) + {{field_logic.get_counter_incrvalue(node)}}) > {{get_value(2**node.width - 1, node.width)}});
next_c = next_c + {{field_logic.get_counter_incrvalue(node)}};
{%- endif %}
load_next_c = '1;

View File

@@ -5,7 +5,7 @@ from systemrdl.node import SignalNode, RegNode
if TYPE_CHECKING:
from systemrdl.node import Node, FieldNode, AddressableNode, AddrmapNode
from .exporter import RegblockExporter
from .exporter import DesignState
class DesignScanner(RDLListener):
@@ -15,14 +15,13 @@ class DesignScanner(RDLListener):
Also collects any information that is required prior to the start of the export process.
"""
def __init__(self, exp:'RegblockExporter') -> None:
self.exp = exp
self.ds = exp.ds
def __init__(self, ds:'DesignState') -> None:
self.ds = ds
self.msg = self.top_node.env.msg
@property
def top_node(self) -> 'AddrmapNode':
return self.exp.ds.top_node
return self.ds.top_node
def _get_out_of_hier_field_reset(self) -> None:
current_node = self.top_node.parent
@@ -93,7 +92,7 @@ class DesignScanner(RDLListener):
def enter_Reg(self, node: 'RegNode') -> None:
# The CPUIF's bus width is sized according to the largest accesswidth in the design
accesswidth = node.get_property('accesswidth')
self.exp.ds.cpuif_data_width = max(self.exp.ds.cpuif_data_width, accesswidth)
self.ds.cpuif_data_width = max(self.ds.cpuif_data_width, accesswidth)
self.ds.has_buffered_write_regs = self.ds.has_buffered_write_regs or bool(node.get_property('buffer_writes'))
self.ds.has_buffered_read_regs = self.ds.has_buffered_read_regs or bool(node.get_property('buffer_reads'))

View File

@@ -1,5 +1,5 @@
import re
from typing import Match, Union
from typing import Match, Union, Optional
from systemrdl.rdltypes.references import PropertyReference
from systemrdl.node import Node, AddrmapNode
@@ -65,10 +65,13 @@ def ref_is_internal(top_node: AddrmapNode, ref: Union[Node, PropertyReference])
# This is considerd internal for this exporter
return True
def get_sv_int(n: int) -> str:
if n.bit_length() <= 32:
return f"'h{n:x}"
else:
def get_sv_int(n: int, width: Optional[int]=None) -> str:
if width is not None:
# Explicit width
return f"{width}'h{n:x}"
elif n.bit_length() > 32:
# SV standard only enforces that unsized literals shall be at least 32-bits
# To support larger literals, they need to be sized explicitly
return f"{n.bit_length()}'h{n:x}"
else:
return f"'h{n:x}"