Items

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

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

Each item may be preceded by a documentation comment (//>). Items may be made visible to other packages with the pub keyword.

Module Definitions

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

ModDef :=
    DocString? Annotations "pub"? "ext"? "mod" Ident ForClause? Generics? "{" 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 pub modifier makes the module visible to other packages that import this package.

pub mod Top {
    // ...
}

Struct Type Definitions

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

StructDef :=
    DocString? Annotations "pub"? "struct" "type" Ident Generics? "{" 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 "pub"? "union" "type" Ident Generics? "{" 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 "pub"? "enum" "type" Ident Generics? "{" EnumDefStmt* "}"

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

Each enumerant is assigned a constant expression; the width of the enum type is taken from the first enumerant’s literal. The assigned values must be distinct within a single enum type. When no enumerant specifies a value, the enumerants are one-hot encoded by default — see Types for details.

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 "pub"? "builtin" "type" Ident Generics? "{" "}"
pub builtin type Clock {}
pub builtin type Bit {}
pub builtin type Word[n : Nat] {}

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 "pub"? "socket" Ident Generics? "{" 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.