Skip to content

Constants

Constants are defined using the Constant type and are declared directly within the package. They carry a fixed value, which may be computed from other constants, and may be given an explicit bit width.

Example

The Packtype definition can either use a Python dataclass style or the Packtype custom grammar:

1
2
3
4
5
6
7
import packtype
from packtype import Constant

@packtype.package()
class ThePackage:
    VALUE_A : Constant = 123
    VALUE_B : Constant[16] = 234
package the_package {
    VALUE_A : constant = 123
        "Comments may be attached to values with a string following the definition"
    VALUE_B : constant[16] = 234
        "These are attached to the constant definitions"
    VALUE_C: constant[2] = 3
        """
        Multiline comments can be used for long descriptions.
        Use triple quotes for these like with Python docstrings.
        """
}

As rendered to SystemVerilog:

1
2
3
4
5
6
package the_package;

localparam VALUE_A = 123;
localparam bit [15:0] VALUE_B = 234;

endpackage : the_package

Syntax

Unsized Constants

A constant defined without an explicit size will be treated as unsized and it will be left to the target language template to decide what size container to allocate it.

1
2
3
4
@packtype.package()
class ThePackage:
    # Format: <NAME> : Constant = <VALUE>
    MY_CONSTANT : Constant = 123
1
2
3
4
package the_package {
    // Format: <NAME> : constant = <VALUE>
    MY_CONSTANT : constant = 123
}

Implicit Constants

Unsized constants may be declared implicitly by omitting the : Constant keyword from the declaration:

1
2
3
4
@packtype.package()
class ThePackage:
    # Format: <NAME> = <VALUE>
    MY_CONSTANT = 123

Note

This is only supported in the Python dataclass style syntax

Sized Constants

Constants may be defined with an explicit bit width, in which case Packtype will respect the request bit width internally and target language templates will allocate the nearest possible size large enough to hold the full range of that number of bits.

1
2
3
4
@packtype.package()
class ThePackage:
    # Format: <NAME> : Constant[<WIDTH>] = <VALUE>
    MY_CONSTANT : Constant[8] = 123
1
2
3
4
package the_package {
    // Format: <NAME> : constant[<WIDTH>] = <VALUE>
    MY_CONSTANT : constant[8] = 123
}

Expressions

Both the width and value assignment for a constant declaration may be computed from other constant definitions within the package.

1
2
3
4
5
6
@packtype.package()
class ThePackage:
    DOUBLE_WIDTH : Constant = 32
    VALUE_A      : Constant = 9
    VALUE_B      : Constant = 3
    COMPUTED     : Constant[DOUBLE_WIDTH // 2] = (VALUE_A * VALUE_B) + 1
1
2
3
4
5
6
package the_package {
    DOUBLE_WIDTH : constant = 32
    VALUE_A      : constant = 9
    VALUE_B      : constant = 3
    COMPUTED     : constant[DOUBLE_WIDTH // 2] = (VALUE_A * VALUE_B) + 1
}

Note

Both Python (.py) and Packtype (.pt) syntaxes use Python's arithmetic and logical operators

Oversized Values

When using explicitly sized constants, if a value is allocated to the constant that is outside the legal range a ValueError will be raised:

1
2
3
4
@packtype.package()
class ThePackage:
    # Attempt to store 123 in a 4 bit value
    MY_CONSTANT : Constant[4] = 123
1
2
3
4
package the_package {
    // Attempt to store 123 in a 4 bit value
    MY_CONSTANT : constant[4] = 123
}

Will lead to:

ValueError: 123 is out of 4 bit range (0 to 15)