The Designer's Guide to VHDL

Peter J. Ashenden


If you detect an error, I would be pleased to hear about it. You can send email to me at I will add errata to this list and acknowledge you as the finder. However, before sending an erratum, please check to make sure it's not already on the list.


Errata for the first to fourth printings (corrected in fifth printing)

You can tell which printing of the book you have by looking at the copyright page overleaf from the title page.  Below the line "Printed in the United States of America" is a line with one or more double-digit and single-digit numbers.  The rightmost double-digit number is the year of printing, and the rightmost single-digit number is the printing number.  For example, the line
00   99   98   97   96     5   4   3   2   1
indicates the first printing (in 1996).

From: (Robert Hutchins x2441)

In Figure 1-4 on page 6, there are two blocks labeled S. The one on the right should be labeled M. 

From: Ben Cohen <>

On page 198, in the discussion of procedure parameters, the text states:

"It is just a quirk of VHDL that we can specify both constant and in, even though to do so is redundant. Usually we simply leave out the keyword constant, relying on the mode to make our intentions clear."
The LRM states that a constant parameter may not be of an access type or a file type. Thus, a parameter of an access type must be of class variable . In VHDL-87, a parameter of a file type must be of class variable . In VHDL-93, a parameter of a file type must be of class file. Insert after the above quoted sentences:
"(The exceptions are parameters of access types, discussed in Chapter 17, and file types, discussed in Chapter 18.)"

From: Peter J. Ashenden <>

In Figure 6-10 on page 174, the labels "ovf" on the two adders should be moved left a bit to clear the symbol outline.

In Figure 7-23 on page 220, the leftmost of the two vertical lines should be extended to meet the end of the horizontal line. 

From: Marvin Rich <mrich@VNET.IBM.COM>

In Figure 7-21 on page 218, the procedure p1 contains an assignment to the signal s. Since s and p1 are both declared in the enclosing architecture body, the asignment to s is illegal, for the reasons discussed in the last paragraph on page 202. In Figure 7-21, replace "s <= v1;" with "v1 := s;". 

From: Garland Bayley <>

On page 320, second to last line, the text states, "If there is a primary binding indication, the incremental binding indication may not include an entity part." Replace "may not" with "must not", to emphasize that in this circumstance an entity part is prohibited in the incremental binding indication. 

From: Pat Narikawa <>

On page 38, make the following corrections.

Line 17: change "There are two predefined ..." to "There are three predefined ..."

Insert after line 18 a new code line:

type file_open_kind is (read_mode, write_mode, append_mode);
Line 21: change "and the type file_open_status is" to "and the types file_open_kind and file_open_status are".

Change the sentence in the VHDL-87 break-out to:

The types file_open_kind and file_open_status are not predefined in VHDL-87.

From: Christoph Cerny <>

On page 217, in the VHDL-87 break-out, replace the operator xor with xnor.

On page 624, in the VHDL-87 break-out, replace the operator xor with xnor.

On page 688, in the index entry for "xnor operator", add a reference to page 217. 

From: Peter J. Ashenden <>

In Figure 5-32 on page 150, the instances of the reg4 entity should not include the and gates.  Instead, the clr and clk inputs to each reg4 instance should be connected as separate inputs to each flipflop, as shown in this corrected version.

From: Ken DellaPenta at Morgan Kaufmann Publishers, Inc.

On page 28, the cross-reference to Chapter 7 should be to Chapter 8.

On page 36, the cross-reference to Section 2.3 should be to Section 2.4.

Exercise 3 of Chapter 5 is not completely answered in Appendix G.  On page 659, add the following to the end of the answer to Exercise 3:

From: Peter J. Ashenden <>

On page 52, Exercise 9 should be marked as difficulty level 2, not 1.

From: Alexei Krouglov <>

On page 181, change the last word of the page from "subtract" to "add".

From: Edward Wade at Morgan Kaufmann Publishers, Inc.

On page 136, Figure 5-24 is missing a caption.  Insert the following caption:

From: Alexei Krouglov <>

On page 346, fourth to last line: change "back_array" to "bank_array".

On page 359, eighth line, insert a new sentence after "... of the value.":

In Figure 15-35 on page 400, change the lower of the two labels "S1 bus" to "S2 bus".

On page 430, tenth line from the bottom, change "ir_enable" to "ir_immed2_en".

From: Graham Minchin <>

On page 43, Figure 2-4: the line from "record types" to "constrained array types" should be from "array types" to "constrained array types."

Errata remaining in the fifth and subsequent printings

You can tell which printing of the book you have by looking at the copyright page overleaf from the title page.  Below the line "Printed in the United States of America" is a line with one or more double-digit and single-digit numbers.  The rightmost double-digit number is the year of printing, and the rightmost single-digit number is the printing number.  For example, the line
00   99   98     5
indicates the fifth printing (in 1998).

From: Neil Boroky at The University of Adelaide

In Figure 5-10 on page 120: the labelling of the fourth and fifth delta cycles should be "0 + 3 delta" and "0 + 4 delta" respectively.

From: John A. Rupf, Ph.D. <>

On page 35: In the type definition for length, the correct number of um per mil is 25.4.  However, VHDL requires the multiple in a secondary units definition to be an integer.  Thus we cannot change 254 um to 25.4 um in this context.  Instead, change the type declaration to the following:

    type length is range 0 to 1E9
        um;               -- primary unit: micron
        mm = 1000 um;     -- metric units
        m = 1000 mm;
        inch = 25400 um;  -- imperial units
        foot = 12 inch;
      end units length;

Also, in the examples of physical literals at the bottom of page 35, delete "450 mil", and insert "2 foot" at the end of the line.

From: Todd Salter <>

In Exercise 11 on page 79: The problem statement requires you to develop a model with an input of an enumeration type.  This requires an entity declaration with an input port of the enumeration type.  The only way an enumeration type can be made visible at the point of a port declaration is to declare the enumeration type in a package.  However, packages are not introduced until a later chapter.

To avoid this difficulty, change the problem statement as follows:

Develop a model for a floating-point arithmetic unit with data inputs x and y, data output z and function code inputs f1 and f0 of type bit.  Function codes f1 = '0' and f0 = '0' produce addition; f1 = '0' and f0 = '1' produce subtraction of y from x; f1 = '1' and f0 = '0' produce multiplication; and f1 = '1' and f0 = '1' produce division of x by y.

In the solution to Exercise 3 on page 658: The exit statement should exit from all of the nested loops.  Label the outermost loop with the label "search_loop", and change the exit statement to refer to this label.  The corrected code is:

    search_loop : for side in 0 to 1 loop
        for track in 0 to 79 loop
           for sector in 0 to 17 loop
           if ... then
               exit search_loop;

From Konrad Schlögl <>

On page 477: In the second to last line, replace "current_stimulus" with "current_cell".

From Sue Tyerman <>

In Figure 6-9 on page 173: The first value in the waveform for x_real should be "4000", not "0004".

From: Peter J. Ashenden <>

On page 513, seventh and eighth lines: Replace the sentence "The operation writes ... to null." with:

The operation writes the complete line of text to the output file and resets the pointer to point to an empty string.  If the pointer passed to writeline is null, the operation writes a blank line to the output file.

From: Peter J. Ashenden <>

In Figure 10-14 on pages 265-266, make the following changes:

Delete the initial value expressions in the variable declarations for bv_s1 and bv_s2:
variable bv_s1 : bit_vector(s1'range);
variable bv_s2 : bit_vector(s2'range);
Insert the following statements immediately before the line "case func is":
bv_s1 := To_bitvector(s1);
bv_s2 := To_bitvector(s2);
Change the line:
temp_result := X"0000_0000";
temp_result := (others => '0');  temp_overflow := false;

From: Peter J. Ashenden <>

In Figure 15-31 on page 393: Replace the declarations of the type memory_array and the variable mem with:

type memory_array is array ( natural range <> ) of dlx_bv_word;

variable mem : memory_array(0 to high_address / 4)
    := ( others => X"00000000" );

Also, immediately before the declaration of procedure do_write, insert the following procedure declaration:
procedure load is

    constant program : memory_array
        := ( X"20020000",    --           addi  r2, r0, 0
             X"ac020018",    -- loop:     sw    counter(r0), r2
             X"20420001",    --           addi  r2, r2, 1
             X"6441000a",    --           snei  r1, r2, 10
             X"1420fff0",    --           bnez  r1, loop
             X"44000000",    --           trap  0
             X"00000000" );  -- counter:  .word 0

    assert program'length <= mem'length
        report "memory too small for program"
        severity failure;
    mem(program'range) := program;
end load;

In Figure 15-31 on page 394: Insert the following statement immediately before the line "-- initialize outputs":
On page 392, Replace the last paragraph with:
A behavioral architecture body for the memory is shown in Figure 15-31.  The process mem_behavior implements the behavior.  The constant high_address defines the range of addresses to which the memory responds, based on the size of the memory.  Next, the process declares an array type memory_array and a variable mem of the array type to represent the memory storage.  Each element of the array is a one-word bit vector.  Since we are using byte addresses to access memory, we must divide the high address bound by four to derive the index range for the array of words.  Since we have not yet described how to use file operations to load data, we do not initialize the memory from the file named by load_file_name.  Instead, for this case study, we simply use the procedure load to "preload" the memory.  In Chapter 18, when we cover file operations, we present an alternative architecture body that loads the memory from a file.  The array aggregate we have written in the declaration of the constant program in load contains the binary representation of the small test program shown in the comments.  The procedure copies the program into the memory array, starting at address 0.  The program initializes register r2 to zero and then enters a loop.  For each iteration, it stores the value in r2 into memory at the location labeled "counter" and then increments r2.  The "snei" instruction tests whether the value in r2 is not 10, and the "bnez" instruction transfers back to the top of the loop if the test succeeded.  When r2 is 10, the loop terminates, and the "trap" instruction halts execution.
On page 395, first paragraph after the figure: Replace the first sentence with:
The body of the process begins by calling the load procedure to preload the memory and initializing the memory output ports.  It then enters a loop to handle memory access cycles.

From Tom Haas <>

In the subsection "Overloading Operator Symbols" on pages 215-217:  There is no mention that the syntax rule for function names is extended beyond that shown on page 209.  Thus the use of operator symbols as function names appears to be inconsistent with the rules for forming identifiers, described on page 18.

To avoid this confusion, insert the following sentence on page 215 before the last sentence ("Our bit-vector addition function..."):

The extended syntax rules for subprogram declarations are shown in Appendix E.

From Gary M Beihl <>

In Exercise 31 on page 157: A concurrent assertion statement in the entity declaration cannot read the output port, and so cannot perform the required verification.  Instead, the concurrent assertion statement must be included in the architecture body and use intermediate signals declared in the architecture body.  The problem statement should be amended by replacing "Augment the entity declaration by including" with "Include".

From Duane Clark <>

In Exercise 7 on page 52, the expression B"100010" sra 2 & X"2C" is syntactically correct, but semantically incorrect.  The operator "&" has higher precedence than "sra", but has the wrong type of operands.  The expression should be replaced with:

(B"100010" sra 2) & X"2C"
Then, in the answer for this expression on page 656, the expression should be corrected in the same way and the result should be B"11100000101100".

From Peter Ashenden <>

In Figure 20-3 on page 566, the attribute S'last_active is described as returning time'high if no event has yet occurred.  Replace "no event" with "no transaction".

From Gary M Beihl <>

In Figure 20-3 on page 566, the attributes S'last_event and S'last_active are described as returning time'high if no event/transaction has yet occurred.  For VHDL-87, however, these attributes return 0 ns in that case.  Add the following sentence to the VHDL-87 paragraph below Figure 20-3:

Furthermore, the behavior of the 'last_event and 'last_active attributes differs from VHDL-93.  In VHDL-87,  'last_event returns 0 ns if no event has yet occurred, and 'last_active returns 0 ns if no transaction has yet occurred.

From Peter Ashenden <>

In Figure 15-35 on page 400, the labels "a" and "d" at the bottom of the diagram should be swapped.