python2verilog.ir package

Submodules

python2verilog.ir.context module

The context of a generator

Includes the function, its representation and its usage information

class Context(_frozen: bool = False, name: str = '', testbench_suffix: str = '_tb', is_generator: bool = False, prefix: str = '', test_cases: list[tuple[int, ...]] = <factory>, py_func: function | None = None, py_string: str | None = None, _py_ast: ~ast.FunctionDef | None = None, input_types: list[type[~typing.Any]] | None = None, output_types: list[type[~typing.Any]] | None = None, optimization_level: int = -1, mode: ~python2verilog.api.modes.Modes = Modes.NO_WRITE, _local_vars: list[~python2verilog.ir.expressions.Var] = <factory>, _input_vars: list[~python2verilog.ir.expressions.Var] | None = None, _output_vars: list[~python2verilog.ir.expressions.ExclusiveVar] | None = None, _states: set[str] = <factory>, signals: ~python2verilog.ir.signals.ProtocolSignals = <python2verilog.ir.signals.ProtocolSignals object>, state_var: ~python2verilog.ir.expressions.Var = _state, _done_state: ~python2verilog.ir.expressions.State = _state_done, idle_state: ~python2verilog.ir.expressions.State = _state_idle, _entry_state: ~python2verilog.ir.expressions.State | None = None, namespace: dict[str, ~python2verilog.ir.context.Context] = <factory>, generator_instances: dict[str, ~python2verilog.ir.instance.Instance] = <factory>)[source]

Bases: GenericReprAndStr

Context needed by the Intermediate Representation E.g. variables, I/O, parameters, localparam

add_local_var(var: Var)[source]

Appends to global vars with restrictions.

Good for appending Vars created from Python source

add_special_local_var(var: Var)[source]

Appends to local vars without restrictions.

Good for appending Vars created internally (e.g. inline function calls)

add_state(name: str)[source]

Add a state, making sure no pre-existing state what that name exists

add_state_weak(name: str)[source]

Add a state

check_input_types(input_)[source]

Checks if input to functions’ types matches previous inputs

check_output_types(output)[source]

Checks if outputs to functions’ types matches previous outputs

create_generator_instance(name: str) Instance[source]

Create generator instance

default_output_vars()[source]

Sets own output vars to default based on number of output variables

property done_state

The ready state

classmethod empty_valid()[source]

Creates an empty but valid context for testing purposes

property entry_state

The first state that does work in the graph representation

freeze()[source]

Freeze this context to be immutable

generator_instances: dict[str, Instance]
idle_state: State = _state_idle
input_types: list[type[Any]] | None = None
property input_vars: list[Var]

Input variables

is_generator: bool = False
property local_vars: list[Var]

Gets local variables

make_var(name: str) Var[source]

Makes a variable with own prefix

mode: Modes = 0
name: str = ''
namespace: dict[str, Context]
optimization_level: int = -1
output_types: list[type[Any]] | None = None
property output_vars: list[Var]

Output variables

prefix: str = ''
property py_ast

Python ast node rooted at function

py_func: function | None = None
py_string: str | None = None
refresh_input_output_vars()[source]

Update input vars with prefix

signals: ProtocolSignals = <python2verilog.ir.signals.ProtocolSignals object>
state_var: Var = _state
property states

State variables

test_cases: list[tuple[int, ...]]
property testbench_name: str

Returns test bench module name in the generated verilog

testbench_suffix: str = '_tb'
validate()[source]

Validates that all fields of context are populated.

Populate input & output types from type hints if they’re not determined

Returns:

self

python2verilog.ir.expressions module

Intermediate Representation Expressions

Represents the subset of Python expressions that are synthesizable

class Add(left: Expression, right: Expression)[source]

Bases: BinOp

<left> + <right>

class BinOp(left: Expression, oper: str, right: Expression)[source]

Bases: UBinOp

<left> <op> <right>

In verilog the signed specifier is used. For mixed unsigned and signed operations, the following page explains well https://www.01signal.com/verilog-design/arithmetic/signed-wire-reg/

verilog()[source]

To Verilog

class Div(left: Expression, right: Expression)[source]

Bases: BinOp

<left> / <right>

class ExclusiveVar(py_name: str, ver_name: str = '', width: int = 32, is_signed: bool = True, initial_value: str = '0', exclusive_group: str | None = None, **_)[source]

Bases: Var

Exclusive Variable

Can only be set once before a clock cycle must occur, used by the optimizer to determine if it needs to make a edge clocked or not

class Expression(string: str)[source]

Bases: GenericRepr

An expression that can be equated

to_string() str[source]

To String

verilog() str[source]

In Verilog syntax

class FloorDiv(left: Expression, right: Expression)[source]

Bases: BinOp

<left> // <right>

Follows Python conventions

verilog()[source]

Verilog

class Int(value: int)[source]

Bases: Expression

Signed integer literal

to_string() str[source]

String

verilog() str[source]

In Verilog

class LessThan(left: Expression, right: Expression)[source]

Bases: UBinOp

<left> < <right>

class Mod(left: Expression, right: Expression)[source]

Bases: BinOp

<left> % <right>

to_string()[source]

String

verilog()[source]

Verilog

class Mul(left: Expression, right: Expression)[source]

Bases: BinOp

<left> * <right>

class Pow(left: Expression, right: Expression)[source]

Bases: UBinOp

<left> ** <right>

class State(name, width: int = 32, isSigned: bool = True, initial_value: str = '0')[source]

Bases: Var

State constant

class Sub(left: Expression, right: Expression)[source]

Bases: BinOp

<left> - <right>

class Ternary(condition: Expression, left: Expression, right: Expression)[source]

Bases: Expression

<condition> ? <left> : <right>

to_string()[source]

To String

verilog()[source]

In Verilog syntax

class UBinOp(left: Expression, oper: str, right: Expression)[source]

Bases: Expression

Unsigned BinOp Is usually better for comparators

to_string()[source]

To String

verilog()[source]

To Verilog

class UInt(value: int)[source]

Bases: Expression

Unsigned integer literal

class UnaryOp(oper: str, expr: Expression)[source]

Bases: Expression

<op>(<expr>)

to_string()[source]

string

verilog()[source]

Verilog

class Unknown[source]

Bases: Expression

Unknown or “don’t care” value

class Var(py_name: str, ver_name: str = '', width: int = 32, is_signed: bool = True, initial_value: str = '0', **_)[source]

Bases: Expression

Named-variable

python2verilog.ir.graph module

Graph representation of the logic

Naming convention: Vertex Edge Element := Vertex | Edge

class AssignNode(unique_id: str, *args, lvalue: Var, rvalue: Expression, child: Edge | None = None, **kwargs)[source]

Bases: BasicNode

Represents a non-blocking assignment, i.e. assignments that do not block the execution of the next statements, without a clock cycle having to pass

exclusions()[source]

Yields all exclusion groups that will be read or written to within this group of nonclocked nodes.

The reason reads are also included is because checking a callee’s ready signal more than once in a clock cycle is usually incorrect.

class BasicElement(unique_id: str, *args, child: Element | None = None, **kwargs)[source]

Bases: Element

Basic element with a single child

property child: Element

child or optimal_child if no child

children()[source]

Gets children of node

has_child() bool[source]

Returns True if has child

property optimal_child

Optimal child or child otherwise

visit_nonclocked() Iterator[Element][source]

Yields self and recursively yields optimal nonclocked children of element

Returns:

[children_branch_0, children_branch_1, …]

class BasicNode(unique_id: str, *args, child: Edge | None = None, **kwargs)[source]

Bases: Node, BasicElement

Basic node. Has one child.

property edge: Edge

Gets edge

class ClockedEdge(unique_id: str, *args, child: Element | None = None, **kwargs)[source]

Bases: Edge

Represents a clocked edge, i.e. a clock cycle has to pass for the next node to be executed

exclusions()[source]

Yields all exclusion groups that will be read or written to within this group of nonclocked nodes.

The reason reads are also included is because checking a callee’s ready signal more than once in a clock cycle is usually incorrect.

class Edge(unique_id: str, *args, child: Element | None = None, **kwargs)[source]

Bases: BasicElement

Represents an edge between two vertices

get_name()[source]

Gets edge name

class Element(unique_id: str, name: str = '')[source]

Bases: object

Element, base class for vertex or edge

children() Iterator[Element][source]

Gets children of node

exclusions() Iterator[str][source]

Yields all exclusion groups that will be read or written to within this group of nonclocked nodes.

The reason reads are also included is because checking a callee’s ready signal more than once in a clock cycle is usually incorrect.

view_children() str[source]

Views children of node

visit_nonclocked() Iterator[Element][source]

Yields self and recursively yields optimal nonclocked children of element

Returns:

[children_branch_0, children_branch_1, …]

class IfElseNode(unique_id: str, *args, true_edge: Edge, false_edge: Edge, condition: Expression, **kwargs)[source]

Bases: Node, Element

Represents an if-else statement

children() Iterator[Edge][source]

Gets edges

exclusions()[source]

Yields all exclusion groups that will be read or written to within this group of nonclocked nodes.

The reason reads are also included is because checking a callee’s ready signal more than once in a clock cycle is usually incorrect.

property optimal_false_edge

optimal false edge

property optimal_true_edge

optimal true edge or edge otherwise

visit_nonclocked() Iterator[Element][source]

Yields self and recursively yields optimal nonclocked children of element

Returns:

[children_branch_0, children_branch_1, …]

class Node(unique_id: str, name: str = '')[source]

Bases: Element

Vertex

class NonClockedEdge(unique_id: str, *args, child: Element | None = None, **kwargs)[source]

Bases: Edge

Represents a non-clocked edge, i.e. no clock cycle has to pass for the next node to be executed

exclusions()[source]

Yields all exclusion groups that will be read or written to within this group of nonclocked nodes.

The reason reads are also included is because checking a callee’s ready signal more than once in a clock cycle is usually incorrect.

create_cytoscape_elements(node: Element)[source]

Creates adjacency list from a node

Assumes names are unique

create_networkx_adjacency_list(node: Element)[source]

Creates adjacency list from a node

Assumes names are unique

get_variables(exp: Expression) Iterator[Var][source]

Gets variables from expression

python2verilog.ir.instance module

An instance of a generator

Can be created from a context

class Instance(module_name: str, var: Var, inputs: list[Var], outputs: list[Var], signals: ProtocolSignals)[source]

Bases: object

Parameters:
  • module_name – generator function name

  • var – variable name assigned to generator instance

inputs: list[Var]
module_name: str
outputs: list[Var]
signals: ProtocolSignals
var: Var

python2verilog.ir.signals module

Protocol signals used by the converter

class InstanceSignals(prefix: str = '')[source]

Bases: object

Signals that are often named differently for each instance

static apply_prefix(name: str, prefix: str)[source]

Creates a Var with prefix

class ProtocolSignals(prefix: str = '')[source]

Bases: InstanceSignals

Protocol signals

Includes ready, valid, clock, reset, done, etc.

instance_specific_items() Iterator[tuple[str, Var]][source]

Get the instance-specific signals

instance_specific_values() Iterator[Var][source]

Get the instance-specific signals

variable_items() Iterator[tuple[str, Var]][source]

Key, Value pairs

variable_values() Iterator[Var][source]

Values

Module contents

Intermediate Representation

A Control Flow Graph represented as a Directed Graph