[Home] [Articles, Categories, Tags] [Books, Quotes]
VHDL 101 - Everything You Need to Know to Get Started
Pub Year:
Read: 2017-12-08
Last Update: 2017-12-08

Five Sentence Abstract:

The book is divided into two main parts, the first of which is a review (if you read FPGA 101 first) of coding styles (behavioral, structural, register transfer level) and the design process including synthesis, simulation, and implementation, while the second part is further divided into a 3 pass approach to VHDL, going deeper with each iteration. Part two starts off with the basics including entities and architectures, signals, data types, operators, concurrent statements which give you a solid foundation to build on. The next section builds on this foundation with the introduction of processes, variables, sequential statements, and some of the limitations of simulation versus synthesis. The last, and most detailed, iteration introduces libraries, generics, the generate statement, loops, functions, procedures, and packages. It concludes with a look at a few common libraries and a nice quick reference appendix that is helpful when first learning a language.


A welcome follow up to FPGA 101. It includes just the right amount of simple code snippets that are explained line by line. Also included are a few larger, more realistic examples (UART) that are equally well described.

Completing Eduvance the VHDL tutorial I watched as I read FPGA 101 proved to be a nice supplement for both books.

Here is another tutorial series I worked through as I read this book. This is a basic beginner tutorial that eases you into VHDL. It uses a homebrew development board, but I did everything in simulation since I don't have any board yet.

The more advanced Bruce Land/Cornell FPGA/Verilog course, ECE5760 DE2/115 lectures 2011, available on youtube was also more approachable as I read this book. It is quite a bit more advanced and uses Verilog instead of VHDL.

Exceptional Excerpts:

Never drive a clock input with a signal that was generated by FPGA fabric (LUTs or Flops)!

Best Design Practices calls for us to design from the 'top-down' and code from the 'bottom-up'

To achieve the fastest and most reliable performance, avoid using latches! It is important to use the 'when others' clause if all possibilities of the case statement are not expressed – especially in an asynchronous process.

The 'Moore'-type state machine tends to have more states, with each state producing one, and only one, set of outputs. This makes the 'Moore'-type state machine very easy to validate in simulation and performs better in the register-rich FPGA environment.


Table of Contents

01 - Introduction and Background
02 - Overview of the Process of Implementing an FPGA Design
03 - Loop 1 - Going with the Flow
04 - Loop 2 - Going Deeper
05 - Loop 3


page ix:

CHAPTER 1: Introduction and Background

page 1:
page 2:
page 3:
page 4:
page 7:

''' 1."Divide and Conquer" - break the design into manageable pieces a. Divide by functionality b. Complex modules can be further broken into smaller pieces7 until basic functionality is reached c. Write a single sentence describing what each module at each level of hierarchy does. If you can't do this, you don’t have a clear enough idea of what the module should do. Think about it some more

  1. Draw a top-level block diagram for each hierarchical level in the design a. Draw lower levels of the design hierarchy for more complex blocks

  2. List the signals which move from module to module a. For the same level of hierarchy b. Through vertical levels of hierarchy c. Don't just list signal names, but include types and units8 d. Choose meaningful signal names – be descriptive, complete, and unambiguous

  3. Don't start coding until the above steps are complete '''

CHAPTER 2: Overview of the Process of Implementing an FPGA Design

page 12:

page 16:

CHAPTER 3: Loop 1 - Going with the Flow

page 20:

page 21:

page 22:
page 23:
page 24:
page 26:
page 27:
page 28:
page 29:
page 30:
page 32:
signal input_from_laser_gyro: std_logic_vector(15 downto 0) := (others=>0);
page 33:

page 34:

page 35:

page 36:
page 37:
page 38:

page 39:

page 41:
page 42:

page 43:
page 47:
Binary logical operators (and, nand, or, nor, xor, xnor)
Relational operators (1⁄4, /1⁄4, <, <1⁄4, >, >1⁄4)
Shifting operators (sll, srl, sla, sra, rol, ror)
Addition operators (þ, À, &)
Unary sign operators (þ, À)
Multiplying operators (), /, mod, rem)
Other operators (not, abs, )))
page 48:

page 52:

page 53:
Line 6: rotRightResult <= slvValue(2 downto 0) & slvValue(7 downto 3);

page 54:

page 55:
page 63:
page 68:
page 69:

page 70:

page 72:
page 73:
page 75:

page 77:
page 81:

page 84:

page 85:
page 88:

CHAPTER 4: Loop 2 - Going Deeper

page 93:
page 95:
wait for <time>
wait until <event>
wait on <signal list>

page 96:

page 97:

page 100:
page 101:
page 110:
page 111:
page 112:

page 113:
  1. If it makes sense to NOT have a reset for a process, then do so.

  2. If a reset must be used, it should use positive logic ('1' = reset, '0' = operational).

  3. If a reset must be used, make it synchronous to the established clock.

page 115:

page 117:
page 121:

page 123:

page 125:
page 130:
page 133:

page 137:

page 141:

CHAPTER 5: Loop 3

page 146:

page 158:
1. Generics can be of any legal type or subtype.
2. Generics are used in the same way as constants are within a module.
3. Generic values can change from instantiation to instantiation, but are
constant within a module.
4. Top-level Generics can usually be set via synthesis tool options (GUI) or
command line arguments so that source code doesn't need to be modified.
5. Generate statements come in two flavors: conditional and looping.
6. Generate statements can wrap one or more concurrent statements – this
includes component instantiations, assignments, conditional assignments, and
even processes.
7. Generic and Generate statements are often, but not always, used together to
make code more flexible for reuse.
page 161:

page 165:
page 166:
page 167:

page 168:

page 171:
page 173:

page 177:
‘left – returns the leftmost value in the range
‘right – returns the rightmost value in the range
‘high – returns the largest value in the range (regardless of order)
‘low – returns the smallest value in the range (regardless of order)
‘range – returns the range of the array
‘reverse_range – the reversed range of an array

page 179:

page 181:

page 182:

page 183:

page 184:
page 188:

page 189:

page 190:

page 195:

[About] [Contact]