This article was inspired by a book that Actel published some years ago. It's out of print now, and I lost my copy a long time ago, but the original information seems to be largely duplicated in chapter 2 of the current Actel HDL Coding Style Guide.
Chapter 2 is titled 'Technology Independent Coding Styles', and contains example Verilog and VHDL code for a range of simple devices, through to complete FSMs. The great charm of the book was that it was short, you could quickly look up whatever it was you'd forgotten and, if you only knew one of the two languages, it was a good way to learn the other language.
However, the example code had, and still has, its problems. All the Verilog examples are written exclusively with blocking assignments; this is incorrect, and potentially dangerous. There are, in addition, a number of other errors. Some of the code is inefficient and verbose; the VHDL code uses C-style bracketing and uses packages inappropriately, and so on. And, of course, none of the code was verified. It may not be obvious that simple devices need verification, but anyone can make mistakes. The Verilog flip-flop model on page 21 (dff_async) and the VHDL decoder on page 37 (decode), for example, both contain errors, and will simulate incorrectly.
This article, then, does much the same as chapter 2, but with corrected and verified code. Each device has VHDL and Verilog source, together with a short Maia testbench. The same testbench may be used to verify both the VHDL and the Verilog code. Most of the devices are simple, and so most of the testbenches are simply lists of test vectors.
I've also updated the RTL code in a number of areas. The Verilog code uses 2001-style module declarations (pre-2001 declarations are verbose and confusing). The Verilog code uses non-blocking assignments where appropriate. The VHDL code uses the IEEE numeric_std package for arithmetic, rather than the original vendor-specific packages. The VHDL code also reads out-mode ports directly, for conciseness; this is a VHDL-2008 addition.
All the code is synthesisable. Where synthesis results are shown, they are for Xilinx XST L.57, on ISE 11.3, targetting a Virtex-5 device (the XC5VLX30), with a -3 speed grading.
Gate naming conventions
All the examples which have upper-case names have the same specification, and the same pin and device names, as a Xilinx primitive✝. The Xilinx primitives use a number of conventions for names and functionality, which are described here. Any examples which do not have all upper-case names do not follow these conventions.
For the basic gates, the name prefix is either FD, for a D Flip-flop, or LD, for a transparent latch. This prefix is optionally followed by one or more of these letters:
|C||Asynchronous Clear to 0|
|P||Asynchronous Preset to 1|
|R||Synchronous Reset to 0|
|S||Synchronous Set to 1|
|E||Clock (or Gate) Enable|
If a gate has both a clear and preset input, then the clear takes precedence over the preset. Similarly, if a gate has both a reset and a set input, the reset takes precedence over the set. The control inputs are all active-high.
The D Flip-flops which have an E suffix in their name are described as having a Clock Enable (CE) input. However, a synchronous set or reset input takes precedence over the CE input, so CE is more correctly described as a 'data enable' (in other words, it is implemented as a mux in front of the gate's D input).