Items ===== An item is a top-level declaration in a Virdant package. Items include module definitions, type definitions, socket definitions, and platform definitions. .. code-block:: grammar 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. .. code-block:: grammar 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. .. code-block:: virdant 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 :doc:`modules` chapter. The optional `ext` modifier declares an external module --- one whose implementation is provided by the host language (Verilog). .. code-block:: virdant 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. .. code-block:: virdant pub mod Top { // ... } Struct Type Definitions ----------------------- A struct type definition declares a new nominal product type with named fields. .. code-block:: grammar StructDef := DocString? Annotations "pub"? "struct" "type" Ident Generics? "{" StructDefStmt* "}" StructDefStmt := DocString? Annotations Ident ":" Type .. code-block:: virdant 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 :doc:`types`. Union Type Definitions ---------------------- A union type definition declares a new sum type with a set of variants. .. code-block:: grammar 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 .. code-block:: virdant 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 :doc:`types`. Enum Type Definitions --------------------- An enum type definition declares a set of named constants with a fixed bit width. .. code-block:: grammar EnumDef := DocString? Annotations "pub"? "enum" "type" Ident Generics? "{" EnumDefStmt* "}" EnumDefStmt := DocString? Annotations Ident "=" Expr | DocString? Annotations Ident ParamList? | DocString? Annotations Ident ParamList "=" Expr .. code-block:: virdant 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 :doc:`types` for details. For more details on enum types, see :doc:`types`. Builtin Type Definitions ------------------------ A builtin type definition declares a type whose implementation is provided by the compiler rather than by user code. .. code-block:: grammar BuiltinDef := DocString? Annotations "pub"? "builtin" "type" Ident Generics? "{" "}" .. code-block:: virdant 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. .. code-block:: grammar SocketDef := DocString? Annotations "pub"? "socket" Ident Generics? "{" SocketDefStmt* "}" SocketDefStmt := DocString? Annotations "cosi" Ident ":" Type | DocString? Annotations "soci" Ident ":" Type .. code-block:: virdant 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 :doc:`sockets`.