Verilisp

About    |    Download    |    Verilisp for non-Lispers    |    Download cpu.vl    |    Library

About Verilisp

Verilisp is a collection of common lisp macros which spit out verilog HDL code, effectively turning common lisp into a prettier frontend to verilog.
The frontend to verilisp is a python script "verilisp.py" which munges names so you can say 'and' when you're talking about the verilog primitive 'and' gate instead of the builtin common lisp macro. To access the builtin macro 'and', use 'l_and' [which stands for 'lisp and']. If you want to say 'v_and' for the verilog primitive, and 'and' for the builtin macro, feel free to bypass verilisp.py by piping your verilisp file right to __verilisp__.cl.
For sample verilisp code, see the files in the tests directory in the zip.
Note that verilisp.py also wraps all of its input file in an eval-backquote-progn, so you don't have to.
To generate verilog code from verilisp code,
  1. Install Python [version 2.0 or later].
  2. Install Common Lisp.
  3. Unzip verilisp.zip somewhere convenient ["C:\verilisp\", "/usr/share/verilisp/", "~/verilisp/", etc.].
  4. Open a command line.
  5. Navigate to the directory containing verilisp.py.
  6. Run "python verilisp.py YOUR_VERILISP_FILE".
      If a verilog file is not created in the same directory as your verilisp file,
    1. make sure that your verilisp code is valid common lisp syntax,
    2. make sure that running 'python' runs the interactive python interpreter,
    3. make sure that running 'clisp' runs the interactive common lisp interpreter,
    4. determine whether the error messages are generated by python or by lisp, and post the messages to a relevant mailing list/forum, or email me.
I implemented a read-eval-print loop in both verilisp.py [which munges the names for you] and __verilisp__.cl [which does no munging]. Pass a single argument "-" to verilisp.py for the REP loop; run __verilisp__.cl normally.
Run "python verilisp.py" to run the automated test benches.

Verilisp for non-Lispers

If you don't speak lisp, the first question in your mind is probably why verilisp exists in the first place.
First, lisp is one of the better ways to notate trees using ASCII. Trees come up very often in computer science, and hardware design is no exception. Verilog source can be structured like a tree, and lisp syntax allows elimination of extraneous keywords such as "begin", "end", "endmodule", "endfunction", etc.:
(module name (signature signature)
    declarations
    (if (condition)
        statements
    )
    (always (signals)
        statements
    )
    (initial
        statements
    )
)
Additionally, boolean expressions can be structured like trees:
    (
        a
        and
        (b or c)
        and
        (c or (d and e))
    )
or, in lisp syntax:
    (and
        a
        (or b c)
        (or
            c
            (and d e)
        )
    )
Verilisp's expand macro allows the above boolean expression to be translated into the equivalent verilog code:
    and and0 (out, a, temp0, temp1);
    or or0 (temp0, b, c);
    or or1 (temp1, c, temp2);
    and and1 (temp2, d, e);
Now that you are looking for trees, which is more intuitive? Which would you trust yourself to write at 4am? [Imagine that, instead of an example boolean expression which simplifies to (and a c (or b (and d e))), you have a pipelined cpu with hundreds of wires and busses whizzing overhead.]

"Just wait! It gets better! I'll throw in macros FOR FREE!"
One of the main reasons common lisp was chosen as the language for verilisp was for its macro system.
For normal functions [eg. those named "foo"], when you say "(foo a b)", lisp first evaluates the arguments before passing their values to the function foo. So, if i wanted verilisp to name wires "a" and "b", i would have to tell the interpreter that i didn't want it to evaluate a and b before calling foo -- i would have to quote them: "(foo 'a 'b)".
But, if foo were a macro, i wouldn't have to do this. i wouldn't have to sprinkle quotes all over my code and pull my hair out when i forget one. If foo were a macro, the arguments wouldn't be evaluated -- they'd be passed to the macro as symbols or lists of symbols. Now, i can say "(foo a b)".
"Ok, that's nice. So what if i don't know what i want to name a and b?"
Another feature of common lisp's macro system is the reader macros known as backquote, comma, and comma-at. They work together to let you build lists [and therefore lisp code] more easily. For example, " `(foo ,a ,b)" is the same as "(list 'foo a b)" and " `(foo ,@(list a b))", all of which first look up a and b in the current namespace, and insert their values into a list whose first element is the symbol 'foo. This is how you force lisp to evaluate arguments before passing them to a macro: you build code which calls the macro.
Also, a feature that verilisp uses behind the scenes is that, when a macro returns code [lists of symbols], that code is evaluated in place of the macro call. You don't really need to know about this feature until you want to write a macro which generates verilog code.


Library

I've taken the liberty of writing a few macros which generate handy things. Say "(use adders)" or "(use muxes)" to import macros which generate arbitrarily-sized adders or muxes, respectively. The 'use' macro is intelligent enough not to import a package more than once, but not smart enough to find the package unless you a) link ./lib/ to /usr/lib/verilisp/, or b) say '(add-verilisp-path "/home/user/verilisp/lib/")' in your code. The default path includes "./lib/" and "/usr/lib/verilisp/"