Files
PeakRDL-regblock/src/peakrdl_regblock/read_buffering/__init__.py

60 lines
2.0 KiB
Python

from typing import TYPE_CHECKING, Union
from systemrdl.node import AddrmapNode, RegNode, SignalNode
from .storage_generator import RBufStorageStructGenerator
from .implementation_generator import RBufLogicGenerator
from ..utils import get_indexed_path
from ..sv_int import SVInt
if TYPE_CHECKING:
from ..exporter import RegblockExporter
class ReadBuffering:
def __init__(self, exp:'RegblockExporter'):
self.exp = exp
@property
def top_node(self) -> 'AddrmapNode':
return self.exp.ds.top_node
def get_storage_struct(self) -> str:
struct_gen = RBufStorageStructGenerator()
s = struct_gen.get_struct(self.top_node, "rbuf_storage_t")
assert s is not None
return s + "\nrbuf_storage_t rbuf_storage;"
def get_implementation(self) -> str:
gen = RBufLogicGenerator(self)
s = gen.get_content(self.top_node)
assert s is not None
return s
def get_trigger(self, node: RegNode) -> str:
trigger = node.get_property('rbuffer_trigger')
if isinstance(trigger, RegNode):
# Trigger is a register.
# trigger when lowermost address of the register is written
regwidth = node.get_property('regwidth')
accesswidth = node.get_property('accesswidth')
strb_prefix = self.exp.dereferencer.get_access_strobe(trigger, reduce_substrobes=False)
if accesswidth < regwidth:
return f"{strb_prefix}[0] && !decoded_req_is_wr"
else:
return f"{strb_prefix} && !decoded_req_is_wr"
elif isinstance(trigger, SignalNode):
s = self.exp.dereferencer.get_value(trigger)
if trigger.get_property('activehigh'):
return str(s)
else:
return f"~{s}"
else:
# Trigger is a field or propref bit
return str(self.exp.dereferencer.get_value(trigger))
def get_rbuf_data(self, node: RegNode) -> str:
return "rbuf_storage." + get_indexed_path(self.top_node, node) + ".data"