Source code for elasticai.creator.vhdl.code_generation.code_abstractions
from collections.abc import Sequence
from elasticai.creator.vhdl.design.signal import Signal
def _sorted_dict(items: dict[str, str]) -> dict[str, str]:
return dict((key, items[key]) for key in sorted(items))
[docs]
def create_instance(
*,
name: str,
entity: str,
signal_mapping: dict[str, str],
library: str,
architecture: str = "rtl",
) -> list[str]:
signal_mapping = _sorted_dict(signal_mapping)
result = [f"{name} : entity {library}.{entity}({architecture})", "port map("]
for _from in tuple(signal_mapping.keys())[:-1]:
_to = signal_mapping[_from]
result.append(f" {_from} => {_to},")
last_from = tuple(signal_mapping.keys())[-1]
last_to = signal_mapping[last_from]
result.append(f" {last_from} => {last_to}")
result.append(");")
return result
[docs]
def create_connections_using_to_from_pairs(mapping: dict[str, str]) -> list[str]:
connections: list[str] = []
for _to, _from in mapping.items():
connections.append(create_connection(_to, _from))
return connections
[docs]
def create_connection(dst, source) -> str:
return f"{dst} <= {source};"
[docs]
def create_signal_definitions(prefix: str, signals: Sequence[Signal]):
return sorted(
[
signal_definition(name=f"{prefix}{signal.name}", width=signal.width)
for signal in signals
]
)
[docs]
def signal_definition(
*,
name: str,
width: int,
):
def vector_signal(name: str, width) -> str:
return (
f"signal {name} : std_logic_vector({width - 1} downto 0)"
" := (others => '0');"
)
def logic_signal(name: str) -> str:
return f"signal {name} : std_logic := '0';"
if width > 0:
return vector_signal(name, width)
else:
return logic_signal(name)
[docs]
def hex_representation(hex_value: str) -> str:
return f'x"{hex_value}"'
[docs]
def bin_representation(bin_value: str) -> str:
return f'"{bin_value}"'
[docs]
def to_vhdl_binary_string(number: int, number_of_bits: int) -> str:
if abs(number) >= 2**number_of_bits:
raise ValueError(
f"Value '{number}' cannot be represented with {number_of_bits} bits."
)
def _to_unsigned(value: int, total_bits: int) -> int:
def invert(value: int) -> int:
return value ^ int("1" * total_bits, 2)
def discard_leading_bits(value: int) -> int:
return value & int("1" * total_bits, 2)
if value < 0:
value = discard_leading_bits(invert(abs(value)) + 1)
return value
two_complement = _to_unsigned(number, number_of_bits)
return f'"{two_complement:0{number_of_bits}b}"'