Source code for elasticai.creator.vhdl.code_generation.vhdl_ports

from collections.abc import Callable, Sequence
from itertools import chain

from elasticai.creator.vhdl.design.ports import Port
from elasticai.creator.vhdl.design.signal import Signal


[docs] def signal_string(name: str, direction: str, width: int | str) -> str: if isinstance(width, int) and width > 0: data_type = "std_logic" else: data_type = f"std_logic_vector({width} - 1 downto 0)" return f"{name} : {direction} {data_type}"
def _port_definition_from_port( p: Port, signal_width_handler: Callable[[Signal], str] ) -> list[str]: signals = [] signals_and_directions = chain(zip(p.incoming, "in"), zip(p.outgoing, "out")) for signal, direction in signals_and_directions: width = signal_width_handler(signal) signals.append(signal_string(signal.name, direction, width)) return wrap_lines_into_port_statement(signals) def _extract_actual_width(s: Signal) -> str: if s.width == 0: return "std_logic" else: return f"std_logic_vector({s.width} - 1 downto 0)" def _generate_template_width(s: Signal) -> str: if s.width == 0: return "std_logic" else: return f"std_logic_vector(${s.name}_width - downto 0)"
[docs] def vhdl_port_definition(p: Port) -> list[str]: return _port_definition_from_port(p, _extract_actual_width)
[docs] def template_string_for_port_definition(p: Port) -> list[str]: return _port_definition_from_port(p, _generate_template_width)
[docs] def wrap_lines_into_port_statement(lines: Sequence[str]) -> list[str]: semicolon_ended_lines = (f"{line};" for line in lines[:-1]) last_line = lines[-1] return list(chain(["port ("], semicolon_ended_lines, [last_line, ");"]))
[docs] def expand_to_parameters_for_port_template(p: Port) -> dict[str, str]: return { f"{s.name}_width": f"{s.width}" for s in filter(lambda s: s.width > 0, p.signals) }