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.
module
property
¶
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
¶
segments: CustomDict[int, PortSegment]
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
¶
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
¶
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:
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
¶
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: MetadataMixin = MetadataMixin()
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.
circuit
property
¶
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:
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
¶
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
¶
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:
Returns:
-
NonNegativeInt(NonNegativeInt) –The number of times the target signal appears in this port's signal array.
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 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:
-
NotImplementedError–If this method is not implemented for the object's type.