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

Add methods to architecture

parent dd6a54f3
No related branches found
No related tags found
1 merge request!356Add methods to architecture
Pipeline #96761 passed
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
B-ASIC architecture classes. B-ASIC architecture classes.
""" """
from collections import defaultdict from collections import defaultdict
from io import TextIOWrapper
from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union, cast from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union, cast
from graphviz import Digraph from graphviz import Digraph
...@@ -77,6 +78,37 @@ class HardwareBlock: ...@@ -77,6 +78,37 @@ class HardwareBlock:
def _digraph(self) -> Digraph: def _digraph(self) -> Digraph:
raise NotImplementedError() raise NotImplementedError()
@property
def schedule_time(self) -> int:
"""The schedule time for hardware block"""
raise NotImplementedError()
def write_component_declaration(self, f: TextIOWrapper, indent: int = 1) -> None:
"""
Write component declaration of hardware block.
Parameters
----------
f : TextIOWrapper
File object (or other TextIOWrapper object) to write the declaration to.
indent : int, default: 1
Indentation level to use for this process.
"""
raise NotImplementedError()
def write_component_instantiation(self, f: TextIOWrapper, indent: int = 1) -> None:
"""
Write component instantiation of hardware block.
Parameters
----------
f : TextIOWrapper
File object (or other TextIOWrapper object) to write the instantiation to.
indent : int, default: 1
Indentation level to use for this process.
"""
raise NotImplementedError()
class Resource(HardwareBlock): class Resource(HardwareBlock):
""" """
...@@ -135,6 +167,11 @@ class Resource(HardwareBlock): ...@@ -135,6 +167,11 @@ class Resource(HardwareBlock):
ret += f"|{{{'|'.join(outstrs)}}}" ret += f"|{{{'|'.join(outstrs)}}}"
return "{" + ret + "}" return "{" + ret + "}"
@property
def schedule_time(self) -> int:
# doc-string inherited
return self._collection.schedule_time
class ProcessingElement(Resource): class ProcessingElement(Resource):
""" """
...@@ -277,11 +314,25 @@ of :class:`~b_asic.architecture.ProcessingElement` ...@@ -277,11 +314,25 @@ of :class:`~b_asic.architecture.ProcessingElement`
self._operation_inport_to_resource: Dict[InputPort, Resource] = {} self._operation_inport_to_resource: Dict[InputPort, Resource] = {}
self._operation_outport_to_resource: Dict[OutputPort, Resource] = {} self._operation_outport_to_resource: Dict[OutputPort, Resource] = {}
self._schedule_time = self._check_and_get_schedule_time()
# Validate input and output ports # Validate input and output ports
self.validate_ports() self.validate_ports()
self._build_dicts() self._build_dicts()
def _check_and_get_schedule_time(self) -> int:
schedule_times = set()
for memory in self._memories:
schedule_times.add(memory.schedule_time)
for pe in self._processing_elements:
schedule_times.add(pe.schedule_time)
if self._direct_interconnects is not None:
schedule_times.add(self._direct_interconnects.schedule_time)
if len(schedule_times) != 1:
raise ValueError(f"Different schedule times: {schedule_times}")
return schedule_times.pop()
def _build_dicts(self): def _build_dicts(self):
for pe in self.processing_elements: for pe in self.processing_elements:
for operator in pe.processes: for operator in pe.processes:
...@@ -446,3 +497,8 @@ of :class:`~b_asic.architecture.ProcessingElement` ...@@ -446,3 +497,8 @@ of :class:`~b_asic.architecture.ProcessingElement`
@property @property
def direct_interconnects(self) -> Optional[ProcessCollection]: def direct_interconnects(self) -> Optional[ProcessCollection]:
return self._direct_interconnects return self._direct_interconnects
@property
def schedule_time(self) -> int:
# doc-string inherited
return self._schedule_time
...@@ -26,14 +26,14 @@ def memory_based_storage( ...@@ -26,14 +26,14 @@ def memory_based_storage(
Parameters Parameters
---------- ----------
f : TextIOWrapper
File object (or other TextIOWrapper object) to write the architecture onto.
assignment : dict assignment : dict
A possible cell assignment to use when generating the memory based storage. A possible cell assignment to use when generating the memory based storage.
The cell assignment is a dictionary int to ProcessCollection where the integer The cell assignment is a dictionary int to ProcessCollection where the integer
corresponds to the cell to assign all MemoryVariables in corresponding process corresponds to the cell to assign all MemoryVariables in corresponding process
collection. collection.
If unset, each MemoryVariable will be assigned to a unique cell. If unset, each MemoryVariable will be assigned to a unique cell.
f : TextIOWrapper
File object (or other TextIOWrapper object) to write the architecture onto.
word_length : int word_length : int
Word length of the memory variable objects. Word length of the memory variable objects.
read_ports : int read_ports : int
......
...@@ -110,6 +110,7 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule): ...@@ -110,6 +110,7 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{{<in0> in0}|MEM0|{<out0>' 'digraph {\n\tnode [shape=record]\n\tMEM0 [label="{{<in0> in0}|MEM0|{<out0>'
' out0}}"]\n}' ' out0}}"]\n}'
) )
assert memory.schedule_time == 18
assert memory._digraph().source in (s, s + '\n') assert memory._digraph().source in (s, s + '\n')
# Create architecture from # Create architecture from
...@@ -117,9 +118,12 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule): ...@@ -117,9 +118,12 @@ def test_architecture(schedule_direct_form_iir_lp_filter: Schedule):
processing_elements, memories, direct_interconnects=direct_conn processing_elements, memories, direct_interconnects=direct_conn
) )
assert architecture.schedule_time == 18
# assert architecture._digraph().source == "foo" # assert architecture._digraph().source == "foo"
for pe in processing_elements: for pe in processing_elements:
print(pe) print(pe)
assert pe.schedule_time == 18
for operation in pe._collection: for operation in pe._collection:
operation = cast(OperatorProcess, operation) operation = cast(OperatorProcess, operation)
print(f' {operation}') print(f' {operation}')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment