Skip to content
Snippets Groups Projects
Commit bdbc7a24 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Improve memory port rendering (although currently faked)

parent d3244f31
No related branches found
No related tags found
1 merge request!350Improve memory port rendering (although currently faked)
Pipeline #96703 passed
......@@ -104,7 +104,7 @@ class Resource:
if outputs:
outstrs = [f"<{outstr}> {outstr}" for outstr in outputs]
ret += f"|{{{'|'.join(outstrs)}}}"
return ret
return "{" + ret + "}"
@property
def entity_name(self) -> str:
......@@ -243,16 +243,16 @@ class Architecture:
self._memories = memories
self._entity_name = entity_name
self._direct_interconnects = direct_interconnects
self._variable_inport_to_resource: Dict[InputPort, Resource] = {}
self._variable_outport_to_resource: Dict[OutputPort, Resource] = {}
self._variable_inport_to_resource: Dict[InputPort, Tuple[Resource, int]] = {}
self._variable_outport_to_resource: Dict[OutputPort, Tuple[Resource, int]] = {}
self._operation_inport_to_resource: Dict[InputPort, Resource] = {}
self._operation_outport_to_resource: Dict[OutputPort, Resource] = {}
self._build_dicts()
# Validate input and output ports
self.validate_ports()
self._build_dicts()
def _build_dicts(self):
for pe in self.processing_elements:
for operator in pe.processes:
......@@ -264,18 +264,20 @@ class Architecture:
for memory in self.memories:
for mv in memory:
for read_port in mv.read_ports:
self._variable_inport_to_resource[read_port] = memory
self._variable_outport_to_resource[mv.write_port] = memory
self._variable_inport_to_resource[read_port] = (memory, 0) # Fix
self._variable_outport_to_resource[mv.write_port] = (memory, 0) # Fix
if self._direct_interconnects:
for di in self._direct_interconnects:
di = cast(MemoryVariable, di)
for read_port in di.read_ports:
self._variable_inport_to_resource[
read_port
] = self._operation_outport_to_resource[di.write_port]
self._variable_outport_to_resource[
di.write_port
] = self._operation_inport_to_resource[read_port]
self._variable_inport_to_resource[read_port] = (
self._operation_outport_to_resource[di.write_port],
di.write_port.index,
)
self._variable_outport_to_resource[di.write_port] = (
self._operation_inport_to_resource[read_port],
read_port.index,
)
def validate_ports(self):
# Validate inputs and outputs of memory variables in all the memories in this
......@@ -350,7 +352,9 @@ class Architecture:
def get_interconnects_for_pe(
self, pe: ProcessingElement
) -> Tuple[List[Dict[Resource, int]], List[Dict[Resource, int]]]:
) -> Tuple[
List[Dict[Tuple[Resource, int], int]], List[Dict[Tuple[Resource, int], int]]
]:
"""
Return lists of dictionaries with interconnect information for a
ProcessingElement.
......@@ -402,7 +406,9 @@ class Architecture:
return self._digraph()._repr_mimebundle_(include=["image/png"])["image/png"]
def _digraph(self) -> Digraph:
edges = set()
dg = Digraph(node_attr={'shape': 'record'})
# dg.attr(rankdir="LR")
for i, mem in enumerate(self._memories):
dg.node(mem.entity_name, mem._struct_def())
for i, pe in enumerate(self._processing_elements):
......@@ -410,15 +416,25 @@ class Architecture:
for pe in self._processing_elements:
inputs, outputs = self.get_interconnects_for_pe(pe)
for i, inp in enumerate(inputs):
for source, cnt in inp.items():
dg.edge(
source.entity_name, f"{pe.entity_name}:in{i}", label=f"{cnt}"
for (source, port), cnt in inp.items():
edges.add(
(
f"{source.entity_name}:out{port}",
f"{pe.entity_name}:in{i}",
f"{cnt}",
)
)
for o, outp in enumerate(outputs):
for dest, cnt in outp.items():
dg.edge(
f"{pe.entity_name}:out{o}", dest.entity_name, label=f"{cnt}"
for (dest, port), cnt in outp.items():
edges.add(
(
f"{pe.entity_name}:out{o}",
f"{dest.entity_name}:in{port}",
f"{cnt}",
)
)
for src, dest, cnt in edges:
dg.edge(src, dest, label=cnt)
return dg
@property
......
......@@ -84,3 +84,31 @@ for i, mem in enumerate(mem_vars_set):
# %%
# Create architecture
arch = Architecture({p1, p2, p_in, p_out}, memories, direct_interconnects=direct)
# %%
# The architecture can be rendered in enriched shells.
#
# .. graphviz::
#
# digraph {
# node [shape=record]
# memory1 [label="{{<in0> in0}|memory1|{<out0> out0}}"]
# memory0 [label="{{<in0> in0}|memory0|{<out0> out0}}"]
# memory2 [label="{{<in0> in0}|memory2|{<out0> out0}}"]
# in [label="{in|{<out0> out0}}"]
# out [label="{{<in0> in0}|out}"]
# cmul [label="{{<in0> in0}|cmul|{<out0> out0}}"]
# adder [label="{{<in0> in0|<in1> in1}|adder|{<out0> out0}}"]
# memory1:out0 -> adder:in1 [label=1]
# cmul:out0 -> adder:in0 [label=1]
# cmul:out0 -> memory0:in0 [label=3]
# memory0:out0 -> adder:in0 [label=1]
# adder:out0 -> adder:in1 [label=1]
# memory1:out0 -> cmul:in0 [label=5]
# memory0:out0 -> adder:in1 [label=2]
# adder:out0 -> memory1:in0 [label=2]
# adder:out0 -> out:in0 [label=1]
# memory2:out0 -> adder:in0 [label=2]
# cmul:out0 -> memory2:in0 [label=2]
# in:out0 -> cmul:in0 [label=1]
# }
......@@ -89,9 +89,9 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
s = (
'digraph {\n\tnode [shape=record]\n\t'
+ pe._entity_name
+ ' [label="{<in0> in0|<in1> in1}|'
+ ' [label="{{<in0> in0|<in1> in1}|'
+ pe._entity_name
+ '|{<out0> out0}"]\n}'
+ '|{<out0> out0}}"]\n}'
)
assert pe._digraph().source in (s, s + '\n')
......@@ -107,8 +107,8 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
for i, memory in enumerate(memories):
memory.set_entity_name(f"MEM{i}")
s = (
'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{<in0> in0}|MEM0|{<out0>'
' out0}"]\n}'
'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{{<in0> in0}|MEM0|{<out0>'
' out0}}"]\n}'
)
assert memory._digraph().source in (s, s + '\n')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment