b_asic.code_printer.vhdl

B-ASIC code generation module for VHDL.

vhdl_printer module

class b_asic.code_printer.vhdl.vhdl_printer.VhdlPrinter(dt: DataType, vhdl_2008: bool = False)

Generate VHDL source files for an Architecture.

Parameters:
dtDataType

Data type configuration used for generated VHDL.

vhdl_2008bool, default: False

Enable VHDL-2008 specific output where applicable.

get_compile_order(arch: Architecture) list[str]

Return the file names for the VHDL code describing the provided architecture.

Parameters:
arch

Architecture instance used to determine the compile order of the generated VHDL files.

print(arch: Architecture, *, path: str | Path = PosixPath('.'), vhdl_ls: bool = False, **kwargs) None

Write VHDL files for an Architecture.

Parameters:
archArchitecture

Architecture instance to generate code for.

pathstr | Path, optional

Output directory. Defaults to the current directory.

vhdl_lsbool, default False

Also write a vhdl_ls.toml configuration file for the VHDL Language Server alongside the generated VHDL files.

**kwargs

Optional VHDL code-generation settings. For info, see Notes.

Notes

Recognised keyword arguments, grouped by the component they affect:

Top-level / architecture

io_registersbool, default False

Insert registers on all top-level I/O ports.

multiplexer_control_registeredbool, default False

Register multiplexer control signals in generated top-level.

enable_pinbool, default True

Whether to include an enable pin on the top-level entity.

Processing elements

fp_backendstr or dict[str, str]

Floating-point IP backend to use. Pass a string to apply the same backend to every PE, or a {entity_name: backend} dict to select on a per-PE basis.

pe_registersdict[str, tuple[int, int]]

Register split (pre, post) inserted around the operator of a PE. Keys are either the PE entity name or the PE type name.

control_cycledict

Clock cycle inside an operation at which each control signal becomes available.

pipeline_pe_controlbool, default False

Register PE control signals after generation.

Memories (RAM)

output_syncbool, default True

Place output registers after memory read.

external_schedule_counterbool, default True

Use an external schedule counter signal.

std_logic_vectorbool, default False

Use std_logic_vector data instead of signed/unsigned.

pipeline_mem_controlbool, default False

Register memory control signals after generation.

Memories (register-based)

external_schedule_counterbool, default True

Use an external schedule counter signal.

std_logic_vectorbool, default False

Use std_logic_vector data.

common module

Generation of common VHDL constructs.

b_asic.code_printer.vhdl.common.alias_declaration(f: TextIO, name: str, signal_type: str, value: str | None = None, name_pad: int | None = None) None
b_asic.code_printer.vhdl.common.asynchronous_read_memory(f: TextIO, clk: str, read_ports: set[tuple[str, str, str]], write_ports: set[tuple[str, str, str]], name: str | None = None, enable: str | None = None, use_to_integer: bool = True) None

Infer a VHDL memory with synchronous writes and asynchronous reads.

Parameters:
fTextIO

The TextIO to write the VHDL code onto.

clkstr

Name of clock identifier to the synchronous memory.

read_portsSet[Tuple[str,str]]

A set of strings used as identifiers for the read ports of the memory.

write_portsSet[Tuple[str,str,str]]

A set of strings used as identifiers for the write ports of the memory.

namestr, optional

An optional name for the memory process.

enablestr, optional

An optional enable signal to gate the memory writes.

use_to_integerbool, default: True

Wrap address signals in to_integer(). Set to False when the address signal is already an integer type.

b_asic.code_printer.vhdl.common.b_asic_preamble(f: TextIO) None

Write a standard B-ASIC VHDL preamble comment.

Parameters:
fTextIO

The file object to write the header to.

b_asic.code_printer.vhdl.common.blank(f: TextIO) None

Write a blank line.

Parameters:
fTextIO

The file object to emit VHDL code to.

b_asic.code_printer.vhdl.common.component_declaration(f: TextIO, entity_name: str, generics: list[str] | None = None, ports: list[str] | None = None, indent: int = 1) None
b_asic.code_printer.vhdl.common.component_instantiation(f: TextIO, label: str, entity_name: str, generic_mappings: list[str] | None = None, port_mappings: list[str] | None = None, indent: int = 1) None
b_asic.code_printer.vhdl.common.constant_declaration(f: TextIO, name: str, signal_type: str, value: Any, name_pad: int | None = None) None

Write a VHDL constant declaration with a name, a type and a value.

Parameters:
fTextIO

The TextIO object to write the constant declaration to.

namestr

Signal name.

signal_typestr

Signal type.

valueanything convertible to str

Default value to the signal.

name_padint, optional

An optional left padding value applied to the name.

b_asic.code_printer.vhdl.common.entity_declaration(f: TextIO, entity_name: str, generics: list[str] | None = None, ports: list[str] | None = None, indent: int = 0) None
b_asic.code_printer.vhdl.common.ieee_header(f: TextIO, std_logic_1164: bool = True, numeric_std: bool = True, fixed_pkg: bool = False) None

Write the standard IEEE VHDL use header.

This includes std_logic_1164 and numeric_std.

Parameters:
fTextIO

The TextIO object to write the IEEE header to.

std_logic_1164bool, default: True

Include the std_logic_1164 header.

numeric_stdbool, default: True

Include the numeric_std header.

fixed_pkgbool, default: False

Include the fixed_pkg header.

b_asic.code_printer.vhdl.common.is_valid_vhdl_identifier(identifier: str) bool

Test if identifier is a valid VHDL identifier, as specified by VHDL 2019.

An identifier is a valid VHDL identifier if it is not a VHDL reserved keyword and it is a valid basic identifier as specified by IEEE STD 1076-2019 (VHDL standard).

Parameters:
identifierstr

The identifier to test.

Returns:
Returns True if identifier is a valid VHDL identifier, False otherwise.
b_asic.code_printer.vhdl.common.is_vhdl_reserved_keyword(identifier: str) bool

Test if identifier is a reserved VHDL keyword.

Parameters:
identifierstr

The identifier to test.

Returns:
Returns True if identifier is reserved, False otherwise.
b_asic.code_printer.vhdl.common.package_header(f: TextIO, package_name: str) None
b_asic.code_printer.vhdl.common.process_epilogue(f: TextIO, sensitivity_list: str | None = None, indent: int = 1, name: str | None = None) None

Write the epilogue of a regular VHDL process.

Parameters:
fTextIO

The TextIO object to write the type declaration to.

sensitivity_liststr, optional

Content of the process sensitivity list. Not needed when writing the epilogue.

indentint, default: 1

Indentation level to use for this process.

indentint, default: 1

Indentation level to use for this process.

namestr, optional

An optional name of the ending process.

b_asic.code_printer.vhdl.common.process_prologue(f: TextIO, sensitivity_list: str, indent: int = 1, name: str | None = None) None

Write the prologue of a regular VHDL process with a user provided sensitivity list.

This method should almost always be followed by a process_epilogue().

Parameters:
fTextIO

The TextIO object to write the type declaration to.

sensitivity_liststr

Content of the process sensitivity list.

indentint, default: 1

Indentation level to use for this process.

namestr, optional

An optional name for the process.

b_asic.code_printer.vhdl.common.signal_declaration(f: TextIO, name: str, signal_type: str, default_value: str | None = None, indent: int = 1, name_pad: int | None = None, vivado_ram_style: Literal['block', 'distributed', 'registers', 'ultra', 'mixed', 'auto'] | None = None, quartus_ram_style: Literal['M4K', 'M9K', 'M10K', 'M20K', 'M144K', 'MLAB', 'logic'] | None = None) None

Create a VHDL signal declaration.

The declaration looks like:

signal {name} : {type} [:= {default_value}];
Parameters:
fTextIO

The TextIO object to write the IEEE header to.

namestr

Signal name.

signal_typestr

Signal type.

indentint, optional

Indentation level to use for this process.

default_valuestr, optional

An optional default value to the signal.

name_padint, optional

An optional left padding value applied to the name.

vivado_ram_stylestr, optional

An optional Xilinx Vivado RAM style attribute to apply to this signal declaration. If set, exactly one of: “block”, “distributed”, “registers”, “ultra”, “mixed” or “auto”.

quartus_ram_stylestr, optional

An optional Quartus Prime RAM style attribute to apply to this signal declaration. If set, exactly one of: “M4K”, “M9K”, “M10K”, “M20K”, “M144K”, “MLAB” or “logic”.

b_asic.code_printer.vhdl.common.synchronous_memory(f: TextIO, clk: str, read_ports: set[tuple[str, str, str]], write_ports: set[tuple[str, str, str]], name: str | None = None) None

Infer a VHDL synchronous reads and writes.

Parameters:
fTextIO

The TextIO to write the VHDL code onto.

clkstr

Name of clock identifier to the synchronous memory.

read_portsSet[Tuple[str,str]]

A set of strings used as identifiers for the read ports of the memory.

write_portsSet[Tuple[str,str,str]]

A set of strings used as identifiers for the write ports of the memory.

namestr, optional

An optional name for the memory process.

b_asic.code_printer.vhdl.common.synchronous_process(f: TextIO, clk: str, body: str, indent: int = 1, name: str | None = None) None

Write a regular VHDL synchronous process with a single clock.

The clock is the only item in the sensitivity list and is triggering a rising edge block by some body of VHDL code.

Parameters:
fTextIO

The TextIO to write the VHDL code onto.

clkstr

Name of the clock.

bodystr

Body of the if rising_edge(clk) then block.

indentint, default: 1

Indentation level to use for this process.

namestr, optional

An optional name for the process.

b_asic.code_printer.vhdl.common.synchronous_process_epilogue(f: TextIO, clk: str | None = None, indent: int = 1, name: str | None = None) None

Write the epilogue of a regular VHDL synchronous process with a single clock.

The clock is the only item in the sensitivity list and is triggering a rising edge block by some body of VHDL code.

Parameters:
fTextIO

The TextIO to write the VHDL code onto.

clkstr, optional

Name of the clock.

indentint, default: 1

Indentation level to use for this process.

namestr, optional

An optional name for the process.

b_asic.code_printer.vhdl.common.synchronous_process_prologue(f: TextIO, clk: str = 'clk', indent: int = 1, name: str | None = None) None

Write the prologue of a regular VHDL synchronous process with a single clock object.

The clock is the only item in the sensitivity list and is triggering a rising edge block by some body of VHDL code.

This method is almost always followed by a synchronous_process_epilogue().

Parameters:
fTextIO

The TextIO to write the VHDL code onto.

clkstr

Name of the clock.

indentint, default: 1

Indentation level to use for this process.

namestr, optional

An optional name for the process.

b_asic.code_printer.vhdl.common.type_declaration(f: TextIO, name: str, alias: str) None

Write a VHDL type declaration with a name tied to an alias.

Parameters:
fTextIO

The TextIO object to write the type declaration to.

namestr

Type name alias.

aliasstr

The type to tie the new name to.

b_asic.code_printer.vhdl.common.write(f: TextIO, indent_level: int, text: str, *, end: str = '\n', start: str | None = None) None

Write text to a VHDL file.

First, f'{VHDL_TAB*indent_level}' is written to f as indentation. Immediately after the indentation, text is written to f. Finally, text is also written to f.

Parameters:
fTextIO

The file object to emit VHDL code to.

indent_levelint

Indentation level to use. Exactly f'{VHDL_TAB*indent_level}' is written before the text is written.

textstr

The text to write to.

endstr, default: ‘n’

Text to write exactly after text is written to f.

startstr, optional

Text to write before both indentation and text.

b_asic.code_printer.vhdl.common.write_lines(f: TextIO, lines: list[tuple[int, str] | tuple[int, str, str]]) None

Write provided lines to a VHDL file.

Each tuple (int, str, [int]) in the list lines is written to the TextIO object f using the vhdl.write() function.

Parameters:
fTextIO

The file object to emit VHDL code to.

lineslist 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 vhdl.write().

memory_storage module

Module for VHDL code generation of memory based storage.

b_asic.code_printer.vhdl.memory_storage.architecture(f: TextIO, memory: Memory, dt: _VhdlDataType, *, output_sync: bool = True, external_schedule_counter: bool = True, std_logic_vector: bool = False, pipeline_control_signals: bool = False) None

Generate the VHDL architecture for a memory-based storage architecture.

Settings should be sanitized when calling this function, e.g. from calling generate_memory_based_storage_vhdl from one of the memory classes.

Parameters:
fTextIO

File object (or other TextIO object) to write the architecture onto.

memoryMemory

Memory object to generate code for.

dtDataType

Meta information of data signals.

output_syncbool, default: True

Add registers to the output signal.

external_schedule_counterbool, default: True

If True, schedule counter comes from external input port. If False, schedule counter is generated internally with synchronous reset.

std_logic_vectorbool, default: False

If True, use std_logic_vector for data signals. If False, use dt.type_str.

pipeline_control_signalsbool, default: False

If True, register the control signals.

b_asic.code_printer.vhdl.memory_storage.entity(f: TextIO, mem: Memory, dt: _VhdlDataType, external_schedule_counter: bool = True, std_logic_vector: bool = False) None

Generate entity for memory storage.

Parameters:
fTextIO

File object to write to.

memMemory

Memory object to generate entity for.

dt_VhdlDataType

Data type information.

external_schedule_counterbool, default: True

If True, schedule counter is an input port. If False, it’s generated internally.

std_logic_vectorbool, default: False

If True, use std_logic_vector for data signals. If False, use dt.type_str.

processing_element module

Module for VHDL code generation of processing elements.

b_asic.code_printer.vhdl.processing_element.architecture(f: TextIO, pe: ProcessingElement, dt: _VhdlDataType, core_code: tuple[str, str], register_split: tuple[int, int], control_cycle: dict[str, int] | None = None, pipeline_control_signals: bool = False) None
b_asic.code_printer.vhdl.processing_element.entity(f: TextIO, pe: ProcessingElement, dt: _VhdlDataType) None

register_storage module

Module for VHDL code generation of register based storage.

b_asic.code_printer.vhdl.register_storage.architecture(f: TextIO, forward_backward_table: _ForwardBackwardTable, memory: Memory, dt: _VhdlDataType, sync_rst: bool = False, async_rst: bool = False, std_logic_vector: bool = True, pipeline_control_signals: bool = False) None

Generate architecture for register-based storage.

Parameters:
fTextIO

File object to write to.

forward_backward_table_ForwardBackwardTable

Forward-backward allocation table.

memoryMemory

Memory object.

dt_VhdlDataType

Data type information.

sync_rstbool, default: False

Enable synchronous reset.

async_rstbool, default: False

Enable asynchronous reset.

std_logic_vectorbool, default: True

If True, use std_logic_vector for data signals. If False, use dt.type_str.

pipeline_control_signalsbool, default: False

If True, register the control signals.

b_asic.code_printer.vhdl.register_storage.entity(f: TextIO, memory: Memory, dt: _VhdlDataType, std_logic_vector: bool = True) None

Generate entity for register-based storage.

Parameters:
fTextIO

File object to write to.

memoryMemory

Memory object to generate entity for.

dt_VhdlDataType

Data type information.

std_logic_vectorbool, default: True

If True, use std_logic_vector for data signals. If False, use dt.type_str.

test_bench module

Module for VHDL code generation of test benches.

b_asic.code_printer.vhdl.test_bench.architecture(f: TextIO, arch: Architecture, dt: _VhdlDataType, enable_pin: bool = True) None
b_asic.code_printer.vhdl.test_bench.entity(f: TextIO, arch: Architecture) None

top_level module

Module for VHDL code generation of top level designs.

b_asic.code_printer.vhdl.top_level.architecture(f: TextIO, arch: Architecture, dt: _VhdlDataType, io_registers: bool = False, multiplexer_control_registered: bool = True, enable_pin: bool = True) None
b_asic.code_printer.vhdl.top_level.entity(f: TextIO, arch: Architecture, dt: _VhdlDataType, enable_pin: bool = True) None

util module

Utility functions for VHDL Printer.

b_asic.code_printer.vhdl.util.schedule_time_type(time: int) str
b_asic.code_printer.vhdl.util.signed_type(bits: int) str
b_asic.code_printer.vhdl.util.unsigned_type(bits: int) str