CIRCT

Circuit IR Compilers and Tools

'llhd' Dialect

A low-level hardware description dialect in MLIR.

Attribute definition 

TimeAttr 

time attribute

Represents a value of the LLHD time type.

Example: #llhd.time<0ns, 1d, 0e>

Parameters: 

ParameterC++ typeDescription
typellhd::TimeType
timeunsigned
timeUnit::llvm::StringRefSI time unit
deltaunsigned
epsilonunsigned

Type constraint definition 

LLHD time type 

pointer type 

Represents a pointer to a memory location holding a value of its element type. May be used to load and store data in distinct memory slots.

signal type 

Signals correspond directly to wires in a physical design, and are used to model propagation delays and timing. Signals are used to carry values across time steps in the LLHD execution model.

time type 

Represents a simulation time value as a combination of a real time value in seconds (or any smaller SI time unit), a delta value representing infinitesimal time steps, and an epsilon value representing an absolute time slot within a delta step (used to model SystemVerilog scheduling regions).

Operation definition 

llhd.con (::circt::llhd::ConnectOp) 

Connect two signals.

Syntax:

operation ::= `llhd.con` operands attr-dict `:` type($lhs)

The con instruction connects two signals such that they essentially become one signal. All driven values on one signal will be reflected on the other.

Traits: HasParent, SameTypeOperands

Operands: 

OperandDescription
lhsLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
rhsLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values

llhd.constant_time (::circt::llhd::ConstantTimeOp) 

Introduce a new time constant.

Syntax:

operation ::= `llhd.constant_time` $value attr-dict

The llhd.constant_time instruction introduces a new constant time value as an SSA-operator.

Example:

%1 = llhd.constant_time #llhd.time<1ns, 2d, 3d>

Traits: ConstantLike

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes: 

AttributeMLIR TypeDescription
valuellhd::TimeAttrtime attribute

Results: 

ResultDescription
resultLLHD time type

llhd.drv (::circt::llhd::DrvOp) 

Drive a value into a signal.

Syntax:

operation ::= `llhd.drv` $signal `,` $value `after` $time ( `if` $enable^ )? attr-dict `:`
              type($signal)

The llhd.drv operation drives a new value onto a signal. A time operand also has to be passed, which specifies the frequency at which the drive will be performed. An optional enable value can be passed as last argument. In this case the drive will only be performed if the value is 1. In case no enable signal is passed the drive will always be performed. This operation does not define any new SSA operands.

Syntax:

drv-op ::= `llhd.drv` ssa-signal `,` ssa-const `after` ssa-time
  (`if` ssa-enable)? `:` !llhd.sig<const-type>

Example:

%init = llhd.const 1 : i1
%en = llhd.const 0 : i1
%time = llhd.const #llhd.time<1ns, 0d, 0e> : !llhd.time
%sig = llhd.sig %init : i1
%new = llhd.not %init : i1

llhd.drv %sig, %new after %time : !llhd.sig<i1>
llhd.drv %sig, %new after %time if %en : !llhd.sig<i1>

Operands: 

OperandDescription
signalLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
valuean integer bitvector of one or more bits or an ArrayType or a StructType
timeLLHD time type
enable1-bit signless integer

llhd.entity (::circt::llhd::EntityOp) 

Create an entity.

The llhd.entity operation defines a new entity unit. An entity represents the data-flow description of how a circuit’s output values change in reaction to changing input values. An entity contains one region with a single block and an implicit TerminatorOp terminator. Both the block name and terminator are omitted in the custom syntax. No further blocks and control-flow are legal inside an entity.

Syntax:

entity-op ::= `llhd.entity` entity-symbol `(` arg-list `)` `->`
  `(` out-list `)` attr-dict entity-region

Example:

llhd.entity @Foo () -> () {
  %0 = llhd.const 0 : i1
  %toggle = llhd.sig %0 : i1 -> !llhd.sig<i1>
  %1 = llhd.prb %toggle : !llhd.sig<i1> -> i1
  %2 = llhd.not %1 : i1
  %dt = llhd.const #llhd.time<1ns, 0d, 0e> : !llhd.time
  llhd.drv %toggle, %2, %dt : !llhd.sig<i1>, i1, !llhd.time
}

Traits: FunctionLike, IsolatedFromAbove, NoTerminator, SingleBlock

Interfaces: CallableOpInterface, Symbol

Attributes: 

AttributeMLIR TypeDescription
ins::mlir::IntegerAttr64-bit signless integer attribute

llhd.halt (::circt::llhd::HaltOp) 

Terminates execution of a process.

Syntax:

operation ::= `llhd.halt` attr-dict

The halt instruction terminates execution of a process. All processes must halt eventually or consist of an infinite loop.

  • This is a terminator instruction
  • This instruction is only allowed in processes (llhd.proc).

Syntax:

halt-op ::= `llhd.halt`

Example:

llhd.halt

Traits: HasParent, Terminator

llhd.inst (::circt::llhd::InstOp) 

Instantiates a process or entity.

Syntax:

operation ::= `llhd.inst` $name $callee `(` $inputs `)` `->` `(` $outputs `)` attr-dict `:`
              functional-type($inputs, $outputs)

Instantiates a process or entity and thus allows to build hierarchies. Can only be used within an entity. An instance defines a unique name within the entity it resides in.

Syntax:

inst-op ::= `llhd.inst` inst-name symbol-name `(` ssa-input-list `)` `->`
  `(` ssa-output-list `)` attr-dict `:`
  functional-type(ssa-input-list, ssa-output-list)

Example:

llhd.inst "foo" @empty() -> () : () -> ()
llhd.inst "bar" @proc_symbol() -> (%out0) : () -> !llhd.sig<i32>
llhd.inst "baz" @entity_symbol(%in0, %in1) -> (%out0, %out1) :
  (!llhd.sig<i32>, !llhd.sig<i16>) -> (!llhd.sig<i8>, !llhd.sig<i4>)

Traits: AttrSizedOperandSegments, HasParent

Interfaces: CallOpInterface

Attributes: 

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute
callee::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands: 

OperandDescription
inputsLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
outputsLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values

llhd.load (::circt::llhd::LoadOp) 

Load a value.

Syntax:

operation ::= `llhd.load` $pointer attr-dict `:` type($pointer)

The llhd.load operation loads a value from a memory region given by pointer.

Examples:

%int = llhd.const 0 : i32
%arr = llhd.array_uniform %int : !llhd.array<3xi32>
%iPtr = llhd.var %int : i32
%arrPtr = llhd.var %arr : !llhd.array<3xi32>

%iLd = llhd.load %iPtr : !llhd.ptr<i32>
%arrLd = llhd.load %arrPtr : !llhd.ptr<!llhd.array<3xi32>>

Operands: 

OperandDescription
pointerLLHD pointer type of an integer bitvector of one or more bits or an ArrayType or a StructType values

Results: 

ResultDescription
resultan integer bitvector of one or more bits or an ArrayType or a StructType

llhd.prb (::circt::llhd::PrbOp) 

Probe a signal.

Syntax:

operation ::= `llhd.prb` $signal attr-dict `:` type($signal)

The llhd.prb instruction probes a signal and returns the value it currently carries as a new SSA operand. The result type is always the type carried by the signal.

Syntax:

prb-op ::= ssa-id `=` `llhd.prb` ssa-sig attr-dict `:` !llhd.sig<type>

Example:

%const_i1 = llhd.const 1 : i1
%sig_i1 = llhd.sig %const_i1 : i1
%prbd = llhd.prb %sig_i1 : !llhd.sig<i1>

Operands: 

OperandDescription
signalLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values

Results: 

ResultDescription
resultan integer bitvector of one or more bits or an ArrayType or a StructType

llhd.proc (::circt::llhd::ProcOp) 

Create a process

A llhd.proc represents control-flow in a timed fashion. It allows a procedural description of how a circuit’s output signals change in reaction to changing input signals. It has a region with arbitrarily many basic blocks. The first block is the entry block and cannot be targeted by the terminators. It uses llhd.wait as a terminator to add timed control-flow. Immediate control-flow with br or cond_br is also possible. Every process must either contain an infinite loop or terminate with the llhd.halt terminator.

How does a process compare to functions and entities?

UnitParadigmTimingModels
Functioncontrol-flowimmediateComputation in zero time
Processcontrol-flowtimedBehavioral circuit description
Entitydata-flowtimedStructural circuit description

Syntax:

proc-op ::= `llhd.proc` proc-symbol `(` ssa-input-list `)` `->`
  `(` ssa-output-list `)` attr-dict `{` proc-region `}`

Examples:

llhd.proc @example(%in0 : !llhd.sig<i64>, %in1 : !llhd.sig<i1>) ->
    (%out2 : !llhd.sig<i1>) {
  br ^bb1
^bb1:
  llhd.halt
}

Traits: FunctionLike, IsolatedFromAbove

Interfaces: CallableOpInterface, Symbol

Attributes: 

AttributeMLIR TypeDescription
ins::mlir::IntegerAttr64-bit signless integer attribute

llhd.ptr.array_get (::circt::llhd::PtrArrayGetOp) 

Extract an element from a pointer to an array.

Syntax:

operation ::= `llhd.ptr.array_get` $input `[` $index `]` attr-dict `:` type($input)

The llhd.ptr.array_get operation allows to access the element of the $input operand at position $index. A new pointer aliasing the element will be returned.

Example:

// Returns a !llhd.ptr<i8>
%0 = llhd.ptr.array_get %arr[%index] : !llhd.ptr<!hw.array<4xi8>>

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of an ArrayType values
indexan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD pointer type of a type without inout values

llhd.ptr.array_slice (::circt::llhd::PtrArraySliceOp) 

Get a range of consecutive values from a pointer to an array

Syntax:

operation ::= `llhd.ptr.array_slice` $input `at` $lowIndex attr-dict `:` functional-type($input, $result)

The llhd.ptr.array_slice operation allows to access a sub-range of the $input operand, starting at the index given by the $lowIndex operand. The resulting slice length is defined by the result type. Returns a pointer aliasing the elements of the slice.

Width of ‘lowIndex’ is defined to be the precise number of bits required to index the ‘input’ array. More precisely: for an input array of size M, the width of ‘lowIndex’ is ceil(log2(M)). Lower and upper bound indexes which are larger than the size of the ‘input’ array results in undefined behavior.

Example:

%3 = llhd.ptr.array_slice %input at %lowIndex :
  (!llhd.ptr<!hw.array<4xi8>>) -> !llhd.ptr<!hw.array<2xi8>>

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of an ArrayType values
lowIndexan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD pointer type of an ArrayType values

llhd.ptr.extract (::circt::llhd::PtrExtractOp) 

Extract a range of bits from an integer pointer

Syntax:

operation ::= `llhd.ptr.extract` $input `from` $lowBit attr-dict `:` functional-type($input, $result)

The llhd.ptr.extract operation allows to access a range of bits of the $input operand, starting at the index given by the $lowBit operand. The result length is defined by the result type.

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of an integer bitvector of one or more bits values
lowBitan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD pointer type of an integer bitvector of one or more bits values

llhd.ptr.struct_extract (::circt::llhd::PtrStructExtractOp) 

Extract a field from a pointer to a struct.

Syntax:

operation ::= `llhd.ptr.struct_extract` $input `[` $field `]` attr-dict `:` type($input)

The llhd.ptr.struct_extract operation allows access to the field of the $input operand given by its name via the $field attribute. A new pointer aliasing the field will be returned.

Example:

// Returns a !llhd.ptr<i8>
%0 = llhd.ptr.struct_extract %struct["foo"]
  : !llhd.ptr<!hw.struct<foo: i8, bar: i16>>

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes: 

AttributeMLIR TypeDescription
field::mlir::StringAttrstring attribute

Operands: 

OperandDescription
inputLLHD pointer type of a StructType values

Results: 

ResultDescription
resultLLHD pointer type of a type without inout values

llhd.reg (::circt::llhd::RegOp) 

Represents a storage element

This instruction represents a storage element. It drives its output onto the ‘signal’ value. An arbitrary amount of triggers can be added to the storage element. However, at least one is required. They are quadruples consisting of the new value to be stored if the trigger applies, the mode and trigger value which specify when this trigger has to be applied as well as a delay. Optionally, each triple may also have a gate condition, in this case the trigger only applies if the gate is one. If multiple triggers apply the left-most in the list takes precedence.

There are five modes available:

ModeMeaning
“low”Storage element stores value while the trigger is low. Models active-low resets and low-transparent latches.
“high”Storage element stores value while the trigger is high. Models active-high resets and high-transparent latches.
“rise”Storage element stores value upon the rising edge of the trigger. Models rising-edge flip-flops.
“fall”Storage element stores value upon the falling edge of the trigger. Models falling-edge flip-flops.
“both”Storage element stores value upon the a rising or a falling edge of the trigger. Models dual-edge flip-flops.

This instruction may only be used in an LLHD entity.

Syntax:

reg-op ::= `llhd.reg` signal-ssa-value
  ( `,` `(` value-ssa-value `,` mode-string trigger-ssa-value `after`
  delay-ssa-value ( `if` gate-ssa-value )? `:` value-type )+
  attr-dict `:` signal-type

Examples:

A rising, falling, and dual-edge triggered flip-flop:

llhd.reg %Q, (%D, "rise" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>
llhd.reg %Q, (%D, "fall" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>
llhd.reg %Q, (%D, "both" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>

A rising-edge triggered flip-flop with active-low reset:

llhd.reg %Q, (%init, "low" %RSTB after %T : !llhd.sig<i8>),
  (%D, "rise" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>

A rising-edge triggered enable flip-flop with active-low reset:

llhd.reg %Q, (%init, "low" %RSTB after %T : !llhd.sig<i8>),
  (%D, "rise" %CLK after %T if %EN : !llhd.sig<i8>) : !llhd.sig<i8>

A transparent-low and transparent-high latch:

llhd.reg %Q, (%D, "low" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>
llhd.reg %Q, (%D, "high" %CLK after %T : !llhd.sig<i8>) : !llhd.sig<i8>

An SR latch:

%0 = llhd.const 0 : i1
%1 = llhd.const 1 : i1
llhd.reg %Q, (%0, "high" %R after %T : !llhd.sig<i1>),
  (%1, "high" %S after %T : !llhd.sig<i1>) : !llhd.sig<i1>

Traits: AttrSizedOperandSegments, HasParent

Attributes: 

AttributeMLIR TypeDescription
modes::mlir::ArrayAttrreg mode array attribute
gateMask::mlir::ArrayAttr64-bit integer array attribute

Operands: 

OperandDescription
signalLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
valuesan integer bitvector of one or more bits or an ArrayType or a StructType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
triggers1-bit signless integer
delaysLLHD time type
gates1-bit signless integer

llhd.shl (::circt::llhd::ShlOp) 

Shifts a value to the left by a given amount.

Syntax:

operation ::= `llhd.shl` operands attr-dict `:` functional-type(operands, results)

The type of the base value and the hidden value must be the same, but may differ in the number of bits or elements. The result always has the same type (including width) of the base value. The instruction is transparent to signals and pointers. For example, passing a signal as argument will shift the underlying value and return a signal to the shifted value. Allowed (underlying) types are signless integers, nine-valued-logic values and arrays. The shift amount has to be a signless integer. A shift amount bigger than the number of bits or elements of the hidden value is undefined. The hidden value is uncovered by non-zero shift amounts. E.g. consider the four bit values base = 0xf, hidden = 0xc shifted by an amount of three result in 0xe.

Syntax:

shl-op ::= ssa-id `=`
  `llhd.shl` ssa-base `,` ssa-hidden `,` ssa-amount attr-dict `:`
  `(` base-type `,` hidden-type `,` amount-type `)` `->` result-type

Examples:

%0 = llhd.shl %base, %hidden, %amount : (i4, i2, i2) -> i4

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
basean integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values
hiddenan integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values
amountan integer bitvector of one or more bits

Results: 

ResultDescription
resultan integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values

llhd.shr (::circt::llhd::ShrOp) 

Shifts a value to the right by a given amount.

Syntax:

operation ::= `llhd.shr` operands attr-dict `:` functional-type(operands, results)

The type of the base value and the hidden value must be the same, but may differ in the number of bits or elements. The result always has the same type (including width) of the base value. The instruction is transparent to signals and pointers. For example, passing a signal as argument will shift the underlying value and return a signal to the shifted value. Allowed (underlying) types are signless integers, nine-valued-logic values and arrays. The shift amount has to be a signless integer. A shift amount bigger than the number of bits or elements of the hidden value is undefined. The hidden value is uncovered by non-zero shift amounts. E.g. consider the four bit values base = 0xf, hidden = 0xc shifted by an amount of three result in 0x9.

Syntax:

shr-op ::= ssa-id `=`
  `llhd.shr` ssa-base `,` ssa-hidden `,` ssa-amount attr-dict `:`
  `(` base-type `,` hidden-type `,` amount-type `)` `->` result-type

Examples:

%0 = llhd.shr %base, %hidden, %amount : (i4, i2, i2) -> i4

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
basean integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values
hiddenan integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values
amountan integer bitvector of one or more bits

Results: 

ResultDescription
resultan integer bitvector of one or more bits or an ArrayType or LLHD sig type of an integer bitvector of one or more bits or an ArrayType values

llhd.sig.array_get (::circt::llhd::SigArrayGetOp) 

Extract an element from a signal of an array.

Syntax:

operation ::= `llhd.sig.array_get` $input `[` $index `]` attr-dict `:` type($input)

The llhd.sig.array_get operation allows to access the element of the $input operand at position $index. A new subsignal aliasing the element will be returned.

Example:

// Returns a !llhd.sig<i8>
%0 = llhd.sig.array_get %arr[%index] : !llhd.sig<!hw.array<4xi8>>

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of an ArrayType values
indexan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD sig type of a type without inout values

llhd.sig.array_slice (::circt::llhd::SigArraySliceOp) 

Get a range of consecutive values from a signal of an array

Syntax:

operation ::= `llhd.sig.array_slice` $input `at` $lowIndex attr-dict `:` functional-type($input, $result)

The llhd.sig.array_slice operation allows to access a sub-range of the $input operand, starting at the index given by the $lowIndex operand. The resulting slice length is defined by the result type. Returns a signal aliasing the elements of the slice.

Width of ‘lowIndex’ is defined to be the precise number of bits required to index the ‘input’ array. More precisely: for an input array of size M, the width of ‘lowIndex’ is ceil(log2(M)). Lower and upper bound indexes which are larger than the size of the ‘input’ array results in undefined behavior.

Example:

%3 = llhd.sig.array_slice %input at %lowIndex : 
  (!llhd.sig<!hw.array<4xi8>>) -> !llhd.sig<!hw.array<2xi8>>

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of an ArrayType values
lowIndexan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD sig type of an ArrayType values

llhd.sig.extract (::circt::llhd::SigExtractOp) 

Extract a range of bits from an integer signal

Syntax:

operation ::= `llhd.sig.extract` $input `from` $lowBit attr-dict `:` functional-type($input, $result)

The llhd.sig.extract operation allows to access a range of bits of the $input operand, starting at the index given by the $lowBit operand. The result length is defined by the result type.

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of an integer bitvector of one or more bits values
lowBitan integer bitvector of one or more bits

Results: 

ResultDescription
resultLLHD sig type of an integer bitvector of one or more bits values

llhd.sig (::circt::llhd::SigOp) 

Create a signal.

Syntax:

operation ::= `llhd.sig` $name $init attr-dict `:` type($init)

The llhd.sig instruction introduces a new signal in the IR. The input operand determines the initial value carried by the signal, while the result type will always be a signal carrying the type of the init operand. A signal defines a unique name within the entity it resides in. Signals can only be allocated within entities.

Syntax:

sig-op ::= ssa-id `=` `llhd.sig` sig-name ssa-init attr-dict `:` init-type

Example:

%init_i64 = llhd.const 123 : i64
%sig_i64 = llhd.sig "foo" %init_64 : i64

%init_i1 = llhd.const 1 : i1
%sig_i1 = llhd.sig "bar" %init_i1 : i1

The first llhd.sig instruction creates a new signal named “foo”, carrying an i64 type with initial value of 123, while the second one creates a new signal named “bar”, carrying an i1 type with initial value of 1.

Traits: HasParent

Attributes: 

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute

Operands: 

OperandDescription
initan integer bitvector of one or more bits or an ArrayType or a StructType

Results: 

ResultDescription
resultLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values

llhd.sig.struct_extract (::circt::llhd::SigStructExtractOp) 

Extract a field from a signal of a struct.

Syntax:

operation ::= `llhd.sig.struct_extract` $input `[` $field `]` attr-dict `:` type($input)

The llhd.sig.struct_extract operation allows access to the field of the $input operand given by its name via the $field attribute. A new subsignal aliasing the field will be returned.

Example:

// Returns a !llhd.sig<i8>
%0 = llhd.sig.struct_extract %struct["foo"]
  : !llhd.sig<!hw.struct<foo: i8, bar: i16>>

Interfaces: InferTypeOpInterface, NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes: 

AttributeMLIR TypeDescription
field::mlir::StringAttrstring attribute

Operands: 

OperandDescription
inputLLHD sig type of a StructType values

Results: 

ResultDescription
resultLLHD sig type of a type without inout values

llhd.store (::circt::llhd::StoreOp) 

Store a value.

Syntax:

operation ::= `llhd.store` $pointer `,` $value attr-dict `:` type($pointer)

The llhd.store operation stores the value value to the memory region given by pointer.

Examples:

%int = llhd.const 0 : i32
%arr = llhd.array_uniform %int : !llhd.array<3xi32>
%iPtr = llhd.var %int : i32
%arrPtr = llhd.var %arr : !llhd.array<3xi32>

llhd.store %iPtr, %int : !llhd.ptr<i32>
llhd.store %arrPtr, %arr : !llhd.ptr<!llhd.array<3xi32>>

Operands: 

OperandDescription
pointerLLHD pointer type of an integer bitvector of one or more bits or an ArrayType or a StructType values
valuean integer bitvector of one or more bits or an ArrayType or a StructType

llhd.var (::circt::llhd::VarOp) 

Stack allocation.

Syntax:

operation ::= `llhd.var` $init attr-dict `:` type($init)

The llhd.var operation allocates a memory region on the stack with the initial value given by init, and returns a pointer to the allocated region.

Examples:

%int = llhd.const 0 : i32
%arr = llhd.array_uniform %int : !llhd.array<3xi32>

%iPtr = llhd.var %int : i32
%arrPtr = llhd.var %arr : !llhd.array<3xi32>

Operands: 

OperandDescription
initan integer bitvector of one or more bits or an ArrayType or a StructType

Results: 

ResultDescription
resultLLHD pointer type of an integer bitvector of one or more bits or an ArrayType or a StructType values

llhd.wait (::circt::llhd::WaitOp) 

Suspends execution of a process.

Syntax:

operation ::= `llhd.wait` (`for` $time^ `,`)? (`(`$obs^ `:` type($obs)`)` `,`)?
              $dest (`(` $destOps^ `:` type($destOps) `)`)? attr-dict

The wait instruction suspends execution of a process until any of the observed signals change or a fixed time interval has passed. Execution resumes at the specified basic block with the passed arguments.

  • This is a terminator instruction.
  • This instruction is only allowed in processes (llhd.proc).

Example:

llhd.wait ^bb1
llhd.wait for %time, ^bb1(%time : !llhd.time)
llhd.wait (%0, %1 : !llhd.sig<i64>, !llhd.sig<i1>), ^bb1(%1 : !llhd.sig<i1>)
llhd.wait for %time, (%0, %1 : !llhd.sig<i64>, !llhd.sig<i1>),
  ^bb1(%1, %0 : !llhd.sig<i1>, !llhd.sig<i64>)

Traits: AttrSizedOperandSegments, HasParent, Terminator

Interfaces: BranchOpInterface

Operands: 

OperandDescription
obsLLHD sig type of an integer bitvector of one or more bits or an ArrayType or a StructType values
timeLLHD time type
destOpsany type

Successors: 

SuccessorDescription
destany successor

Type definition 

PtrType 

pointer type

Represents a pointer to a memory location holding a value of its element type. May be used to load and store data in distinct memory slots.

Parameters: 

ParameterC++ typeDescription
underlyingType::mlir::Type

SigType 

signal type

Signals correspond directly to wires in a physical design, and are used to model propagation delays and timing. Signals are used to carry values across time steps in the LLHD execution model.

Parameters: 

ParameterC++ typeDescription
underlyingType::mlir::Type

TimeType 

time type

Represents a simulation time value as a combination of a real time value in seconds (or any smaller SI time unit), a delta value representing infinitesimal time steps, and an epsilon value representing an absolute time slot within a delta step (used to model SystemVerilog scheduling regions).