Notes

  1. The issue of X propagation in an HDL is complex, and the description here is simplistic. It should be noted, however, that Verilog treats X and Z as special cases in the 4-value logic system, but deals with them inconsistently, which potentially causes significant problems. VHDL has no built-in knowledge of metavalues, and expects them to be handled by the user (through enumerated types and operator overloading).
  2. It might be argued that the ?: result is preferable for a hardware architecture which is based on look-up tables.The Xilinx Verilog unisims model for a 2-to-1 mux in fact uses an if-else, and so produces I[0] if the select input is unknown. The simprims model uses a primitive table to reproduce the same output as the ?: operator.
  3. VHDL's type system provides type safety, with both static and dynamic enforcement; in other words, potentially erroneous or undesirable behaviour may be caught both during compilation, and at runtime (during simulation). Verilog, on the other hand, is weakly typed (in fact, the Verilog type system is so loosely defined that some might consider it to be essentially untyped). In principle, VHDL's type safety gives a greater degree of confidence that a device built using VHDL is less likely to have hidden bugs. However, there is little or no academic work comparing bugs in devices coded in Verilog and VHDL, and known problems which can be traced to language features appear not to be related to the type system. One obvious example is a failure to exit reset after power-on; this is frequently blamed on X propagation issues with Verilog's if and casex statements (and, fundamentally, on Verilog's definition of "true" and "false").
    While the advantages of strong typing may not be obvious (or even real), the disadvantage is certainly obvious: VHDL code occasionally requires much more typing. Compare the Verilog and VHDL versions of mux8to1_a4, for example. The difference is particularly obvious where you need to handle objects of different types in an expression; the assignment to O requires a combination of integer, boolean, and std_logic.
  4. This style is normally referred to as a 'one-process' FSM, despite the fact that, for VHDL, the two outputs are combinatorially generated with conditional signal assignments (which are defined to be identical to a process containing an if statement). 'One-process' generally refers to a single clocked process which contains both the state register and the next state logic. However, the XST documentation describes this form as a 'two-process' FSM.
  5. Verilog parameter encoding is also frequently referred to as enumerated encoding, although it has several differences from VHDL enumerated encoding.
  6. The 'none' style instructs XST not to attempt FSM extraction. The logfiles for all the other styles showed that XST had identified an FSM. For the 'None' style, however, XST still encoded the state register as a 4-bit one-hot register, giving 6 flip-flops.
  7. There is, of course, no 'user' encoding for a VHDL FSM using an enumerated type. XST simply uses an ascending binary code in this case (equivalent to the Verilog parameter st0 = 0, st1 = 1, st2 = 2, st3 = 3; code).
  8. Parentheses around the * are optional. always @(*) is equivalent to always @*. However, some older tools may confuse (*) for an attribute.
  9. For clocks which are DUT outputs, the generated testbench actually advances time using your declared clock waveform, and your create_clock declaration must therefore match whatever the DUT is producing. However, for simplicity, the .C directive can be considered to 'synchronise' to the actual DUT waveform.
  10. Compilers don't have to produce 'object code'. The Dragon Book ('Compilers', by Aho, Sethi, and Ullman) defines a compiler as "a program that reads a program written in one language - the source language - and translates it into an equivalent program in another language - the target language".
  11. The current TIOBE index of the most popular 100 programming languages lists VHDL at a lumped unspecified position in the 51-100 bracket (down from #49 in 2017), while Verilog doesn't appear in the list (down from 51-100 in 2017). An analysis of GitHub repo counts lists Verilog at #49, and VHDL at #55.
  12. At first sight, this might appear to be the same as the Verilog behaviour. However, the equivalent procedure in Verilog is actually more complex: operand information propagates from the leaves of the expression, up to the destination, and back down, potentially modifying the size and signedness of the operators.
  13. Time can be advanced arbitrarily using the 'wait' statement, and drive statements will therefore automatically synchronise to an OP, if necessary, before again advancing time to the next OP. However, in the simplest case, your functions will only execute code at a given OP, and then advance to the next OP.
  14. A virtual clock is a clock which is generated by the testbench, but which is not connected to the DUT. These have a number of uses: you might use one, for example, to sample a SERDES output which is clocked by a PLL which is internal to the DUT. See any sdc documentation for more details.
  15. The VHDL Configuration test in the tutorial directory incorrectly tests only a small part of the mux functionality in the 2019.11 distribution. See the mux8to1_a6.tv file on the Testing VHDL DUTs page for the correct version.
  16. mtv statically constructs (during compilation) a call graph to determine if a port or signal is being driven by more than one thread. If the -cg option is specified mtv will output the graph in 'dot' format.
  17. In other words, arrays are first-class objects in Maia, unlike C. In C, arrays cannot be assigned to, or returned from functions, and the value of an array of 'type' 'array N of T' is 'pointer to T'.