Skip to content

netlist_carpentry.core.netlist_elements.port

Module for handling of ports (both instance and module ports) inside a circuit module.

Classes:

  • Port

    Represents a port in the netlist.

Port

Bases: NetlistElement, BaseModel, Generic[T_PARENT]

Represents a port in the netlist.

This class is generic to sensibly differentiate between module and instance ports. The value of the generic is derived from module_or_instance and is used mainly for type annotation. If this port belongs to a module, use Port[Module] otherwise use Port[Instance].

Attributes:

  • direction (Direction) –

    The direction of this port.

  • msb_first (bool) –

    Whether the index order of this port is MSB first. Defaults to True.

  • module_or_instance(Optional[Module, (Instance]) –

    The parent object (module or instance) to which this port belongs. Can also be None, in which case the port does not belong to any object initially, but should be assigned to an instance or module later.

Methods:

  • __getitem__

    Allows subscripting of a Port object to access its port segments directly.

  • create_port_segment

    Creates a port segment and adds it to this port.

  • create_port_segments

    Creates a port segment and adds it to this port.

  • remove_port_segment

    Removes a port segment from this port.

  • get_port_segment

    Returns a PortSegment with the given index from this port.

  • tie_signal

    Ties a signal to a constant value on the specified port segment.

  • set_signal

    Sets the signal of the port segment at the given index to the given new signal.

  • count_signals

    Counts the number of occurrences of a given signal in this port's signal array.

  • change_connection

    Changes the connection of a port segment to the given wire segment path.

  • evaluate

    Evaluate the element depending on the incoming signals.

direction instance-attribute

direction: Direction

The direction of this port, indicating whether it's an input, output, or bidirectional connection.

msb_first class-attribute instance-attribute

msb_first: bool = True

Whether this port is MSB (most significant bit) first or not

path property

path: PortPath

Returns the PortPath of the netlist element.

The PortPath object is constructed using the element's type and its raw hierarchical path.

Returns:

  • PortPath ( PortPath ) –

    The hierarchical path of the netlist element.

type property

type: EType

The type of the element, which is a port.

module property

module: 'Module'

The parent module of this port.

For a module port, this returns the immediate parent. For an instance port, it returns the module to which the instance belongs (i.e. the parent of the instance, or the grandparent of this port).

segments property

Returns the port segments of this port, where the key is the bit index.

signal property

signal: Signal

Returns the signal associated with this port.

Does only work for 1-bit wide ports, as a convenient alternative for Port.signal_array.

If there's only one segment in the port (i.e. the port is exactly 1 bit wide), returns the signal of that segment. Otherwise, returns Signal.UNDEFINED to indicate ambiguity. This is meant as a shortcut of signal_array[0], since many ports commonly are only 1 bit wide. Thus, this property should only be used for 1-bit wide ports!

Returns:

  • Signal ( Signal ) –

    The signal associated with this port, if this port is 1 bit wide, otherwise returns Signal.UNDEFINED.

signal_int property

signal_int: Optional[int]

The signal currently applied to this port as an integer, if possible.

If Port.signed is False, the value is treated as an unsigned signal. If Port.signed is True, the value is treated as a signed signal, using the two's complement, if the sign bit is 1.

Offset is ignored when calculating this property. If a 4 bit port has an offset of 3, the returned integer is built form the actually present segments (i.e. the integer value is between 0 and 15). Analogously, if segments are missing in between, they are also ignored and treated as if there was no gap. If a port has a segment with index 0 and with index 2, but a segment for index 1 is missing, the returned integer will be the decimal representation of the values of the segments 2 and 0, without including or mentioning the gap at index 1. The calculated number ranges thus between 0 and 3, and not between 0 and 7.

If the signal string for a 4 bit port is '1001', then this property will return 9. If the string contains 'x' or 'z', the signal does not form an integer and this property returns None.

signal_array property

signal_array: Dict[int, Signal]

Returns an array of signals associated with this port, ordered by bit index.

If the port is empty (i.e., no segments), returns an empty list. Otherwise, returns a list of signals corresponding to each segment in the port, where the index of the list corresponds to the bit index of the segment.

Returns:

  • Dict[int, Signal]

    Dict[int, Signal]: The array of signals associated with each segment of this port.

signal_str property

signal_str: str

The signal currently applied to this port as a string (MSB first).

The length of the string corresponds to the width of this port. Offset is ignored by this property. If a 4 bit port has an offset of 3, the returned string only consists of the actually present segments (i.e. the string consists of the signals at the 4 present segments). Analogously, if segments are missing in between, they are also ignored and treated as if there was no gap. If a port has a segment with index 0 and with index 2, but a segment for index 1 is missing (not to be confused with an unconnected segment), the returned string will have the values of the segments 2 and 0 (in descending order), without including or mentioning the gap at index 1.

If the signal string for a 4 bit port is '1010', then the segments with indices 3 and 1 (plus offset) are currently 1 and the other two segments are 0. If the string contains 'x', the corresponding segment has an undefined value, and if the string contains 'z', the corresponding segment is floating.

has_undefined_signals property

has_undefined_signals: bool

Whether any of the port's signals are undefined (e.g. "X" or "Z").

False, if the signals on all port segments are either "0" or "1". Otherwise, returns True.

is_tied property

is_tied: bool

True if all of the port's segments are tied to a constant (e.g. "0" or "1"). Unconnected ("X") or floating port segments ("Z") are also considered tied in this context. To check if all port segments are tied to "0" or "1", use Port.is_tied_defined.

False, if any segments are connected to a wire.

is_tied_partly property

is_tied_partly: bool

True if any of the port's segments are tied to a constant (e.g. "0" or "1"). Unconnected ("X") or floating port segments ("Z") are also considered tied in this context. To check if all port segments are tied to "0" or "1", use Port.is_tied_defined.

False, if all segments are connected to a wire.

is_connected_partly property

is_connected_partly: bool

Determines whether the port is partly connected.

A port is considered partly connected if at least one of its segments is connected to a wire.

Returns:

  • bool ( bool ) –

    True if at least one segment is connected, False otherwise.

is_connected property

is_connected: bool

Determines whether the port is fully connected.

A port is considered fully connected if all of its segments are connected to a wire.

Returns:

  • bool ( bool ) –

    True if all segments are connected, False otherwise.

is_unconnected property

is_unconnected: bool

Determines whether the port is completely unconnected.

A port is considered completely unconnected if none of its segments are connected to a wire.

Returns:

  • bool ( bool ) –

    True if no segments are connected, False otherwise.

is_unconnected_partly property

is_unconnected_partly: bool

Determines whether the port is partly unconnected.

A port is considered partly unconnected if at least one of its segments is unconnected.

Returns:

  • bool ( bool ) –

    True if at least one segment is unconnected, False otherwise.

is_floating property

is_floating: bool

Determines whether the port is completely floating.

A port is considered completely floating if at least one of its segments is floating.

Returns:

  • bool ( bool ) –

    True if at least one segment is floating, False otherwise.

is_floating_partly property

is_floating_partly: bool

Determines whether the port is partly floating.

A port is considered partly floating if at least one of its segments is floating.

Returns:

  • bool ( bool ) –

    True if at least one segment is floating, False otherwise.

is_tied_defined property

is_tied_defined: bool

True if all segments are tied to a defined value (0 or 1), False otherwise.

is_tied_defined_partly property

is_tied_defined_partly: bool

True if at least one segment is tied to a defined value (0 or 1), False otherwise.

is_tied_undefined property

is_tied_undefined: bool

True if all segments are tied to an undefined value (X or Z), False otherwise.

If True, every segment is either unconnected or floating. Can also be mixed. If False, at least one segment is either connected or tied to 0 or 1.

is_tied_undefined_partly property

is_tied_undefined_partly: bool

True if at least one segment is tied to an undefined value (X or Z), False otherwise.

If True, at least one segment is either unconnected or floating. If False, all segments are either connected or tied to 0 or 1.

width property

width: int

The width of the port in bits, which is simply the number of port segments in the port.

lsb_first property

lsb_first: bool

Whether the LSB (least significant bit) comes first.

This property is coupled with Port.msb_first. To change this value, change Port.msb_first, and this property is updated accordingly.

is_instance_port property

is_instance_port: bool

Whether this port is an instance port.

True, if this port is an instance port. False, if this port is a module port.

is_module_port property

is_module_port: bool

Whether this port is a module port.

True, if this port is a module port. False, if this port is an instance port.

is_input property

is_input: bool

Whether this port is an input port.

Returns:

  • bool ( bool ) –

    True if this port is an input port, False otherwise.

is_output property

is_output: bool

Whether this port is an output port.

Returns:

  • bool ( bool ) –

    True if this port is an output port, False otherwise.

is_driver property

is_driver: bool

Whether this port is a driver port, i.e. a port driving a signal.

A driver port is an input port of a module, or an output port of an instance.

Returns:

  • bool ( bool ) –

    True if this port is a driver port, False otherwise.

is_load property

is_load: bool

Whether this port is a load port, i.e. a port being driven by a signal.

A load port is an output port of a module, or an input port of an instance.

Returns:

  • bool ( bool ) –

    True if this port is a load port, False otherwise.

connected_wire_segments property

connected_wire_segments: Dict[NonNegativeInt, WireSegmentPath]

Returns a dictionary of paths of wire segments connected to this port.

A port is considered connected to a wire segment if at least one of its segments is connected to that wire segment.

connected_wires property

connected_wires: Set[WirePath]

Returns a set of paths of wires connected to this port.

A port is considered connected to a wire if at least one of its segments is connected to that wire.

is_connected_1to1 property

is_connected_1to1: bool

True if this port is connected completely to a certain wire.

True if this conforms to the Verilog expression assign port = wire;. False, if this conforms to other cases including bit slicing or concatenation, e.g. assign port[1:0] = {wire1, wire2}

name instance-attribute

name: str

The name of the element.

!!! Do not modify this variable after instantiating it. Use NetlistElement.set_name() instead. Modifying this variable might lead to inconsistencies later on.

metadata class-attribute instance-attribute

Metadata of a netlist element.

Can be user-defined, or e. g. by Yosys (such as src for the HDL source). Is also grouped by categories, i.e. all metadata from Yosys can be accessed via Module.metadata["yosys"], or via Module.metadata.yosys, which both return a dictionary of all metadata. Read the documentation of MetaDataMixin for more information.

hierarchy_level property

hierarchy_level: int

The level of hierarchy of the element in the design.

The hierarchy level is the number of separators in the element's raw path. For example, a top-level instance has a hierarchy level of 0, while a direct submodule instance has a hierarchy level of 1.

Returns:

  • int ( int ) –

    The hierarchy level of the element.

has_parent property

has_parent: bool

Whether this object has a parent.

circuit property

circuit: 'Circuit'

The circuit object to which this netlist element belongs to.

  • For a module, returns the circuit to which the module belongs.
  • For any other netlist element, recursively returns the circuit of the parent, which ultimately leads to a module, to which the netlist element belongs.

Raises:

  • ParentNotFoundError

    If a parent cannot be resolved somewhere in the hierarchical chain.

  • ObjectNotFoundError

    If for a module no circuit is set.

has_circuit property

has_circuit: bool

Whether this netlist element has a defined circuit it belongs to.

Tries to access self.circuit and returns whether the call was successful. Can be used instead of a try-except clause around the call to NetlistElement.circuit.

locked property

locked: bool

True if this NetlistElement instance is locked (i.e. it is currently structurally unchangeable), False if it is mutable.

Can be changed via NetlistElement.change_mutability(bool).

Immutability is used to prevent accidental changes to the design.

is_placeholder_instance property

is_placeholder_instance: bool

A placeholder represents an element that does not have a specific path.

True if this NetlistElement instance represents a placeholder, False otherwise.

can_carry_signal property

can_carry_signal: bool

Whether this exact object is able to receive, pass or hold signal values.

True for ports (as they drive or receive values) and wires (as they pass the signals from driver to load ports) as well as their respective segments. False for instances and modules.

__getitem__

__getitem__(index: int) -> PortSegment

Allows subscripting of a Port object to access its port segments directly.

This is mainly for convenience, to use Port[i] instead of Port.segments[i].

Parameters:

  • index

    (int) –

    The index of the desired port segment.

Returns:

  • PortSegment ( PortSegment ) –

    The port segment at the specified index.

create_port_segment

create_port_segment(index: NonNegativeInt) -> PortSegment

Creates a port segment and adds it to this port.

Parameters:

  • index

    (NonNegativeInt) –

    The index for which a PortSegment should be created and added to this port.

Returns:

  • PortSegment ( PortSegment ) –

    The PortSegment that was created and added to this port.

create_port_segments

create_port_segments(
    count: PositiveInt, offset: NonNegativeInt = 0
) -> Dict[int, PortSegment]

Creates a port segment and adds it to this port.

The number of port segments can be specified via count, which will create and add exactly this much port segments (in ascending order) to this port. With offset, the start index can be set

Parameters:

  • count

    (PositiveInt) –

    The amount of PortSegments to be created and added to this port.

  • offset

    (NonNegativeInt, default: 0 ) –

    The index from which the generated port segments start.

Returns:

  • Dict[int, PortSegment]

    List[PortSegment]: A list of PortSegment objects created and added to this port.

remove_port_segment

remove_port_segment(index: NonNegativeInt) -> None

Removes a port segment from this port.

Parameters:

  • index

    (NonNegativeInt) –

    The index of the PortSegment to remove from this port.

get_port_segment

get_port_segment(index: NonNegativeInt) -> Optional[PortSegment]

Returns a PortSegment with the given index from this port.

Parameters:

  • index

    (NonNegativeInt) –

    The index of the PortSegment to retrieve from this port.

Returns:

  • Optional[PortSegment]

    Optional[PortSegment]: The PortSegment with the given index, or None if no port segment with that index exists.

tie_signal

tie_signal(signal: LogicLevel, index: NonNegativeInt = 0) -> None
tie_signal(signal: Signal, index: NonNegativeInt = 0) -> None
tie_signal(signal: SignalOrLogicLevel, index: NonNegativeInt = 0) -> None

Ties a signal to a constant value on the specified port segment.

If the specified index corresponds to an existing port segment, ties its constant signal value and returns True. Otherwise, does nothing and returns False.

If signal is X, which is interpreted as UNDEFINED, the port segment is unconnected to achieve this.

Does not work for instance output ports, as they are always driven by their parent instances.

Parameters:

  • signal

    (SignalOrLogicLevel) –

    The new constant signal value. 'X' unconnects the port.

  • index

    (NonNegativeInt, default: 0 ) –

    The bit index of the port segment. Defaults to 0.

Raises:

  • ObjectNotFoundError

    If no segment with the given index exists.

  • AlreadyConnectedError

    (raised by: PortSegment.tie_signal) If this segment is belongs to a load port and is already connected to a wire, from which it receives its value.

  • InvalidDirectionError

    (raised by: PortSegment.tie_signal) If this port segment belongs to an instance output port, which is driven by the instance inputs and the instance's internal logic.

  • InvalidSignalError

    (raised by: PortSegment.tie_signal) If an invalid value is provided.

set_signal

set_signal(signal: LogicLevel, index: NonNegativeInt = 0) -> None
set_signal(signal: Signal, index: NonNegativeInt = 0) -> None
set_signal(signal: SignalOrLogicLevel, index: NonNegativeInt = 0) -> None

Sets the signal of the port segment at the given index to the given new signal.

Does only work for NON-CONSTANT port segments! This method is intended to be used in the signal evaluation process, where constant signals should be treated accordingly. Accordingly, it should be avoided that constant inputs are accidentally modified during signal evaluation. To change the signal of a port segment to be a constant value, use the tie_signal method instead.

Parameters:

  • signal

    (SignalOrLogicLevel) –

    The new signal to set on the port segment.

  • index

    (NonNegativeInt, default: 0 ) –

    The index of the port segment to set the signal on. Defaults to 0, which is the LSB of the port.

Raises:

  • ValueError

    If the index is out of range of the port's segments.

count_signals

count_signals(target_signal: Signal) -> NonNegativeInt

Counts the number of occurrences of a given signal in this port's signal array.

Parameters:

  • target_signal

    (Signal) –

    The signal to count occurrences of.

Returns:

  • NonNegativeInt ( NonNegativeInt ) –

    The number of times the target signal appears in this port's signal array.

Example
>>> sig_a = Signal.HIGH
>>> sig_b = Signal.LOW
>>> some_port.set_signal(sig_a, index=0)
>>> some_port.set_signal(sig_a, index=1)
>>> some_port.set_signal(sig_b, index=2)
>>> print(some_port.count_signals(Signal.HIGH))
2

change_connection

change_connection(
    new_wire_segment_path: WireSegmentPath, index: Optional[NonNegativeInt] = 0
) -> None

Changes the connection of a port segment to the given wire segment path.

Parameters:

  • new_wire_segment_path

    (WireSegmentPath) –

    The new wire segment path to connect the port segment to.

  • index

    (int, default: 0 ) –

    The index of the port segment to change the connection for. Defaults to 0.

Note

If index is None, changes the connections of all segments in this port to the same given wire segment.

evaluate

evaluate() -> None

Evaluate the element depending on the incoming signals.

This is used for instances, which have some sort of transfer function. The combination of input signals and the transfer function determine the output signal. For simple gate instances, such as AND and OR gates, this is trivial, as the transfer function is just a small truth table. Complex structures, like submodules, are comprised of other instances, which are evaluated recursively, down to the leaf instances, which in return are primitive gates. Thus, to evaluate a module, first all of its submodules and gates are evaluated, to calculate the output signals of the module.

Raises: