VHDL samples

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.

Click here to have all references included, BIG!

Contents

  • 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.
    
    

    Example of VHDL writing to standard output

      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.
       
    

    Example of VHDL reading and writing disk files

      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.
     
    

    Simple parallel 8-bit sqrt using one component

      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
      and wikipedia
    
    

    Optimized parallel 8-bit sqrt using many components

      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
    sqrtsn.jpg
    sqrts0.jpg
    sqrts1.jpg
    sqrtsb.jpg
    sqrts0b.jpg
    sqrts1b.jpg
    
    
    

    32-bit parallel integer square root

      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
    
    

    A group of VHDL components using generic parameters

      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
    
    

    A serial multiplier using generic components

      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
      example.
    
    

    Example of behavioral and circuit VHDL barrel shifter

      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
      
    
    

    Example of serial multiplier model

      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
      values.
    
      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
      
      
    

    Example of serial divider model

      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
      
      
    

    Example of parallel 32-bit multiplier model

      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
      is bmul32.vhdl
      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
      various multiplexors.
    
    
    
    
      A partial schematic of the multiplier is
      
    
      A partial schematic of the add32csa is
      
    
    

    Example of parallel 4-bit divider model

      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
    
    

    Simple example of component vs entity

      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.
     
    

    Pipeline stalling on rising and falling clocks

      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
    
    

    Tracing all changes in a signal

      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;
              begin
                write(my_line, string'("xxx="));
                write(my_line, xxx);
                write(my_line, string'(",  at="));
                write(my_line, now);
                writeline(output, my_line);
              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
    
    

    Other Links

    Go to top

    Last updated 8/20/07