""" Module for basic VHDL code generation. """ from io import TextIOWrapper from typing import List, Optional, Tuple, Union # VHDL code generation tab length VHDL_TAB = r" " def write( f: TextIOWrapper, indent_level: int, text: str, *, end: str = '\n', start: Optional[str] = None, ): """ Base VHDL code generation utility. `f'{VHDL_TAB*indent_level}'` is first written to the :class:`io.TextIOWrapper` object `f`. Immediatly after the indentation, `text` is written to `f`. Finally, `text` is also written to `f`. Parameters ---------- f : :class:`io.TextIOWrapper` The file object to emit VHDL code to. indent_level : int Indentation level to use. Exactly ``f'{VHDL_TAB*indent_level}`` is written before the text is written. text : str The text to write to. end : str, default: '\n' Text to write exactly after *text* is written to *f*. start : str, optional Text to write before both indentation and *text*. """ if start is not None: f.write(start) f.write(f'{VHDL_TAB*indent_level}{text}{end}') def write_lines( f: TextIOWrapper, lines: List[Union[Tuple[int, str], Tuple[int, str, str]]] ): """ Multiline VHDL code generation utility. Each tuple (int, str, [int]) in the list `lines` is written to the :class:`io.TextIOWrapper` object `f` using the :function:`vhdl.write` function. Parameters ---------- f : :class:`io.TextIOWrapper` The file object to emit VHDL code to. lines : list of tuple (int,str) [1], or list of tuple (int,str,str) [2] [1]: The first `int` of the tuple is used as indentation level for the line and the second `str` of the tuple is the content of the line. [2]: Same as [1], but the third `str` of the tuple is passed to parameter `end` when calling :function:`vhdl.write`. """ for tpl in lines: if len(tpl) == 2: write(f, indent_level=tpl[0], text=tpl[1]) elif len(tpl) == 3: write(f, indent_level=tpl[0], text=tpl[1], end=tpl[2]) else: raise ValueError('All tuples in list `lines` must have length 2 or 3') from b_asic.codegen.vhdl import architecture, common, entity