Next: Miscellaneous procedures, Previous: Event log procedures, Up: Procedures and variables
The module (thud thgen) provides procedures to instantiate THUD HDL
forms for a named device using a generator that you specify
for that device. The installed program thgen makes these
facilities available to the shell.
A generator comprises three pieces of information: the list of configuration variables specific to the device (if any); the template of THUD HDL forms with specially indicated subtitution locations; and the variables-alist callback procedure that computes what values to substitute, taking an lookup procedure get and returning the settings as a list of variable/value pairs (an alist).
Configuration variables are specified with the general form:
(NAME DEFAULT-VALUE TYPE [RESERVED...])
name is a symbol. type is a keyword, one of:
#:string
#:integer
#:symbol
#:sexp
Finally, default-value is either the keyword #:UNSET (note
uppercase), or some suitable value to use in the case name is not
overridden. The reserved... means that the specification is
not yet finalized; i.e., do not rely on type being the “last”
field, etc.
Here are the built-in configuration variables:
(seed 0 #:integer)(seq-beg 0 #:integer)(seq-end 15 #:integer)seed for any purpose; its value ranges from seq-beg
through seq-end (inclusively).
(width 1 #:integer)(block-name #:UNSET #:symbol)blk form.
The template is a list of top-level THUD HDL forms, typically starting
with a blk form, followed by one or more a. and n.
forms that implement the device's behavior. Within the forms, the
location where configuration variables are to be substituted is
indicated by either comma, which substitutes the variable's value
directly; or comma-at, which takes the variable's value as a list and
substitutes the elements of the list (without the top-level surrounding
parentheses). This is directly analogous to the unquote and
unquote-splicing Scheme constructs (no surprise).
The template may also be a symbol naming another device generator to inherit from. In this way you can share a general device's template with more specific devices.
Return a symbol whose name is formatted by applying
simple-formatto fstr and args.
name is a unique name for the generator, a symbol that identifies the device generated, such as
fully-decoded-mux. args is a list of alternating keywords and associated values. Valid keywords:
#:vars '(VARSPEC...)- Declare configuration variables specific to name. Note that the list of varspec forms is prefixed with a single-quote.
#:template 'TEMPLATE- Declare template for name. template may be the name of another device, or a list of HDL forms. Note that template is prefixed with a single-quote.
#:var-alist-proc (lambda (get) ...)- get is a procedure that retrieves the current value of a configuration variable:
(get 'seed) 42The var-alist-proc should return an alist associating configuration variables with computed values.
Generate a sequence of instances, ranging a seed value from seq-beg to seq-end (inclusive). Return the sequence.
Process the list of strings rest (as if they were command-line arguments from the shell) and call
thgenwith the properly massaged configuration. Return whatthgenreturns. The first element of rest should name a previously-defined device.
THUD is distributed with two generators built-in: mux and
flop. We include their definitions here as an example of how to
use define-generator.
(define-generator 'mux
#:template
'((blk ,block-name
(out ,width x)
(in ,width a0)
(in ,width a1)
(in sel))
(a. x (| (& (! sel) a0) (& sel a1))))
#:var-alist-proc
(lambda (get)
(let ((seed (get 'seed)))
`((block-name . ,(format-symbol "mux~A" seed))
(width . ,seed)))))
(define-generator 'flop
#:template
'((blk ,block-name
(out ,width q)
(in ,width d)
(in en))
(reg ,width state)
(a. q state)
(n. state (| (& en d)
(& (! en) state))))
#:var-alist-proc
(lambda (get)
(let ((seed (get 'seed)))
`((block-name . ,(format-symbol "flop~A" seed))
(width . ,seed)))))
Some quick examples, presuming we are in the distribution's bin
subdirectory after successfully completing make && make check:
# To use the `mux' built-in type:
./thgen -- mux
# To try the fully-decoded mux example:
./thgen -l ../examples/thgen/fully-decoded-mux.thgen-config -- \
fully-decoded-mux
# Similarly, but only from 2:1 through 8:1, with a 53-bit
# datapath, changed name pattern, and displaying the output
# using `pretty-print':
./thgen -p -l ../examples/thgen/fully-decoded-mux.thgen-config -- \
fully-decoded-mux --seq-beg 2 \
--seq-end 8 \
--width 53 \
--block-name-pattern "dmux~A"
Note that in all cases, the -- (double-dash) separates the arguments (if any) for program thgen from the device name and the subsequent configuration variable settings (if any).