Items

An item is a top-level declaration in a Virdant package. Items include module definitions, type definitions, socket definitions, and function definitions.

Item :=
    ModDef
    | StructDef
    | UnionDef
    | EnumDef
    | BuiltinDef
    | SocketDef
    | FnDef

Each item may be preceded by a documentation comment (///). Items may be exported from a package with the export keyword.

Module Definitions

A module definition declares a reusable hardware block. Modules are the primary building block of Virdant designs.

ModDef :=
    DocString Annotations "ext"? "export"? "mod" Ident "{" ModDefStmt* "}"

A module definition begins with the mod keyword, followed by the module name, and a body enclosed in curly braces.

mod Passthrough {
    incoming inp : Word[8]
    outgoing out : Word[8]

    out := inp
}

The module body contains ports, components, instances, and statements. For a detailed description of module bodies, see the Modules chapter.

The optional ext modifier declares an external module — one whose implementation is provided by the host language (Verilog).

ext mod LedDriver {
    incoming clock : Clock
    incoming inp : Bit
    outgoing out : Bit
}

External modules may only declare ports. The Virdant compiler generates a stub that connects to the corresponding Verilog implementation.

The optional export modifier makes the module visible to other packages that import this package.

export mod Top {
    // ...
}

Struct Type Definitions

A struct type definition declares a new nominal product type with named fields.

StructDef :=
    DocString Annotations "struct" "type" Ident "{" StructDefStmt* "}"

StructDefStmt :=
    DocString Annotations Ident ":" Type
struct type Color {
    red   : Word[8]
    green : Word[8]
    blue  : Word[8]
}

Each field has a name and a type separated by :. Fields may be preceded by documentation comments.

For more details on struct types, see Types.

Union Type Definitions

A union type definition declares a new sum type with a set of variants.

UnionDef :=
    DocString Annotations "union" "type" Ident "{" UnionDefStmt* "}"

UnionDefStmt :=
    DocString Annotations Ident ParamList?

ParamList :=
    "(" Params? ")"

Params :=
    Param | Params "," Param

Param :=
    DocString Annotations Ident ":" Type
union type MaybeWord {
    Nothing()
    Just(val : Word[8])
}

Variants may carry associated data. A variant with no data is written with empty parentheses. Variants with data list typed parameters inside the parentheses.

For more details on union types, see Types.

Enum Type Definitions

An enum type definition declares a set of named constants with a fixed bit width.

EnumDef :=
    DocString Annotations "enum" "type" Ident "width" Width "{" EnumDefStmt* "}"

EnumDefStmt :=
    DocString Annotations Ident "=" Expr
enum type State width 2 {
    Idle    = 0
    Active  = 1
    Done    = 2
    Error   = 3
}

Each variant is assigned a constant expression matching the declared width. The assigned values must be distinct within a single enum type.

For more details on enum types, see Types.

Builtin Type Definitions

A builtin type definition declares a type whose implementation is provided by the compiler rather than by user code.

BuiltinDef :=
    DocString Annotations "builtin" "type" Ident Generics? "{" "}"
builtin type Clock {}
builtin type Bit {}
builtin type Word[n : Width] {}

Builtin types may have generic parameters. The builtin types Clock, Bit, and Word are predefined in every Virdant package.

Socket Definitions

A socket definition declares a reusable interface consisting of a group of named ports with directions.

SocketDef :=
    DocString Annotations "socket" Ident "{" SocketDefStmt* "}"

SocketDefStmt :=
    DocString Annotations "cosi" Ident ":" Type
    | DocString Annotations "soci" Ident ":" Type
socket Mem {
    cosi addr : Word[16]
    soci data : Word[8]
}

cosi stands for “client-out, server-in”. soci stands for “server-out, client-in”.

For a client socket instance, cosi ports are outputs and soci ports are inputs. For a server socket instance, the directions are reversed.

For more details on sockets, see Sockets.