You are on page 1of 8

Libraries and Packages

Dr DC Hendry

March 21, 2006

1 Libraries

The VHDL language refers to locations on computer discs where a number of


designs are stored together as a library. Since different computer systems have
different conventions for referring to disc files, it is necessary to use an approach
that provides computer independent VHDL source code (so that it can be easily
transferred from one computer system to another), yet can support access to a
number of different libraries.

VHDL does not completely define this mechanism, rather, the final mapping of
a library name to a disc file is left to the vendor to define, Cadence use the file
cds.lib to do this, Synopsys use a file called .synopsys vss.setup for this.
Each vendor has their own conventions within such files. These files indicate for
each VHDL library name where to find that library on disc. Again depending
on the vendor, a library may reside in a single disc file (unusual), or more likely,
be mapped to a directory.

Here is the contents of the cds.lib file for the laboratory exercise:

define worklib ./workLib


define tsmc018 /eng/goss/apps6/designKits/artisan/tsmc018/aci/sc/vhdl/tsmc018
include \$CDS_INST_DIR/tools/inca/files/cds.lib

The first line says that the VHDL library called worklib is to be found in the
directory ./workLib, i.e. a directory called workLib in the current directory.
Note that Cadence associates each VHDL library name with a directory.

The second line states that the library called tsmc018 is to be found in the given
directory. This library is that containing the simulation models for the TSMC
1.1 WORK Libraries and Packages

0.18m process used in the laboratory. You will see the name tsmc018 used in
the configuration files for those examples where a netlist is simulated.

The final line is replaced by the contents of the given filename (supplied by
Cadence) and contains define lines for libraries such as ieee.

1.1 WORK

All VHDL systems assume that one library called WORK is available. WORK is not
another library but an alias for an existing library to which all compiled designs
are written. The mechanism by which WORK is pointed at an existing library
is again tool vendor dependent, Cadence uses the file hdl.var to contain this
among other things. Here is the hdl.var file for the laboratory exercise:

INCLUDE /eng/goss/apps6/cds/ldv5.0/tools/inca/files/hdl.var
DEFINE WORK worklib
DEFINE NCVHDLOPTS -v93 -linedebug

1. The first line include a Cadence supplied hdl.var file that contains stan-
dard information needed by all simulations.
2. The second line indicates that WORK should be aliased to the library worklib.
3. The last line says to assume -v93 -linedebug by default when compiling
VHDL code.

The first line includes a Cadence supplied hdl.var that contains standard in-
formation needed by all simulations. The second line is the important one as
regards WORK, this indicates that the current WORK library is the VHDL library
called worklib. Finally, the last line says to assume -v93 -linedebug by de-
fault when compiling VHDL code.

1.2 Creating Your Own Library

In this section well briefly look at how to create your own library and then
to use that library in another design. Let us assume that we wish to create a
library called usb 2, and then later use components from that library within
designs stored in a library called soc.

Here are the steps involved (Cadence assumed)

Revision : 1.1 Page 2 of 8 Dr DC Hendry


Libraries and Packages

1. Create a directory to contain the usb 2 code, create a cds.lib file defining
usb 2 as residing in the directory just created.
2. In the hdl.var file set WORK to point to usb 2.
3. Compile the code for the usb 2 design(s).
4. Create a second directory for the library called soc, and add a line to the
cds.lib file defining that library.
5. Edit the hdl.var file and now point WORK to the soc library.
6. Compile code for the soc design, using where required statements such as
library usb 2;.

2 Packages

Packages provide a means of making a collection of VHDL objects (such as types,


functions etc.) visible to a large number of design units. This is accomplished by
placing the objects to be made visible into one package, and then making that
package available to a number of design units using use clauses (such as use
ieee.std logic 1164.all). We will look at the rules for Scope and Visibility
later.

A package requires a Package Declaration, all of whose contents can be made


visible to other design units, and an optional package body which is not made
visible to other design units. Typically, a package declaration will include dec-
larations for types and perhaps functions (but not the body of the function).
This is sufficient to use those types and any functions declared. The body of the
package will then contain the code of the function. A package body is optional.

2.1 Package Declaration

A package declaration simply consists of:

package <package_name> is

<list of declarations>

end package <package_name> ;

where:

Revision : 1.1 Page 3 of 8 Dr DC Hendry


2.2 Package Body Libraries and Packages

<package name> is the name given to this package.


<list of declarations> is the contents of the package declaration.

Here is an example package declaration that includes two constants and one
function:

package pckg_demo is

constant MEMORY_DATA_WIDTH : integer := 32;


constant MEMORY_ADDRESS_WIDTH : integer := 20;

function ceillog2(constant n : natural) return natural;

end package pckg_demo;

This package defines two constants for use throughout the design. The intention
here is that if the need arises to change either of these values then the change
need only be made once in the package source code. All code dependent on
the package is then recompiled and if the coding has made correct use of these
constants, all units will then consistently use the new value. Note that automatic
methods are available to recompile code dependent on these changes (Cadences
ncupdate for example).

The function declaration declares the function called ceillog2 that takes a
single natural number as its argument and then returns a single natural number
as its result. The constant in front of the argument indicates that the function
does not modify the argument n. This particular function returns the value of
dlog2 (n)e.

2.2 Package Body

A package body for the above package need only contain the implementation of
the function ceillog2. Note that where this function is used in other design,
the implementation of the function is not needed by either the compiler or the
designer to use the function. The implementation is only needed when the
design is elaborated. Here is the formal syntax of a package body:

package body <package_name> is

<list of declarations>

end package <package_name>;

Revision : 1.1 Page 4 of 8 Dr DC Hendry


2.3 USE Clauses Libraries and Packages

The package body for the above example with ceillog2 is:

package body pckg_demo is


function ceillog2(constant n : natural)
return natural is
begin -- ceillog2
-- pragma synthesis_off
assert n >= 1
report Ceillog2: value of n is less than 1
severity error;
-- pragma synthesis_on
for m in 0 to 35 loop
if 2**m >= n then
return m;
end if;
end loop;
-- pragma synthesis_off
report Ceillog2: value of n is too large
severity error;
-- pragma synthesis_on
end ceillog2;
end pckg_demo;

2.3 USE Clauses

We have used in most of our design the code:

library ieee;
use ieee.std_logic_1164.all;

The first line here states that the name ieee is a VHDL library. The second line,
the use clause, states that all objects within the package called std logic 1164
are to be made visible to the design unit that follows.

Note that it is to only the following design unit that the clause applies, not to
all design units in the file. A design unit consists of for example an entity header
and an architecture body. Thus if more than one design unit is in the same file,
then each must be preceded by the above.

If the package pckg demo above has been compiled into the library pointed to
by WORK then to use the package above we need only say:

where mylib is the name of the library whose contents are all to be made visible.

Revision : 1.1 Page 5 of 8 Dr DC Hendry


Libraries and Packages

Note that use clauses can also be included within the declarations section of an
architecture body.

3 Configurations

When we construct a design consisting of many design units with a choice of


architectures for certain of these design units, we need a mechanism to indicate
which choice is to be made. This is done in a separate design unit called a
configuration. A configuration can be included in the same file as an entity
header and architecture, or more usually in a separate file. With components
that will only be simulated at RTL level, not at netlist level, it is common to
find the configuration in the same file as the testbench.

The syntax of a configuration is:

configuration <configuration_name> of <entity_name> is

<configuration_declarations>

<block_configuration>

end [configuration] [<configuration_name>];

This text is often preceded by library clauses and use clauses. In the above
<configuration name> is the name given by the designer to this configuration.
<entity name> is the name of the design entity to which the configuration
applies - this will usually be a testbench.

The <configuration declarations> section is often blank, but may contain


use clauses and other items. Each configuration then contains a single <block configuration>.
A block configuration refers to a single design unit, and will then internal to
that block configuration indicate further configuration information needed for
nested design units. As an example consider the configuration for the RTL level
design of example1.vhd used in the laboratories.

configuration example1_tb_cfg_rtl of example1_tb is


for tb
for dut : example1
use entity work.example1(rtl);
end for;
end for;

Revision : 1.1 Page 6 of 8 Dr DC Hendry


Libraries and Packages

end example1_tb_cfg_rtl;

Note the use of the name example1 tb cfg rtl, it is intended to make the
relationship to the testbench example1 tb very clear. Use of such naming con-
ventions is all but essential for large designs. The <entity name> in this case
is example1 tb. The single block configuration is the text:

for tb
..
end for;

and indicates that this block (and since it is the outermost block, the entire con-
figuration) applies to the architecture called tb of the design unit example1 tb.
If you examine the source code of the example1 tb testbench you will find that
the testbench architecture is called tb, the relevant line of code is:

architecture tb of example1 tb is

Within the block configuration we then have optionally a use clause, followed
by one or more <configuration items>. A configuration item is very similar
to a block configuration item, it can in fact be a block configuration, but can
also be a component configuration.

In the example above the component configuration is the text:

for dut : example1


use entity work.example1(rtl);
end for;

and in this case states that for the example1 component with instantiation label
dut, the architecture rtl of the design example1 in the library work should be
used.

Here is a second example, this time for the netlist simulation of example1:

library tsmc018;

configuration example1_tb_cfg_net of example1_tb is

for tb
for dut : example1
use entity work.example1(netlist);

Revision : 1.1 Page 7 of 8 Dr DC Hendry


Libraries and Packages

for netlist
use tsmc018.all;
end for;
end for;
end for;

end example1_tb_cfg_net;

Note how tsmc018 is first declared as a library. In addition to stating that


the component dut should be instantiated with the netlist architecture of
example1, that netlist, using a block configuration, is given access to all objects
in the library tsmc018.

Revision : 1.1 Page 8 of 8 Dr DC Hendry