CIRCT

Circuit IR Compilers and Tools

'hwarith' Dialect

Types and operations for the HWArith dialect This dialect defines the HWArith dialect, modeling bit-width aware arithmetic operations.

Operation definition

hwarith.add (::circt::hwarith::AddOp)

Bitwidth-aware integer addition.

Syntax:

operation ::= `hwarith.add` $inputs attr-dict `:` functional-type($inputs, $result)

The add operation takes two operands and returns one result. The result type is inferred from the operand types, which may be signed or unsigned scalar integer types of arbitrary bitwidth.

LHS typeRHS typeResult type
ui<a>ui<b>ui<r>, r = max(a, b) + 1
si<a>si<b>si<r>, r = max(a, b) + 1
ui<a>si<b>si<r>, r = a + 2 if ab
si<r>, r = b + 1 if a < b
si<a>ui<b>Same as ui<b> + si<a>

Examples:

%0 = hwarith.add %10, %11 : (ui3, ui4) -> ui5
%1 = hwarith.add %12, %13 : (si3, si3) -> si4
%2 = hwarith.add %14, %15 : (ui3, si4) -> si5
%3 = hwarith.add %16, %17 : (si4, ui6) -> si8

Traits: Commutative

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

OperandDescription
inputsan arbitrary precision integer with signedness semantics

Results:

ResultDescription
resultan arbitrary precision integer with signedness semantics

hwarith.constant (::circt::hwarith::ConstantOp)

Produce a constant value

The constant operation produces a sign-aware constant value.

  %result = hwarith.constant 42 : t1

Traits: ConstantLike, FirstAttrDerivedResultType

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
rawValue::mlir::IntegerAttrarbitrary integer attribute

Results:

ResultDescription
resultan arbitrary precision integer with signedness semantics

hwarith.div (::circt::hwarith::DivOp)

Bitwidth-aware integer division.

Syntax:

operation ::= `hwarith.div` $inputs attr-dict `:` functional-type($inputs, $result)

The div operation takes two operands and returns one result. The result type is inferred from the operand types, which may be signed or unsigned scalar integer types of arbitrary bitwidth.

LHS typeRHS typeResult type
ui<a>ui<b>ui<r>, r = a
si<a>si<b>si<r>, r = a + 1
ui<a>si<b>si<r>, r = a + 1
si<a>ui<b>si<r>, r = a

Examples:

%0 = hwarith.div %10, %11 : (ui3, ui4) -> ui3
%1 = hwarith.div %12, %13 : (si3, si3) -> si4
%2 = hwarith.div %14, %15 : (ui3, si4) -> si4
%3 = hwarith.div %16, %17 : (si4, ui6) -> si4

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

OperandDescription
inputsan arbitrary precision integer with signedness semantics

Results:

ResultDescription
resultan arbitrary precision integer with signedness semantics

hwarith.cast (::circt::hwarith::CastOp)

Signedness-aware cast.

Syntax:

operation ::= `hwarith.cast` $in attr-dict `:` functional-type($in, $out)

The cast operation takes one operand and returns one result. Both, the result type and the operand type can be of any scalar integer type with arbitrary bitwidth. However, at least one of them needs to be a HWArithIntegerType.

Input typeResult typeBehavior
ui<a>ui<b>/si<b>/i<b>zero-extension if ba
truncation if b < a
si<a>ui<b>/si<b>/i<b>sign-extension if ba
truncation if b < a
i<a>ui<b>/si<b>truncation if b a
i<a>ui<b>/si<b>prohibited if b > a

†) prohibited because of the ambiguity whether a sign or a zero extension is required.

Examples:

%0 = hwarith.cast %10 : (ui3) -> si5
%1 = hwarith.cast %11 : (si3) -> si4
%2 = hwarith.cast %12 : (si7) -> ui4
%3 = hwarith.cast %13 : (i7) -> si5
%3 = hwarith.cast %13 : (si14) -> i4

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

OperandDescription
ininteger

Results:

ResultDescription
outinteger

hwarith.icmp (::circt::hwarith::ICmpOp)

Sign- and bitwidth-aware integer comparison.

Syntax:

operation ::= `hwarith.icmp` $predicate $lhs `,` $rhs  attr-dict `:` type($lhs) `,` type($rhs)

The icmp operation compares two integers using a predicate. If the predicate is true, returns 1, otherwise returns 0. This operation always returns a one bit wide result of type ui1. Both operand types may be signed or unsigned scalar integer types of arbitrary bitwidth.

LHS typeRHS typeComparison typeResult type
ui<a>ui<b>ui<r>, r = max(a, b)ui1
si<a>si<b>si<r>, r = max(a, b)ui1
ui<a>si<b>si<r>, r = a + 1 if abui1
si<r>, r = b if a < bui1
si<a>ui<b>Same as ui<b> si<a>ui1

Examples:

%0 = hwarith.icmp lt %10, %11 : ui5, ui6
%1 = hwarith.icmp lt %12, %13 : si3, si4
%2 = hwarith.icmp lt %12, %11 : si3, ui6

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
predicatecirct::hwarith::ICmpPredicateAttrhwarith.icmp comparison predicate

Operands:

OperandDescription
lhsan arbitrary precision integer with signedness semantics
rhsan arbitrary precision integer with signedness semantics

Results:

ResultDescription
result1-bit unsigned integer

hwarith.mul (::circt::hwarith::MulOp)

Bitwidth-aware integer multiplication.

Syntax:

operation ::= `hwarith.mul` $inputs attr-dict `:` functional-type($inputs, $result)

The mul operation takes two operands and returns one result. The result type is inferred from the operand types, which may be signed or unsigned scalar integer types of arbitrary bitwidth.

LHS typeRHS typeResult type
ui<a>ui<b>ui<r>, r = a + b
si<a>si<b>si<r>, r = a + b
ui<a>si<b>si<r>, r = a + b
si<a>ui<b>si<r>, r = a + b

Examples:

%0 = hwarith.mul %10, %11 : (ui3, ui4) -> ui7
%1 = hwarith.mul %12, %13 : (si3, si3) -> si6
%2 = hwarith.mul %14, %15 : (si3, ui5) -> si8

Traits: Commutative

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

OperandDescription
inputsan arbitrary precision integer with signedness semantics

Results:

ResultDescription
resultan arbitrary precision integer with signedness semantics

hwarith.sub (::circt::hwarith::SubOp)

Bitwidth-aware integer subtraction.

Syntax:

operation ::= `hwarith.sub` $inputs attr-dict `:` functional-type($inputs, $result)

The sub operation takes two operands and returns one result. The result type is inferred from the operand types, which may be signed or unsigned scalar integer types of arbitrary bitwidth.

LHS typeRHS typeResult type
ui<a>ui<b>si<r>, r = max(a, b) + 1
si<a>si<b>si<r>, r = max(a, b) + 1
ui<a>si<b>si<r>, r = a + 2 if ab
si<r>, r = b + 1 if a < b
si<a>ui<b>Same as ui<b> - si<a>

Examples:

%0 = hwarith.sub %10, %11 : (ui3, ui4) -> si5
%1 = hwarith.sub %12, %13 : (si3, si3) -> si4
%2 = hwarith.sub %14, %15 : (ui3, si4) -> si5
%3 = hwarith.sub %16, %17 : (si4, ui6) -> si8

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

OperandDescription
inputsan arbitrary precision integer with signedness semantics

Results:

ResultDescription
resultan arbitrary precision integer with signedness semantics

Type constraint definition

an arbitrary precision integer with signedness semantics

'hwarith' Dialect Docs