Next: Some adders, Previous: Running THUD, Up: Top
THUD's HDL (TH) is based on Scheme, but at this time is not a proper
superset, although there are long term plans in that direction. This
means that general Scheme code cannot be used; instead, a limited subset
is available, in addition to the HDL-specific constructs. This chapter
fully presents the language that THUD understands. THUD HDL filenames
typically have the extension .th, although that is not required.
Identifier names are relatively unconstrained. You can use dashes, dollar-signs or whatever makes you happy. The one exception is that a name cannot contain the "/" character, as this is used as a scope separator. Also, for the sake of interoperability, be aware that other tools may impose restrictions on identifier names.
In the following discussion, upper-case symbols are non-terminal, while lower-case symbols, strings, periods and parentheses should be used verbatim. The only meta syntax is the open and close square brace to indicate optional items. The term form indicates a balanced expression (all left parens have a corresponding right paren).
Briefly, here are the language operators and keywords:
;; operators
^ % ! ~ + - * / & | = << >>
;; keywords
bx Bx begin c. case cond if or and die fln
eq? else bx Bx begin not dump n!
Comments begin with a semicolon and run to the end of the line. Whitespace is ignored.
To start a block, use the blk top-level form, which looks like:
(blk BLK-NAME [PORTS])
ports is an optional list of ports. Omitting it means blk-name has no ports. Each element in the list looks like:
(PORT-DIR [BIT-WIDTH] PORT-NAME)
A port is a communication channel from this block to whomever
instantiates it. Thus, port-dir must be either in or
out. bit-width is optional and defaults to 1 if not
specified.
The blk form does not surround all the definitions in the block;
using it is enough to tell the THUD scanner that the following text
(until either EOF or the next blk form) is part of the current
block.
Each port is a type of wire. Inside the block, you may have
additional wires and registers to hold state. They are introduced after
the blk form by wire and reg declarations, which
look like:
(wire [BIT-WIDTH] WIRE-NAME)
(reg [BIT-WIDTH] REG-NAME)
bit-width is optional and defaults to 1 if not specified. These declarations can be interspersed with their definitions as long as the declaration is scanned before the definition. (A definition will not auto-declare anything, unlike with some other HDLs.)
There are two types of definition, assign and next. These are used for wires and registers, respectively. Definitions, always written at the top-level, look like:
(a. WIRE-NAME EXPRESSION)
(n. REG-NAME EXPRESSION)
Note: the dot in a. and n. is required. expression
can be one of the following:
A numberA port, wire or reg.
A bit-extraction, indicated by square-braces, of a port, wire or reg.
An operator applied to its arguments.^ ARG ...| ARG ...& ARG ...+ ARG ...- ARG ...* ARG ...% ARG1 ARG2= ARG1 ARG2<< ARG1 ARG2>> ARG1 ARG2Note that each ARG can also be an EXPRESSION.
A (possibly side-effecting) behavioral construct.#f is interpreted as "unspecified".
begin case cond if or and eq? else notbx signal bitposBx signal bitpos lenc. bit ...n! signal valuen. for signal for one cycle. If n! is used more
than once (for a particular signal), THUD issues a warning and
ignores subsequent calls.
This construct is useful for blocks that serve as stimulus for other
blocks. [TODO: give example.]
die fln dumpAs a convenience, declarations and definitions can be elided into one form. For example, the following two lines are equivalent.
(wire sig) (a. sig expression) ; two forms: decl and def
(wire sig expression) ; one form: elided decl and def
A block may also instantiate other blocks by referring to them with a proper port mapping. Each instance reference, or iref, is a top-level form that looks like:
(w/ BLK-NAME IREF-NAME PORT-MAPS)
References must be named. PORT-MAPS looks like:
((IREF-PORT-NAME . HOOKUP) ...)
Because a direct connection is made via IREF-PORT-NAME, the ordering in PORT-MAPS does not matter. All ports must be addressed. HOOKUP is either a port, wire or reg.