CIRCT

Circuit IR Compilers and Tools

'llhd' Dialect

A low-level hardware description dialect in MLIR.

Operations 

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

Connect two signals.

Syntax:

operation ::= `llhd.con` operands attr-dict `:` qualified(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<EntityOp>, SameTypeOperands

Operands: 

OperandDescription
lhsLLHD sig type of a signless integer bitvector or an ArrayType or a StructType values
rhsLLHD sig type of a signless integer bitvector 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: AlwaysSpeculatableImplTrait, ConstantLike

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (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 `:`
              qualified(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 a signless integer bitvector or an ArrayType or a StructType values
valuea signless integer bitvector 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: IsolatedFromAbove, NoTerminator, SingleBlock

Interfaces: CallableOpInterface, FunctionOpInterface, Symbol

Attributes: 

AttributeMLIR TypeDescription
function_type::mlir::TypeAttrtype attribute of function type
ins::mlir::IntegerAttr64-bit signless integer attribute
arg_attrs::mlir::ArrayAttrArray of dictionary attributes
res_attrs::mlir::ArrayAttrArray of dictionary attributes

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<ProcOp>, 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<EntityOp>

Interfaces: CallOpInterface

Attributes: 

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

Operands: 

OperandDescription
inputsvariadic of LLHD sig type of a signless integer bitvector or an ArrayType or a StructType values
outputsvariadic of LLHD sig type of a signless integer bitvector or an ArrayType or a StructType values

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

Load a value.

Syntax:

operation ::= `llhd.load` $pointer attr-dict `:` qualified(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>>

Interfaces: InferTypeOpInterface

Operands: 

OperandDescription
pointerLLHD pointer type of a signless integer bitvector or an ArrayType or a StructType values

Results: 

ResultDescription
resulta signless integer bitvector or an ArrayType or a StructType

llhd.output (::circt::llhd::OutputOp) 

Introduce a new signal and drive a value onto it.

Syntax:

operation ::= `llhd.output` ( $name^ )? $value `after` $time attr-dict `:` qualified(type($value))

The llhd.output operation introduces a new signal and continuously drives a the given value onto it after a given time-delay. The same value is used to initialize the signal in the same way as the ‘init’ value in llhd.sig. An optional name can be given to the created signal. This shows up, e.g., in the simulation trace.

Example:

%value = llhd.const 1 : i1
%time = llhd.const #llhd.time<1ns, 0d, 0e> : !llhd.time
%sig = llhd.output "sigName" %value after %time : i1

// is equivalent to

%value = llhd.const 1 : i1
%time = llhd.const #llhd.time<1ns, 0d, 0e> : !llhd.time
%sig = llhd.sig "sigName" %value : i1
llhd.drv %sig, %value after %time : !llhd.sig<i1>

Interfaces: InferTypeOpInterface

Attributes: 

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute

Operands: 

OperandDescription
valuea signless integer bitvector or an ArrayType or a StructType
timeLLHD time type

Results: 

ResultDescription
resultLLHD sig type of a signless integer bitvector or an ArrayType or a StructType values

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

Probe a signal.

Syntax:

operation ::= `llhd.prb` $signal attr-dict `:` qualified(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>

Interfaces: InferTypeOpInterface

Operands: 

OperandDescription
signalLLHD sig type of a signless integer bitvector or an ArrayType or a StructType values

Results: 

ResultDescription
resulta signless integer bitvector 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: IsolatedFromAbove

Interfaces: CallableOpInterface, FunctionOpInterface, Symbol

Attributes: 

AttributeMLIR TypeDescription
function_type::mlir::TypeAttrtype attribute of function type
ins::mlir::IntegerAttr64-bit signless integer attribute
arg_attrs::mlir::ArrayAttrArray of dictionary attributes
res_attrs::mlir::ArrayAttrArray of dictionary attributes

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 `:` qualified(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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of an ArrayType values
indexa signless integer bitvector

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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of an ArrayType values
lowIndexa signless integer bitvector

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.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD pointer type of a signless integer bitvector values
lowBita signless integer bitvector

Results: 

ResultDescription
resultLLHD pointer type of a signless integer bitvector 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 `:` qualified(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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (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<EntityOp>

Attributes: 

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

Operands: 

OperandDescription
signalLLHD sig type of a signless integer bitvector or an ArrayType or a StructType values
valuesvariadic of a signless integer bitvector or an ArrayType or a StructType or LLHD sig type of a signless integer bitvector or an ArrayType or a StructType values
triggersvariadic of 1-bit signless integer
delaysvariadic of LLHD time type
gatesvariadic of 1-bit signless integer

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

Create a signal.

Syntax:

operation ::= `llhd.sig` $name $init attr-dict `:` qualified(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.

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<llhd::EntityOp, llhd::ProcOp>

Interfaces: InferTypeOpInterface

Attributes: 

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute

Operands: 

OperandDescription
inita signless integer bitvector or an ArrayType or a StructType

Results: 

ResultDescription
resultLLHD sig type of a signless integer bitvector or an ArrayType or a StructType 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 `:` qualified(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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of an ArrayType values
indexa signless integer bitvector

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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of an ArrayType values
lowIndexa signless integer bitvector

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.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
inputLLHD sig type of a signless integer bitvector values
lowBita signless integer bitvector

Results: 

ResultDescription
resultLLHD sig type of a signless integer bitvector 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 `:` qualified(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>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (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 `:` qualified(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 a signless integer bitvector or an ArrayType or a StructType values
valuea signless integer bitvector or an ArrayType or a StructType

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

Stack allocation.

Syntax:

operation ::= `llhd.var` $init attr-dict `:` qualified(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>

Interfaces: InferTypeOpInterface

Operands: 

OperandDescription
inita signless integer bitvector or an ArrayType or a StructType

Results: 

ResultDescription
resultLLHD pointer type of a signless integer bitvector or an ArrayType or a StructType values

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

Suspends execution of a process.

Syntax:

operation ::= `llhd.wait` (`for` $time^ `,`)? (`(`$obs^ `:` qualified(type($obs))`)` `,`)?
              $dest (`(` $destOps^ `:` qualified(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<ProcOp>, Terminator

Interfaces: BranchOpInterface

Operands: 

OperandDescription
obsvariadic of LLHD sig type of a signless integer bitvector or an ArrayType or a StructType values
timeLLHD time type
destOpsvariadic of any type

Successors: 

SuccessorDescription
destany successor

Attributes 

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 constraints 

LLHD time type 

Types 

PtrType 

pointer type

Syntax:

!llhd.ptr<
  ::mlir::Type   # underlyingType
>

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

Syntax:

!llhd.sig<
  ::mlir::Type   # underlyingType
>

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

Syntax: !llhd.time

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).