CIRCT

Circuit IR Compilers and Tools

'llhd' Dialect

A low-level hardware description dialect in MLIR.

Type constraint definition 

LLHD time type 

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.

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>

Attributes: 

AttributeMLIR TypeDescription
valueTimeAttrLLHD time 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.dyn_extract_element (::circt::llhd::DynExtractElementOp) 

Dynamically extract an element from an array or signal of array.

Syntax:

operation ::= `llhd.dyn_extract_element` $target `,` $index attr-dict `:` functional-type(operands, results)

The llhd.dyn_extract_element operation allows to dynamically access an element of the $target operand. The $index operand defines the index of the element to extract. If %target is a signal, a new subsignal aliasing the element will be returned.

Example:

%index = llhd.const 1 : i2

%init = llhd.const 3 : i8
%0 = llhd.array_uniform %init : !llhd.array<3xi8>
%1 = llhd.dyn_extract_element %0, %index : (!llhd.array<3xi8>, i2) -> i8

%2 = llhd.sig %0 : !llhd.array<3xi8>
%3 = llhd.dyn_extract_element %2, %index
  : (!llhd.sig<!llhd.array<3xi8>>, i2) -> !llhd.sig<i8>

Operands: 

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

Results: 

ResultDescription
resultany type

llhd.dyn_extract_slice (::circt::llhd::DynExtractSliceOp) 

Dynamically extract a slice of consecutive elements

Syntax:

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

The llhd.dyn_extract_slice operation allows to dynamically access a slice of the $target operand, starting at the index given by the $start operand. The resulting slice length is defined by the result type. The $target operand kind has to match the result kind. If $target is an array, only the number of elements can change, while the element type has to remain the same.

Example:

%0 = llhd.const 0x0f0 : i12
%1 = llhd.const 4 : i3

%3 = llhd.dyn_extract_slice %0, %1 : (i12, i3) -> i4    // %3: 0xf

Operands: 

OperandDescription
targetan 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
startan 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.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
}

Attributes: 

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

llhd.eq (::circt::llhd::EqOp) 

Logical Equality

Syntax:

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

This operation compares two values and returns 1 if they are the same and 0 otherwise. It is capable of comparing all types in the LLHD dialect. It performs element-wise equality for arrays and tuples.

Examples:

%const1 = constant 1 : i32
%const2 = constant 2 : i32
%eq = llhd.eq %const1, %const2 : i32  // %eq = 0

%const3 = constant 0 : i1
%tup1 = llhd.tuple %const1, %const3 : tuple<i32, i1>
%tup2 = llhd.tuple %const2, %const3 : tuple<i32, i1>
%tupeq = llhd.eq %tup1, %tup2 : i32  // %tupeq = 0

Operands: 

OperandDescription
lhsany type
rhsany type

Results: 

ResultDescription
result1-bit signless integer

llhd.extract_element (::circt::llhd::ExtractElementOp) 

Extract an element from an array, tuple, or signal of an array or tuple.

Syntax:

operation ::= `llhd.extract_element` $target `,` $index attr-dict `:` type($target) `->` type($result)

The llhd.extract_element operation allows access to an element of the $target operand. The $index attribute defines the index of the element to extract. If %target is a signal, a new subsignal aliasing the element will be returned.

Example:

%init = llhd.const 3 : i8
%0 = llhd.array_uniform %init : !llhd.array<3xi8>
%1 = llhd.extract_element %0, 0 : !llhd.array<3xi8> -> i8

%2 = llhd.sig %0 : !llhd.array<3xi8>
%3 = llhd.extract_element %2, 0
  : !llhd.sig<!llhd.array<3xi8>> -> !llhd.sig<i8>

%4 = llhd.const 8 : i16
%5 = llhd.tuple %0, %4 : tuple<!llhd.array<3xi8>, i16>
%6 = llhd.extract_element %5, 1 : tuple<!llhd.array<3xi8>, i16> -> i16

Attributes: 

AttributeMLIR TypeDescription
index::mlir::IntegerAttrindex attribute

Operands: 

OperandDescription
targetan ArrayType or a StructType or LLHD sig type of an ArrayType or a StructType values

Results: 

ResultDescription
resultany type

llhd.extract_slice (::circt::llhd::ExtractSliceOp) 

Extract a slice of consecutive elements.

Syntax:

operation ::= `llhd.extract_slice` $target `,` $start attr-dict `:` type($target) `->` type($result)

The llhd.extract_slice operation allows access to a slice of the $target operand. The $start attribute defines the index of the first element. The return type is the same as $target but with the width of the specified result type. If %target is a signal, a new subsignal aliasing the slice will be returned.

Example:

%0 = llhd.const 123 : i32
%1 = llhd.extract_slice %0, 0 : i32 -> i2

%2 = llhd.sig %0 : i32
%3 = llhd.extract_slice %2, 0 : !llhd.sig<i32> -> !llhd.sig<i5>

Attributes: 

AttributeMLIR TypeDescription
start::mlir::IntegerAttrindex attribute

Operands: 

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

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

llhd.insert_element (::circt::llhd::InsertElementOp) 

Insert an element into an array or tuple.

Syntax:

operation ::= `llhd.insert_element` $target `,` $element `,` $index attr-dict `:`
              type($target) `,` type($element)

The llhd.insert_element operation allows insertion of an element represented by the $element operand into the $target operand. The $index attribute defines the index where to insert the element. The return type is the same as $target. Note that the $target is not changed, but a new value with the element inserted is returned.

Example:

%init = llhd.const 1 : i8
%target = llhd.array_uniform : !llhd.array<3xi8>
%element = llhd.const 2 : i8
%0 = llhd.insert_element %target, %element, 0 : !llhd.array<3xi8>, i8

%tuptarget = llhd.tuple %element, %target : tuple<i8, !llhd.array<3xi8>
%newelement = llhd.const 4 : i8
%1 = llhd.insert_element %tuptarget, %newelement, 0
  : tuple<i8, !llhd.array<3xi8>>, i8

Attributes: 

AttributeMLIR TypeDescription
index::mlir::IntegerAttrindex attribute

Operands: 

OperandDescription
targetan ArrayType or a StructType
elementany type

Results: 

ResultDescription
resultan ArrayType or a StructType

llhd.insert_slice (::circt::llhd::InsertSliceOp) 

Insert a slice of consecutive elements.

Syntax:

operation ::= `llhd.insert_slice` $target `,` $slice `,` $start attr-dict `:` type($target) `,` type($slice)

The llhd.insert_slice operation allows insertion of a slice represented by the $slice operand into the $target operand. The $start attribute defines the index of the first element. The return type is the same as $target. Note that the $target is not changed, but a new value with the slice inserted is returned.

Example:

%itarget = llhd.const 123 : i32
%islice = llhd.const 2 : i2
%0 = llhd.insert_slice %itarget, %islice, 0 : i32, i2

%init1 = llhd.const 2 : i32
%init2 = llhd.const 3 : i32
%vtarget = llhd.array_uniform %init1 : !llhd.array<3xi32>
%vslice = llhd.array_uniform %init2 : !llhd.array<2xi32>
%1 = llhd.insert_slice %vtarget, %vslice, 0
  : !llhd.array<3xi32>, !llhd.array<2xi32>

Attributes: 

AttributeMLIR TypeDescription
start::mlir::IntegerAttrindex attribute

Operands: 

OperandDescription
targetan integer bitvector of one or more bits or an ArrayType
slicean integer bitvector of one or more bits or an ArrayType

Results: 

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

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

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.neq (::circt::llhd::NeqOp) 

Logical Inequality

Syntax:

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

This operation compares two values and returns 1 if they are not the same and 0 if they are the same. It is capable of comparing all types in the LLHD dialect. It performs element-wise equality for arrays and tuples.

Examples:

%const1 = constant 1 : i32
%const2 = constant 2 : i32
%neq = llhd.neq %const1, %const2 : i32  // %neq = 1

%const3 = constant 0 : i1
%tup1 = llhd.tuple %const1, %const3 : tuple<i32, i1>
%tup2 = llhd.tuple %const2, %const3 : tuple<i32, i1>
%tupneq = llhd.neq %tup1, %tup2 : i32  // %tupeq = 1

Operands: 

OperandDescription
lhsany type
rhsany type

Results: 

ResultDescription
result1-bit signless integer

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
}

Attributes: 

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

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>

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

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

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 (::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.

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.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.terminator (::circt::llhd::TerminatorOp) 

Dummy terminator

The "llhd.terminator" op is a dummy terminator for an EntityOp unit. It provides no further meaning other than ensuring correct termination of an entitiy’s region. This operation provides no custom syntax and should never explicitly appear in LLHD’s custom syntax.

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

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