The sample VHDL code contained below is for tutorial purposes.
An expert may be bothered by some of the wording of the examples
because this WEB page is intended for people just starting to
learn the VHDL language. There is no intention of teaching
logic design, synthesis or designing integrated circuits.
It is hoped that people who become knowledgeable of VHDL will
be able to develop better models and more rapidly meet whatever
their objectives might be using VHDL simulations.
- Example of VHDL writing to standard output
- Example of VHDL reading and writing disk files
- Simple parallel 8-bit sqrt using one component
- Optimized parallel 8-bit sqrt using many components
- 32-bit parallel integer square root
- A group of VHDL components using generic parameters
- A serial multiplier using generic components
- Example of behavioral and circuit VHDL barrel shifter
- Example of serial multiplier model
- Example of serial divider model
- Example of parallel 32-bit multiplier model
- Example of parallel 4-bit divider model
- Pipeline stalling on rising and falling clocks
- Tracing all changes in a signal
A few VHDL compilers have bugs. 'alias' may have to be eliminated.
The VHDL source code is hello_world.vhdl
This demonstrates the use of formatting text output to a screen.
A process is used to contain the sequential code that builds an
output line, then writes the line to standard output, the display screen.
Almost identical VHDL code hello_proc.vhdl
uses a procedure in place of the process to contain the sequential code.
note that the procedure has no arguments and the call needs no label.
Simply the statement my_proc; in the architecture is the call.
The VHDL source code is file_io.vhdl
This example is a skeleton for a VHDL simulation that needs input
from a file, simulates based on the input and produces output to
a file. The output file may be used as input to other applications.
The importance of being able to write to the display screen and to
read and write files is to maintain portability of your VHDL code.
Especially test benches, must be independent of any specific VHDL
systems Graphic User Interface, GUI. GUI differ radically and it
may be important to you to be able to develop and debug your
VHDL code independent of the host machine and independent of
the VHDL system supplier.
The VHDL source code is sqrt8.vhdl
The output of the VHDL simulation is sqrt8.out
The schematic is sqrt8.jpg
The Sm component schematic is sqrtsm.jpg
This example shows how a Sm component is directly coded in VHDL as
concurrent statements. The multiplexor is coded as a single "when"
statement. "Sm" is mnemonic for subtractor-multiplexor.
The overall circuit that inputs an 8-bit integer and outputs a 4-bit
integer square root uses many copies of the Sm component. This circuit
uses the "entity" method of instantiating copies of a component. The
"port map" is the mapping of actual parameters onto the formal
parameters in the Sm entity.
The theory of operation is described in sqrt.txt
The VHDL source code is sqrt8m.vhdl
The output of the VHDL simulation is sqrt8m.out
The schematic is sqrt8m.jpg
This circuit performs the same function on the input as does
sqrt8.vhdl above. The difference is that many specialized
entities were created as building block components. The specialization
eliminates circuitry that is not needed because the inputs are
logical 0 or 1. This was a step in developing the parallel 32-bit
square root circuit shown next.
The Sm component family are subsets of the schematic sqrtsm.jpg
The VHDL source code is sqrt32.vhdl
The output of the VHDL simulation is sqrt32.out
The schematic was never drawn. sqrt8m.vhdl was expanded
using "generate" statements to create sqrt32.vhdl
Common building blocks for simulating digital logic are adders, registers,
multiplexors and counters. This example shows a set of generic entities
and the corresponding architectures that have the word length and delay
time as generic parameters. In addition to being useful in circuits,
the generic word length allows much smaller circuits to be debugged and
then the word length increased to the final desired value. The test
bench uses a word length of 8 while the example circuit that performs
a sequential multiplication uses a 16 bit word length.
Similar to the entity declaration "port" and the entity instantiation
"port map", with generics there is an entity declaration "generic" and
the entity instantiation "generic map."
The VHDL source code for the generic adder is add_g.vhdl
The VHDL source code for the generic register is reg_g.vhdl
The VHDL source code for the generic multiplexor is mux_g.vhdl
The VHDL source code for the generic counter is cntr_g.vhdl
The VHDL source code for the generic test bench is test_g.vhdl
The output of the VHDL simulation is test_g.out
The VHDL source code for the generic serial multiplier is mul_ser_g.vhdl
The output of the VHDL simulation is mul_ser_g.out
This simulation models a multiplier using "hi" and "lo" registers used
in the MIPS architecture and is similar to the Patterson and Hennessey
The VHDL source code for a barrel shifter, includes both behavioral
and circuit description bshift.vhdl
The VHDL source code for testing bshift.vhdl and comparing the behavioral
model to the circuit model test_bshift.vhdl
Note the example use of a package and a function definition to convert
the 5-bit std_logic_vector shift count "shift" to an integer "shft"
The one process "test_data_generator" updates the signal "count" and
also prints the results of the behavioral and circuit model for the
three types of shifts: left logical, right logical and right arithmetic.
The output of the VHDL simulation is test_bshift.out
A partial schematic of the right logical shift is
The VHDL source code for a serial multiplier, using a shortcut model
where a signal acts like a register. "hi" and "lo" are registers
clocked by the condition mulclk'event and mulclk='1'
The VHDL is mul_ser.vhdl
The output of the simulation is mul_ser.out
At the start of multiply: the multiplicand is in "md", the multiplier
is in "lo" and "hi" contains 00000000. This multiplier only works
for positive numbers. Use a Booth multiplier for twos-complement
At the end of multiply: the upper product is in "hi and the
lower product is in "lo."
A partial schematic of just the multiplier data flow is
The modified Booth serial multiplier, using a shortcut model is:
The VHDL is bmul_ser.vhdl
The output of the simulation is bmul_ser.out
A partial schematic of the Booth multiplier data flow is
The VHDL source code for a serial divider, using a shortcut model
where a signal acts like a register. "hi", "lo" and quo are registers
clocked by the condition divclk'event and divclk='1'
The VHDL is div_ser.vhdl
The output of the simulation is div_ser.out
At the start of the divide: the divisor is in "md" ,
the upper dividend is in "hi" and the lower dividend is in "lo."
At the end of the divide: "lo" contains the quotient and "hi" contains
the uncorrected remainder (may need the divisor added to remainder)
A partial schematic of just the divider data flow is
An unsigned multiplier using a carry save adder structure.
The VHDL source code for a parallel multiplier, using 'generate'
to make the VHDL source code small is mul32c.vhdl
The test bench is mul32c_test.vhdl
The output of the simulation is mul32c_test.out
The VHDL source code for a parallel Booth multiplier, two's complement
32-bit multiplicand by 32-bit multiplier input producing 64-bit product
The test bench is bmul32_test.vhdl
The output of the simulation is bmul32_test.out
Both VHDL models use a concurrent conditional statement to model
A partial schematic of the multiplier is
A partial schematic of the add32csa is
An unsigned divider using non-restoring divide with uncorrected
remainder. The basic cell is a Controlled Add/Subtract, CAS.
A partial schematic of the divider is
The test bench is divcas4_test.vhdl
The output of the simulation is divcas4_test.out
VHDL allows a hierarchy of entities containing components.
At each level VHDL allows multiple architectures and multiple
configurations for each entity.
The following two examples, ctest1 and ctest1a, show use of
components with a configuration and use of "entity WORK."
that does not need a configuration.
ctest1.vhdl uses two components, fadd and add32
with a configuration file to select the element-architecture pair from
a library to use for each component. There could be a behavioral
architecture, a detailed circuit architecture, a timing architecture and
possibly others. The configuration can be used to select for each
component the desired architecture(s).
ctest1a.vhdl uses the same entities without
component declarations and without a configuration. This latter case
is not recommended for large designs or team projects.
When designing a pipeline where all data moves to the next stage on
a common clock, it requires two different circuits to stall the pipeline,
depending on registers accepting data on rising or falling clock.
Coding techniques include:
When storage elements accept data on a rising clock
Initialize clk to 0 so that a transition does not occur at time zero
The stall clock is clk or stall
When storage elements accept data on a falling clock
Initialize clk to 1 so that a transition does not occur at time zero
The stall clock is clk or not stall
The schematics for the rising and falling clock cases are :
The corresponding VHDL source code and output for the cases are:
stall_up.vhdl and stall_up.out
stall_down.vhdl and stall_down.out
When debugging VHDL it is sometimes useful to follow every change
to some signal. This signal tracing is easily accomplished by
a small process.
The technique is to have a process that monitors the signal(s)
For each signal, say xxx, create a process in the design unit with the signal
prtxxx: process (xxx)
variable my_line : LINE;
write(my_line, string'(", at="));
end process prtxxx;
Obviously edit the above and replace xxx with your signal name.
Now, every time your signal changes a line out output shows it's value
and the time when it changed. Of particular interest is if 'U' or 'X'
appears, meaning Uninitialized or X for "don't know" ambiguous.
Do not use hwrite, this masks the 'U' and 'X'
a specific example is shown below on sum and cout
An example circuit using this technique on a 32-bit ripple carry
adder in signal_trace.vhdl