Newer
Older
Angus Lothian
committed
Contains operations with special purposes that may be treated differently from
normal operations in an SFG.
"""
from typing import Optional, Sequence, Tuple
Angus Lothian
committed
from b_asic.operation import (
AbstractOperation,
DelayMap,
MutableDelayMap,
MutableResultMap,
)
Angus Lothian
committed
from b_asic.port import SignalSourceProvider
Angus Lothian
committed
class Input(AbstractOperation):
Angus Lothian
committed
Angus Lothian
committed
Its value will be updated on each iteration when simulating the SFG.
Parameters
==========
name : Name, optional
Operation name.
Angus Lothian
committed
"""
Angus Lothian
committed
"""Construct an Input operation."""
super().__init__(
input_count=0,
output_count=1,
Angus Lothian
committed
self.set_param("value", 0)
@classmethod
def type_name(cls) -> TypeName:
Angus Lothian
committed
def evaluate(self):
return self.param("value")
@property
def latency(self) -> int:
return self.latency_offsets["out0"]
Angus Lothian
committed
@property
Angus Lothian
committed
"""Get the current value of this input."""
return self.param("value")
@value.setter
Angus Lothian
committed
"""Set the current value of this input."""
self.set_param("value", value)
) -> Tuple[Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]]:
(
(-0.5, 0),
(-0.5, 1),
(-0.25, 1),
(0, 0.5),
(-0.25, 0),
(-0.5, 0),
),
(
(-0.5, 0),
(-0.5, 1),
(-0.25, 1),
(0, 0.5),
(-0.25, 0),
(-0.5, 0),
),
def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
# doc-string inherited
return tuple()
def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
# doc-string inherited
return ((0, 0.5),)
Angus Lothian
committed
class Output(AbstractOperation):
Angus Lothian
committed
Angus Lothian
committed
The SFG will forward its input to the corresponding output signal
destinations.
Parameters
==========
src0 : SignalSourceProvider, optional
The signal connected to the Output operation.
name : Name, optional
Operation name.
Angus Lothian
committed
"""
self,
src0: Optional[SignalSourceProvider] = None,
name: Name = Name(""),
Angus Lothian
committed
"""Construct an Output operation."""
super().__init__(
input_count=1,
output_count=0,
input_sources=[src0],
latency_offsets={"in0": 0},
Angus Lothian
committed
@classmethod
def type_name(cls) -> TypeName:
Angus Lothian
committed
def evaluate(self, _):
return None
) -> Tuple[Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]]:
((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
# doc-string inherited
return ((0, 0.5),)
def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
# doc-string inherited
return tuple()
@property
def latency(self) -> int:
return self.latency_offsets["in0"]
Angus Lothian
committed
class Delay(AbstractOperation):
Angus Lothian
committed
Represents a delay of one iteration.
The initial value is zero unless otherwise specified.
Parameters
----------
src0 : SignalSourceProvider, optional
The node to be delayed.
initial_value : Number, default: 0
Initial value of the delay.
name : Name, default ""
Name.
Angus Lothian
committed
"""
def __init__(
self,
src0: Optional[SignalSourceProvider] = None,
Angus Lothian
committed
"""Construct a Delay operation."""
input_count=1,
output_count=1,
name=Name(name),
input_sources=[src0],
Angus Lothian
committed
self.set_param("initial_value", initial_value)
@classmethod
def type_name(cls) -> TypeName:
Angus Lothian
committed
def evaluate(self, a):
return self.param("initial_value")
def current_output(
self, index: int, delays: Optional[DelayMap] = None, prefix: str = ""
Angus Lothian
committed
if delays is not None:
return delays.get(self.key(index, prefix), self.param("initial_value"))
Angus Lothian
committed
return self.param("initial_value")
results: Optional[MutableResultMap] = None,
delays: Optional[MutableDelayMap] = None,
prefix: str = "",
bits_override: Optional[int] = None,
Angus Lothian
committed
if index != 0:
raise IndexError(f"Output index out of range (expected 0-0, got {index})")
Angus Lothian
committed
if len(input_values) != 1:
raise ValueError(
"Wrong number of inputs supplied to SFG for evaluation"
f" (expected 1, got {len(input_values)})"
)
Angus Lothian
committed
key = self.key(index, prefix)
value = self.param("initial_value")
if delays is not None:
value = delays.get(key, value)
self.quantize_inputs(input_values, bits_override)[0]
if quantize
Angus Lothian
committed
if results is not None:
results[key] = value
return value
@property
Angus Lothian
committed
"""Get the initial value of this delay."""
return self.param("initial_value")
@initial_value.setter
Angus Lothian
committed
"""Set the initial value of this delay."""
self.set_param("initial_value", value)