Add support for external components. (#4 & #36)

This commit is contained in:
Alex Mykyta
2023-05-03 21:57:25 -07:00
parent f1a75f8d38
commit ca9185dac7
35 changed files with 1341 additions and 78 deletions

View File

@@ -9,9 +9,10 @@ if TYPE_CHECKING:
from systemrdl.node import AddrmapNode
class Readback:
def __init__(self, exp:'RegblockExporter', do_fanin_stage: bool):
def __init__(self, exp:'RegblockExporter', do_fanin_stage: bool, has_external_addressable: bool):
self.exp = exp
self.do_fanin_stage = do_fanin_stage
self.has_external_addressable = has_external_addressable
@property
def top_node(self) -> 'AddrmapNode':
@@ -33,6 +34,7 @@ class Readback:
"get_always_ff_event": lambda resetsignal : get_always_ff_event(self.exp.dereferencer, resetsignal),
"cpuif": self.exp.cpuif,
"do_fanin_stage": self.do_fanin_stage,
"has_external_addressable": self.has_external_addressable,
}
if self.do_fanin_stage:

View File

@@ -1,6 +1,7 @@
from typing import TYPE_CHECKING, List
from systemrdl.node import RegNode
from systemrdl.node import RegNode, AddressableNode
from systemrdl.walker import WalkerAction
from ..forloop_generator import RDLForLoopGenerator, LoopBody
@@ -77,9 +78,26 @@ class ReadbackAssignmentGenerator(RDLForLoopGenerator):
self.current_offset = start_offset + n_regs * dim
def enter_Reg(self, node: RegNode) -> None:
def enter_AddressableComponent(self, node: 'AddressableNode') -> WalkerAction:
super().enter_AddressableComponent(node)
if node.external and not isinstance(node, RegNode):
# External block
strb = self.exp.hwif.get_external_rd_ack(node)
data = self.exp.hwif.get_external_rd_data(node)
self.add_content(f"assign readback_array[{self.current_offset_str}] = {strb} ? {data} : '0;")
self.current_offset += 1
return WalkerAction.SkipDescendants
return WalkerAction.Continue
def enter_Reg(self, node: RegNode) -> WalkerAction:
if node.external:
self.process_external_reg(node)
return WalkerAction.SkipDescendants
if not node.has_sw_readable:
return
return WalkerAction.SkipDescendants
accesswidth = node.get_property('accesswidth')
regwidth = node.get_property('regwidth')
@@ -100,6 +118,19 @@ class ReadbackAssignmentGenerator(RDLForLoopGenerator):
else:
self.process_reg(node)
return WalkerAction.SkipDescendants
def process_external_reg(self, node: RegNode) -> None:
strb = self.exp.hwif.get_external_rd_ack(node)
data = self.exp.hwif.get_external_rd_data(node)
regwidth = node.get_property('regwidth')
if regwidth < self.exp.cpuif.data_width:
self.add_content(f"assign readback_array[{self.current_offset_str}][{self.exp.cpuif.data_width-1}:{regwidth}] = '0;")
self.add_content(f"assign readback_array[{self.current_offset_str}][{regwidth-1}:0] = {strb} ? {data} : '0;")
else:
self.add_content(f"assign readback_array[{self.current_offset_str}] = {strb} ? {data} : '0;")
self.current_offset += 1
def process_reg(self, node: RegNode) -> None:
current_bit = 0

View File

@@ -35,7 +35,11 @@ always_ff @(posedge clk) begin
readback_done_r <= '0;
end else begin
readback_array_r <= readback_array_c;
{%- if has_external_addressable %}
readback_done_r <= decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
{%- else %}
readback_done_r <= decoded_req & ~decoded_req_is_wr;
{%- endif %}
end
end
@@ -54,7 +58,11 @@ end
// Reduce the array
always_comb begin
automatic logic [{{cpuif.data_width-1}}:0] readback_data_var;
{%- if has_external_addressable %}
readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
{%- else %}
readback_done = decoded_req & ~decoded_req_is_wr;
{%- endif %}
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<{{array_size}}; i++) readback_data_var |= readback_array[i];