'esi' Dialect
Operation definition
esi.decode.capnp
(::circt::esi::CapnpDecodeOp)
Translate bits in Cap’nProto messages to HW typed data
Syntax:
operation ::= `esi.decode.capnp` $clk $valid $capnpBits attr-dict `:` qualified(type($capnpBits)) `->`
qualified(type($decodedData))
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
clk | 1-bit signless integer |
valid | 1-bit signless integer |
capnpBits | an HW bit array |
Results:
Result | Description |
---|---|
decodedData | any type |
esi.encode.capnp
(::circt::esi::CapnpEncodeOp)
Translate HW typed data to Cap’nProto
Syntax:
operation ::= `esi.encode.capnp` $clk $valid $dataToEncode attr-dict `:` qualified(type($dataToEncode))
`->` qualified(type($capnpBits))
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
clk | 1-bit signless integer |
valid | 1-bit signless integer |
dataToEncode | any type |
Results:
Result | Description |
---|---|
capnpBits | an HW bit array |
esi.buffer
(::circt::esi::ChannelBufferOp)
Control options for an ESI channel.
A channel buffer (buffer
) is essentially a set of options on a channel.
It always adds at least one cycle of latency (pipeline stage) to the
channel, but this is configurable.
This operation is inserted on an ESI dataflow edge. It must exist previous to SystemVerilog emission but can be added in a lowering pass.
A stages
attribute may be provided to specify a specific number of cycles
(pipeline stages) to use on this channel. Must be greater than 0.
A name
attribute may be provided to assigned a name to a buffered
connection.
Example:
%esiChan = hw.instance "sender" @Sender () : () -> (!esi.channel<i1>)
// Allow automatic selection of options.
%bufferedChan = esi.buffer %esiChan : i1
hw.instance "recv" @Reciever (%bufferedChan) : (!esi.channel<i1>) -> ()
// Alternatively, specify the number of stages.
%fourStageBufferedChan = esi.buffer %esiChan { stages = 4 } : i1
Traits: AlwaysSpeculatableImplTrait
Interfaces: ChannelOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
stages | ::mlir::IntegerAttr | 64-bit signless integer attribute whose minimum value is 1 |
name | ::mlir::StringAttr | string attribute |
Operands:
Operand | Description |
---|---|
clk | 1-bit signless integer |
rst | 1-bit signless integer |
input | An ESI-compatible channel port |
Results:
Result | Description |
---|---|
output | An ESI-compatible channel port |
esi.cosim
(::circt::esi::CosimEndpointOp)
Co-simulation endpoint
Syntax:
operation ::= `esi.cosim` $clk `,` $rst `,` $send `,` $name attr-dict
`:` qualified(type($send)) `->` qualified(type($recv))
A co-simulation endpoint is a connection from the simulation to some outside process, usually a software application responsible for driving the simulation (driver).
ESI uses a serialization protocol called Cap’n Proto (capnp for short). The advantage of capnp is the decoding overhead: for value types (ints, structs, etc.) there is none! This stands in contrast to Protocol Buffers and Bond as their messages contain metadata for each field which must be interpreted.
The advantage of using a well-supported serialization protocol is language support – driver applications can be written in any language supported by the specific protocol.
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
name | ::mlir::StringAttr | string attribute |
Operands:
Operand | Description |
---|---|
clk | 1-bit signless integer |
rst | 1-bit signless integer |
send | An ESI-compatible channel port |
Results:
Result | Description |
---|---|
recv | An ESI-compatible channel port |
esi.service.decl
(::circt::esi::CustomServiceDeclOp)
An ESI service interface declaration
Syntax:
operation ::= `esi.service.decl` $sym_name $ports attr-dict
A declaration of an ESI service interface. Defines a contract between a service provider and its clients.
Example:
esi.service.decl @HostComms {
esi.service.to_server send : !esi.channel<!esi.any>
esi.service.to_client recieve : !esi.channel<i8>
}
Traits: HasParent<::mlir::ModuleOp>, NoTerminator, SingleBlock
Interfaces: ServiceDeclOpInterface, Symbol
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
esi.null
(::circt::esi::NullSourceOp)
An op which never produces messages.
Syntax:
operation ::= `esi.null` attr-dict `:` qualified(type($out))
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Results:
Result | Description |
---|---|
out | An ESI-compatible channel port |
esi.stage
(::circt::esi::PipelineStageOp)
An elastic buffer stage.
An individual elastic pipeline register. Generally lowered to from a ChannelBuffer (‘buffer’), though can be inserted anywhere to add an additional pipeline stage. Adding individually could be useful for late-pass latency balancing.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ChannelOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
clk | 1-bit signless integer |
rst | 1-bit signless integer |
input | An ESI-compatible channel port |
Results:
Result | Description |
---|---|
output | An ESI-compatible channel port |
esi.mem.ram
(::circt::esi::RandomAccessMemoryDeclOp)
Random access memory service
Syntax:
operation ::= `esi.mem.ram` $sym_name $innerType `x` $depth attr-dict
Declares a service which is backed by a memory of some sort. Allows random access of the inner elements.
Ports: read(address: clog2(depth)) -> data: innerType write({address: clog2(depth), data: innerType}) -> done: i0
Users can ensure R/W ordering by waiting for the write “done” message before issuing a potentially dependant read. Ordering of R/W messages in flight is undefined.
Traits: HasParent<::mlir::ModuleOp>, NoTerminator, SingleBlock
Interfaces: ServiceDeclOpInterface, Symbol
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
innerType | ::mlir::TypeAttr | any type attribute |
depth | ::mlir::IntegerAttr | 64-bit signless integer attribute |
esi.service.req.inout
(::circt::esi::RequestInOutChannelOp)
Request a bidirectional channel
Syntax:
operation ::= `esi.service.req.inout` $toServer `->` $servicePort `(` $clientNamePath `)` attr-dict `:`
qualified(type($toServer)) `->` qualified(type($toClient))
Interfaces: SymbolUserOpInterface
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
servicePort | ::circt::hw::InnerRefAttr | name reference attribute |
clientNamePath | ::mlir::ArrayAttr | string array attribute |
Operands:
Operand | Description |
---|---|
toServer | An ESI-compatible channel port |
Results:
Result | Description |
---|---|
toClient | An ESI-compatible channel port |
esi.service.req.to_client
(::circt::esi::RequestToClientConnectionOp)
Request a connection to receive data
Syntax:
operation ::= `esi.service.req.to_client` $servicePort `(` $clientNamePath `)`
attr-dict `:` qualified(type($toClient))
Interfaces: SymbolUserOpInterface
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
servicePort | ::circt::hw::InnerRefAttr | name reference attribute |
clientNamePath | ::mlir::ArrayAttr | string array attribute |
Results:
Result | Description |
---|---|
toClient | An ESI-compatible channel port |
esi.service.req.to_server
(::circt::esi::RequestToServerConnectionOp)
Request a connection to send data
Syntax:
operation ::= `esi.service.req.to_server` $toServer `->` $servicePort `(` $clientNamePath `)`
attr-dict `:` qualified(type($toServer))
Interfaces: SymbolUserOpInterface
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
servicePort | ::circt::hw::InnerRefAttr | name reference attribute |
clientNamePath | ::mlir::ArrayAttr | string array attribute |
Operands:
Operand | Description |
---|---|
toServer | An ESI-compatible channel port |
esi.service.inout
(::circt::esi::ServiceDeclInOutOp)
An ESI service port which has both directions
Syntax:
operation ::= `esi.service.inout` $inner_sym attr-dict
`:` qualified($toServerType) `->` qualified($toClientType)
Traits: HasParent<::circt::esi::CustomServiceDeclOp>
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
inner_sym | ::mlir::StringAttr | string attribute |
toServerType | ::mlir::TypeAttr | any type attribute |
toClientType | ::mlir::TypeAttr | any type attribute |
esi.service.hierarchy.metadata
(::circt::esi::ServiceHierarchyMetadataOp)
Metadata about a service in the service hierarchy
Syntax:
operation ::= `esi.service.hierarchy.metadata` `path` $serverNamePath (`implementing` $service_symbol^)?
`impl` `as` $impl_type (`opts` $impl_details^)?
`clients` $clients attr-dict
Interfaces: SymbolUserOpInterface
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
service_symbol | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
serverNamePath | ::mlir::ArrayAttr | array attribute |
impl_type | ::mlir::StringAttr | string attribute |
impl_details | ::mlir::DictionaryAttr | dictionary of named attribute values |
clients | ::mlir::ArrayAttr | array attribute |
esi.service.impl_req
(::circt::esi::ServiceImplementReqOp)
Request for a service to be implemented
Syntax:
operation ::= `esi.service.impl_req` (`svc` $service_symbol^)? `impl` `as` $impl_type (`opts` $impl_opts^)?
`(` $inputs `)` attr-dict `:` functional-type($inputs, results)
$portReqs
The connect services pass replaces service.instance
s with this op. The
portReqs
region is the set of connection requests which need to be
implemented for this service instance. Channels to/from the requests have
been added to the operands/results of this op and consumers/producers have
been redirected.
Some other pass or frontend is expected to replace this op with an actual implementation.
Traits: NoTerminator
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
service_symbol | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
impl_type | ::mlir::StringAttr | string attribute |
impl_opts | ::mlir::DictionaryAttr | dictionary of named attribute values |
Operands:
Operand | Description |
---|---|
inputs | any type |
Results:
Result | Description |
---|---|
outputs | any type |
esi.service.instance
(::circt::esi::ServiceInstanceOp)
Instantiate a server module
Syntax:
operation ::= `esi.service.instance` (`svc` $service_symbol^)? `impl` `as` $impl_type (`opts` $impl_opts^)?
`(` $inputs `)` attr-dict `:` functional-type($inputs, results)
Instantiate a service adhering to a service declaration interface.
A pass collects all of the connection requests to the service this op
implements from the containing modules’ descendants (in the instance
hierarchy). It bubbles them all up to the module containing this op,
creating the necessary ESI channel ports, groups them appropriately, then
replaces this op with a service.impl_req
.
If ‘service_symbol’ isn’t specified, this instance will be used to implement all of the service requests which get surfaced to here. This option is generally used at the top level to specify host connectivity.
Since implementing the server will usually need “normal” I/O, inputs
and
results
act like normal hw.instance
ports.
$identifier is used by frontends to specify or remember the type of implementation to use for this service.
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
service_symbol | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
impl_type | ::mlir::StringAttr | string attribute |
impl_opts | ::mlir::DictionaryAttr | dictionary of named attribute values |
Operands:
Operand | Description |
---|---|
inputs | any type |
Results:
Result | Description |
---|---|
«unnamed» | any type |
esi.service.to_client
(::circt::esi::ToClientOp)
An ESI service port headed to a particular client
Syntax:
operation ::= `esi.service.to_client` $inner_sym attr-dict `:` $toClientType
Traits: HasParent<::circt::esi::CustomServiceDeclOp>
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
inner_sym | ::mlir::StringAttr | string attribute |
toClientType | ::mlir::TypeAttr | any type attribute |
esi.service.to_server
(::circt::esi::ToServerOp)
An ESI service port headed to the service
Syntax:
operation ::= `esi.service.to_server` $inner_sym attr-dict `:` $toServerType
Traits: HasParent<::circt::esi::CustomServiceDeclOp>
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
inner_sym | ::mlir::StringAttr | string attribute |
toServerType | ::mlir::TypeAttr | any type attribute |
esi.unwrap.iface
(::circt::esi::UnwrapSVInterfaceOp)
Unwrap an SV interface from an ESI port
Syntax:
operation ::= `esi.unwrap.iface` $chanInput `into` $interfaceSource attr-dict `:` `(` qualified(type($chanInput)) `,` qualified(type($interfaceSource)) `)`
Unwrap an ESI channel into a SystemVerilog interface containing valid, ready, and data signals.
Interfaces: ChannelOpInterface
Operands:
Operand | Description |
---|---|
chanInput | An ESI-compatible channel port |
interfaceSource | sv.interface |
esi.unwrap.vr
(::circt::esi::UnwrapValidReadyOp)
Unwrap a value from an ESI port
Unwrapping a value allows operations on the contained value. Unwrap the channel along with a ready signal that you generate. Result is the data along with a valid signal.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ChannelOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
chanInput | An ESI-compatible channel port |
ready | 1-bit signless integer |
Results:
Result | Description |
---|---|
rawOutput | any type |
valid | 1-bit signless integer |
esi.wrap.iface
(::circt::esi::WrapSVInterfaceOp)
Wrap an SV interface into an ESI port
Syntax:
operation ::= `esi.wrap.iface` $interfaceSink attr-dict `:` qualified(type($interfaceSink)) `->` qualified(type($output))
Wrap a SystemVerilog interface into an ESI channel. Interface MUST look like an interface produced by ESI meaning it MUST contain valid, ready, and data signals. Any other signals will be discarded.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ChannelOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
interfaceSink | sv.interface |
Results:
Result | Description |
---|---|
output | An ESI-compatible channel port |
esi.wrap.vr
(::circt::esi::WrapValidReadyOp)
Wrap a value into an ESI port
Wrapping a value into an ESI port type allows modules to send values down an ESI port. Wrap data with valid bit, result is the ESI channel and the ready signal from the other end of the channel.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ChannelOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
rawInput | any type |
valid | 1-bit signless integer |
Results:
Result | Description |
---|---|
chanOutput | An ESI-compatible channel port |
ready | 1-bit signless integer |
Type definition
ChannelType
An ESI-compatible channel port
Syntax:
!esi.channel<
Type # inner
>
An ESI port kind which models a latency-insensitive, unidirectional, point-to-point data stream. Channels are typed (like all of ESI). Said type can be any MLIR type, but must be lowered to something a backend knows how to output (i.e. something emitVerilog knows about).
Example:
hw.module.extern @Sender() -> (%x: !esi.channel<i1>)
hw.module @Reciever(%a: !esi.channel<hw.array<5xi16>>) { }
Parameters:
Parameter | C++ type | Description |
---|---|---|
inner | Type |
AnyType
any type
Syntax: !esi.any
Used to state that any type is accepted. The specific type will be determined later in compilation.