Skip to content

Latest commit

 

History

History
919 lines (628 loc) · 27.3 KB

File metadata and controls

919 lines (628 loc) · 27.3 KB

'coredsl' Dialect

CoreDSL-specific constructs for ISAX descriptions.

The coredsl dialect provides the necessary operations to model a CoreDSL description of an ISA extensions (ISAX), contained in a named builtin.module.

The dialect is designed to be mixed with MLIR's scf and func dialects, and augments CIRCT's hwarith dialect.

The available operations can be classified as follows:

  • coredsl.instruction, coredsl.spawn and coredsl.always are containers for high-level, untimed behavior descriptions.
  • coredsl.register, coredsl.addrspace and coredsl.alias represent architectural state elements, which are accessed by the coredsl.get and .set ops.
  • The remaining ops implement the bitwidth-aware arithmetic/logic operators on MLIR's uiN/siN types that are missing in the hwarith dialect.

Example:

coredsl.isax "sparkle" {
  coredsl.register core_x @X[32] : ui32
  coredsl.register local const @ROT_0[4] = [31, 17, 0, 24] : ui8
  coredsl.register local const @ROT_1[4] = [24, 17, 31, 16] : ui8
  coredsl.register local const @RCON[8] =
    [3084996962, 3211876480, 951376470, 844003128,
    3138487787, 1333558103, 3485442504, 3266521405] : ui32

  func.func @ROTR(%arg0: ui32, %arg1: ui8) -> ui32 {
    %0 = hwarith.constant 32 : ui6
    %1 = coredsl.shift_right %arg0, %arg1 : ui32, ui8
    %2 = hwarith.sub %0, %arg1 : (ui6, ui8) -> si9
    %3 = coredsl.shift_left %arg0, %2 : ui32, si9
    %4 = coredsl.or %1, %3 : ui32, ui32
    return %4 : ui32
  }

  func.func @ELL(%arg0: ui32) -> ui32 {
    %0 = hwarith.constant 16 : ui5
    %1 = coredsl.shift_left %arg0, %0 : ui32, ui5
    %2 = coredsl.xor %arg0, %1 : ui32, ui32
    %3 = coredsl.cast %0 : ui5 to ui8
    %4 = call @ROTR(%2, %3) : (ui32, ui8) -> ui32
    return %4 : ui32
  }

  coredsl.instruction @sparkle_ell("0000010", %rs2 : ui5, %rs1 : ui5, "111", %rd : ui5, "1111011"){
    %0 = coredsl.get @X[%rs1 : ui5] : ui32
    %1 = coredsl.get @X[%rs2 : ui5] : ui32
    %2 = coredsl.xor %0, %1 : ui32, ui32
    %3 = func.call @ELL(%2) : (ui32) -> ui32
    coredsl.set @X[%rd : ui5] = %3 : ui32
    coredsl.end
  }

  coredsl.instruction @sparkle_rcon("0000", %imm : ui3, %rs2 : ui5, %rs1 : ui5, "110", %rd : ui5, "1111011"){
    %0 = coredsl.get @X[%rs1 : ui5] : ui32
    %1 = coredsl.get @RCON[%imm : ui3] : ui32
    %2 = coredsl.xor %0, %1 : ui32, ui32
    coredsl.set @X[%rd : ui5] = %2 : ui32
    coredsl.end
  }
}

[TOC]

Operations

coredsl.addrspace (coredsl::AddressSpaceOp)

Declares an address space.

Syntax:

operation ::= `coredsl.addrspace` $accessMode oilist(`const` $isConst | `volatile` $isVolatile) $sym_name `:` (`(`$addrType^`)` `->`)? $resType attr-dict

This operation declares a CoreDSL address space with the given name, element type, flags, and access mode. The optional unsigned address type determines the number of addressable elements.

An address space can be marked as read-only by the const keyword. The volatile keyword is accepted but ignored by the lowering passes.

The following access modes are supported:

  • core_mem: Access to the core's main memory via SCAIE-V.
  • core_csr: Access to the core's control-status registers via SCAIE-V.
  • (axi4mm and wire are reserved for future use.)

Examples:

coredsl.addrspace core_mem @MEM : (ui32) -> ui8
coredsl.addrspace core_csr @CSR : (ui12) -> ui32

Interfaces: GetSetOpInterface, Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
isConst::mlir::UnitAttrunit attribute
isVolatile::mlir::UnitAttrunit attribute
addrType::mlir::TypeAttrany type attribute
resType::mlir::TypeAttrany type attribute
accessMode::mlir::coredsl::AddressSpaceAccessModeAttrcoredsl.addrspace access protocol

coredsl.alias (coredsl::AliasOp)

Declares an alias.

Syntax:

operation ::= `coredsl.alias` oilist(`const` $isConst | `volatile` $isVolatile) $sym_name `=` $ref `` custom<IdxRange>($from, $to)
              attr-dict

This operation declares a CoreDSL alias with the given name to another architectural state item, referencing either a single element or a range of elements. The optional const keyword marks the alias as read-only. Aliases to read-only architectural state must be const. The volatile keyword is accepted, but ignored in the lowering passes.

Examples:

coredsl.alias @A1 = @REG
coredsl.alias @A2 = @REGFIELD[6]
coredsl.alias @A3 = @MEM[7:0]

Interfaces: Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
ref::mlir::FlatSymbolRefAttrflat symbol reference attribute
isConst::mlir::UnitAttrunit attribute
isVolatile::mlir::UnitAttrunit attribute
from::mlir::IntegerAttrindex attribute whose value is non-negative
to::mlir::IntegerAttrindex attribute whose value is non-negative

coredsl.always (coredsl::AlwaysOp)

Defines an always-block.

Syntax:

operation ::= `coredsl.always` $sym_name $body attr-dict

This operation defines an always-block with the given name. The behavior, described in the single-block region, will be executed repeatedly at the same rate as instructions are fetched, and in parallel with regular instructions and other always-blocks.

Example:

coredsl.always @implicit_pc_increment {
  %oldpc = coredsl.get @PC : ui32
  %c1 = hwarith.constant 4 : ui3
  %incr = hwarith.add %oldpc, %c1 : (ui32, ui3) -> ui33
  %newpc = coredsl.cast %incr : ui33 to ui32
  coredsl.set @PC = %newpc : ui32
  coredsl.end
}

Traits: HasParent<coredsl::ISAXOp>, IsolatedFromAbove, NoRegionArguments, SingleBlock

Interfaces: Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute

coredsl.and (coredsl::AndOp)

Bitwise AND operator.

Syntax:

operation ::= `coredsl.and` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation computes the bitwise AND of the operands. Differently signed and sized operands are allowed; the smaller of the operands will be zero- or sign-extended to the result type with is determined by the corresponding CoreDSL type rules.

Example:

%2 = coredsl.and %0, %1 : ui3, si2 // yields si3

Traits: AlwaysSpeculatableImplTrait, Commutative

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.bitextract (coredsl::BitExtractOp)

Extracts bits from a scalar value.

Syntax:

operation ::= `coredsl.bitextract` $value`` custom<RangedAccess>("false", $base, type($base), $from, $to) `:` functional-type($value, $result) attr-dict

This operation extracts a single bit or a range of bits from the given operand. In the latter case, the bits are optionally reversed and concatened according the rules of the CoreDSL subscript operator, though here we use a slightly different notation with a base index and constant from/to offsets.

Examples:

coredsl.bitextract %0[63] : (si64) -> ui1 // sign-bit
coredsl.bitextract %1[%2 : ui5] : (ui32) -> ui1
coredsl.bitextract %3[23:16] : (ui32) -> ui8
coredsl.bitextract %4[%5 : ui4, 0:3] : (si16) -> ui4 // reversed nibble

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
from::mlir::IntegerAttrindex attribute
to::mlir::IntegerAttrindex attribute

Operands:

Operand Description
base an arbitrary precision integer with signedness semantics and unsigned integer
value an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.bitset (coredsl::BitSetOp)

Sets bits in a scalar value.

Syntax:

operation ::= `coredsl.bitset` $value`` custom<RangedAccess>("false", $base, type($base), $from, $to) `=` $rhs `:` custom<FancyFunctionalType>(type($result), type($value), type($rhs)) attr-dict

This operation updates a single bit or a range of bits in first operands with the second operand. In the latter case, the bits are optionally reversed and concatened according the rules of the CoreDSL subscript operator, though here we use a slightly different notation with a base index and constant from/to offsets.

Examples:

coredsl.bitset %0[42] = %1 : (si64, ui1) -> si64
coredsl.bitset %2[%3 : ui5] = %4 : (ui32, ui1) -> ui32
coredsl.bitset %5[23:16] = %6 : (ui32, ui8) -> ui32
coredsl.bitset %7[%8 : ui4, 0:3] = %9 : (si16, ui4) -> si16 // reversed nibble

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
from::mlir::IntegerAttrindex attribute
to::mlir::IntegerAttrindex attribute

Operands:

Operand Description
base an arbitrary precision integer with signedness semantics and unsigned integer
rhs an arbitrary precision integer with signedness semantics
value an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.cast (coredsl::CastOp)

Generic cast operation.

Syntax:

operation ::= `coredsl.cast` $value `:` type($value) `to` type($result) attr-dict

This operations allows casts between arbitrary signed and unsigned types, and as a special case, casts single-bit values (si1/ui1) to the signless i1 to provide a bridge to standard MLIR dialects such as scf.

Casts are implemented as truncations, or zero-/sign-extensions depending on the type of the source operand.

Examples:

%1 = coredsl.cast %0 : ui8 to si8
%3 = coredsl.cast %2 : ui1 to i1
%5 = coredsl.cast %4 : si65 to ui32

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
value an arbitrary precision integer with signedness semantics

Results:

Result Description
result integer

coredsl.concat (coredsl::ConcatOp)

Concatenates two values.

Syntax:

operation ::= `coredsl.concat` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation represents the CoreDSL ::-operator and concatenates its two operands. The result is always unsigned.

Example:

%2 = coredsl.concat %0, %1 : ui8, si3 // yields ui11

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.end (coredsl::EndOp)

No-op terminator.

Syntax:

operation ::= `coredsl.end` attr-dict

Traits: HasParent<InstructionOp, AlwaysOp, SpawnOp>, Terminator

coredsl.get (coredsl::GetOp)

Reads from architectural state.

Syntax:

operation ::= `coredsl.get` $sym`` custom<RangedAccess>("true", $base, type($base), $from, $to) `:` type($result) attr-dict

This operation accesses the register, address space or alias denoted by the given symbol. If the architectural state item has multiple elements (e.g. a register file), then either a single element or a range of elements can be retrieved. In the latter case, the elements are optionally reversed and concatened according the rules of the CoreDSL subscript operator, though here we use a slightly different notation with a base index and constant from/to offsets.

Examples:

%pc  = coredsl.get @X : ui32
%addr = coredsl.get @X[%rs1 : ui5] : ui32
%half_le = coredsl.get @MEM[%addr : ui32, 1:0] : ui16 // little-endian
%word_be = coredsl.get @MEM[%addr : ui32, 0:3] : ui32 // big-endian

Attributes:

AttributeMLIR TypeDescription
from::mlir::IntegerAttrindex attribute
to::mlir::IntegerAttrindex attribute
sym::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

Operand Description
base an arbitrary precision integer with signedness semantics and unsigned integer

Results:

Result Description
result any type

coredsl.instruction (coredsl::InstructionOp)

Defines an instruction.

This operation defines a CoreDSL instruction with the given symbol name, binary encoding, and behavior.

The operation's argument list naturally captures the encoding from MSB to LSB as a sequence of fields and patterns. The single-block region describes the instruction's behavior, which is terminated by either a coredsl.end or a coredsl.spawn operation.

Example:

coredsl.instruction @ADDI(%imm : ui12, %rs1 : ui5, "000", %rd : ui5, "0010011") {
  %arg1 = coredsl.get @X[%rs1 : ui5] : ui32
  %simm = coredsl.cast %imm : ui12 to si12
  %add = hwarith.add %arg1, %simm : (ui32, si12) -> si34
  %trunc = coredsl.bitextract %add[31:0] : (si34) -> ui32
  coredsl.set @X[%rd : ui5] = %trunc : ui32
  coredsl.end
}

Traits: HasParent<coredsl::ISAXOp>, IsolatedFromAbove

Interfaces: ArgAndResultAttrsOpInterface, CallableOpInterface, FunctionOpInterface, OpAsmOpInterface, Symbol

Attributes:

AttributeMLIR TypeDescription
function_type::mlir::TypeAttrtype attribute of function type
arg_attrs::mlir::ArrayAttrArray of dictionary attributes
res_attrs::mlir::ArrayAttrArray of dictionary attributes
encoding::mlir::ArrayAttrstring array attribute

coredsl.isax (coredsl::ISAXOp)

Container for coredsl instructions.

Syntax:

operation ::= `coredsl.isax` $name $body attr-dict

This operation represents an ISAX as a collection of coredsl.instructions, coredsl state elements and functions.

Traits: IsolatedFromAbove, NoRegionArguments, NoTerminator, SingleBlock, SymbolTable

Attributes:

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute

coredsl.mod (coredsl::ModOp)

Modulus/remainder operator.

Syntax:

operation ::= `coredsl.mod` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation computes the modulus of the operands. The result type is determined by the type rules of the CoreDSL %-operator.

Examples:

%2 = coredsl.mod %0, %1 : ui2, ui8 // yields ui2
%5 = coredsl.mod %3, %4 : si5, ui2 // yields si3

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.or (coredsl::OrOp)

Bitwise OR operator.

Syntax:

operation ::= `coredsl.or` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation computes the bitwise OR of the operands. Differently signed and sized operands are allowed; the smaller of the operands will be zero- or sign-extended to the result type with is determined by the corresponding CoreDSL type rules.

Example:

%2 = coredsl.or %0, %1 : ui3, si2 // yields si3

Traits: AlwaysSpeculatableImplTrait, Commutative

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.register (coredsl::RegisterOp)

Declares a register (file).

Syntax:

operation ::= `coredsl.register` $accessMode oilist(`const` $isConst | `volatile` $isVolatile) $sym_name (`[` $numElements^ `]`)? custom<Initializer>($initializer, $regType) attr-dict

This operation declares a CoreDSL register with the given name, type, flags, and access mode. Optionally, a number of elements and and an initializer can be specified.

A register can be marked as read-only by the const keyword. The volatile keyword is accepted but ignored by the lowering passes.

The following access modes are supported:

  • core_x: Access the core's general-purpose register file via SCAIE-V.
  • core_pc: Access the core's program counter via SCAIE-V.
  • local: Access a custom register or register file instantiated by SCAIE-V.
  • (core_fp: Reserved for future F/D-extension use).

Examples:

coredsl.register core_x @X[32] : ui32
coredsl.register core_pc @PC : ui32
coredsl.register local @MY_REG = 44 : ui14
coredsl.register const local @MY_REG_FIELD[3] = [282, 999, 151] : ui37

Interfaces: GetSetOpInterface, Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
isConst::mlir::UnitAttrunit attribute
isVolatile::mlir::UnitAttrunit attribute
numElements::mlir::IntegerAttrindex attribute
initializer::mlir::ElementsAttrconstant vector/tensor attribute
regType::mlir::TypeAttrany type attribute
accessMode::mlir::coredsl::RegisterAccessModeAttrcoredsl.register access mode

coredsl.set (coredsl::SetOp)

Writes to architectural state.

Syntax:

operation ::= `coredsl.set` $sym`` custom<RangedAccess>("true", $base, type($base), $from, $to) `=` $value `:` type($value) attr-dict

This operation accesses the register, address space or alias denoted by the given symbol. If the architectural state item has multiple elements (e.g. a register file), then either a single element or a range of elements can be stored. In the latter case, the elements are optionally reversed and concatened according the rules of the CoreDSL subscript operator, though here we use a slightly different notation with a base index and constant from/to offsets.

Examples:

coredsl.set @PC = %0 : ui32
coredsl.set @X[%rd : ui5] = %1 : ui32
coredsl.set @MEM[%addr : ui32, 1:0] = %2 : ui16 // little-endian
coredsl.set @MEM[%addr : ui32, 0:3] = %3 : ui32 // big-endian

Attributes:

AttributeMLIR TypeDescription
from::mlir::IntegerAttrindex attribute
to::mlir::IntegerAttrindex attribute
sym::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

Operand Description
base an arbitrary precision integer with signedness semantics and unsigned integer
value any type

coredsl.shift_left (coredsl::ShiftLeftOp)

Left shift.

Syntax:

operation ::= `coredsl.shift_left` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation performs a left-shift on the first operand by the amount given in the second operand. The result type is equal to the type of the first operand. In accordance to the CoreDSL <<-operator, negative shift amounts are legal and result in a right shift by the absolute value of the amount.

Example:

%shl = coredsl.shift_left %arg1, %shamt : ui32, ui5

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.shift_right (coredsl::ShiftRightOp)

Right shift.

Syntax:

operation ::= `coredsl.shift_right` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation performs a right-shift on the first operand by the amount given in the second operand. The result type is equal to the type of the first operand. Depending on the signedness of the first operand, either a logical or arithmetic right shift is performed. In accordance to the specification of the CoreDSL <<-operator, negative shift amounts are legal and result in a left shift by the absolute value of the amount.

Examples:

%lshr = coredsl.shift_right %0, %shamt : ui32, ui5
%ashr = coredsl.shift_right %1, %shamt : si17, ui5

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

coredsl.spawn (coredsl::SpawnOp)

Initiates decoupled execution.

Syntax:

operation ::= `coredsl.spawn` $body attr-dict

This operation defines a spawn-block. Its single-block region contains the decoupled behavior, which must be terminated by a coredsl.end op (i.e. spawn-blocks cannot be nested).

Example:

coredsl.instruction @SQRT("000000000000", %rs1 : ui5, "000", %rd : ui5, "0001011") {
  %arg1 = coredsl.get @X[%rs1 : ui5] : ui32
  coredsl.spawn {
    %res = func.call @sqrt_cordic_fixp(%arg1) : (ui32) -> ui32
    coredsl.set @X[%rd : ui5] = %res : ui32
    coredsl.end
  }
}

Traits: HasParent<InstructionOp>, NoRegionArguments, SingleBlock, Terminator

coredsl.xor (coredsl::XorOp)

Bitwise XOR operator.

Syntax:

operation ::= `coredsl.xor` $lhs `,` $rhs attr-dict `:` type($lhs) `,` type($rhs)

This operation computes the bitwise XOR of the operands. Differently signed and sized operands are allowed; the smaller of the operands will be zero- or sign-extended to the result type with is determined by the corresponding CoreDSL type rules.

Example:

%2 = coredsl.xor %0, %1 : ui3, si2 // yields si3

Traits: AlwaysSpeculatableImplTrait, Commutative

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs an arbitrary precision integer with signedness semantics
rhs an arbitrary precision integer with signedness semantics

Results:

Result Description
result an arbitrary precision integer with signedness semantics

Enums

AddressSpaceAccessMode

Coredsl.addrspace access protocol

Cases:

Symbol Value String
core_mem 1 core_mem
core_csr 2 core_csr
axi4mm 4 axi4mm
wire 8 wire

RegisterAccessMode

Coredsl.register access mode

Cases:

Symbol Value String
core_x 1 core_x
core_pc 2 core_pc
core_fp 4 core_fp
local 8 local